<commit_before>package main

import (
	"bytes"
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	"github.com/flynn/go-crypto-ssh"
	"github.com/flynn/go-shlex"
)

const PrereceiveHook = `#!/bin/bash
set -eo pipefail; while read oldrev newrev refname; do
[[ $refname = "refs/heads/master" ]] && git archive $newrev | {{RECEIVER}} "$RECEIVE_USER" "$RECEIVE_REPO" "$RECEIVE_KEYNAME" "$RECEIVE_FINGERPRINT" | sed -$([[ $(uname) == "Darwin" ]] && echo l || echo u) "s/^/"$'\e[1G'"/"
done
`

var port *string = flag.String("p", "22", "port to listen on")
var repoPath *string = flag.String("r", "/tmp/repos", "path to repo cache")
var keyPath *string = flag.String("k", "/tmp/keys", "path to named keys")
var noAuth *bool = flag.Bool("n", false, "no client authentication")

var receiver string
var privateKey string
var keyNames = make(map[string]string)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage:  %v [options] <privatekey> <receiver>\n\n", os.Args[0])
		flag.PrintDefaults()
	}
}

func main() {
	flag.Parse()
	if len(os.Args) < 2 {
		flag.Usage()
		return
	}
	privateKey = flag.Arg(0)
	receiver = flag.Arg(1)

	var config *ssh.ServerConfig
	if *noAuth {
		config = &ssh.ServerConfig{NoClientAuth: true}
	} else {
		config = &ssh.ServerConfig{PublicKeyCallback: keyCallback}
	}

	pemBytes, err := ioutil.ReadFile(privateKey)
	if err != nil {
		log.Fatal("Failed to load private key:", err)
	}
	if err = config.SetRSAPrivateKey(pemBytes); err != nil {
		log.Fatal("Failed to parse private key:", err)
	}

	listener, err := ssh.Listen("tcp", "0.0.0.0:"+*port, config)
	if err != nil {
		log.Fatal("failed to listen for connection")
	}
	for {
		// SSH connections just house multiplexed connections
		conn, err := listener.Accept()
		if err != nil {
			log.Println("failed to accept incoming connection:", err)
			continue
		}
		if err := conn.Handshake(); err != nil {
			log.Println("failed to handshake:", err)
			continue
		}
		go handleConnection(conn)
	}
}

func keyCallback(conn *ssh.ServerConn, user, algo string, pubkey []byte) bool {
	clientkey, _, ok := ssh.ParsePublicKey(pubkey)
	if !ok {
		return false
	}
	os.MkdirAll(*keyPath, 0755)
	files, err := ioutil.ReadDir(*keyPath)
	if err != nil {
		panic(err)
	}
	for _, file := range files {
		if !file.IsDir() {
			data, err := ioutil.ReadFile(*keyPath + "/" + file.Name())
			if err != nil {
				panic(err)
			}
			filekey, _, _, _, ok := ssh.ParseAuthorizedKey(data)
			if !ok {
				continue
			}
			if bytes.Equal(clientkey.Marshal(), filekey.Marshal()) {
				keyNames[publicKeyFingerprint(clientkey)] = file.Name()
				return true
			}
		}
	}
	return false
}

func handleConnection(conn *ssh.ServerConn) {
	defer conn.Close()
	for {
		// Accept reads from the connection, demultiplexes packets
		// to their corresponding channels and returns when a new
		// channel request is seen. Some goroutine must always be
		// calling Accept; otherwise no messages will be forwarded
		// to the channels.
		ch, err := conn.Accept()
		if err == io.EOF {
			return
		}
		if err != nil {
			log.Println("handleConnection Accept:", err)
			break
		}
		if ch.ChannelType() != "session" {
			ch.Reject(ssh.UnknownChannelType, "unknown channel type")
			break
		}
		go handleChannel(conn, ch)
	}
}

func handleChannel(conn *ssh.ServerConn, ch ssh.Channel) {
	err := ch.Accept()
	if err != nil {
		panic(err)
	}
	defer ch.Close()
	for {
		req, err := ch.ReadRequest()
		if err == io.EOF {
			return
		}
		if err != nil {
			log.Println("handleChannel read request err:", err)
			continue
		}
		switch req.Request {
		case "exec":
			if req.WantReply {
				ch.AckRequest(true)
			}
			cmdline := string(req.Payload[4:])
			cmdargs, err := shlex.Split(cmdline)
			if err != nil {
				panic(err)
			}
			if strings.HasPrefix(cmdargs[1], "/") {
				cmdargs[1] = cmdargs[1][1:]
			}
			ensureCacheRepo(cmdargs[1])
			var keyname, fingerprint string
			if *noAuth {
				fingerprint = ""
				keyname = ""
			} else {
				fingerprint = publicKeyFingerprint(conn.PublicKey)
				keyname = keyNames[fingerprint]
			}
			cmd := exec.Command("git-shell", "-c", cmdargs[0]+" '"+cmdargs[1]+"'")
			cmd.Dir = *repoPath
			cmd.Env = []string{
				"RECEIVE_USER=" + conn.User,
				"RECEIVE_REPO=" + cmdargs[1],
				"RECEIVE_KEYNAME=" + keyname,
				"RECEIVE_FINGERPRINT=" + fingerprint,
			}
			errCh := attachCmd(cmd, ch, ch.Stderr(), ch)
			err = cmd.Start()
			if err != nil {
				panic(err)
			}
			exitCh := exitStatusCh(cmd)
			if err = <-errCh; err != nil {
				panic(err)
			}
			ch.Exit(<-exitCh)
		case "env":
			if req.WantReply {
				ch.AckRequest(true)
			}
		}
	}
}

func attachCmd(cmd *exec.Cmd, stdout, stderr io.Writer, stdin io.Reader) chan error {
	errCh := make(chan error)

	stdinIn, err := cmd.StdinPipe()
	if err != nil {
		panic(err)
	}
	stdoutOut, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}
	stderrOut, err := cmd.StderrPipe()
	if err != nil {
		panic(err)
	}

	go func() {
		_, e := io.Copy(stdinIn, stdin)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stdout, stdoutOut)
		errCh <- e
	}()
	go func() {
		_, e := io.Copy(stderr, stderrOut)
		errCh <- e
	}()

	return errCh
}

func exitStatusCh(cmd *exec.Cmd) chan uint {
	exitCh := make(chan uint)
	go func() {
		err := cmd.Wait()
		if err != nil {
			if exiterr, ok := err.(*exec.ExitError); ok {
				// There is no platform independent way to retrieve
				// the exit code, but the following will work on Unix
				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
					exitCh <- uint(status.ExitStatus())
				}
			} else {
				panic(err)
			}
			return
		}
		exitCh <- uint(0)
	}()
	return exitCh
}

var cacheMtx sync.Mutex

func ensureCacheRepo(path string) {
	cacheMtx.Lock()
	defer cacheMtx.Unlock()

	cachePath := *repoPath + "/" + path
	if _, err := os.Stat(cachePath); os.IsNotExist(err) {
		os.MkdirAll(cachePath, 0755)
		cmd := exec.Command("git", "init", "--bare")
		cmd.Dir = cachePath
		err = cmd.Run()
		if err != nil {
			panic(err)
		}
	}
	receiver, err := filepath.Abs(receiver)
	if err != nil {
		panic(err)
	}
	ioutil.WriteFile(
		cachePath+"/hooks/pre-receive",
		[]byte(strings.Replace(PrereceiveHook, "{{RECEIVER}}", receiver, 1)),
		0755)
}

func publicKeyFingerprint(key ssh.PublicKey) string {
	var values []string
	h := md5.New()
	h.Write(ssh.MarshalPublicKey(key))
	for _, value := range h.Sum(nil) {
		values = append(values, fmt.Sprintf("%x", value))
	}
	return strings.Join(values, ":")
}
<commit_msg>Refactor attach/exit handling<commit_after>package main

import (
	"bytes"
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
	"syscall"

	"github.com/flynn/go-crypto-ssh"
	"github.com/flynn/go-shlex"
)

const PrereceiveHook = `#!/bin/bash
set -eo pipefail; while read oldrev newrev refname; do
[[ $refname = "refs/heads/master" ]] && git archive $newrev | {{RECEIVER}} "$RECEIVE_USER" "$RECEIVE_REPO" "$RECEIVE_KEYNAME" "$RECEIVE_FINGERPRINT" | sed -$([[ $(uname) == "Darwin" ]] && echo l || echo u) "s/^/"$'\e[1G'"/"
done
`

var port *string = flag.String("p", "22", "port to listen on")
var repoPath *string = flag.String("r", "/tmp/repos", "path to repo cache")
var keyPath *string = flag.String("k", "/tmp/keys", "path to named keys")
var noAuth *bool = flag.Bool("n", false, "no client authentication")

var receiver string
var privateKey string
var keyNames = make(map[string]string)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage:  %v [options] <privatekey> <receiver>\n\n", os.Args[0])
		flag.PrintDefaults()
	}
}

func main() {
	flag.Parse()
	if len(os.Args) < 2 {
		flag.Usage()
		return
	}
	privateKey = flag.Arg(0)
	receiver = flag.Arg(1)

	var config *ssh.ServerConfig
	if *noAuth {
		config = &ssh.ServerConfig{NoClientAuth: true}
	} else {
		config = &ssh.ServerConfig{PublicKeyCallback: keyCallback}
	}

	pemBytes, err := ioutil.ReadFile(privateKey)
	if err != nil {
		log.Fatal("Failed to load private key:", err)
	}
	if err = config.SetRSAPrivateKey(pemBytes); err != nil {
		log.Fatal("Failed to parse private key:", err)
	}

	listener, err := ssh.Listen("tcp", "0.0.0.0:"+*port, config)
	if err != nil {
		log.Fatal("failed to listen for connection")
	}
	for {
		// SSH connections just house multiplexed connections
		conn, err := listener.Accept()
		if err != nil {
			log.Println("failed to accept incoming connection:", err)
			continue
		}
		if err := conn.Handshake(); err != nil {
			log.Println("failed to handshake:", err)
			continue
		}
		go handleConnection(conn)
	}
}

func keyCallback(conn *ssh.ServerConn, user, algo string, pubkey []byte) bool {
	clientkey, _, ok := ssh.ParsePublicKey(pubkey)
	if !ok {
		return false
	}
	os.MkdirAll(*keyPath, 0755)
	files, err := ioutil.ReadDir(*keyPath)
	if err != nil {
		panic(err)
	}
	for _, file := range files {
		if !file.IsDir() {
			data, err := ioutil.ReadFile(*keyPath + "/" + file.Name())
			if err != nil {
				panic(err)
			}
			filekey, _, _, _, ok := ssh.ParseAuthorizedKey(data)
			if !ok {
				continue
			}
			if bytes.Equal(clientkey.Marshal(), filekey.Marshal()) {
				keyNames[publicKeyFingerprint(clientkey)] = file.Name()
				return true
			}
		}
	}
	return false
}

func handleConnection(conn *ssh.ServerConn) {
	defer conn.Close()
	for {
		// Accept reads from the connection, demultiplexes packets
		// to their corresponding channels and returns when a new
		// channel request is seen. Some goroutine must always be
		// calling Accept; otherwise no messages will be forwarded
		// to the channels.
		ch, err := conn.Accept()
		if err == io.EOF {
			return
		}
		if err != nil {
			log.Println("handleConnection Accept:", err)
			break
		}
		if ch.ChannelType() != "session" {
			ch.Reject(ssh.UnknownChannelType, "unknown channel type")
			break
		}
		go handleChannel(conn, ch)
	}
}

func handleChannel(conn *ssh.ServerConn, ch ssh.Channel) {
	err := ch.Accept()
	if err != nil {
		panic(err)
	}
	defer ch.Close()
	for {
		req, err := ch.ReadRequest()
		if err == io.EOF {
			return
		}
		if err != nil {
			log.Println("handleChannel read request err:", err)
			continue
		}
		switch req.Request {
		case "exec":
			if req.WantReply {
				ch.AckRequest(true)
			}
			cmdline := string(req.Payload[4:])
			cmdargs, err := shlex.Split(cmdline)
			if err != nil {
				panic(err)
			}
			if strings.HasPrefix(cmdargs[1], "/") {
				cmdargs[1] = cmdargs[1][1:]
			}
			ensureCacheRepo(cmdargs[1])
			var keyname, fingerprint string
			if *noAuth {
				fingerprint = ""
				keyname = ""
			} else {
				fingerprint = publicKeyFingerprint(conn.PublicKey)
				keyname = keyNames[fingerprint]
			}
			cmd := exec.Command("git-shell", "-c", cmdargs[0]+" '"+cmdargs[1]+"'")
			cmd.Dir = *repoPath
			cmd.Env = []string{
				"RECEIVE_USER=" + conn.User,
				"RECEIVE_REPO=" + cmdargs[1],
				"RECEIVE_KEYNAME=" + keyname,
				"RECEIVE_FINGERPRINT=" + fingerprint,
			}
			done, err := attachCmd(cmd, ch, ch.Stderr(), ch)
			if err != nil {
				panic(err)
			}
			err = cmd.Start()
			if err != nil {
				panic(err)
			}
			done.Wait()
			status, err := exitStatus(cmd)
			if err != nil {
				panic(err)
			}
			ch.Exit(uint(status))
		case "env":
			if req.WantReply {
				ch.AckRequest(true)
			}
		}
	}
}

func attachCmd(cmd *exec.Cmd, stdout, stderr io.Writer, stdin io.Reader) (*sync.WaitGroup, error) {
	var wg sync.WaitGroup
	wg.Add(2)

	stdinIn, err := cmd.StdinPipe()
	if err != nil {
		return nil, err
	}
	stdoutOut, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stderrOut, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}

	go func() {
		io.Copy(stdinIn, stdin)
		stdinIn.Close()
	}()
	go func() {
		io.Copy(stdout, stdoutOut)
		wg.Done()
	}()
	go func() {
		io.Copy(stderr, stderrOut)
		wg.Done()
	}()

	return &wg, nil
}

func exitStatus(cmd *exec.Cmd) (int, error) {
	err := cmd.Wait()
	if err != nil {
		if exiterr, ok := err.(*exec.ExitError); ok {
			// There is no platform independent way to retrieve
			// the exit code, but the following will work on Unix
			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
				return status.ExitStatus(), nil
			}
		}
		return 0, err
	}
	return 0, nil
}

var cacheMtx sync.Mutex

func ensureCacheRepo(path string) {
	cacheMtx.Lock()
	defer cacheMtx.Unlock()

	cachePath := *repoPath + "/" + path
	if _, err := os.Stat(cachePath); os.IsNotExist(err) {
		os.MkdirAll(cachePath, 0755)
		cmd := exec.Command("git", "init", "--bare")
		cmd.Dir = cachePath
		err = cmd.Run()
		if err != nil {
			panic(err)
		}
	}
	receiver, err := filepath.Abs(receiver)
	if err != nil {
		panic(err)
	}
	ioutil.WriteFile(
		cachePath+"/hooks/pre-receive",
		[]byte(strings.Replace(PrereceiveHook, "{{RECEIVER}}", receiver, 1)),
		0755)
}

func publicKeyFingerprint(key ssh.PublicKey) string {
	var values []string
	h := md5.New()
	h.Write(ssh.MarshalPublicKey(key))
	for _, value := range h.Sum(nil) {
		values = append(values, fmt.Sprintf("%x", value))
	}
	return strings.Join(values, ":")
}
<|endoftext|>


<commit_before>package processor_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/nanobox-io/nanobox/processor"
	_ "github.com/nanobox-io/nanobox/processor/code"
	_ "github.com/nanobox-io/nanobox/processor/platform"
	_ "github.com/nanobox-io/nanobox/processor/provider"
	_ "github.com/nanobox-io/nanobox/processor/service"
)

type testProcessor struct {
	run bool
}

func TestMain(m *testing.M) {
	err := os.Chdir("../testing/")
	if err != nil {
		fmt.Println(err)
		return
	}
	processor.DefaultConfig.Force = true
	processor.DefaultConfig.Quiet = true
	// for testing we dont want to drop into a console
	// or hang on mist logging
	processor.Register("dev_console", testProcessBuilder)
	processor.Register("mist_log", testProcessBuilder)
	os.Exit(m.Run())
}

func (self testProcessor) Process() error {
	self.run = true
	return nil
}

func (self testProcessor) Results() processor.ProcessControl {
	return processor.ProcessControl{}
}

func testProcessBuilder(p processor.ProcessControl) (processor.Processor, error) {
	return testProcessor{}, nil
}

func TestRegister(t *testing.T) {
	processor.Register("test", testProcessBuilder)
	err := processor.Run("test", processor.DefaultConfig)
	if err != nil {
		t.Errorf("error from processor run", err)
	}
}

func TestBuild(t *testing.T) {
	err := processor.Run("build", processor.DefaultConfig)
	if err != nil {
		t.Errorf("error from build run", err)
	}
}

func TestDevDeploy(t *testing.T) {
	err := processor.Run("dev", processor.DefaultConfig)
	if err != nil {
		t.Errorf("error from dev run", err)
	}
}

// func TestDevDestroy(t *testing.T) {
// 	err := processor.Run("dev_destroy", processor.DefaultConfig)
// 	if err != nil {
// 		t.Errorf("error from build run", err)
// 	}
// }
<commit_msg>show the stack dump<commit_after>package processor_test

import (
	"fmt"
	"os"
	"testing"

	"github.com/nanobox-io/nanobox/processor"
	_ "github.com/nanobox-io/nanobox/processor/code"
	_ "github.com/nanobox-io/nanobox/processor/platform"
	_ "github.com/nanobox-io/nanobox/processor/provider"
	_ "github.com/nanobox-io/nanobox/processor/service"
)

type testProcessor struct {
	run bool
}

func TestMain(m *testing.M) {
	err := os.Chdir("../testing/")
	if err != nil {
		fmt.Println(err)
		return
	}
	processor.DefaultConfig.Force = true
	processor.DefaultConfig.Quiet = true
	// for testing we dont want to drop into a console
	// or hang on mist logging
	processor.Register("dev_console", testProcessBuilder)
	processor.Register("mist_log", testProcessBuilder)
	os.Exit(m.Run())
}

func (self testProcessor) Process() error {
	self.run = true
	return nil
}

func (self testProcessor) Results() processor.ProcessControl {
	return processor.ProcessControl{}
}

func testProcessBuilder(p processor.ProcessControl) (processor.Processor, error) {
	return testProcessor{}, nil
}

func TestRegister(t *testing.T) {
	processor.Register("test", testProcessBuilder)
	err := processor.Run("test", processor.DefaultConfig)
	if err != nil {
		t.Errorf("error from processor run", err)
	}
}

func TestBuild(t *testing.T) {
	err := processor.Run("build", processor.DefaultConfig)
	if err != nil {
		panic(err)
		t.Errorf("error from build run", err)
	}
}

func TestDevDeploy(t *testing.T) {
	err := processor.Run("dev", processor.DefaultConfig)
	if err != nil {
		panic(err)
		t.Errorf("error from dev run", err)
	}
}

// func TestDevDestroy(t *testing.T) {
// 	err := processor.Run("dev_destroy", processor.DefaultConfig)
// 	if err != nil {
// 		t.Errorf("error from build run", err)
// 	}
// }
<|endoftext|>


<commit_before>package main

// TODO
// error handling and dns errors should be displayed

import (
	"net"
	"dns"
	"dns/resolver"
	"os"
	"flag"
	"fmt"
	"strings"
)

func main() {
	var dnssec *bool = flag.Bool("dnssec", false, "Set the DO (DNSSEC OK) bit and set the bufsize to 4096")
	var port *string = flag.String("port", "53", "Set the query port")
	var aa *bool = flag.Bool("aa", false, "Set AA flag in query")
	var ad *bool = flag.Bool("ad", false, "Set AD flag in query")
	var cd *bool = flag.Bool("cd", false, "Set CD flag in query")
	var rd *bool = flag.Bool("rd", true, "Unset RD flag in query")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	nameserver := "@127.0.0.1"      // Default nameserver
	qtype := uint16(dns.TypeA)      // Default qtype
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

FLAGS:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue FLAGS
		}
		// If it looks like a class, it is a class
		for k, v := range dns.Class_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qclass = k
				continue FLAGS
			}
		}
		// And if it looks like type, it is a type
		for k, v := range dns.Rr_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qtype = k
				continue FLAGS
			}
		}
		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	r := new(resolver.Resolver)
	r.Timeout = 2
	r.Port = *port
	r.Attempts = 1

	qr := resolver.NewQuerier(r)
	// @server may be a name, resolv that
	var err os.Error
	nameserver = string([]byte(nameserver)[1:]) // chop off @
	_, addr, err := net.LookupHost(nameserver)
	if err == nil {
		r.Servers = addr
	} else {
		r.Servers = []string{nameserver}
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec {
		opt := new(dns.RR_OPT)
		opt.Hdr = dns.RR_Header{Name: "", Rrtype: dns.TypeOPT}
		opt.Version(0, true)
		opt.DoBit(true, true)
		opt.UDPSize(4096, true)
		m.Extra = make([]dns.RR, 1)
		m.Extra[0] = opt
	}
	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		qr <- resolver.DnsMsg{m, nil}
		in := <-qr
		if in.Dns != nil {
			fmt.Printf("%v\n", in.Dns)
		}
	}
	qr <- resolver.DnsMsg{nil, nil}
	<-qr
}
<commit_msg>finish q.go<commit_after>package main
// a (simple) dig-like query tool in 99 lines of Go
import (
	"net"
	"dns"
	"dns/resolver"
	"os"
	"flag"
	"fmt"
	"strings"
)

func main() {
	var dnssec *bool = flag.Bool("dnssec", false, "Set DO flag; set bufsize to 4096")
	var port *string = flag.String("port", "53", "Set the query port")
	var aa *bool = flag.Bool("aa", false, "Set AA flag in query")
	var ad *bool = flag.Bool("ad", false, "Set AD flag in query")
	var cd *bool = flag.Bool("cd", false, "Set CD flag in query")
	var rd *bool = flag.Bool("rd", true, "Unset RD flag in query")
	var tcp *bool = flag.Bool("tcp", false, "TCP mode")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	nameserver := "@127.0.0.1"      // Default nameserver
	qtype := uint16(dns.TypeA)      // Default qtype
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

FLAGS:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue FLAGS
		}
		// If it looks like a class, it is a class
		for k, v := range dns.Class_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qclass = k
				continue FLAGS
			}
		}
		// And if it looks like type, it is a type
		for k, v := range dns.Rr_str {
			if v == strings.ToUpper(flag.Arg(i)) {
				qtype = k
				continue FLAGS
			}
		}
		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	r := new(resolver.Resolver)
	r.Timeout = 2
	r.Port = *port
	r.Tcp = *tcp
	r.Attempts = 1

	qr := resolver.NewQuerier(r)
	// @server may be a name, resolv that
	var err os.Error
	nameserver = string([]byte(nameserver)[1:]) // chop off @
	_, addr, err := net.LookupHost(nameserver)
	if err == nil {
		r.Servers = addr
	} else {
		r.Servers = []string{nameserver}
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec {
		opt := new(dns.RR_OPT)
		opt.Hdr = dns.RR_Header{Name: "", Rrtype: dns.TypeOPT}
		opt.Version(0, true)
		opt.DoBit(true, true)
		opt.UDPSize(4096, true)
		m.Extra = make([]dns.RR, 1)
		m.Extra[0] = opt
	}
	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		qr <- resolver.DnsMsg{m, nil}
		in := <-qr
		if in.Dns != nil {
			fmt.Printf("%v\n", in.Dns)
		}
	}
	qr <- resolver.DnsMsg{nil, nil}
	<-qr
}
<|endoftext|>


<commit_before>package exec

import (
	"io/ioutil"
	"log"
	"fileutil"
	"os"
	"os/exec"
	"os/signal"
	"queue"
	"strconv"
	"strings"
	"syscall"
	"tee"
	"time"
)

/*
  Calculate the 'checksum' of a file and compare it to
	the '# Checksum' line.
	The main pourpose is to know when the file has been fully
	written to disk, so we can execute it without having a
	'text file busy' error
*/
func (be *BdsExec) checksum() bool {
	buff, err := ioutil.ReadFile(be.command);
	if err != nil {
		return false
	}

	// Find 'checksum' line position
	cmd := string(buff)
	idx := strings.Index(cmd, CHECKSUM_LINE_START)
	if idx < 0 {
		return false
	}
	idx-- // Don't include '\n' prior to line

	// Extract checksum value
	chsumStr := strings.TrimSpace(string(buff[idx+len(CHECKSUM_LINE_START):]))
	chsum, err := strconv.ParseInt(chsumStr, 16, 32)
	chsum32 := uint32(chsum);
	if err != nil {
		return false
	}

	// Checksum all bytes before 'idx'
	var sum uint32
	for i := 0 ; i < idx ; i++ {
		sum = sum * 33 + uint32(buff[i])
	}

	// Is checksum correct?
	if VERBOSE && (sum != chsum32) {
		log.Printf("WARNING: Checksum for file '%s' differs. Expected checksum %d, got %d\n", be.command, sum, chsum32)
	}

	return sum == chsum32
}

/*
  This function reads a 'shell' file created by Task.java
	(see Task.createProgramFile() method) and checks that the 'checksum'
	line at the end of the file matches the result. It waits for some
	predefined time until the line appears.
	The main purpose is to avoid 'text file busy' errors that are
	triggered by executing a shell file that is still begin written (or
	flushed) to the disk.
	Ideally we'd like to have some sort of 'lsof' command line
	functionality but it might be difficult to do it in a platform
	independent way.
*/
func (be *BdsExec) checksumWait() bool {
	if be.noCheckSum {
		return true
	}
	for i := 0 ; i < MAX_CHECKSUM_ITERS ; i++ {
			if DEBUG {
				log.Printf("Debug checksumWait (iteration %d): '%s'\n", i, be.command)
			}
		 	if be.checksum() {
				return true
			}
			time.Sleep(CHECKSUM_SLEEP_TIME) // Sleep for a while
		}
	return false
}

/*
	Execute a command and writing exit status to 'exitCode' channel
*/
func execute(cmd *exec.Cmd, exitCode chan string) {
	if DEBUG {
		log.Printf("Debug execute: Start\n")
	}

	// Wait for command to finish
	if err := cmd.Wait(); err != nil {
		if DEBUG {
			log.Printf("Debug execute: Failed (%s)\n", err)
		}

		exitCode <- err.Error()
		return
	}

	if DEBUG {
		log.Printf("Debug execute: Finished OK\n")
	}

	exitCode <- "0"
}

/*
	Execute a command (using arguments 'args')
	Redirect stdout to outFile    (unless file name is empty)
	Redirect stderr to errFile    (unless file name is empty)
	Write exit code to exitFile   (unless file name is empty)
	Timeout after timeout seconds (unless time is zero)
*/
func (be *BdsExec) executeCommand() int {
	var err error
	if DEBUG {
		log.Printf("Debug executeCommand: %v (len: %d)\n", be.cmdargs, len(be.cmdargs))
	}

	// Redirect all signals to channel (e.g. Ctrl-C)
	osSignal := make(chan os.Signal)

	if be.taskLoggerFile != "" {
		// Main bds program
		signal.Notify(osSignal) // Capture all signals
	} else {
		if !be.checksumWait() {
			log.Printf("Error: Error trying to checksum file '%s'", be.command)
		}

		// Set a new process group.
		// We want to be able to kill all child processes, without killing the
		// calling program. E.g. When running using a local executor, the Java Bds
		// calls 'bds exec', so sending a kill to the group when a timeOut occurs,
		// would also kill the parent Java program and kill the whole bds execution
		// (clearly not what we want).
		// To avoid this, we create a new group thus we can send a kill signal to
		// this new process group.

		gpidOri, _ :=  syscall.Getpgid(0);
		if err := syscall.Setpgid(0, 0); err != nil {
			// During an ssh remote execution we will no be albe to do this.
			// In this case, we assume that the SSH daemon will catch the sinals
			// and kill al child processes.
			if DEBUG {
				log.Printf("Error: Error setting process group: %s", err)
			}
		}

		if DEBUG {
			gpidNew, _ :=  syscall.Getpgid(0);
			log.Printf("Info: Setting new process group. Original GPID: %d, new GPID: %d\n", gpidOri, gpidNew)
		}
	}

	// Create command
	be.cmd = exec.Command(be.command)
	be.cmd.Args = be.cmdargs

	// Create queue channels (e.g. AWS SQS)
	var q *queue.Queue
	var stdoutCh, stderrCh chan []byte
	if be.awsSqsName != "" {
		q, err = queue.NewQueue(be.awsSqsName, be.taskId)
		if err != nil {
			log.Printf("Error: Creating queue '%v'\n", err)
			os.Exit(1)
		} else if DEBUG {
			log.Printf("Debug executeCommand: Created queue '%s'\n", be.awsSqsName)
		}
		stdoutCh, stderrCh = q.StdoutChan, q.StderrChan
	}

	// Copy stdout
	stdout := tee.NewTee(be.outFile, stdoutCh, false)
	defer stdout.Close()
	be.cmd.Stdout = stdout

	// Copy stderr
	stderr := tee.NewTee(be.errFile, stderrCh, true)
	defer stderr.Close()
	be.cmd.Stderr = stderr

	// Connect to stdin
	be.cmd.Stdin = os.Stdin

	// Start process
	err = be.cmd.Start()
	if err != nil {
		log.Fatal(err)
	}

	be.exitCode = be.executeCommandTimeout(osSignal, q)
	if DEBUG {
		log.Printf("Debug executeCommand: Exit code %d\n", be.exitCode)
	}

	return be.exitCode
}

/*
	Execute a command enforcing a timeout and writing exit status to 'exitFile'
*/
func (be *BdsExec) executeCommandTimeout(osSignal chan os.Signal, q *queue.Queue) int {
	if DEBUG {
		log.Printf("Debug executeCommandTimeout: Start\n")
	}

	// Wait for execution to finish or timeout
	exitStr := ""
	if be.timeSecs <= 0 {
		be.timeSecs = 31536000 // Default: One year
	}

	// Create a timeout process
	// References: http://blog.golang.org/2010/09/go-concurrency-patterns-timing-out-and.html
	exitCode := make(chan string, 1)
	go execute(be.cmd, exitCode)	// Run command
	if q != nil {
		go q.Transmit()	// Transmit stdout/stderr to Queue
	}

	// Wait until executions ends, timeout or OS signal
	run, kill := true, false
	for run {
		select {
			case exitStr = <-exitCode:
				run, kill = false, false
				if DEBUG {
					log.Printf("Debug executeCommandTimeout: Execution finished (%s)\n", exitStr)
				}

			case <-time.After(time.Duration(be.timeSecs) * time.Second):
				run, kill = false, true
				exitStr = "Time out"
				if DEBUG {
					log.Printf("Debug executeCommandTimeout: Timeout!\n")
				}

			case sig := <-osSignal:
				// Operating system signas (e.g. Ctrl-C)
				// Ignore some signals (e.g. "window changed")
				sigStr := sig.String()
				if sigStr != "window changed" && sigStr != "child exited" && sigStr != "window size changes" {
					if VERBOSE {
						log.Printf("bds: Received OS signal '%s'\n", sigStr)
					}

					run, kill = false, true
					exitStr = "Signal received"
				}
		}
	}

	// Write exitCode to file and to queue exit channel
	be.updateExitFile(exitStr)

	// Wait until all data has been sent to the queue
	if q != nil {
		q.Exit(exitStr)
		q.WaitFinish()
	}

	// Should we kill child process?
	if kill {
		// WARNING: The kill(0) signal will also kill this process, so nothing
		// may be execited after this call (platform dependent)
		be.kill()
	}

	// TODO: Wait for channels to close

	// Analyze exit code
	switch exitStr  {
		case "0":
			return EXITCODE_OK	// OK, exit value should be zero
		case "Time out":
			return EXITCODE_TIMEOUT	// Timeout exit code
		default:
			return EXITCODE_ERROR	// Other error conditions
	}
}

/*
	Write exit information to 'exitFile'
*/
func (be *BdsExec) updateExitFile(exitStr string) {
	if (be.exitFile != "") && (be.exitFile != "-") {
		if DEBUG {
			log.Printf("Debug updateExitFile: Writing exit status '%s' to exit file '%s'\n", exitStr, be.exitFile )
		}
		fileutil.WriteFile(be.exitFile, exitStr)
	}
}
<commit_msg>Project updated<commit_after>package exec

import (
	"io/ioutil"
	"log"
	"fileutil"
	"os"
	"os/exec"
	"os/signal"
	"queue"
	"strconv"
	"strings"
	"syscall"
	"tee"
	"time"
)

/*
  Calculate the 'checksum' of a file and compare it to
	the '# Checksum' line.
	The main pourpose is to know when the file has been fully
	written to disk, so we can execute it without having a
	'text file busy' error
*/
func (be *BdsExec) checksum() bool {
	buff, err := ioutil.ReadFile(be.command);
	if err != nil {
		return false
	}

	// Find 'checksum' line position
	cmd := string(buff)
	idx := strings.Index(cmd, CHECKSUM_LINE_START)
	if idx < 0 {
		return false
	}
	idx-- // Don't include '\n' prior to line

	// Extract checksum value
	chsumStr := strings.TrimSpace(string(buff[idx+len(CHECKSUM_LINE_START):]))
	chsum, err := strconv.ParseInt(chsumStr, 16, 32)
	chsum32 := uint32(chsum);
	if err != nil {
		return false
	}

	// Checksum all bytes before 'idx'
	var sum uint32
	for i := 0 ; i < idx ; i++ {
		sum = sum * 33 + uint32(buff[i])
	}

	// Is checksum correct?
	if VERBOSE && (sum != chsum32) {
		log.Printf("WARNING: Checksum for file '%s' differs. Expected checksum %d, got %d\n", be.command, sum, chsum32)
	}

	return sum == chsum32
}

/*
  This function reads a 'shell' file created by Task.java
	(see Task.createProgramFile() method) and checks that the 'checksum'
	line at the end of the file matches the result. It waits for some
	predefined time until the line appears.
	The main purpose is to avoid 'text file busy' errors that are
	triggered by executing a shell file that is still begin written (or
	flushed) to the disk.
	Ideally we'd like to have some sort of 'lsof' command line
	functionality but it might be difficult to do it in a platform
	independent way.
*/
func (be *BdsExec) checksumWait() bool {
	if be.noCheckSum {
		return true
	}
	for i := 0 ; i < MAX_CHECKSUM_ITERS ; i++ {
			if DEBUG {
				log.Printf("Debug checksumWait (iteration %d): '%s'\n", i, be.command)
			}
		 	if be.checksum() {
				return true
			}
			time.Sleep(CHECKSUM_SLEEP_TIME) // Sleep for a while
		}
	return false
}

/*
	Execute a command and writing exit status to 'exitCode' channel
*/
func execute(cmd *exec.Cmd, exitCode chan string) {
	if DEBUG {
		log.Printf("Debug execute: Start\n")
	}

	// Wait for command to finish
	if err := cmd.Wait(); err != nil {
		if DEBUG {
			log.Printf("Debug execute: Failed (%s)\n", err)
		}

		exitCode <- err.Error()
		return
	}

	if DEBUG {
		log.Printf("Debug execute: Finished OK\n")
	}

	exitCode <- "0"
}

/*
	Execute a command (using arguments 'args')
	Redirect stdout to outFile    (unless file name is empty)
	Redirect stderr to errFile    (unless file name is empty)
	Write exit code to exitFile   (unless file name is empty)
	Timeout after timeout seconds (unless time is zero)
*/
func (be *BdsExec) executeCommand() int {
	var err error
	if DEBUG {
		log.Printf("Debug executeCommand: %v (len: %d)\n", be.cmdargs, len(be.cmdargs))
	}

	// Redirect all signals to channel (e.g. Ctrl-C)
	osSignal := make(chan os.Signal)

	if be.taskLoggerFile != "" {
		// Main bds program
		signal.Notify(osSignal) // Capture all signals
	} else {
		if !be.checksumWait() && DEBUG {
			log.Printf("WARNING: Error trying to checksum file '%s'", be.command)
		}

		// Set a new process group.
		// We want to be able to kill all child processes, without killing the
		// calling program. E.g. When running using a local executor, the Java Bds
		// calls 'bds exec', so sending a kill to the group when a timeOut occurs,
		// would also kill the parent Java program and kill the whole bds execution
		// (clearly not what we want).
		// To avoid this, we create a new group thus we can send a kill signal to
		// this new process group.

		gpidOri, _ :=  syscall.Getpgid(0);
		if err := syscall.Setpgid(0, 0); err != nil {
			// During an ssh remote execution we will no be albe to do this.
			// In this case, we assume that the SSH daemon will catch the sinals
			// and kill al child processes.
			if DEBUG {
				log.Printf("Error: Error setting process group: %s", err)
			}
		}

		if DEBUG {
			gpidNew, _ :=  syscall.Getpgid(0);
			log.Printf("Info: Setting new process group. Original GPID: %d, new GPID: %d\n", gpidOri, gpidNew)
		}
	}

	// Create command
	be.cmd = exec.Command(be.command)
	be.cmd.Args = be.cmdargs

	// Create queue channels (e.g. AWS SQS)
	var q *queue.Queue
	var stdoutCh, stderrCh chan []byte
	if be.awsSqsName != "" {
		q, err = queue.NewQueue(be.awsSqsName, be.taskId)
		if err != nil {
			log.Printf("Error: Creating queue '%v'\n", err)
			os.Exit(1)
		} else if DEBUG {
			log.Printf("Debug executeCommand: Created queue '%s'\n", be.awsSqsName)
		}
		stdoutCh, stderrCh = q.StdoutChan, q.StderrChan
	}

	// Copy stdout
	stdout := tee.NewTee(be.outFile, stdoutCh, false)
	defer stdout.Close()
	be.cmd.Stdout = stdout

	// Copy stderr
	stderr := tee.NewTee(be.errFile, stderrCh, true)
	defer stderr.Close()
	be.cmd.Stderr = stderr

	// Connect to stdin
	be.cmd.Stdin = os.Stdin

	// Start process
	err = be.cmd.Start()
	if err != nil {
		log.Fatal(err)
	}

	be.exitCode = be.executeCommandTimeout(osSignal, q)
	if DEBUG {
		log.Printf("Debug executeCommand: Exit code %d\n", be.exitCode)
	}

	return be.exitCode
}

/*
	Execute a command enforcing a timeout and writing exit status to 'exitFile'
*/
func (be *BdsExec) executeCommandTimeout(osSignal chan os.Signal, q *queue.Queue) int {
	if DEBUG {
		log.Printf("Debug executeCommandTimeout: Start\n")
	}

	// Wait for execution to finish or timeout
	exitStr := ""
	if be.timeSecs <= 0 {
		be.timeSecs = 31536000 // Default: One year
	}

	// Create a timeout process
	// References: http://blog.golang.org/2010/09/go-concurrency-patterns-timing-out-and.html
	exitCode := make(chan string, 1)
	go execute(be.cmd, exitCode)	// Run command
	if q != nil {
		go q.Transmit()	// Transmit stdout/stderr to Queue
	}

	// Wait until executions ends, timeout or OS signal
	run, kill := true, false
	for run {
		select {
			case exitStr = <-exitCode:
				run, kill = false, false
				if DEBUG {
					log.Printf("Debug executeCommandTimeout: Execution finished (%s)\n", exitStr)
				}

			case <-time.After(time.Duration(be.timeSecs) * time.Second):
				run, kill = false, true
				exitStr = "Time out"
				if DEBUG {
					log.Printf("Debug executeCommandTimeout: Timeout!\n")
				}

			case sig := <-osSignal:
				// Operating system signas (e.g. Ctrl-C)
				// Ignore some signals (e.g. "window changed")
				sigStr := sig.String()
				if sigStr != "window changed" && sigStr != "child exited" && sigStr != "window size changes" {
					if VERBOSE {
						log.Printf("bds: Received OS signal '%s'\n", sigStr)
					}

					run, kill = false, true
					exitStr = "Signal received"
				}
		}
	}

	// Write exitCode to file and to queue exit channel
	be.updateExitFile(exitStr)

	// Wait until all data has been sent to the queue
	if q != nil {
		q.Exit(exitStr)
		q.WaitFinish()
	}

	// Should we kill child process?
	if kill {
		// WARNING: The kill(0) signal will also kill this process, so nothing
		// may be execited after this call (platform dependent)
		be.kill()
	}

	// TODO: Wait for channels to close

	// Analyze exit code
	switch exitStr  {
		case "0":
			return EXITCODE_OK	// OK, exit value should be zero
		case "Time out":
			return EXITCODE_TIMEOUT	// Timeout exit code
		default:
			return EXITCODE_ERROR	// Other error conditions
	}
}

/*
	Write exit information to 'exitFile'
*/
func (be *BdsExec) updateExitFile(exitStr string) {
	if (be.exitFile != "") && (be.exitFile != "-") {
		if DEBUG {
			log.Printf("Debug updateExitFile: Writing exit status '%s' to exit file '%s'\n", exitStr, be.exitFile )
		}
		fileutil.WriteFile(be.exitFile, exitStr)
	}
}
<|endoftext|>


<commit_before>package chat

import (
	"bytes"
	"io/ioutil"
	"strings"
	"testing"
)

func TestSignEncrypter(t *testing.T) {
	e := NewSignEncrypter()
	el := e.EncryptedLen(100)
	if el != 180 {
		t.Errorf("enc len: %d, expected 180", el)
	}

	el = e.EncryptedLen(50 * 1024 * 1024)
	if el != 52432880 {
		t.Errorf("enc len: %d, expected 52432880", el)
	}

	pt := "plain text"
	er, err := e.Encrypt(strings.NewReader(pt))
	if err != nil {
		t.Fatal(err)
	}
	ct, err := ioutil.ReadAll(er)
	if err != nil {
		t.Fatal(err)
	}

	if string(ct) == pt {
		t.Fatal("Encrypt did not change plaintext")
	}

	d := NewSignDecrypter()
	dr := d.Decrypt(bytes.NewReader(ct), e.EncryptKey(), e.VerifyKey())
	ptOut, err := ioutil.ReadAll(dr)
	if err != nil {
		t.Fatal(err)
	}
	if string(ptOut) != pt {
		t.Errorf("decrypted ciphertext doesn't match plaintext: %q, expected %q", ptOut, pt)
	}
}
<commit_msg>Test key reuse<commit_after>package chat

import (
	"bytes"
	"io/ioutil"
	"strings"
	"testing"
)

func TestSignEncrypter(t *testing.T) {
	e := NewSignEncrypter()
	el := e.EncryptedLen(100)
	if el != 180 {
		t.Errorf("enc len: %d, expected 180", el)
	}

	el = e.EncryptedLen(50 * 1024 * 1024)
	if el != 52432880 {
		t.Errorf("enc len: %d, expected 52432880", el)
	}

	pt := "plain text"
	er, err := e.Encrypt(strings.NewReader(pt))
	if err != nil {
		t.Fatal(err)
	}
	ct, err := ioutil.ReadAll(er)
	if err != nil {
		t.Fatal(err)
	}

	if string(ct) == pt {
		t.Fatal("Encrypt did not change plaintext")
	}

	d := NewSignDecrypter()
	dr := d.Decrypt(bytes.NewReader(ct), e.EncryptKey(), e.VerifyKey())
	ptOut, err := ioutil.ReadAll(dr)
	if err != nil {
		t.Fatal(err)
	}
	if string(ptOut) != pt {
		t.Errorf("decrypted ciphertext doesn't match plaintext: %q, expected %q", ptOut, pt)
	}

	// reuse e to do another Encrypt, make sure keys change:
	firstEncKey := e.EncryptKey()
	firstVerifyKey := e.VerifyKey()

	er2, err := e.Encrypt(strings.NewReader(pt))
	if err != nil {
		t.Fatal(err)
	}
	ct2, err := ioutil.ReadAll(er2)
	if err != nil {
		t.Fatal(err)
	}

	if string(ct2) == pt {
		t.Fatal("Encrypt did not change plaintext")
	}
	if bytes.Equal(ct, ct2) {
		t.Fatal("second Encrypt result same as first")
	}
	if bytes.Equal(firstEncKey, e.EncryptKey()) {
		t.Fatal("first enc key reused")
	}
	if bytes.Equal(firstVerifyKey, e.VerifyKey()) {
		t.Fatal("first verify key reused")
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	keybase1 "github.com/keybase/client/go/protocol"
)

type IdentifyState struct {
	res      *IdentifyOutcome
	u        *User
	track    *TrackLookup
	tmpTrack *TrackLookup
}

func NewIdentifyState(res *IdentifyOutcome, u *User) IdentifyState {
	if res == nil {
		res = NewIdentifyOutcomeWithUsername(u.GetName())
	}
	return IdentifyState{res: res, u: u}
}

func (s *IdentifyState) SetTrackLookup(t *TrackChainLink) {
	s.track = NewTrackLookup(t)
	if s.res != nil {
		s.res.TrackUsed = s.track
	}
}

func (s *IdentifyState) SetTmpTrackLookup(t *TrackChainLink) {
	s.tmpTrack = NewTrackLookup(t)
}

func (s *IdentifyState) TrackLookup() *TrackLookup {
	return s.track
}

func (s *IdentifyState) HasPreviousTrack() bool {
	return s.track != nil
}

func (s *IdentifyState) Result() *IdentifyOutcome {
	return s.res
}

func (s *IdentifyState) computeRevokedProofs() {
	if s.track == nil {
		return
	}

	found := s.res.TrackSet()
	tracked := s.track.set

	// These are the proofs that we previously tracked that we
	// didn't observe in the current profile
	diff := (*tracked).Subtract(*found)

	for _, e := range diff {
		// If the proofs in the difference are for GOOD proofs,
		// the we have a problem.  Mark the proof as "REVOKED"
		if e.GetProofState() == keybase1.ProofState_OK {
			s.res.Revoked = append(s.res.Revoked, TrackDiffRevoked{e})
			s.res.RevokedDetails = append(s.res.RevokedDetails, ExportTrackIDComponentToRevokedProof(e))
		}
	}
}

func (s *IdentifyState) initResultList() {
	idt := s.u.IDTable()
	if idt == nil {
		return
	}
	activeProofs := idt.remoteProofLinks.Active()
	s.res.ProofChecks = make([]*LinkCheckResult, len(activeProofs))
	for i, p := range activeProofs {
		s.res.ProofChecks[i] = &LinkCheckResult{link: p, trackedProofState: keybase1.ProofState_NONE, position: i}
	}
}

func (s *IdentifyState) computeTrackDiffs() {
	if s.track == nil {
		return
	}

	G.Log.Debug("| with tracking %v", s.track.set)
	for _, c := range s.res.ProofChecks {
		c.diff = c.link.ComputeTrackDiff(s.track)
		c.trackedProofState = s.track.GetProofState(c.link.ToIDString())
		if s.tmpTrack != nil {
			c.tmpTrackedProofState = s.tmpTrack.GetProofState(c.link.ToIDString())
			c.tmpTrackExpireTime = s.tmpTrack.GetTmpExpireTime()
		}
	}
}

func (s *IdentifyState) Precompute(dhook func(keybase1.IdentifyKey)) {
	s.computeKeyDiffs(dhook)
	s.initResultList()
	s.computeTrackDiffs()
	s.computeRevokedProofs()
}

func (s *IdentifyState) computeKeyDiffs(dhook func(keybase1.IdentifyKey)) {
	mapify := func(v []keybase1.KID) map[keybase1.KID]bool {
		ret := make(map[keybase1.KID]bool)
		for _, k := range v {
			ret[k] = true
		}
		return ret
	}

	display := func(kid keybase1.KID, diff TrackDiff) {
		k := keybase1.IdentifyKey{
			TrackDiff: ExportTrackDiff(diff),
		}
		k.KID = kid
		if fp, ok := s.u.GetKeyFamily().kid2pgp[kid]; ok {
			k.PGPFingerprint = fp[:]
		}
		// Anything other than a no difference here should be displayed to
		// the user.
		if diff != nil {
			k.BreaksTracking = diff.BreaksTracking()
		}
		dhook(k)
	}

	// first check the eldest key
	observedEldest := s.u.GetEldestKID()
	if s.track != nil {
		trackedEldest := s.track.GetEldestKID()
		if observedEldest.NotEqual(trackedEldest) {
			diff := TrackDiffNewEldest{tracked: trackedEldest, observed: observedEldest}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
			display(observedEldest, diff)
		}
	}

	found := s.u.GetActivePGPKIDs(true)
	foundMap := mapify(found)
	var tracked []keybase1.KID
	if s.track != nil {
		for _, trackedKey := range s.track.GetTrackedKeys() {
			tracked = append(tracked, trackedKey.KID)
		}
	}
	trackedMap := mapify(tracked)

	for _, kid := range found {
		var diff TrackDiff
		if s.track != nil && !trackedMap[kid] {
			diff = TrackDiffNew{}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
		} else if s.track != nil {
			diff = TrackDiffNone{}
		}
		display(kid, diff)
	}

	for _, kid := range tracked {
		if !foundMap[kid] {
			fp := s.u.GetKeyFamily().kid2pgp[kid]
			diff := TrackDiffRevoked{fp}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
			display(kid, diff)
		}
	}
}
<commit_msg>Include revoked keys in IdentifyOutcome<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	keybase1 "github.com/keybase/client/go/protocol"
)

type IdentifyState struct {
	res      *IdentifyOutcome
	u        *User
	track    *TrackLookup
	tmpTrack *TrackLookup
}

func NewIdentifyState(res *IdentifyOutcome, u *User) IdentifyState {
	if res == nil {
		res = NewIdentifyOutcomeWithUsername(u.GetName())
	}
	return IdentifyState{res: res, u: u}
}

func (s *IdentifyState) SetTrackLookup(t *TrackChainLink) {
	s.track = NewTrackLookup(t)
	if s.res != nil {
		s.res.TrackUsed = s.track
	}
}

func (s *IdentifyState) SetTmpTrackLookup(t *TrackChainLink) {
	s.tmpTrack = NewTrackLookup(t)
}

func (s *IdentifyState) TrackLookup() *TrackLookup {
	return s.track
}

func (s *IdentifyState) HasPreviousTrack() bool {
	return s.track != nil
}

func (s *IdentifyState) Result() *IdentifyOutcome {
	return s.res
}

func (s *IdentifyState) computeRevokedProofs() {
	if s.track == nil {
		return
	}

	found := s.res.TrackSet()
	tracked := s.track.set

	// These are the proofs that we previously tracked that we
	// didn't observe in the current profile
	diff := (*tracked).Subtract(*found)

	for _, e := range diff {
		// If the proofs in the difference are for GOOD proofs,
		// the we have a problem.  Mark the proof as "REVOKED"
		if e.GetProofState() == keybase1.ProofState_OK {
			s.res.Revoked = append(s.res.Revoked, TrackDiffRevoked{e})
			s.res.RevokedDetails = append(s.res.RevokedDetails, ExportTrackIDComponentToRevokedProof(e))
		}
	}
}

func (s *IdentifyState) initResultList() {
	idt := s.u.IDTable()
	if idt == nil {
		return
	}
	activeProofs := idt.remoteProofLinks.Active()
	s.res.ProofChecks = make([]*LinkCheckResult, len(activeProofs))
	for i, p := range activeProofs {
		s.res.ProofChecks[i] = &LinkCheckResult{link: p, trackedProofState: keybase1.ProofState_NONE, position: i}
	}
}

func (s *IdentifyState) computeTrackDiffs() {
	if s.track == nil {
		return
	}

	G.Log.Debug("| with tracking %v", s.track.set)
	for _, c := range s.res.ProofChecks {
		c.diff = c.link.ComputeTrackDiff(s.track)
		c.trackedProofState = s.track.GetProofState(c.link.ToIDString())
		if s.tmpTrack != nil {
			c.tmpTrackedProofState = s.tmpTrack.GetProofState(c.link.ToIDString())
			c.tmpTrackExpireTime = s.tmpTrack.GetTmpExpireTime()
		}
	}
}

func (s *IdentifyState) Precompute(dhook func(keybase1.IdentifyKey)) {
	s.computeKeyDiffs(dhook)
	s.initResultList()
	s.computeTrackDiffs()
	s.computeRevokedProofs()
}

func (s *IdentifyState) computeKeyDiffs(dhook func(keybase1.IdentifyKey)) {
	mapify := func(v []keybase1.KID) map[keybase1.KID]bool {
		ret := make(map[keybase1.KID]bool)
		for _, k := range v {
			ret[k] = true
		}
		return ret
	}

	display := func(kid keybase1.KID, diff TrackDiff) {
		k := keybase1.IdentifyKey{
			TrackDiff: ExportTrackDiff(diff),
		}
		k.KID = kid
		if fp, ok := s.u.GetKeyFamily().kid2pgp[kid]; ok {
			k.PGPFingerprint = fp[:]
		}
		// Anything other than a no difference here should be displayed to
		// the user.
		if diff != nil {
			k.BreaksTracking = diff.BreaksTracking()
		}
		dhook(k)
	}

	// first check the eldest key
	observedEldest := s.u.GetEldestKID()
	if s.track != nil {
		trackedEldest := s.track.GetEldestKID()
		if observedEldest.NotEqual(trackedEldest) {
			diff := TrackDiffNewEldest{tracked: trackedEldest, observed: observedEldest}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
			display(observedEldest, diff)
		}
	}

	found := s.u.GetActivePGPKIDs(true)
	foundMap := mapify(found)
	var tracked []keybase1.KID
	if s.track != nil {
		for _, trackedKey := range s.track.GetTrackedKeys() {
			tracked = append(tracked, trackedKey.KID)
		}
	}
	trackedMap := mapify(tracked)

	for _, kid := range found {
		var diff TrackDiff
		if s.track != nil && !trackedMap[kid] {
			diff = TrackDiffNew{}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
		} else if s.track != nil {
			diff = TrackDiffNone{}
		}
		display(kid, diff)
	}

	for _, kid := range tracked {
		if !foundMap[kid] {
			fp := s.u.GetKeyFamily().kid2pgp[kid]
			diff := TrackDiffRevoked{fp}
			s.res.KeyDiffs = append(s.res.KeyDiffs, diff)
			// the identify outcome should know that this
			// key was revoked, as well as there being
			// a KeyDiff:
			s.res.Revoked = append(s.res.Revoked, diff)
			display(kid, diff)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package redirect provides hooks to register HTTP handlers that redirect old
// godoc paths to their new equivalents and assist in accessing the issue
// tracker, wiki, code review system, etc.
package redirect

import (
	"net/http"
	"regexp"
)

// Register registers HTTP handlers that redirect old godoc paths to their new
// equivalents and assist in accessing the issue tracker, wiki, code review
// system, etc. If mux is nil it uses http.DefaultServeMux.
func Register(mux *http.ServeMux) {
	if mux == nil {
		mux = http.DefaultServeMux
	}
	handlePathRedirects(mux, pkgRedirects, "/pkg/")
	handlePathRedirects(mux, cmdRedirects, "/cmd/")
	for prefix, redirect := range prefixHelpers {
		p := "/" + prefix + "/"
		mux.Handle(p, PrefixHandler(p, redirect))
	}
	for path, redirect := range redirects {
		mux.Handle(path, Handler(redirect))
	}
}

func handlePathRedirects(mux *http.ServeMux, redirects map[string]string, prefix string) {
	for source, target := range redirects {
		h := Handler(prefix + target + "/")
		p := prefix + source
		mux.Handle(p, h)
		mux.Handle(p+"/", h)
	}
}

// Packages that were renamed between r60 and go1.
var pkgRedirects = map[string]string{
	"asn1":              "encoding/asn1",
	"big":               "math/big",
	"cmath":             "math/cmplx",
	"csv":               "encoding/csv",
	"exec":              "os/exec",
	"exp/template/html": "html/template",
	"gob":               "encoding/gob",
	"http":              "net/http",
	"http/cgi":          "net/http/cgi",
	"http/fcgi":         "net/http/fcgi",
	"http/httptest":     "net/http/httptest",
	"http/pprof":        "net/http/pprof",
	"json":              "encoding/json",
	"mail":              "net/mail",
	"rand":              "math/rand",
	"rpc":               "net/rpc",
	"rpc/jsonrpc":       "net/rpc/jsonrpc",
	"scanner":           "text/scanner",
	"smtp":              "net/smtp",
	"tabwriter":         "text/tabwriter",
	"template":          "text/template",
	"template/parse":    "text/template/parse",
	"url":               "net/url",
	"utf16":             "unicode/utf16",
	"utf8":              "unicode/utf8",
	"xml":               "encoding/xml",
}

// Commands that were renamed between r60 and go1.
var cmdRedirects = map[string]string{
	"gofix":     "fix",
	"goinstall": "go",
	"gopack":    "pack",
	"gotest":    "go",
	"govet":     "vet",
	"goyacc":    "yacc",
}

var redirects = map[string]string{
	"/blog":       "/blog/",
	"/build":      "http://build.golang.org",
	"/change":     "https://code.google.com/p/go/source/list",
	"/cl":         "https://gocodereview.appspot.com/",
	"/cmd/godoc/": "http://godoc.org/code.google.com/p/go.tools/cmd/godoc/",
	"/cmd/vet/":   "http://godoc.org/code.google.com/p/go.tools/cmd/vet/",
	"/issue":      "https://code.google.com/p/go/issues",
	"/issue/new":  "https://code.google.com/p/go/issues/entry",
	"/issues":     "https://code.google.com/p/go/issues",
	"/play":       "http://play.golang.org",

	// In Go 1.2 the references page is part of /doc/.
	"/ref": "/doc/#references",
	// This next rule clobbers /ref/spec and /ref/mem.
	// TODO(adg): figure out what to do here, if anything.
	// "/ref/": "/doc/#references",

	// Be nice to people who are looking in the wrong place.
	"/doc/mem":  "/ref/mem",
	"/doc/spec": "/ref/spec",

	"/talks": "http://talks.golang.org",
	"/tour":  "http://tour.golang.org",
	"/wiki":  "https://code.google.com/p/go-wiki/w/list",

	"/doc/articles/c_go_cgo.html":                    "/blog/c-go-cgo",
	"/doc/articles/concurrency_patterns.html":        "/blog/go-concurrency-patterns-timing-out-and",
	"/doc/articles/defer_panic_recover.html":         "/blog/defer-panic-and-recover",
	"/doc/articles/error_handling.html":              "/blog/error-handling-and-go",
	"/doc/articles/gobs_of_data.html":                "/blog/gobs-of-data",
	"/doc/articles/godoc_documenting_go_code.html":   "/blog/godoc-documenting-go-code",
	"/doc/articles/gos_declaration_syntax.html":      "/blog/gos-declaration-syntax",
	"/doc/articles/image_draw.html":                  "/blog/go-imagedraw-package",
	"/doc/articles/image_package.html":               "/blog/go-image-package",
	"/doc/articles/json_and_go.html":                 "/blog/json-and-go",
	"/doc/articles/json_rpc_tale_of_interfaces.html": "/blog/json-rpc-tale-of-interfaces",
	"/doc/articles/laws_of_reflection.html":          "/blog/laws-of-reflection",
	"/doc/articles/race_detector.html":               "/blog/race-detector",
	"/doc/articles/slices_usage_and_internals.html":  "/blog/go-slices-usage-and-internals",
	"/doc/go_for_cpp_programmers.html":               "https://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers",
	"/doc/go_tutorial.html":                          "http://tour.golang.org/",
}

var prefixHelpers = map[string]string{
	"change": "https://code.google.com/p/go/source/detail?r=",
	"cl":     "https://codereview.appspot.com/",
	"issue":  "https://code.google.com/p/go/issues/detail?id=",
	"play":   "http://play.golang.org/",
	"talks":  "http://talks.golang.org/",
	"wiki":   "https://code.google.com/p/go-wiki/wiki/",
}

func Handler(target string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, target, http.StatusMovedPermanently)
	})
}

var validId = regexp.MustCompile(`^[A-Za-z0-9-]*$`)

func PrefixHandler(prefix, baseURL string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if p := r.URL.Path; p == prefix {
			// redirect /prefix/ to /prefix
			http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
			return
		}
		id := r.URL.Path[len(prefix):]
		if !validId.MatchString(id) {
			http.Error(w, "Not found", http.StatusNotFound)
			return
		}
		target := baseURL + id
		http.Redirect(w, r, target, http.StatusFound)
	})
}
<commit_msg>go.tools/godoc/redirect: remove race detector blog post redirect<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package redirect provides hooks to register HTTP handlers that redirect old
// godoc paths to their new equivalents and assist in accessing the issue
// tracker, wiki, code review system, etc.
package redirect

import (
	"net/http"
	"regexp"
)

// Register registers HTTP handlers that redirect old godoc paths to their new
// equivalents and assist in accessing the issue tracker, wiki, code review
// system, etc. If mux is nil it uses http.DefaultServeMux.
func Register(mux *http.ServeMux) {
	if mux == nil {
		mux = http.DefaultServeMux
	}
	handlePathRedirects(mux, pkgRedirects, "/pkg/")
	handlePathRedirects(mux, cmdRedirects, "/cmd/")
	for prefix, redirect := range prefixHelpers {
		p := "/" + prefix + "/"
		mux.Handle(p, PrefixHandler(p, redirect))
	}
	for path, redirect := range redirects {
		mux.Handle(path, Handler(redirect))
	}
}

func handlePathRedirects(mux *http.ServeMux, redirects map[string]string, prefix string) {
	for source, target := range redirects {
		h := Handler(prefix + target + "/")
		p := prefix + source
		mux.Handle(p, h)
		mux.Handle(p+"/", h)
	}
}

// Packages that were renamed between r60 and go1.
var pkgRedirects = map[string]string{
	"asn1":              "encoding/asn1",
	"big":               "math/big",
	"cmath":             "math/cmplx",
	"csv":               "encoding/csv",
	"exec":              "os/exec",
	"exp/template/html": "html/template",
	"gob":               "encoding/gob",
	"http":              "net/http",
	"http/cgi":          "net/http/cgi",
	"http/fcgi":         "net/http/fcgi",
	"http/httptest":     "net/http/httptest",
	"http/pprof":        "net/http/pprof",
	"json":              "encoding/json",
	"mail":              "net/mail",
	"rand":              "math/rand",
	"rpc":               "net/rpc",
	"rpc/jsonrpc":       "net/rpc/jsonrpc",
	"scanner":           "text/scanner",
	"smtp":              "net/smtp",
	"tabwriter":         "text/tabwriter",
	"template":          "text/template",
	"template/parse":    "text/template/parse",
	"url":               "net/url",
	"utf16":             "unicode/utf16",
	"utf8":              "unicode/utf8",
	"xml":               "encoding/xml",
}

// Commands that were renamed between r60 and go1.
var cmdRedirects = map[string]string{
	"gofix":     "fix",
	"goinstall": "go",
	"gopack":    "pack",
	"gotest":    "go",
	"govet":     "vet",
	"goyacc":    "yacc",
}

var redirects = map[string]string{
	"/blog":       "/blog/",
	"/build":      "http://build.golang.org",
	"/change":     "https://code.google.com/p/go/source/list",
	"/cl":         "https://gocodereview.appspot.com/",
	"/cmd/godoc/": "http://godoc.org/code.google.com/p/go.tools/cmd/godoc/",
	"/cmd/vet/":   "http://godoc.org/code.google.com/p/go.tools/cmd/vet/",
	"/issue":      "https://code.google.com/p/go/issues",
	"/issue/new":  "https://code.google.com/p/go/issues/entry",
	"/issues":     "https://code.google.com/p/go/issues",
	"/play":       "http://play.golang.org",

	// In Go 1.2 the references page is part of /doc/.
	"/ref": "/doc/#references",
	// This next rule clobbers /ref/spec and /ref/mem.
	// TODO(adg): figure out what to do here, if anything.
	// "/ref/": "/doc/#references",

	// Be nice to people who are looking in the wrong place.
	"/doc/mem":  "/ref/mem",
	"/doc/spec": "/ref/spec",

	"/talks": "http://talks.golang.org",
	"/tour":  "http://tour.golang.org",
	"/wiki":  "https://code.google.com/p/go-wiki/w/list",

	"/doc/articles/c_go_cgo.html":                    "/blog/c-go-cgo",
	"/doc/articles/concurrency_patterns.html":        "/blog/go-concurrency-patterns-timing-out-and",
	"/doc/articles/defer_panic_recover.html":         "/blog/defer-panic-and-recover",
	"/doc/articles/error_handling.html":              "/blog/error-handling-and-go",
	"/doc/articles/gobs_of_data.html":                "/blog/gobs-of-data",
	"/doc/articles/godoc_documenting_go_code.html":   "/blog/godoc-documenting-go-code",
	"/doc/articles/gos_declaration_syntax.html":      "/blog/gos-declaration-syntax",
	"/doc/articles/image_draw.html":                  "/blog/go-imagedraw-package",
	"/doc/articles/image_package.html":               "/blog/go-image-package",
	"/doc/articles/json_and_go.html":                 "/blog/json-and-go",
	"/doc/articles/json_rpc_tale_of_interfaces.html": "/blog/json-rpc-tale-of-interfaces",
	"/doc/articles/laws_of_reflection.html":          "/blog/laws-of-reflection",
	"/doc/articles/slices_usage_and_internals.html":  "/blog/go-slices-usage-and-internals",
	"/doc/go_for_cpp_programmers.html":               "https://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers",
	"/doc/go_tutorial.html":                          "http://tour.golang.org/",
}

var prefixHelpers = map[string]string{
	"change": "https://code.google.com/p/go/source/detail?r=",
	"cl":     "https://codereview.appspot.com/",
	"issue":  "https://code.google.com/p/go/issues/detail?id=",
	"play":   "http://play.golang.org/",
	"talks":  "http://talks.golang.org/",
	"wiki":   "https://code.google.com/p/go-wiki/wiki/",
}

func Handler(target string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, target, http.StatusMovedPermanently)
	})
}

var validId = regexp.MustCompile(`^[A-Za-z0-9-]*$`)

func PrefixHandler(prefix, baseURL string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if p := r.URL.Path; p == prefix {
			// redirect /prefix/ to /prefix
			http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
			return
		}
		id := r.URL.Path[len(prefix):]
		if !validId.MatchString(id) {
			http.Error(w, "Not found", http.StatusNotFound)
			return
		}
		target := baseURL + id
		http.Redirect(w, r, target, http.StatusFound)
	})
}
<|endoftext|>


<commit_before>package google

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"golang.org/x/oauth2/google"
)

const testFakeCredentialsPath = "./test-fixtures/fake_account.json"
const testOauthScope = "https://www.googleapis.com/auth/compute"

func TestConfigLoadAndValidate_accountFilePath(t *testing.T) {
	config := Config{
		Credentials: testFakeCredentialsPath,
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}
}

func TestConfigLoadAndValidate_accountFileJSON(t *testing.T) {
	contents, err := ioutil.ReadFile(testFakeCredentialsPath)
	if err != nil {
		t.Fatalf("error: %v", err)
	}
	config := Config{
		Credentials: string(contents),
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	err = config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}
}

func TestConfigLoadAndValidate_accountFileJSONInvalid(t *testing.T) {
	config := Config{
		Credentials: "{this is not json}",
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	if config.loadAndValidate() == nil {
		t.Fatalf("expected error, but got nil")
	}
}

func TestAccConfigLoadValidate_credentials(t *testing.T) {
	if os.Getenv(resource.TestEnvVar) == "" {
		t.Skip(fmt.Sprintf("Network access not allowed; use %s=1 to enable", resource.TestEnvVar))
	}
	testAccPreCheck(t)

	creds := getTestCredsFromEnv()
	proj := getTestProjectFromEnv()

	config := Config{
		Credentials: creds,
		Project:     proj,
		Region:      "us-central1",
	}

	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}

	_, err = config.clientCompute.Zones.Get(proj, "us-central1-a").Do()
	if err != nil {
		t.Fatalf("expected call with loaded config client to work, got error: %s", err)
	}
}

func TestAccConfigLoadValidate_accessToken(t *testing.T) {
	if os.Getenv(resource.TestEnvVar) == "" {
		t.Skip(fmt.Sprintf("Network access not allowed; use %s=1 to enable", resource.TestEnvVar))
	}
	testAccPreCheck(t)

	creds := getTestCredsFromEnv()
	proj := getTestProjectFromEnv()

	c, err := google.CredentialsFromJSON(context.Background(), []byte(creds), testOauthScope)
	if err != nil {
		t.Fatalf("invalid test credentials: %s", err)
	}

	token, err := c.TokenSource.Token()
	if err != nil {
		t.Fatalf("Unable to generate test access token: %s", err)
	}

	config := Config{
		AccessToken: token.AccessToken,
		Project:     proj,
		Region:      "us-central1",
	}

	err = config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}

	_, err = config.clientCompute.Zones.Get(proj, "us-central1-a").Do()
	if err != nil {
		t.Fatalf("expected API call with loaded config to work, got error: %s", err)
	}
}

func TestConfigLoadAndValidate_defaultScopes(t *testing.T) {
	config := Config{}
	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	for index, scope := range defaultClientScopes {
		if config.Scopes[index] != scope {
			t.Fatalf("Unexpected default client scopes: %v, index %d", config.Scopes[index], index)
		}
	}
}
<commit_msg>[Terraform] Fix config's defaultScopes tests. (#428)<commit_after>package google

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"golang.org/x/oauth2/google"
)

const testFakeCredentialsPath = "./test-fixtures/fake_account.json"
const testOauthScope = "https://www.googleapis.com/auth/compute"

func TestConfigLoadAndValidate_accountFilePath(t *testing.T) {
	config := Config{
		Credentials: testFakeCredentialsPath,
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}
}

func TestConfigLoadAndValidate_accountFileJSON(t *testing.T) {
	contents, err := ioutil.ReadFile(testFakeCredentialsPath)
	if err != nil {
		t.Fatalf("error: %v", err)
	}
	config := Config{
		Credentials: string(contents),
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	err = config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}
}

func TestConfigLoadAndValidate_accountFileJSONInvalid(t *testing.T) {
	config := Config{
		Credentials: "{this is not json}",
		Project:     "my-gce-project",
		Region:      "us-central1",
	}

	if config.loadAndValidate() == nil {
		t.Fatalf("expected error, but got nil")
	}
}

func TestAccConfigLoadValidate_credentials(t *testing.T) {
	if os.Getenv(resource.TestEnvVar) == "" {
		t.Skip(fmt.Sprintf("Network access not allowed; use %s=1 to enable", resource.TestEnvVar))
	}
	testAccPreCheck(t)

	creds := getTestCredsFromEnv()
	proj := getTestProjectFromEnv()

	config := Config{
		Credentials: creds,
		Project:     proj,
		Region:      "us-central1",
	}

	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}

	_, err = config.clientCompute.Zones.Get(proj, "us-central1-a").Do()
	if err != nil {
		t.Fatalf("expected call with loaded config client to work, got error: %s", err)
	}
}

func TestAccConfigLoadValidate_accessToken(t *testing.T) {
	if os.Getenv(resource.TestEnvVar) == "" {
		t.Skip(fmt.Sprintf("Network access not allowed; use %s=1 to enable", resource.TestEnvVar))
	}
	testAccPreCheck(t)

	creds := getTestCredsFromEnv()
	proj := getTestProjectFromEnv()

	c, err := google.CredentialsFromJSON(context.Background(), []byte(creds), testOauthScope)
	if err != nil {
		t.Fatalf("invalid test credentials: %s", err)
	}

	token, err := c.TokenSource.Token()
	if err != nil {
		t.Fatalf("Unable to generate test access token: %s", err)
	}

	config := Config{
		AccessToken: token.AccessToken,
		Project:     proj,
		Region:      "us-central1",
	}

	err = config.loadAndValidate()
	if err != nil {
		t.Fatalf("error: %v", err)
	}

	_, err = config.clientCompute.Zones.Get(proj, "us-central1-a").Do()
	if err != nil {
		t.Fatalf("expected API call with loaded config to work, got error: %s", err)
	}
}

func TestConfigLoadAndValidate_customScopes(t *testing.T) {
	config := Config{
		Credentials: testFakeCredentialsPath,
		Project:     "my-gce-project",
		Region:      "us-central1",
		Scopes:      []string{"https://www.googleapis.com/auth/compute"},
	}
	err := config.loadAndValidate()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	if len(config.Scopes) != 1 {
		t.Fatalf("expected 1 scope, got %d scopes: %v", len(config.Scopes), config.Scopes)
	}
	if config.Scopes[0] != "https://www.googleapis.com/auth/compute" {
		t.Fatalf("expected scope to be %q, got %q", "https://www.googleapis.com/auth/compute", config.Scopes[0])
	}
}
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"reflect"
)

func GetComputeSnapshotCaiObject(d TerraformResourceData, config *Config) (Asset, error) {
	name, err := assetName(d, config, "//compute.googleapis.com/projects/{{project}}/global/snapshots/{{name}}")
	if err != nil {
		return Asset{}, err
	}
	if obj, err := GetComputeSnapshotApiObject(d, config); err == nil {
		return Asset{
			Name: name,
			Type: "compute.googleapis.com/Snapshot",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
				DiscoveryName:        "Snapshot",
				Data:                 obj,
			},
		}, nil
	} else {
		return Asset{}, err
	}
}

func GetComputeSnapshotApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	nameProp, err := expandComputeSnapshotName(d.Get("name"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	descriptionProp, err := expandComputeSnapshotDescription(d.Get("description"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
		obj["description"] = descriptionProp
	}
	labelsProp, err := expandComputeSnapshotLabels(d.Get("labels"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
		obj["labels"] = labelsProp
	}
	labelFingerprintProp, err := expandComputeSnapshotLabelFingerprint(d.Get("label_fingerprint"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("label_fingerprint"); !isEmptyValue(reflect.ValueOf(labelFingerprintProp)) && (ok || !reflect.DeepEqual(v, labelFingerprintProp)) {
		obj["labelFingerprint"] = labelFingerprintProp
	}
	sourceDiskProp, err := expandComputeSnapshotSourceDisk(d.Get("source_disk"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("source_disk"); !isEmptyValue(reflect.ValueOf(sourceDiskProp)) && (ok || !reflect.DeepEqual(v, sourceDiskProp)) {
		obj["sourceDisk"] = sourceDiskProp
	}
	zoneProp, err := expandComputeSnapshotZone(d.Get("zone"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("zone"); !isEmptyValue(reflect.ValueOf(zoneProp)) && (ok || !reflect.DeepEqual(v, zoneProp)) {
		obj["zone"] = zoneProp
	}
	snapshotEncryptionKeyProp, err := expandComputeSnapshotSnapshotEncryptionKey(d.Get("snapshot_encryption_key"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("snapshot_encryption_key"); !isEmptyValue(reflect.ValueOf(snapshotEncryptionKeyProp)) && (ok || !reflect.DeepEqual(v, snapshotEncryptionKeyProp)) {
		obj["snapshotEncryptionKey"] = snapshotEncryptionKeyProp
	}
	sourceDiskEncryptionKeyProp, err := expandComputeSnapshotSourceDiskEncryptionKey(d.Get("source_disk_encryption_key"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("source_disk_encryption_key"); !isEmptyValue(reflect.ValueOf(sourceDiskEncryptionKeyProp)) && (ok || !reflect.DeepEqual(v, sourceDiskEncryptionKeyProp)) {
		obj["sourceDiskEncryptionKey"] = sourceDiskEncryptionKeyProp
	}

	return obj, nil
}

func expandComputeSnapshotName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
	if v == nil {
		return map[string]string{}, nil
	}
	m := make(map[string]string)
	for k, val := range v.(map[string]interface{}) {
		m[k] = val.(string)
	}
	return m, nil
}

func expandComputeSnapshotLabelFingerprint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSourceDisk(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	f, err := parseZonalFieldValue("disks", v.(string), "project", "zone", d, config, true)
	if err != nil {
		return nil, fmt.Errorf("Invalid value for source_disk: %s", err)
	}
	return f.RelativeLink(), nil
}

func expandComputeSnapshotZone(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	f, err := parseGlobalFieldValue("zones", v.(string), "project", d, config, true)
	if err != nil {
		return nil, fmt.Errorf("Invalid value for zone: %s", err)
	}
	return f.RelativeLink(), nil
}

func expandComputeSnapshotSnapshotEncryptionKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRawKey, err := expandComputeSnapshotSnapshotEncryptionKeyRawKey(original["raw_key"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRawKey); val.IsValid() && !isEmptyValue(val) {
		transformed["rawKey"] = transformedRawKey
	}

	transformedSha256, err := expandComputeSnapshotSnapshotEncryptionKeySha256(original["sha256"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedSha256); val.IsValid() && !isEmptyValue(val) {
		transformed["sha256"] = transformedSha256
	}

	return transformed, nil
}

func expandComputeSnapshotSnapshotEncryptionKeyRawKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSnapshotEncryptionKeySha256(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSourceDiskEncryptionKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRawKey, err := expandComputeSnapshotSourceDiskEncryptionKeyRawKey(original["raw_key"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRawKey); val.IsValid() && !isEmptyValue(val) {
		transformed["rawKey"] = transformedRawKey
	}

	return transformed, nil
}

func expandComputeSnapshotSourceDiskEncryptionKeyRawKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<commit_msg>Add Snapshot location to compute snapshot (#3896) (#518)<commit_after>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    AUTO GENERATED CODE     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"reflect"
)

func GetComputeSnapshotCaiObject(d TerraformResourceData, config *Config) (Asset, error) {
	name, err := assetName(d, config, "//compute.googleapis.com/projects/{{project}}/global/snapshots/{{name}}")
	if err != nil {
		return Asset{}, err
	}
	if obj, err := GetComputeSnapshotApiObject(d, config); err == nil {
		return Asset{
			Name: name,
			Type: "compute.googleapis.com/Snapshot",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
				DiscoveryName:        "Snapshot",
				Data:                 obj,
			},
		}, nil
	} else {
		return Asset{}, err
	}
}

func GetComputeSnapshotApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	nameProp, err := expandComputeSnapshotName(d.Get("name"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}
	descriptionProp, err := expandComputeSnapshotDescription(d.Get("description"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
		obj["description"] = descriptionProp
	}
	storageLocationsProp, err := expandComputeSnapshotStorageLocations(d.Get("storage_locations"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("storage_locations"); !isEmptyValue(reflect.ValueOf(storageLocationsProp)) && (ok || !reflect.DeepEqual(v, storageLocationsProp)) {
		obj["storageLocations"] = storageLocationsProp
	}
	labelsProp, err := expandComputeSnapshotLabels(d.Get("labels"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
		obj["labels"] = labelsProp
	}
	labelFingerprintProp, err := expandComputeSnapshotLabelFingerprint(d.Get("label_fingerprint"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("label_fingerprint"); !isEmptyValue(reflect.ValueOf(labelFingerprintProp)) && (ok || !reflect.DeepEqual(v, labelFingerprintProp)) {
		obj["labelFingerprint"] = labelFingerprintProp
	}
	sourceDiskProp, err := expandComputeSnapshotSourceDisk(d.Get("source_disk"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("source_disk"); !isEmptyValue(reflect.ValueOf(sourceDiskProp)) && (ok || !reflect.DeepEqual(v, sourceDiskProp)) {
		obj["sourceDisk"] = sourceDiskProp
	}
	zoneProp, err := expandComputeSnapshotZone(d.Get("zone"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("zone"); !isEmptyValue(reflect.ValueOf(zoneProp)) && (ok || !reflect.DeepEqual(v, zoneProp)) {
		obj["zone"] = zoneProp
	}
	snapshotEncryptionKeyProp, err := expandComputeSnapshotSnapshotEncryptionKey(d.Get("snapshot_encryption_key"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("snapshot_encryption_key"); !isEmptyValue(reflect.ValueOf(snapshotEncryptionKeyProp)) && (ok || !reflect.DeepEqual(v, snapshotEncryptionKeyProp)) {
		obj["snapshotEncryptionKey"] = snapshotEncryptionKeyProp
	}
	sourceDiskEncryptionKeyProp, err := expandComputeSnapshotSourceDiskEncryptionKey(d.Get("source_disk_encryption_key"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("source_disk_encryption_key"); !isEmptyValue(reflect.ValueOf(sourceDiskEncryptionKeyProp)) && (ok || !reflect.DeepEqual(v, sourceDiskEncryptionKeyProp)) {
		obj["sourceDiskEncryptionKey"] = sourceDiskEncryptionKeyProp
	}

	return obj, nil
}

func expandComputeSnapshotName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotStorageLocations(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
	if v == nil {
		return map[string]string{}, nil
	}
	m := make(map[string]string)
	for k, val := range v.(map[string]interface{}) {
		m[k] = val.(string)
	}
	return m, nil
}

func expandComputeSnapshotLabelFingerprint(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSourceDisk(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	f, err := parseZonalFieldValue("disks", v.(string), "project", "zone", d, config, true)
	if err != nil {
		return nil, fmt.Errorf("Invalid value for source_disk: %s", err)
	}
	return f.RelativeLink(), nil
}

func expandComputeSnapshotZone(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	f, err := parseGlobalFieldValue("zones", v.(string), "project", d, config, true)
	if err != nil {
		return nil, fmt.Errorf("Invalid value for zone: %s", err)
	}
	return f.RelativeLink(), nil
}

func expandComputeSnapshotSnapshotEncryptionKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRawKey, err := expandComputeSnapshotSnapshotEncryptionKeyRawKey(original["raw_key"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRawKey); val.IsValid() && !isEmptyValue(val) {
		transformed["rawKey"] = transformedRawKey
	}

	transformedSha256, err := expandComputeSnapshotSnapshotEncryptionKeySha256(original["sha256"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedSha256); val.IsValid() && !isEmptyValue(val) {
		transformed["sha256"] = transformedSha256
	}

	transformedKmsKeySelfLink, err := expandComputeSnapshotSnapshotEncryptionKeyKmsKeySelfLink(original["kms_key_self_link"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedKmsKeySelfLink); val.IsValid() && !isEmptyValue(val) {
		transformed["kmsKeyName"] = transformedKmsKeySelfLink
	}

	transformedKmsKeyServiceAccount, err := expandComputeSnapshotSnapshotEncryptionKeyKmsKeyServiceAccount(original["kms_key_service_account"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedKmsKeyServiceAccount); val.IsValid() && !isEmptyValue(val) {
		transformed["kmsKeyServiceAccount"] = transformedKmsKeyServiceAccount
	}

	return transformed, nil
}

func expandComputeSnapshotSnapshotEncryptionKeyRawKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSnapshotEncryptionKeySha256(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSnapshotEncryptionKeyKmsKeySelfLink(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSnapshotEncryptionKeyKmsKeyServiceAccount(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSourceDiskEncryptionKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedRawKey, err := expandComputeSnapshotSourceDiskEncryptionKeyRawKey(original["raw_key"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedRawKey); val.IsValid() && !isEmptyValue(val) {
		transformed["rawKey"] = transformedRawKey
	}

	transformedKmsKeyServiceAccount, err := expandComputeSnapshotSourceDiskEncryptionKeyKmsKeyServiceAccount(original["kms_key_service_account"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedKmsKeyServiceAccount); val.IsValid() && !isEmptyValue(val) {
		transformed["kmsKeyServiceAccount"] = transformedKmsKeyServiceAccount
	}

	return transformed, nil
}

func expandComputeSnapshotSourceDiskEncryptionKeyRawKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandComputeSnapshotSourceDiskEncryptionKeyKmsKeyServiceAccount(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<|endoftext|>


<commit_before>package shared

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"math/rand"
	"os"
	"strings"
	"testing"
)

func TestFileCopy(t *testing.T) {
	helloWorld := []byte("hello world\n")
	source, err := ioutil.TempFile("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(source.Name())

	if err := WriteAll(source, helloWorld); err != nil {
		source.Close()
		t.Error(err)
		return
	}
	source.Close()

	dest, err := ioutil.TempFile("", "")
	defer os.Remove(dest.Name())
	if err != nil {
		t.Error(err)
		return
	}
	dest.Close()

	if err := FileCopy(source.Name(), dest.Name()); err != nil {
		t.Error(err)
		return
	}

	dest2, err := os.Open(dest.Name())
	if err != nil {
		t.Error(err)
		return
	}

	content, err := ioutil.ReadAll(dest2)
	if err != nil {
		t.Error(err)
		return
	}

	if string(content) != string(helloWorld) {
		t.Error("content mismatch: ", string(content), "!=", string(helloWorld))
		return
	}
}

func TestReadLastNLines(t *testing.T) {
	source, err := ioutil.TempFile("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(source.Name())

	for i := 0; i < 50; i++ {
		fmt.Fprintf(source, "%d\n", i)
	}

	lines, err := ReadLastNLines(source, 100)
	if err != nil {
		t.Error(err)
		return
	}

	split := strings.Split(lines, "\n")
	for i := 0; i < 50; i++ {
		if fmt.Sprintf("%d", i) != split[i] {
			t.Error(fmt.Sprintf("got %s expected %d", split[i], i))
			return
		}
	}

	source.Seek(0, 0)
	for i := 0; i < 150; i++ {
		fmt.Fprintf(source, "%d\n", i)
	}

	lines, err = ReadLastNLines(source, 100)
	if err != nil {
		t.Error(err)
		return
	}

	split = strings.Split(lines, "\n")
	for i := 0; i < 100; i++ {
		if fmt.Sprintf("%d", i+50) != split[i] {
			t.Error(fmt.Sprintf("got %s expected %d", split[i], i))
			return
		}
	}
}

func TestReaderToChannel(t *testing.T) {
	buf := make([]byte, 64*1024*1024)
	rand.Read(buf)

	offset := 0
	finished := false

	ch := ReaderToChannel(bytes.NewBuffer(buf), -1)
	for {
		data, ok := <-ch
		if len(data) > 0 {
			for i := 0; i < len(data); i++ {
				if buf[offset+i] != data[i] {
					t.Error(fmt.Sprintf("byte %d didn't match", offset+i))
					return
				}
			}

			offset += len(data)
			if offset > len(buf) {
				t.Error("read too much data")
				return
			}

			if offset == len(buf) {
				finished = true
			}
		}

		if !ok {
			if !finished {
				t.Error("connection closed too early")
				return
			} else {
				break
			}
		}
	}
}
<commit_msg>use crypto/rand instead of math/rand for testing<commit_after>package shared

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"crypto/rand"
	"os"
	"strings"
	"testing"
)

func TestFileCopy(t *testing.T) {
	helloWorld := []byte("hello world\n")
	source, err := ioutil.TempFile("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(source.Name())

	if err := WriteAll(source, helloWorld); err != nil {
		source.Close()
		t.Error(err)
		return
	}
	source.Close()

	dest, err := ioutil.TempFile("", "")
	defer os.Remove(dest.Name())
	if err != nil {
		t.Error(err)
		return
	}
	dest.Close()

	if err := FileCopy(source.Name(), dest.Name()); err != nil {
		t.Error(err)
		return
	}

	dest2, err := os.Open(dest.Name())
	if err != nil {
		t.Error(err)
		return
	}

	content, err := ioutil.ReadAll(dest2)
	if err != nil {
		t.Error(err)
		return
	}

	if string(content) != string(helloWorld) {
		t.Error("content mismatch: ", string(content), "!=", string(helloWorld))
		return
	}
}

func TestReadLastNLines(t *testing.T) {
	source, err := ioutil.TempFile("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(source.Name())

	for i := 0; i < 50; i++ {
		fmt.Fprintf(source, "%d\n", i)
	}

	lines, err := ReadLastNLines(source, 100)
	if err != nil {
		t.Error(err)
		return
	}

	split := strings.Split(lines, "\n")
	for i := 0; i < 50; i++ {
		if fmt.Sprintf("%d", i) != split[i] {
			t.Error(fmt.Sprintf("got %s expected %d", split[i], i))
			return
		}
	}

	source.Seek(0, 0)
	for i := 0; i < 150; i++ {
		fmt.Fprintf(source, "%d\n", i)
	}

	lines, err = ReadLastNLines(source, 100)
	if err != nil {
		t.Error(err)
		return
	}

	split = strings.Split(lines, "\n")
	for i := 0; i < 100; i++ {
		if fmt.Sprintf("%d", i+50) != split[i] {
			t.Error(fmt.Sprintf("got %s expected %d", split[i], i))
			return
		}
	}
}

func TestReaderToChannel(t *testing.T) {
	buf := make([]byte, 64*1024*1024)
	rand.Read(buf)

	offset := 0
	finished := false

	ch := ReaderToChannel(bytes.NewBuffer(buf), -1)
	for {
		data, ok := <-ch
		if len(data) > 0 {
			for i := 0; i < len(data); i++ {
				if buf[offset+i] != data[i] {
					t.Error(fmt.Sprintf("byte %d didn't match", offset+i))
					return
				}
			}

			offset += len(data)
			if offset > len(buf) {
				t.Error("read too much data")
				return
			}

			if offset == len(buf) {
				finished = true
			}
		}

		if !ok {
			if !finished {
				t.Error("connection closed too early")
				return
			} else {
				break
			}
		}
	}
}
<|endoftext|>


<commit_before>package version

import "fmt"

type Version struct {
	Major, Minor, Patch int
	Label               string
	Nick                string
}

var Ver = Version{
	Major: 2,
	Minor: 0,
	Patch: 1,
	Label: ""}

// CommitHash may be set on the build command line:
// go build -ldflags "-X main.CommitHash=`git rev-parse --short HEAD`"
var CommitHash string

const AppName string = "dcrdata"

func (v *Version) String() string {
	var hashStr string
	if CommitHash != "" {
		hashStr = "+" + CommitHash
	}
	if v.Label != "" {
		return fmt.Sprintf("%d.%d.%d-%s%s",
			v.Major, v.Minor, v.Patch, v.Label, hashStr)
	}
	return fmt.Sprintf("%d.%d.%d%s",
		v.Major, v.Minor, v.Patch, hashStr)
}
<commit_msg>bump dcrdata to v2.1.0<commit_after>package version

import "fmt"

type Version struct {
	Major, Minor, Patch int
	Label               string
	Nick                string
}

var Ver = Version{
	Major: 2,
	Minor: 1,
	Patch: 0,
	Label: ""}

// CommitHash may be set on the build command line:
// go build -ldflags "-X main.CommitHash=`git rev-parse --short HEAD`"
var CommitHash string

const AppName string = "dcrdata"

func (v *Version) String() string {
	var hashStr string
	if CommitHash != "" {
		hashStr = "+" + CommitHash
	}
	if v.Label != "" {
		return fmt.Sprintf("%d.%d.%d-%s%s",
			v.Major, v.Minor, v.Patch, v.Label, hashStr)
	}
	return fmt.Sprintf("%d.%d.%d%s",
		v.Major, v.Minor, v.Patch, hashStr)
}
<|endoftext|>


<commit_before>package stdlib

import (
	"bufio"
	"fmt"

	"github.com/PuerkitoBio/agora/runtime"
)

type FmtMod struct {
	ctx *runtime.Ctx
	ob  runtime.Object
}

func (f *FmtMod) ID() string {
	return "fmt"
}

func (f *FmtMod) Run(_ ...runtime.Val) (v runtime.Val, err error) {
	defer runtime.PanicToError(&err)
	if f.ob == nil {
		// Prepare the object
		f.ob = runtime.NewObject()
		f.ob.Set(runtime.String("Print"), runtime.NewNativeFunc(f.ctx, "fmt.Print", f.fmt_Print))
		f.ob.Set(runtime.String("Println"), runtime.NewNativeFunc(f.ctx, "fmt.Println", f.fmt_Println))
		f.ob.Set(runtime.String("Scanln"), runtime.NewNativeFunc(f.ctx, "fmt.Scanln", f.fmt_Scanln))
		f.ob.Set(runtime.String("Scanint"), runtime.NewNativeFunc(f.ctx, "fmt.Scanint", f.fmt_Scanint))
	}
	return f.ob, nil
}

func (f *FmtMod) SetCtx(c *runtime.Ctx) {
	f.ctx = c
}

func toNative(args []runtime.Val) []interface{} {
	var ifs []interface{}

	if len(args) > 0 {
		ifs = make([]interface{}, len(args))
		for i, v := range args {
			ifs[i] = v.Native()
		}
	}
	return ifs
}

func (f *FmtMod) fmt_Print(args ...runtime.Val) runtime.Val {
	ifs := toNative(args)
	n, err := fmt.Fprint(f.ctx.Stdout, ifs...)
	if err != nil {
		panic(err)
	}
	return runtime.Number(n)
}

func (f *FmtMod) fmt_Println(args ...runtime.Val) runtime.Val {
	ifs := toNative(args)
	n, err := fmt.Fprintln(f.ctx.Stdout, ifs...)
	if err != nil {
		panic(err)
	}
	return runtime.Number(n)
}

func (f *FmtMod) fmt_Scanln(args ...runtime.Val) runtime.Val {
	var (
		b, l []byte
		e    error
		pre  bool
	)
	r := bufio.NewReader(f.ctx.Stdin)
	for l, pre, e = r.ReadLine(); pre && e == nil; l, pre, e = r.ReadLine() {
		b = append(b, l...)
	}
	if e != nil {
		panic(e)
	}
	return runtime.String(b)
}

func (f *FmtMod) fmt_Scanint(args ...runtime.Val) runtime.Val {
	var i int
	if _, e := fmt.Fscanf(f.ctx.Stdin, "%d", &i); e != nil {
		panic(e)
	}
	return runtime.Number(i)
}
<commit_msg>fix scanln, closes #6<commit_after>package stdlib

import (
	"bufio"
	"fmt"

	"github.com/PuerkitoBio/agora/runtime"
)

type FmtMod struct {
	ctx *runtime.Ctx
	ob  runtime.Object
}

func (f *FmtMod) ID() string {
	return "fmt"
}

func (f *FmtMod) Run(_ ...runtime.Val) (v runtime.Val, err error) {
	defer runtime.PanicToError(&err)
	if f.ob == nil {
		// Prepare the object
		f.ob = runtime.NewObject()
		f.ob.Set(runtime.String("Print"), runtime.NewNativeFunc(f.ctx, "fmt.Print", f.fmt_Print))
		f.ob.Set(runtime.String("Println"), runtime.NewNativeFunc(f.ctx, "fmt.Println", f.fmt_Println))
		f.ob.Set(runtime.String("Scanln"), runtime.NewNativeFunc(f.ctx, "fmt.Scanln", f.fmt_Scanln))
		f.ob.Set(runtime.String("Scanint"), runtime.NewNativeFunc(f.ctx, "fmt.Scanint", f.fmt_Scanint))
	}
	return f.ob, nil
}

func (f *FmtMod) SetCtx(c *runtime.Ctx) {
	f.ctx = c
}

func toNative(args []runtime.Val) []interface{} {
	var ifs []interface{}

	if len(args) > 0 {
		ifs = make([]interface{}, len(args))
		for i, v := range args {
			ifs[i] = v.Native()
		}
	}
	return ifs
}

func (f *FmtMod) fmt_Print(args ...runtime.Val) runtime.Val {
	ifs := toNative(args)
	n, err := fmt.Fprint(f.ctx.Stdout, ifs...)
	if err != nil {
		panic(err)
	}
	return runtime.Number(n)
}

func (f *FmtMod) fmt_Println(args ...runtime.Val) runtime.Val {
	ifs := toNative(args)
	n, err := fmt.Fprintln(f.ctx.Stdout, ifs...)
	if err != nil {
		panic(err)
	}
	return runtime.Number(n)
}

func (f *FmtMod) fmt_Scanln(args ...runtime.Val) runtime.Val {
	var (
		b, l []byte
		e    error
		pre  bool
	)
	r := bufio.NewReader(f.ctx.Stdin)
	for l, pre, e = r.ReadLine(); pre && e == nil; l, pre, e = r.ReadLine() {
		b = append(b, l...)
	}
	if e != nil {
		panic(e)
	}
	b = append(b, l...)
	return runtime.String(b)
}

func (f *FmtMod) fmt_Scanint(args ...runtime.Val) runtime.Val {
	var i int
	if _, e := fmt.Fscanf(f.ctx.Stdin, "%d", &i); e != nil {
		panic(e)
	}
	return runtime.Number(i)
}
<|endoftext|>