<commit_before>package routers

import (
	"testing"
)

func TestCreateTrie(t *testing.T) {
	trie := CreateTrie()
	if trie.value != nil {
		t.Errorf("New trie's value is not nil: %v", trie.value)
	}
	if len(trie.children) != 0 {
		t.Errorf("New trie's children is not empty: %v", trie.children)
	}
}

func TestTrieInsert(t *testing.T) {
	trie := CreateTrie()
	trie.Insert("/", nil)
	trie.Insert("/foo", 42)
}<commit_msg>Some more trie testing<commit_after>package routers

import (
	"testing"
)

func TestCreateTrie(t *testing.T) {
	trie := CreateTrie()
	if trie.value != nil {
		t.Errorf("New trie's value is not nil: %v", trie.value)
	}
	if len(trie.children) != 0 {
		t.Errorf("New trie's children is not empty: %v", trie.children)
	}
}

func TestTrieInsert(t *testing.T) {
	trie := CreateTrie()

	trie.Insert("/", "pie")

	if len(trie.children) != 1 {
		t.Errorf("Inserted more than 1 child into trie")
	}

	if trie.children['/'].value != "pie" {
		t.Errorf("Value inserted at root %v != %v", trie.children[0].value, "pie")
	}

	trie.Insert("/abc", 42)

	if len(trie.children) != 1 {
		t.Errorf("Inserted a new children with the same rune")
	}

	node := trie

	for idx, r := range "/abc" {
		if child, ok := node.children[r]; !ok {
			t.Errorf("Didn't insert rune %v (%v) into trie", r, idx)
		} else {
			node = child
		}
	}

	if node.value != 42 {
		t.Errorf("Inserted wrong value at tail of trie: %v != 42", node.value)
	}

	trie.Insert("/bcd", 3.14)
	node = trie.children['/']

	if len(node.children) != 2 {
		t.Errorf("Expected 2 children, got %v", len(node.children))
	}
}<|endoftext|>


<commit_before>package totp

import (
	"fmt"
	"strings"

	log "github.com/mgutz/logxi/v1"

	"github.com/hashicorp/vault/logical"
	"github.com/hashicorp/vault/logical/framework"
)

func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
	return Backend(conf).Setup(conf)
}

func Backend(conf *logical.BackendConfig) *backend {
	var b backend
	b.Backend = &framework.Backend{
		Help: strings.TrimSpace(backendHelp),

		Paths: []*framework.Path{
			pathListRoles(&b),
			pathRoles(&b),
			pathRoleCreate(&b),
		},

		Secrets: []*framework.Secret{},
	}

	b.logger = conf.Logger
	return &b
}

type backend struct {
	*framework.Backend

	logger log.Logger
}

// This needs to be updated
const backendHelp = `
The PostgreSQL backend dynamically generates database users.

After mounting this backend, configure it using the endpoints within
the "config/" path.
`
<commit_msg>Updated TOTP backend.go's structure and help string<commit_after>package totp

import (
	"strings"

	log "github.com/mgutz/logxi/v1"

	"github.com/hashicorp/vault/logical"
	"github.com/hashicorp/vault/logical/framework"
)

func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
	return Backend(conf).Setup(conf)
}

func Backend(conf *logical.BackendConfig) *backend {
	var b backend
	b.Backend = &framework.Backend{
		Help: strings.TrimSpace(backendHelp),

		Paths: []*framework.Path{
			pathListRoles(&b),
			pathRoles(&b),
			pathRoleCreate(&b),
		},

		Secrets: []*framework.Secret{},
	}

	b.logger = conf.Logger
	return &b
}

type backend struct {
	*framework.Backend
	logger log.Logger
}

const backendHelp = `
The TOTP backend dynamically generates time-based one-time use passwords.
`
<|endoftext|>


<commit_before>package http

import (
	"bytes"
	"github.com/viant/endly"
	"github.com/viant/endly/model"
	"github.com/viant/endly/udf"
	"github.com/viant/endly/util"
	"github.com/viant/toolbox"
	"io"
	"net/http"
	"strings"
)

//ServiceRequest represents an http request
type Request struct {
	*model.Repeater
	When        string `description:"criteria to send this request"`
	Method      string `required:"true" description:"HTTP Method"`
	URL         string
	Header      http.Header
	Cookies     Cookies
	Body        string
	JSONBody    interface{}       `description:"body JSON representation"`
	Replace     map[string]string `description:"response body key value pair replacement"`
	RequestUdf  string            `description:"user defined function in context.state key, i,e, json to protobuf"`
	ResponseUdf string            `description:"user defined function in context.state key, i,e, protobuf to json"`
}

//Expand substitute request data with matching context map state.
func (r *Request) Expand(context *endly.Context) *Request {
	header := make(map[string][]string)
	copyExpandedHeaders(r.Header, header, context)
	return &Request{
		When:        context.Expand(r.When),
		Method:      r.Method,
		URL:         context.Expand(r.URL),
		Body:        context.Expand(r.Body),
		JSONBody:    r.JSONBody,
		Header:      header,
		Repeater:    r.Repeater,
		Replace:     r.Replace,
		RequestUdf:  r.RequestUdf,
		ResponseUdf: r.ResponseUdf,
	}
}

//Build builds an http.Request
func (r *Request) Build(context *endly.Context, sessionCookies Cookies) (*http.Request, bool, error) {

	if r.Body == "" && r.JSONBody != nil {
		var err error
		r.Body, err = toolbox.AsJSONText(r.JSONBody)
		if err != nil {
			return nil, false, err
		}
	}
	request := r.Expand(context)
	var reader io.Reader
	var expectBinary = false
	var err error
	var ok bool
	if len(r.Body) > 0 {
		body := []byte(request.Body)
		if request.RequestUdf != "" {
			transformed, err := udf.TransformWithUDF(context, request.RequestUdf, request.URL, string(body))
			if err != nil {
				return nil, false, err
			}
			if body, ok = transformed.([]byte); !ok {
				body = []byte(toolbox.AsString(transformed))
			}
		}
		expectBinary = strings.HasPrefix(string(body), "base64:")
		body, err = util.FromPayload(string(body))
		if err != nil {
			return nil, expectBinary, err
		}
		reader = bytes.NewReader(body)
	}
	httpRequest, err := http.NewRequest(strings.ToUpper(request.Method), request.URL, reader)
	if err != nil {
		return nil, expectBinary, err
	}

	copyHeaders(request.Header, httpRequest.Header)
	//Set cookies from active session
	SetCookies(sessionCookies, request.Header)
	//Set cookies from user http request
	SetCookies(request.Cookies, httpRequest.Header)
	return httpRequest, expectBinary, nil
}
<commit_msg>added clone, and refactored expand<commit_after>package http

import (
	"bytes"
	"github.com/viant/endly"
	"github.com/viant/endly/model"
	"github.com/viant/endly/udf"
	"github.com/viant/endly/util"
	"github.com/viant/toolbox"
	"io"
	"net/http"
	"strings"
	"github.com/viant/toolbox/data"
)

//ServiceRequest represents an http request
type Request struct {
	*model.Repeater
	When        string            `description:"criteria to send this request"`
	Method      string            `required:"true" description:"HTTP Method"`
	URL         string
	Header      http.Header
	Cookies     Cookies
	Body        string
	JSONBody    interface{}       `description:"body JSON representation"`
	Replace     map[string]string `description:"response body key value pair replacement"`
	RequestUdf  string            `description:"user defined function in context.state key, i,e, json to protobuf"`
	ResponseUdf string            `description:"user defined function in context.state key, i,e, protobuf to json"`
}

//Clone substitute request data with matching context map state.
func (r *Request) Clone(context *endly.Context) *Request {
	header := make(map[string][]string)
	copyExpandedHeaders(r.Header, header, context)
	return &Request{
		When:        context.Expand(r.When),
		Method:      r.Method,
		URL:         context.Expand(r.URL),
		Body:        context.Expand(r.Body),
		JSONBody:    r.JSONBody,
		Header:      header,
		Repeater:    r.Repeater,
		Replace:     r.Replace,
		RequestUdf:  r.RequestUdf,
		ResponseUdf: r.ResponseUdf,
	}
}

//Clone substitute request data with matching context map state.
func (r *Request) Expand(state data.Map) {
	r.URL = state.ExpandAsText(r.URL)
	r.Body = state.ExpandAsText(r.Body)
}

//Build builds an http.Request
func (r *Request) Build(context *endly.Context, sessionCookies Cookies) (*http.Request, bool, error) {

	if r.Body == "" && r.JSONBody != nil {
		var err error
		r.Body, err = toolbox.AsJSONText(r.JSONBody)
		if err != nil {
			return nil, false, err
		}
	}
	request := r.Clone(context)

	var reader io.Reader
	var expectBinary = false
	var err error
	var ok bool
	if len(r.Body) > 0 {
		body := []byte(request.Body)
		if request.RequestUdf != "" {
			transformed, err := udf.TransformWithUDF(context, request.RequestUdf, request.URL, string(body))
			if err != nil {
				return nil, false, err
			}
			if body, ok = transformed.([]byte); !ok {
				body = []byte(toolbox.AsString(transformed))
			}
		}
		expectBinary = strings.HasPrefix(string(body), "base64:")
		body, err = util.FromPayload(string(body))
		if err != nil {
			return nil, expectBinary, err
		}
		reader = bytes.NewReader(body)
	}

	httpRequest, err := http.NewRequest(strings.ToUpper(request.Method), request.URL, reader)
	if err != nil {
		return nil, expectBinary, err
	}

	copyHeaders(request.Header, httpRequest.Header)
	//Set cookies from active session
	SetCookies(sessionCookies, request.Header)
	//Set cookies from user http request
	SetCookies(request.Cookies, httpRequest.Header)
	return httpRequest, expectBinary, nil
}
<|endoftext|>


<commit_before>package server

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"golang.org/x/net/context"

	"go.pedge.io/proto/test"
	"go.pedge.io/protolog"

	"github.com/satori/go.uuid"
	"go.pachyderm.com/pachyderm/src/pfs"
	pfstesting "go.pachyderm.com/pachyderm/src/pfs/testing"
	"go.pachyderm.com/pachyderm/src/pkg/require"
	"go.pachyderm.com/pachyderm/src/pkg/timing"
	"go.pachyderm.com/pachyderm/src/pps"
	"go.pachyderm.com/pachyderm/src/pps/container"
	"go.pachyderm.com/pachyderm/src/pps/store"
	"google.golang.org/grpc"
)

const (
	testNumServers = 1
)

func TestBasic(t *testing.T) {
	t.Parallel()
	runTest(t, testBasic)
}

func testBasic(t *testing.T, apiClient pps.ApiClient) {
	_ = os.RemoveAll("/tmp/pachyderm-test")
	pipelineSource, err := apiClient.CreatePipelineSource(
		context.Background(),
		&pps.CreatePipelineSourceRequest{
			PipelineSource: &pps.PipelineSource{
				TypedPipelineSource: &pps.PipelineSource_GithubPipelineSource{
					GithubPipelineSource: &pps.GithubPipelineSource{
						ContextDir: "src/pps/server/testdata/basic",
						User:       "pachyderm",
						Repository: "pachyderm",
						Branch:     "master",
					},
				},
			},
		},
	)
	require.NoError(t, err)
	pipeline, err := apiClient.CreateAndGetPipeline(
		context.Background(),
		&pps.CreateAndGetPipelineRequest{
			PipelineSourceId: pipelineSource.Id,
		},
	)
	require.NoError(t, err)
	pipelineRun, err := apiClient.CreatePipelineRun(
		context.Background(),
		&pps.CreatePipelineRunRequest{
			PipelineId: pipeline.Id,
		},
	)
	require.NoError(t, err)
	_, err = apiClient.StartPipelineRun(
		context.Background(),
		&pps.StartPipelineRunRequest{
			PipelineRunId: pipelineRun.Id,
		},
	)
	require.NoError(t, err)
	pipelineRunID := pipelineRun.Id
	pipelineRunStatus, err := getFinalPipelineRunStatus(apiClient, pipelineRunID)
	require.NoError(t, err)
	require.Equal(t, pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_SUCCESS, pipelineRunStatus.PipelineRunStatusType)
	matches, err := filepath.Glob("/tmp/pachyderm-test/1-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/1-out/1.txt",
			"/tmp/pachyderm-test/1-out/10.txt",
			"/tmp/pachyderm-test/1-out/2.txt",
			"/tmp/pachyderm-test/1-out/20.txt",
			"/tmp/pachyderm-test/1-out/3.txt",
			"/tmp/pachyderm-test/1-out/30.txt",
			"/tmp/pachyderm-test/1-out/4.txt",
			"/tmp/pachyderm-test/1-out/40.txt",
			"/tmp/pachyderm-test/1-out/5.txt",
			"/tmp/pachyderm-test/1-out/50.txt",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/2-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/2-out/1.txt.copy",
			"/tmp/pachyderm-test/2-out/10.txt.copy",
			"/tmp/pachyderm-test/2-out/2.txt.copy",
			"/tmp/pachyderm-test/2-out/20.txt.copy",
			"/tmp/pachyderm-test/2-out/3.txt.copy",
			"/tmp/pachyderm-test/2-out/30.txt.copy",
			"/tmp/pachyderm-test/2-out/4.txt.copy",
			"/tmp/pachyderm-test/2-out/40.txt.copy",
			"/tmp/pachyderm-test/2-out/5.txt.copy",
			"/tmp/pachyderm-test/2-out/50.txt.copy",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/3-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/3-out/1.txt.copy3",
			"/tmp/pachyderm-test/3-out/10.txt.copy3",
			"/tmp/pachyderm-test/3-out/2.txt.copy3",
			"/tmp/pachyderm-test/3-out/20.txt.copy3",
			"/tmp/pachyderm-test/3-out/3.txt.copy3",
			"/tmp/pachyderm-test/3-out/30.txt.copy3",
			"/tmp/pachyderm-test/3-out/4.txt.copy3",
			"/tmp/pachyderm-test/3-out/40.txt.copy3",
			"/tmp/pachyderm-test/3-out/5.txt.copy3",
			"/tmp/pachyderm-test/3-out/50.txt.copy3",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/4-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/4-out/1.txt.copy4",
			"/tmp/pachyderm-test/4-out/10.txt.copy4",
			"/tmp/pachyderm-test/4-out/2.txt.copy4",
			"/tmp/pachyderm-test/4-out/20.txt.copy4",
			"/tmp/pachyderm-test/4-out/3.txt.copy4",
			"/tmp/pachyderm-test/4-out/30.txt.copy4",
			"/tmp/pachyderm-test/4-out/4.txt.copy4",
			"/tmp/pachyderm-test/4-out/40.txt.copy4",
			"/tmp/pachyderm-test/4-out/5.txt.copy4",
			"/tmp/pachyderm-test/4-out/50.txt.copy4",
			"/tmp/pachyderm-test/4-out/build-file.txt4",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/5-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/5-out/1.txt.copy3",
			"/tmp/pachyderm-test/5-out/1.txt.copy4",
			"/tmp/pachyderm-test/5-out/10.txt.copy3",
			"/tmp/pachyderm-test/5-out/10.txt.copy4",
			"/tmp/pachyderm-test/5-out/2.txt.copy3",
			"/tmp/pachyderm-test/5-out/2.txt.copy4",
			"/tmp/pachyderm-test/5-out/20.txt.copy3",
			"/tmp/pachyderm-test/5-out/20.txt.copy4",
			"/tmp/pachyderm-test/5-out/3.txt.copy3",
			"/tmp/pachyderm-test/5-out/3.txt.copy4",
			"/tmp/pachyderm-test/5-out/30.txt.copy3",
			"/tmp/pachyderm-test/5-out/30.txt.copy4",
			"/tmp/pachyderm-test/5-out/4.txt.copy3",
			"/tmp/pachyderm-test/5-out/4.txt.copy4",
			"/tmp/pachyderm-test/5-out/40.txt.copy3",
			"/tmp/pachyderm-test/5-out/40.txt.copy4",
			"/tmp/pachyderm-test/5-out/5.txt.copy3",
			"/tmp/pachyderm-test/5-out/5.txt.copy4",
			"/tmp/pachyderm-test/5-out/50.txt.copy3",
			"/tmp/pachyderm-test/5-out/50.txt.copy4",
			"/tmp/pachyderm-test/5-out/build-file.txt4",
			"/tmp/pachyderm-test/5-out/build-file2.txt",
		},
		matches,
	)
}

func getFinalPipelineRunStatus(apiClient pps.ApiClient, pipelineRunID string) (*pps.PipelineRunStatus, error) {
	// TODO(pedge): not good
	ticker := time.NewTicker(time.Second)
	for i := 0; i < 20; i++ {
		<-ticker.C
		pipelineRunStatuses, err := apiClient.GetPipelineRunStatus(
			context.Background(),
			&pps.GetPipelineRunStatusRequest{
				PipelineRunId: pipelineRunID,
			},
		)
		if err != nil {
			return nil, err
		}
		pipelineRunStatus := pipelineRunStatuses.PipelineRunStatus[0]
		protolog.Printf("status at tick %d: %v\n", i, pipelineRunStatus)
		switch pipelineRunStatus.PipelineRunStatusType {
		case pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_ERROR:
			return pipelineRunStatus, nil
		case pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_SUCCESS:
			return pipelineRunStatus, nil
		}
	}
	return nil, fmt.Errorf("did not get final pipeline status for %s", pipelineRunID)
}

func runTest(
	t *testing.T,
	f func(t *testing.T, apiClient pps.ApiClient),
) {
	containerClient, err := getContainerClient()
	require.NoError(t, err)
	storeClient, err := getRethinkClient()
	require.NoError(t, err)
	pfstesting.RunTest(
		t,
		func(t *testing.T, apiClient pfs.ApiClient, internalApiClient pfs.InternalApiClient, cluster pfstesting.Cluster) {
			prototest.RunT(
				t,
				testNumServers,
				func(servers map[string]*grpc.Server) {
					for _, server := range servers {
						pps.RegisterApiServer(server, newAPIServer(apiClient, containerClient, storeClient, timing.NewSystemTimer()))
					}
				},
				func(t *testing.T, clientConns map[string]*grpc.ClientConn) {
					var clientConn *grpc.ClientConn
					for _, c := range clientConns {
						clientConn = c
						break
					}
					f(
						t,
						pps.NewApiClient(
							clientConn,
						),
					)
				},
			)
		},
	)
}

func getContainerClient() (container.Client, error) {
	dockerHost := os.Getenv("DOCKER_HOST")
	if dockerHost == "" {
		dockerHost = "unix:///var/run/docker.sock"
	}
	return container.NewDockerClient(
		container.DockerClientOptions{
			Host: dockerHost,
		},
	)
}

func getRethinkClient() (store.Client, error) {
	address, err := getRethinkAddress()
	if err != nil {
		return nil, err
	}
	databaseName := strings.Replace(uuid.NewV4().String(), "-", "", -1)
	if err := store.InitDBs(address, databaseName); err != nil {
		return nil, err
	}
	return store.NewRethinkClient(address, databaseName)
}

func getRethinkAddress() (string, error) {
	rethinkAddr := os.Getenv("RETHINK_PORT_28015_TCP_ADDR")
	if rethinkAddr == "" {
		return "", errors.New("RETHINK_PORT_28015_TCP_ADDR not set")
	}
	return fmt.Sprintf("%s:28015", rethinkAddr), nil
}
<commit_msg>skip srs/pps/server testing<commit_after>package server

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"golang.org/x/net/context"

	"go.pedge.io/proto/test"
	"go.pedge.io/protolog"

	"github.com/satori/go.uuid"
	"go.pachyderm.com/pachyderm/src/pfs"
	pfstesting "go.pachyderm.com/pachyderm/src/pfs/testing"
	"go.pachyderm.com/pachyderm/src/pkg/require"
	"go.pachyderm.com/pachyderm/src/pkg/timing"
	"go.pachyderm.com/pachyderm/src/pps"
	"go.pachyderm.com/pachyderm/src/pps/container"
	"go.pachyderm.com/pachyderm/src/pps/store"
	"google.golang.org/grpc"
)

const (
	testNumServers = 1
)

func TestBasic(t *testing.T) {
	t.Skip()
	t.Parallel()
	runTest(t, testBasic)
}

func testBasic(t *testing.T, apiClient pps.ApiClient) {
	_ = os.RemoveAll("/tmp/pachyderm-test")
	pipelineSource, err := apiClient.CreatePipelineSource(
		context.Background(),
		&pps.CreatePipelineSourceRequest{
			PipelineSource: &pps.PipelineSource{
				TypedPipelineSource: &pps.PipelineSource_GithubPipelineSource{
					GithubPipelineSource: &pps.GithubPipelineSource{
						ContextDir: "src/pps/server/testdata/basic",
						User:       "pachyderm",
						Repository: "pachyderm",
						Branch:     "master",
					},
				},
			},
		},
	)
	require.NoError(t, err)
	pipeline, err := apiClient.CreateAndGetPipeline(
		context.Background(),
		&pps.CreateAndGetPipelineRequest{
			PipelineSourceId: pipelineSource.Id,
		},
	)
	require.NoError(t, err)
	pipelineRun, err := apiClient.CreatePipelineRun(
		context.Background(),
		&pps.CreatePipelineRunRequest{
			PipelineId: pipeline.Id,
		},
	)
	require.NoError(t, err)
	_, err = apiClient.StartPipelineRun(
		context.Background(),
		&pps.StartPipelineRunRequest{
			PipelineRunId: pipelineRun.Id,
		},
	)
	require.NoError(t, err)
	pipelineRunID := pipelineRun.Id
	pipelineRunStatus, err := getFinalPipelineRunStatus(apiClient, pipelineRunID)
	require.NoError(t, err)
	require.Equal(t, pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_SUCCESS, pipelineRunStatus.PipelineRunStatusType)
	matches, err := filepath.Glob("/tmp/pachyderm-test/1-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/1-out/1.txt",
			"/tmp/pachyderm-test/1-out/10.txt",
			"/tmp/pachyderm-test/1-out/2.txt",
			"/tmp/pachyderm-test/1-out/20.txt",
			"/tmp/pachyderm-test/1-out/3.txt",
			"/tmp/pachyderm-test/1-out/30.txt",
			"/tmp/pachyderm-test/1-out/4.txt",
			"/tmp/pachyderm-test/1-out/40.txt",
			"/tmp/pachyderm-test/1-out/5.txt",
			"/tmp/pachyderm-test/1-out/50.txt",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/2-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/2-out/1.txt.copy",
			"/tmp/pachyderm-test/2-out/10.txt.copy",
			"/tmp/pachyderm-test/2-out/2.txt.copy",
			"/tmp/pachyderm-test/2-out/20.txt.copy",
			"/tmp/pachyderm-test/2-out/3.txt.copy",
			"/tmp/pachyderm-test/2-out/30.txt.copy",
			"/tmp/pachyderm-test/2-out/4.txt.copy",
			"/tmp/pachyderm-test/2-out/40.txt.copy",
			"/tmp/pachyderm-test/2-out/5.txt.copy",
			"/tmp/pachyderm-test/2-out/50.txt.copy",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/3-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/3-out/1.txt.copy3",
			"/tmp/pachyderm-test/3-out/10.txt.copy3",
			"/tmp/pachyderm-test/3-out/2.txt.copy3",
			"/tmp/pachyderm-test/3-out/20.txt.copy3",
			"/tmp/pachyderm-test/3-out/3.txt.copy3",
			"/tmp/pachyderm-test/3-out/30.txt.copy3",
			"/tmp/pachyderm-test/3-out/4.txt.copy3",
			"/tmp/pachyderm-test/3-out/40.txt.copy3",
			"/tmp/pachyderm-test/3-out/5.txt.copy3",
			"/tmp/pachyderm-test/3-out/50.txt.copy3",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/4-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/4-out/1.txt.copy4",
			"/tmp/pachyderm-test/4-out/10.txt.copy4",
			"/tmp/pachyderm-test/4-out/2.txt.copy4",
			"/tmp/pachyderm-test/4-out/20.txt.copy4",
			"/tmp/pachyderm-test/4-out/3.txt.copy4",
			"/tmp/pachyderm-test/4-out/30.txt.copy4",
			"/tmp/pachyderm-test/4-out/4.txt.copy4",
			"/tmp/pachyderm-test/4-out/40.txt.copy4",
			"/tmp/pachyderm-test/4-out/5.txt.copy4",
			"/tmp/pachyderm-test/4-out/50.txt.copy4",
			"/tmp/pachyderm-test/4-out/build-file.txt4",
		},
		matches,
	)
	matches, err = filepath.Glob("/tmp/pachyderm-test/5-out/*")
	require.NoError(t, err)
	require.Equal(
		t,
		[]string{
			"/tmp/pachyderm-test/5-out/1.txt.copy3",
			"/tmp/pachyderm-test/5-out/1.txt.copy4",
			"/tmp/pachyderm-test/5-out/10.txt.copy3",
			"/tmp/pachyderm-test/5-out/10.txt.copy4",
			"/tmp/pachyderm-test/5-out/2.txt.copy3",
			"/tmp/pachyderm-test/5-out/2.txt.copy4",
			"/tmp/pachyderm-test/5-out/20.txt.copy3",
			"/tmp/pachyderm-test/5-out/20.txt.copy4",
			"/tmp/pachyderm-test/5-out/3.txt.copy3",
			"/tmp/pachyderm-test/5-out/3.txt.copy4",
			"/tmp/pachyderm-test/5-out/30.txt.copy3",
			"/tmp/pachyderm-test/5-out/30.txt.copy4",
			"/tmp/pachyderm-test/5-out/4.txt.copy3",
			"/tmp/pachyderm-test/5-out/4.txt.copy4",
			"/tmp/pachyderm-test/5-out/40.txt.copy3",
			"/tmp/pachyderm-test/5-out/40.txt.copy4",
			"/tmp/pachyderm-test/5-out/5.txt.copy3",
			"/tmp/pachyderm-test/5-out/5.txt.copy4",
			"/tmp/pachyderm-test/5-out/50.txt.copy3",
			"/tmp/pachyderm-test/5-out/50.txt.copy4",
			"/tmp/pachyderm-test/5-out/build-file.txt4",
			"/tmp/pachyderm-test/5-out/build-file2.txt",
		},
		matches,
	)
}

func getFinalPipelineRunStatus(apiClient pps.ApiClient, pipelineRunID string) (*pps.PipelineRunStatus, error) {
	// TODO(pedge): not good
	ticker := time.NewTicker(time.Second)
	for i := 0; i < 20; i++ {
		<-ticker.C
		pipelineRunStatuses, err := apiClient.GetPipelineRunStatus(
			context.Background(),
			&pps.GetPipelineRunStatusRequest{
				PipelineRunId: pipelineRunID,
			},
		)
		if err != nil {
			return nil, err
		}
		pipelineRunStatus := pipelineRunStatuses.PipelineRunStatus[0]
		protolog.Printf("status at tick %d: %v\n", i, pipelineRunStatus)
		switch pipelineRunStatus.PipelineRunStatusType {
		case pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_ERROR:
			return pipelineRunStatus, nil
		case pps.PipelineRunStatusType_PIPELINE_RUN_STATUS_TYPE_SUCCESS:
			return pipelineRunStatus, nil
		}
	}
	return nil, fmt.Errorf("did not get final pipeline status for %s", pipelineRunID)
}

func runTest(
	t *testing.T,
	f func(t *testing.T, apiClient pps.ApiClient),
) {
	containerClient, err := getContainerClient()
	require.NoError(t, err)
	storeClient, err := getRethinkClient()
	require.NoError(t, err)
	pfstesting.RunTest(
		t,
		func(t *testing.T, apiClient pfs.ApiClient, internalApiClient pfs.InternalApiClient, cluster pfstesting.Cluster) {
			prototest.RunT(
				t,
				testNumServers,
				func(servers map[string]*grpc.Server) {
					for _, server := range servers {
						pps.RegisterApiServer(server, newAPIServer(apiClient, containerClient, storeClient, timing.NewSystemTimer()))
					}
				},
				func(t *testing.T, clientConns map[string]*grpc.ClientConn) {
					var clientConn *grpc.ClientConn
					for _, c := range clientConns {
						clientConn = c
						break
					}
					f(
						t,
						pps.NewApiClient(
							clientConn,
						),
					)
				},
			)
		},
	)
}

func getContainerClient() (container.Client, error) {
	dockerHost := os.Getenv("DOCKER_HOST")
	if dockerHost == "" {
		dockerHost = "unix:///var/run/docker.sock"
	}
	return container.NewDockerClient(
		container.DockerClientOptions{
			Host: dockerHost,
		},
	)
}

func getRethinkClient() (store.Client, error) {
	address, err := getRethinkAddress()
	if err != nil {
		return nil, err
	}
	databaseName := strings.Replace(uuid.NewV4().String(), "-", "", -1)
	if err := store.InitDBs(address, databaseName); err != nil {
		return nil, err
	}
	return store.NewRethinkClient(address, databaseName)
}

func getRethinkAddress() (string, error) {
	rethinkAddr := os.Getenv("RETHINK_PORT_28015_TCP_ADDR")
	if rethinkAddr == "" {
		return "", errors.New("RETHINK_PORT_28015_TCP_ADDR not set")
	}
	return fmt.Sprintf("%s:28015", rethinkAddr), nil
}
<|endoftext|>


<commit_before>package discover

import (
	"errors"
	"net"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/flynn/rpcplus"
)

var WaitTimeoutSecs = 10

type Service struct {
	Created int
	Name    string
	Host    string
	Port    string
	Addr    string
	Attrs   map[string]string
}

type ServiceSet struct {
	services   map[string]*Service
	filters    map[string]string
	watches    map[chan *ServiceUpdate]struct{}
	serMutex   sync.Mutex
	filMutex   sync.Mutex
	watchMutex sync.Mutex
	call       *rpcplus.Call
}

func copyService(service *Service) *Service {
	s := *service
	s.Attrs = make(map[string]string, len(service.Attrs))
	for k, v := range service.Attrs {
		s.Attrs[k] = v
	}
	return &s
}

func makeServiceSet(call *rpcplus.Call) *ServiceSet {
	return &ServiceSet{
		services: make(map[string]*Service),
		filters:  make(map[string]string),
		watches:  make(map[chan *ServiceUpdate]struct{}),
		call:     call,
	}
}

func (s *ServiceSet) bind(updates chan *ServiceUpdate) chan struct{} {
	// current is an event when enough service updates have been
	// received to bring us to "current" state (when subscribed)
	current := make(chan struct{})
	go func() {
		isCurrent := false
		for update := range updates {
			if update.Addr == "" && update.Name == "" && !isCurrent {
				close(current)
				isCurrent = true
				continue
			}
			if s.filters != nil && !s.matchFilters(update.Attrs) {
				continue
			}

			s.serMutex.Lock()
			if update.Online {
				if _, exists := s.services[update.Addr]; !exists {
					host, port, _ := net.SplitHostPort(update.Addr)
					s.services[update.Addr] = &Service{
						Name: update.Name,
						Addr: update.Addr,
						Host: host,
						Port: port,
					}
				}
				s.services[update.Addr].Attrs = update.Attrs
			} else {
				if _, exists := s.services[update.Addr]; exists {
					delete(s.services, update.Addr)
				} else {
					s.serMutex.Unlock()
					continue
				}
			}
			s.serMutex.Unlock()
			s.updateWatches(update)
		}
		s.closeWatches()
	}()
	return current
}

func (s *ServiceSet) updateWatches(update *ServiceUpdate) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	for ch := range s.watches {
		ch <- update
	}
}

func (s *ServiceSet) closeWatches() {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	for ch := range s.watches {
		close(ch)
	}
}

func (s *ServiceSet) matchFilters(attrs map[string]string) bool {
	s.filMutex.Lock()
	defer s.filMutex.Unlock()
	for key, value := range s.filters {
		if attrs[key] != value {
			return false
		}
	}
	return true
}

// deprecated
func (s *ServiceSet) Online() []*Service {
	return s.Services()
}

func (s *ServiceSet) Services() []*Service {
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	list := make([]*Service, 0, len(s.services))
	for _, service := range s.services {
		list = append(list, copyService(service))
	}
	return list
}

// deprecated
func (s *ServiceSet) OnlineAddrs() []string {
	return s.Addrs()
}

func (s *ServiceSet) Addrs() []string {
	list := make([]string, 0, len(s.services))
	for _, service := range s.Services() {
		list = append(list, service.Addr)
	}
	return list
}

func (s *ServiceSet) Select(attrs map[string]string) []*Service {
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	list := make([]*Service, 0, len(s.services))
outer:
	for _, service := range s.services {
		for key, value := range attrs {
			if service.Attrs[key] != value {
				continue outer
			}
		}
		list = append(list, service)
	}
	return list
}

func (s *ServiceSet) Filter(attrs map[string]string) {
	s.filMutex.Lock()
	s.filters = attrs
	s.filMutex.Unlock()
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	for key, service := range s.services {
		if !s.matchFilters(service.Attrs) {
			delete(s.services, key)
		}
	}
}

func (s *ServiceSet) Watch(ch chan *ServiceUpdate, bringCurrent bool) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	s.watches[ch] = struct{}{}
	if bringCurrent {
		go func() {
			s.serMutex.Lock()
			defer s.serMutex.Unlock()
			for _, service := range s.services {
				ch <- &ServiceUpdate{
					Name:   service.Name,
					Addr:   service.Addr,
					Online: true,
					Attrs:  service.Attrs,
				}
			}
		}()
	}
}

func (s *ServiceSet) Unwatch(ch chan *ServiceUpdate) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	delete(s.watches, ch)
}

func (s *ServiceSet) Wait() (*ServiceUpdate, error) {
	updateCh := make(chan *ServiceUpdate, 1)
	s.Watch(updateCh, true)
	defer s.Unwatch(updateCh)
	select {
	case update := <-updateCh:
		return update, nil
	case <-time.After(time.Duration(WaitTimeoutSecs) * time.Second):
		return nil, errors.New("discover: wait timeout exceeded")
	}
}

func (s *ServiceSet) Close() error {
	return s.call.CloseStream()
}

type Client struct {
	client     *rpcplus.Client
	heartbeats map[string]chan struct{}
	hbMutex    sync.Mutex
}

func NewClient() (*Client, error) {
	addr := os.Getenv("DISCOVERD")
	if addr == "" {
		addr = "127.0.0.1:1111"
	}
	return NewClientUsingAddress(addr)
}

func NewClientUsingAddress(addr string) (*Client, error) {
	client, err := rpcplus.DialHTTP("tcp", addr)
	return &Client{
		client:     client,
		heartbeats: make(map[string]chan struct{}),
	}, err
}

func pickMostPublicIp() string {
	// TODO: prefer non 10.0.0.0, 172.16.0.0, and 192.168.0.0
	addrs, _ := net.InterfaceAddrs()
	var ip string
	for _, addr := range addrs {
		ip = strings.SplitN(addr.String(), "/", 2)[0]
		if !strings.Contains(ip, "::") && ip != "127.0.0.1" {
			return ip
		}
	}
	return ip
}

func (c *Client) ServiceSet(name string) (*ServiceSet, error) {
	updates := make(chan *ServiceUpdate)
	call := c.client.StreamGo("Agent.Subscribe", &Args{
		Name: name,
	}, updates)
	set := makeServiceSet(call)
	<-set.bind(updates)
	return set, nil
}

func (c *Client) Services(name string) ([]*Service, error) {
	set, err := c.ServiceSet(name)
	if err != nil {
		return nil, err
	}
	if len(set.Services()) == 0 {
		_, err = set.Wait()
		if err != nil {
			return nil, err
		}
	}
	set.Close()
	return set.Services(), nil

}

func (c *Client) Register(name, port string, attributes map[string]string) error {
	return c.RegisterWithHost(name, pickMostPublicIp(), port, attributes)
}

func (c *Client) RegisterWithHost(name, host, port string, attributes map[string]string) error {
	args := &Args{
		Name:  name,
		Addr:  net.JoinHostPort(host, port),
		Attrs: attributes,
	}
	var ret struct{}
	err := c.client.Call("Agent.Register", args, &ret)
	if err != nil {
		return errors.New("discover: register failed: " + err.Error())
	}
	done := make(chan struct{})
	c.hbMutex.Lock()
	c.heartbeats[args.Addr] = done
	c.hbMutex.Unlock()
	go func() {
		ticker := time.NewTicker(HeartbeatIntervalSecs * time.Second) // TODO: add jitter
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
				// TODO: log error here
				c.client.Call("Agent.Heartbeat", &Args{
					Name: name,
					Addr: args.Addr,
				}, &struct{}{})
			case <-done:
				return
			}
		}
	}()
	return nil
}

func (c *Client) Unregister(name, port string) error {
	return c.UnregisterWithHost(name, pickMostPublicIp(), port)
}

func (c *Client) UnregisterWithHost(name, host, port string) error {
	args := &Args{
		Name: name,
		Addr: net.JoinHostPort(host, port),
	}
	c.hbMutex.Lock()
	close(c.heartbeats[args.Addr])
	delete(c.heartbeats, args.Addr)
	c.hbMutex.Unlock()
	err := c.client.Call("Agent.Unregister", args, &struct{}{})
	if err != nil {
		return errors.New("discover: unregister failed: " + err.Error())
	}
	return nil
}
<commit_msg>discoverd: just wait. blocks if no services until first update or timeout, otherwise noop.<commit_after>package discover

import (
	"errors"
	"net"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/flynn/rpcplus"
)

var WaitTimeoutSecs = 10

type Service struct {
	Created int
	Name    string
	Host    string
	Port    string
	Addr    string
	Attrs   map[string]string
}

type ServiceSet struct {
	services   map[string]*Service
	filters    map[string]string
	watches    map[chan *ServiceUpdate]struct{}
	serMutex   sync.Mutex
	filMutex   sync.Mutex
	watchMutex sync.Mutex
	call       *rpcplus.Call
}

func copyService(service *Service) *Service {
	s := *service
	s.Attrs = make(map[string]string, len(service.Attrs))
	for k, v := range service.Attrs {
		s.Attrs[k] = v
	}
	return &s
}

func makeServiceSet(call *rpcplus.Call) *ServiceSet {
	return &ServiceSet{
		services: make(map[string]*Service),
		filters:  make(map[string]string),
		watches:  make(map[chan *ServiceUpdate]struct{}),
		call:     call,
	}
}

func (s *ServiceSet) bind(updates chan *ServiceUpdate) chan struct{} {
	// current is an event when enough service updates have been
	// received to bring us to "current" state (when subscribed)
	current := make(chan struct{})
	go func() {
		isCurrent := false
		for update := range updates {
			if update.Addr == "" && update.Name == "" && !isCurrent {
				close(current)
				isCurrent = true
				continue
			}
			if s.filters != nil && !s.matchFilters(update.Attrs) {
				continue
			}

			s.serMutex.Lock()
			if update.Online {
				if _, exists := s.services[update.Addr]; !exists {
					host, port, _ := net.SplitHostPort(update.Addr)
					s.services[update.Addr] = &Service{
						Name: update.Name,
						Addr: update.Addr,
						Host: host,
						Port: port,
					}
				}
				s.services[update.Addr].Attrs = update.Attrs
			} else {
				if _, exists := s.services[update.Addr]; exists {
					delete(s.services, update.Addr)
				} else {
					s.serMutex.Unlock()
					continue
				}
			}
			s.serMutex.Unlock()
			s.updateWatches(update)
		}
		s.closeWatches()
	}()
	return current
}

func (s *ServiceSet) updateWatches(update *ServiceUpdate) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	for ch := range s.watches {
		ch <- update
	}
}

func (s *ServiceSet) closeWatches() {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	for ch := range s.watches {
		close(ch)
	}
}

func (s *ServiceSet) matchFilters(attrs map[string]string) bool {
	s.filMutex.Lock()
	defer s.filMutex.Unlock()
	for key, value := range s.filters {
		if attrs[key] != value {
			return false
		}
	}
	return true
}

// deprecated
func (s *ServiceSet) Online() []*Service {
	return s.Services()
}

func (s *ServiceSet) Services() []*Service {
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	list := make([]*Service, 0, len(s.services))
	for _, service := range s.services {
		list = append(list, copyService(service))
	}
	return list
}

// deprecated
func (s *ServiceSet) OnlineAddrs() []string {
	return s.Addrs()
}

func (s *ServiceSet) Addrs() []string {
	list := make([]string, 0, len(s.services))
	for _, service := range s.Services() {
		list = append(list, service.Addr)
	}
	return list
}

func (s *ServiceSet) Select(attrs map[string]string) []*Service {
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	list := make([]*Service, 0, len(s.services))
outer:
	for _, service := range s.services {
		for key, value := range attrs {
			if service.Attrs[key] != value {
				continue outer
			}
		}
		list = append(list, service)
	}
	return list
}

func (s *ServiceSet) Filter(attrs map[string]string) {
	s.filMutex.Lock()
	s.filters = attrs
	s.filMutex.Unlock()
	s.serMutex.Lock()
	defer s.serMutex.Unlock()
	for key, service := range s.services {
		if !s.matchFilters(service.Attrs) {
			delete(s.services, key)
		}
	}
}

func (s *ServiceSet) Watch(ch chan *ServiceUpdate, bringCurrent bool) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	s.watches[ch] = struct{}{}
	if bringCurrent {
		go func() {
			s.serMutex.Lock()
			defer s.serMutex.Unlock()
			for _, service := range s.services {
				ch <- &ServiceUpdate{
					Name:   service.Name,
					Addr:   service.Addr,
					Online: true,
					Attrs:  service.Attrs,
				}
			}
		}()
	}
}

func (s *ServiceSet) Unwatch(ch chan *ServiceUpdate) {
	s.watchMutex.Lock()
	defer s.watchMutex.Unlock()
	delete(s.watches, ch)
}

func (s *ServiceSet) Wait() (*ServiceUpdate, error) {
	updateCh := make(chan *ServiceUpdate, 1)
	s.Watch(updateCh, true)
	defer s.Unwatch(updateCh)
	select {
	case update := <-updateCh:
		return update, nil
	case <-time.After(time.Duration(WaitTimeoutSecs) * time.Second):
		return nil, errors.New("discover: wait timeout exceeded")
	}
}

func (s *ServiceSet) Close() error {
	return s.call.CloseStream()
}

type Client struct {
	client     *rpcplus.Client
	heartbeats map[string]chan struct{}
	hbMutex    sync.Mutex
}

func NewClient() (*Client, error) {
	addr := os.Getenv("DISCOVERD")
	if addr == "" {
		addr = "127.0.0.1:1111"
	}
	return NewClientUsingAddress(addr)
}

func NewClientUsingAddress(addr string) (*Client, error) {
	client, err := rpcplus.DialHTTP("tcp", addr)
	return &Client{
		client:     client,
		heartbeats: make(map[string]chan struct{}),
	}, err
}

func pickMostPublicIp() string {
	// TODO: prefer non 10.0.0.0, 172.16.0.0, and 192.168.0.0
	addrs, _ := net.InterfaceAddrs()
	var ip string
	for _, addr := range addrs {
		ip = strings.SplitN(addr.String(), "/", 2)[0]
		if !strings.Contains(ip, "::") && ip != "127.0.0.1" {
			return ip
		}
	}
	return ip
}

func (c *Client) ServiceSet(name string) (*ServiceSet, error) {
	updates := make(chan *ServiceUpdate)
	call := c.client.StreamGo("Agent.Subscribe", &Args{
		Name: name,
	}, updates)
	set := makeServiceSet(call)
	<-set.bind(updates)
	return set, nil
}

func (c *Client) Services(name string) ([]*Service, error) {
	set, err := c.ServiceSet(name)
	if err != nil {
		return nil, err
	}
	_, err = set.Wait()
	if err != nil {
		return nil, err
	}
	set.Close()
	return set.Services(), nil

}

func (c *Client) Register(name, port string, attributes map[string]string) error {
	return c.RegisterWithHost(name, pickMostPublicIp(), port, attributes)
}

func (c *Client) RegisterWithHost(name, host, port string, attributes map[string]string) error {
	args := &Args{
		Name:  name,
		Addr:  net.JoinHostPort(host, port),
		Attrs: attributes,
	}
	var ret struct{}
	err := c.client.Call("Agent.Register", args, &ret)
	if err != nil {
		return errors.New("discover: register failed: " + err.Error())
	}
	done := make(chan struct{})
	c.hbMutex.Lock()
	c.heartbeats[args.Addr] = done
	c.hbMutex.Unlock()
	go func() {
		ticker := time.NewTicker(HeartbeatIntervalSecs * time.Second) // TODO: add jitter
		defer ticker.Stop()
		for {
			select {
			case <-ticker.C:
				// TODO: log error here
				c.client.Call("Agent.Heartbeat", &Args{
					Name: name,
					Addr: args.Addr,
				}, &struct{}{})
			case <-done:
				return
			}
		}
	}()
	return nil
}

func (c *Client) Unregister(name, port string) error {
	return c.UnregisterWithHost(name, pickMostPublicIp(), port)
}

func (c *Client) UnregisterWithHost(name, host, port string) error {
	args := &Args{
		Name: name,
		Addr: net.JoinHostPort(host, port),
	}
	c.hbMutex.Lock()
	close(c.heartbeats[args.Addr])
	delete(c.heartbeats, args.Addr)
	c.hbMutex.Unlock()
	err := c.client.Call("Agent.Unregister", args, &struct{}{})
	if err != nil {
		return errors.New("discover: unregister failed: " + err.Error())
	}
	return nil
}
<|endoftext|>


<commit_before>package libkb

import (
	"fmt"
)

// NOTE: This file is the source of truth for our version number, but we have a
//       script that reads it at packaging/version.sh. If you refactor this
//       file, update that script.

// Version as MAJOR.MINOR.PATCH
const Version = "1.0.0"

// Build number
const Build = ""

// VersionString returns semantic version string.
func VersionString() string {
	return fmt.Sprintf("%s-%s", Version, Build)
}
<commit_msg>New version v1.0.0-28<commit_after>package libkb

import (
	"fmt"
)

// NOTE: This file is the source of truth for our version number, but we have a
//       script that reads it at packaging/version.sh. If you refactor this
//       file, update that script.

// Version as MAJOR.MINOR.PATCH
const Version = "1.0.0"

// Build number
const Build = "28"

// VersionString returns semantic version string.
func VersionString() string {
	return fmt.Sprintf("%s-%s", Version, Build)
}
<|endoftext|>


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

package libkb

// Version is the current version (should be MAJOR.MINOR.PATCH)
const Version = "1.0.28"
<commit_msg>Version bump<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

// Version is the current version (should be MAJOR.MINOR.PATCH)
const Version = "1.0.29"
<|endoftext|>


<commit_before>// Copyright 2012 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 vcs

import (
	"encoding/xml"
	"fmt"
	"io"
	"strings"
)

// charsetReader returns a reader for the given charset. Currently
// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
// error which is printed by go get, so the user can find why the package
// wasn't downloaded if the encoding is not supported. Note that, in
// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
// greater than 0x7f are not rejected).
func charsetReader(charset string, input io.Reader) (io.Reader, error) {
	switch strings.ToLower(charset) {
	case "ascii":
		return input, nil
	default:
		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
	}
}

// parseMetaGoImports returns meta imports from the HTML in r.
// Parsing ends at the end of the <head> section or the beginning of the <body>.
func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
	d := xml.NewDecoder(r)
	d.CharsetReader = charsetReader
	d.Strict = false
	var t xml.Token
	for {
		t, err = d.Token()
		if err != nil {
			if err == io.EOF {
				err = nil
			}
			return
		}
		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
			return
		}
		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
			return
		}
		e, ok := t.(xml.StartElement)
		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
			continue
		}
		if attrValue(e.Attr, "name") != "go-import" {
			continue
		}
		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
			imports = append(imports, metaImport{
				Prefix:   f[0],
				VCS:      f[1],
				RepoRoot: f[2],
			})
		}
	}
}

// attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string {
	for _, a := range attrs {
		if strings.EqualFold(a.Name.Local, name) {
			return a.Value
		}
	}
	return ""
}
<commit_msg>go/vcs: workaround EOF bug in token-based XML decoder<commit_after>// Copyright 2012 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 vcs

import (
	"encoding/xml"
	"fmt"
	"io"
	"strings"
)

// charsetReader returns a reader for the given charset. Currently
// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
// error which is printed by go get, so the user can find why the package
// wasn't downloaded if the encoding is not supported. Note that, in
// order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
// greater than 0x7f are not rejected).
func charsetReader(charset string, input io.Reader) (io.Reader, error) {
	switch strings.ToLower(charset) {
	case "ascii":
		return input, nil
	default:
		return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
	}
}

// parseMetaGoImports returns meta imports from the HTML in r.
// Parsing ends at the end of the <head> section or the beginning of the <body>.
func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
	d := xml.NewDecoder(r)
	d.CharsetReader = charsetReader
	d.Strict = false
	var t xml.Token
	for {
		t, err = d.Token()
		if err != nil {
			if err == io.EOF || len(imports) > 0 {
				err = nil
			}
			return
		}
		if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
			return
		}
		if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
			return
		}
		e, ok := t.(xml.StartElement)
		if !ok || !strings.EqualFold(e.Name.Local, "meta") {
			continue
		}
		if attrValue(e.Attr, "name") != "go-import" {
			continue
		}
		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
			imports = append(imports, metaImport{
				Prefix:   f[0],
				VCS:      f[1],
				RepoRoot: f[2],
			})
		}
	}
}

// attrValue returns the attribute value for the case-insensitive key
// `name', or the empty string if nothing is found.
func attrValue(attrs []xml.Attr, name string) string {
	for _, a := range attrs {
		if strings.EqualFold(a.Name.Local, name) {
			return a.Value
		}
	}
	return ""
}
<|endoftext|>


<commit_before>package types

import (
	"bytes"
	"fmt"
	"net"
	"time"

	crypto "github.com/tendermint/go-crypto"
	wire "github.com/tendermint/go-wire"
	"github.com/tendermint/go-wire/data"
	cmn "github.com/tendermint/tmlibs/common"
	"github.com/tendermint/tmlibs/log"

	"github.com/tendermint/tendermint/types"
)

//-----------------------------------------------------------------

var _ types.PrivValidator = (*PrivValidatorSocketClient)(nil)

// PrivValidatorSocketClient implements PrivValidator.
// It uses a socket to request signatures.
type PrivValidatorSocketClient struct {
	cmn.BaseService

	conn net.Conn

	ID            types.ValidatorID
	SocketAddress string
}

const (
	dialRetryIntervalSeconds = 1
)

// NewPrivValidatorSocketClient returns an instance of
// PrivValidatorSocketClient.
func NewPrivValidatorSocketClient(logger log.Logger, socketAddr string) *PrivValidatorSocketClient {
	pvsc := &PrivValidatorSocketClient{
		SocketAddress: socketAddr,
	}
	pvsc.BaseService = *cmn.NewBaseService(logger, "privValidatorSocketClient", pvsc)
	return pvsc
}

// OnStart implements cmn.Service.
func (pvsc *PrivValidatorSocketClient) OnStart() error {
	if err := pvsc.BaseService.OnStart(); err != nil {
		return err
	}

	var err error
	var conn net.Conn
RETRY_LOOP:
	for {
		conn, err = cmn.Connect(pvsc.SocketAddress)
		if err != nil {
			pvsc.Logger.Error(fmt.Sprintf("PrivValidatorSocket failed to connect to %v.  Retrying...", pvsc.SocketAddress))
			time.Sleep(time.Second * dialRetryIntervalSeconds)
			continue RETRY_LOOP
		}
		pvsc.conn = conn
		return nil
	}
}

// OnStop implements cmn.Service.
func (pvsc *PrivValidatorSocketClient) OnStop() {
	pvsc.BaseService.OnStop()

	if pvsc.conn != nil {
		pvsc.conn.Close()
	}
}

// Address is an alias for PubKey().Address().
func (pvsc *PrivValidatorSocketClient) Address() data.Bytes {
	pubKey := pvsc.PubKey()
	return pubKey.Address()
}

// PubKey implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) PubKey() crypto.PubKey {
	res, err := readWrite(pvsc.conn, PubKeyMsg{})
	if err != nil {
		panic(err)
	}
	return res.(PubKeyMsg).PubKey
}

// SignVote implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignVote(chainID string, vote *types.Vote) error {
	res, err := readWrite(pvsc.conn, SignVoteMsg{Vote: vote})
	if err != nil {
		return err
	}
	*vote = *res.(SignVoteMsg).Vote
	return nil
}

// SignProposal implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignProposal(chainID string, proposal *types.Proposal) error {
	res, err := readWrite(pvsc.conn, SignProposalMsg{Proposal: proposal})
	if err != nil {
		return err
	}
	*proposal = *res.(SignProposalMsg).Proposal
	return nil
}

// SignHeartbeat implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error {
	res, err := readWrite(pvsc.conn, SignHeartbeatMsg{Heartbeat: heartbeat})
	if err != nil {
		return err
	}
	*heartbeat = *res.(SignHeartbeatMsg).Heartbeat
	return nil
}

//---------------------------------------------------------

// PrivValidatorSocketServer implements PrivValidator.
// It responds to requests over a socket
type PrivValidatorSocketServer struct {
	cmn.BaseService

	proto, addr string
	listener    net.Listener

	privVal PrivValidator
	chainID string
}

// NewPrivValidatorSocketServer returns an instance of
// PrivValidatorSocketServer.
func NewPrivValidatorSocketServer(logger log.Logger, socketAddr, chainID string, privVal PrivValidator) *PrivValidatorSocketServer {
	proto, addr := cmn.ProtocolAndAddress(socketAddr)
	pvss := &PrivValidatorSocketServer{
		proto:   proto,
		addr:    addr,
		privVal: privVal,
		chainID: chainID,
	}
	pvss.BaseService = *cmn.NewBaseService(logger, "privValidatorSocketServer", pvss)
	return pvss
}

// OnStart implements cmn.Service.
func (pvss *PrivValidatorSocketServer) OnStart() error {
	if err := pvss.BaseService.OnStart(); err != nil {
		return err
	}
	ln, err := net.Listen(pvss.proto, pvss.addr)
	if err != nil {
		return err
	}
	pvss.listener = ln
	go pvss.acceptConnectionsRoutine()
	return nil
}

// OnStop implements cmn.Service.
func (pvss *PrivValidatorSocketServer) OnStop() {
	pvss.BaseService.OnStop()

	if pvss.listener == nil {
		return
	}

	if err := pvss.listener.Close(); err != nil {
		pvss.Logger.Error("Error closing listener", "err", err)
	}
}

func (pvss *PrivValidatorSocketServer) acceptConnectionsRoutine() {
	for {
		// Accept a connection
		pvss.Logger.Info("Waiting for new connection...")

		conn, err := pvss.listener.Accept()
		if err != nil {
			if !pvss.IsRunning() {
				return // Ignore error from listener closing.
			}
			pvss.Logger.Error("Failed to accept connection: " + err.Error())
			continue
		}

		pvss.Logger.Info("Accepted a new connection")

		// read/write
		for {
			if !pvss.IsRunning() {
				return // Ignore error from listener closing.
			}

			var n int
			var err error
			b := wire.ReadByteSlice(conn, 0, &n, &err) //XXX: no max
			req, err := decodeMsg(b)
			if err != nil {
				panic(err)
			}
			var res PrivValidatorSocketMsg
			switch r := req.(type) {
			case PubKeyMsg:
				res = PubKeyMsg{pvss.privVal.PubKey()}
			case SignVoteMsg:
				pvss.privVal.SignVote(pvss.chainID, r.Vote)
				res = SignVoteMsg{r.Vote}
			case SignProposalMsg:
				pvss.privVal.SignProposal(pvss.chainID, r.Proposal)
				res = SignProposalMsg{r.Proposal}
			case SignHeartbeatMsg:
				pvss.privVal.SignHeartbeat(pvss.chainID, r.Heartbeat)
				res = SignHeartbeatMsg{r.Heartbeat}
			default:
				panic(fmt.Sprintf("unknown msg: %v", r))
			}

			b = wire.BinaryBytes(res)
			_, err = conn.Write(b)
			if err != nil {
				panic(err)
			}
		}
	}
}

//---------------------------------------------------------

const (
	msgTypePubKey        = byte(0x01)
	msgTypeSignVote      = byte(0x10)
	msgTypeSignProposal  = byte(0x11)
	msgTypeSignHeartbeat = byte(0x12)
)

// PrivValidatorSocketMsg is a message sent between PrivValidatorSocket client
// and server.
type PrivValidatorSocketMsg interface{}

var _ = wire.RegisterInterface(
	struct{ PrivValidatorSocketMsg }{},
	wire.ConcreteType{&PubKeyMsg{}, msgTypePubKey},
	wire.ConcreteType{&SignVoteMsg{}, msgTypeSignVote},
	wire.ConcreteType{&SignProposalMsg{}, msgTypeSignProposal},
	wire.ConcreteType{&SignHeartbeatMsg{}, msgTypeSignHeartbeat},
)

func readWrite(conn net.Conn, req PrivValidatorSocketMsg) (res PrivValidatorSocketMsg, err error) {
	b := wire.BinaryBytes(req)
	_, err = conn.Write(b)
	if err != nil {
		return nil, err
	}

	var n int
	b = wire.ReadByteSlice(conn, 0, &n, &err) //XXX: no max
	return decodeMsg(b)
}

func decodeMsg(bz []byte) (msg PrivValidatorSocketMsg, err error) {
	n := new(int)
	r := bytes.NewReader(bz)
	msgI := wire.ReadBinary(struct{ PrivValidatorSocketMsg }{}, r, 0, n, &err)
	msg = msgI.(struct{ PrivValidatorSocketMsg }).PrivValidatorSocketMsg
	return msg, err
}

// PubKeyMsg is a PrivValidatorSocket message containing the public key.
type PubKeyMsg struct {
	PubKey crypto.PubKey
}

// SignVoteMsg is a PrivValidatorSocket message containing a vote.
type SignVoteMsg struct {
	Vote *types.Vote
}

// SignProposalMsg is a PrivValidatorSocket message containing a Proposal.
type SignProposalMsg struct {
	Proposal *types.Proposal
}

// SignHeartbeatMsg is a PrivValidatorSocket message containing a Heartbeat.
type SignHeartbeatMsg struct {
	Heartbeat *types.Heartbeat
}
<commit_msg>wip: check error of wire read<commit_after>package types

import (
	"bytes"
	"fmt"
	"net"
	"time"

	crypto "github.com/tendermint/go-crypto"
	wire "github.com/tendermint/go-wire"
	"github.com/tendermint/go-wire/data"
	cmn "github.com/tendermint/tmlibs/common"
	"github.com/tendermint/tmlibs/log"

	"github.com/tendermint/tendermint/types"
)

//-----------------------------------------------------------------

var _ types.PrivValidator = (*PrivValidatorSocketClient)(nil)

// PrivValidatorSocketClient implements PrivValidator.
// It uses a socket to request signatures.
type PrivValidatorSocketClient struct {
	cmn.BaseService

	conn net.Conn

	ID            types.ValidatorID
	SocketAddress string
}

const (
	dialRetryIntervalSeconds = 1
)

// NewPrivValidatorSocketClient returns an instance of
// PrivValidatorSocketClient.
func NewPrivValidatorSocketClient(logger log.Logger, socketAddr string) *PrivValidatorSocketClient {
	pvsc := &PrivValidatorSocketClient{
		SocketAddress: socketAddr,
	}
	pvsc.BaseService = *cmn.NewBaseService(logger, "privValidatorSocketClient", pvsc)
	return pvsc
}

// OnStart implements cmn.Service.
func (pvsc *PrivValidatorSocketClient) OnStart() error {
	if err := pvsc.BaseService.OnStart(); err != nil {
		return err
	}

	var err error
	var conn net.Conn
RETRY_LOOP:
	for {
		conn, err = cmn.Connect(pvsc.SocketAddress)
		if err != nil {
			pvsc.Logger.Error(fmt.Sprintf("PrivValidatorSocket failed to connect to %v.  Retrying...", pvsc.SocketAddress))
			time.Sleep(time.Second * dialRetryIntervalSeconds)
			continue RETRY_LOOP
		}
		pvsc.conn = conn
		return nil
	}
}

// OnStop implements cmn.Service.
func (pvsc *PrivValidatorSocketClient) OnStop() {
	pvsc.BaseService.OnStop()

	if pvsc.conn != nil {
		pvsc.conn.Close()
	}
}

// Address is an alias for PubKey().Address().
func (pvsc *PrivValidatorSocketClient) Address() data.Bytes {
	pubKey := pvsc.PubKey()
	return pubKey.Address()
}

// PubKey implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) PubKey() crypto.PubKey {
	res, err := readWrite(pvsc.conn, PubKeyMsg{})
	if err != nil {
		panic(err)
	}
	return res.(PubKeyMsg).PubKey
}

// SignVote implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignVote(chainID string, vote *types.Vote) error {
	res, err := readWrite(pvsc.conn, SignVoteMsg{Vote: vote})
	if err != nil {
		return err
	}
	*vote = *res.(SignVoteMsg).Vote
	return nil
}

// SignProposal implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignProposal(chainID string, proposal *types.Proposal) error {
	res, err := readWrite(pvsc.conn, SignProposalMsg{Proposal: proposal})
	if err != nil {
		return err
	}
	*proposal = *res.(SignProposalMsg).Proposal
	return nil
}

// SignHeartbeat implements PrivValidator.
func (pvsc *PrivValidatorSocketClient) SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error {
	res, err := readWrite(pvsc.conn, SignHeartbeatMsg{Heartbeat: heartbeat})
	if err != nil {
		return err
	}
	*heartbeat = *res.(SignHeartbeatMsg).Heartbeat
	return nil
}

//---------------------------------------------------------

// PrivValidatorSocketServer implements PrivValidator.
// It responds to requests over a socket
type PrivValidatorSocketServer struct {
	cmn.BaseService

	proto, addr string
	listener    net.Listener

	privVal PrivValidator
	chainID string
}

// NewPrivValidatorSocketServer returns an instance of
// PrivValidatorSocketServer.
func NewPrivValidatorSocketServer(logger log.Logger, socketAddr, chainID string, privVal PrivValidator) *PrivValidatorSocketServer {
	proto, addr := cmn.ProtocolAndAddress(socketAddr)
	pvss := &PrivValidatorSocketServer{
		proto:   proto,
		addr:    addr,
		privVal: privVal,
		chainID: chainID,
	}
	pvss.BaseService = *cmn.NewBaseService(logger, "privValidatorSocketServer", pvss)
	return pvss
}

// OnStart implements cmn.Service.
func (pvss *PrivValidatorSocketServer) OnStart() error {
	if err := pvss.BaseService.OnStart(); err != nil {
		return err
	}
	ln, err := net.Listen(pvss.proto, pvss.addr)
	if err != nil {
		return err
	}
	pvss.listener = ln
	go pvss.acceptConnectionsRoutine()
	return nil
}

// OnStop implements cmn.Service.
func (pvss *PrivValidatorSocketServer) OnStop() {
	pvss.BaseService.OnStop()

	if pvss.listener == nil {
		return
	}

	if err := pvss.listener.Close(); err != nil {
		pvss.Logger.Error("Error closing listener", "err", err)
	}
}

func (pvss *PrivValidatorSocketServer) acceptConnectionsRoutine() {
	for {
		// Accept a connection
		pvss.Logger.Info("Waiting for new connection...")

		conn, err := pvss.listener.Accept()
		if err != nil {
			if !pvss.IsRunning() {
				return // Ignore error from listener closing.
			}
			pvss.Logger.Error("Failed to accept connection: " + err.Error())
			continue
		}

		pvss.Logger.Info("Accepted a new connection")

		// read/write
		for {
			if !pvss.IsRunning() {
				return // Ignore error from listener closing.
			}

			var n int
			var err error
			b := wire.ReadByteSlice(conn, 0, &n, &err) //XXX: no max
			if err != nil {
				panic(err)
			}

			req, err := decodeMsg(b)
			if err != nil {
				panic(err)
			}
			var res PrivValidatorSocketMsg
			switch r := req.(type) {
			case PubKeyMsg:
				res = PubKeyMsg{pvss.privVal.PubKey()}
			case SignVoteMsg:
				pvss.privVal.SignVote(pvss.chainID, r.Vote)
				res = SignVoteMsg{r.Vote}
			case SignProposalMsg:
				pvss.privVal.SignProposal(pvss.chainID, r.Proposal)
				res = SignProposalMsg{r.Proposal}
			case SignHeartbeatMsg:
				pvss.privVal.SignHeartbeat(pvss.chainID, r.Heartbeat)
				res = SignHeartbeatMsg{r.Heartbeat}
			default:
				panic(fmt.Sprintf("unknown msg: %v", r))
			}

			b = wire.BinaryBytes(res)
			_, err = conn.Write(b)
			if err != nil {
				panic(err)
			}
		}
	}
}

//---------------------------------------------------------

const (
	msgTypePubKey        = byte(0x01)
	msgTypeSignVote      = byte(0x10)
	msgTypeSignProposal  = byte(0x11)
	msgTypeSignHeartbeat = byte(0x12)
)

// PrivValidatorSocketMsg is a message sent between PrivValidatorSocket client
// and server.
type PrivValidatorSocketMsg interface{}

var _ = wire.RegisterInterface(
	struct{ PrivValidatorSocketMsg }{},
	wire.ConcreteType{&PubKeyMsg{}, msgTypePubKey},
	wire.ConcreteType{&SignVoteMsg{}, msgTypeSignVote},
	wire.ConcreteType{&SignProposalMsg{}, msgTypeSignProposal},
	wire.ConcreteType{&SignHeartbeatMsg{}, msgTypeSignHeartbeat},
)

func readWrite(conn net.Conn, req PrivValidatorSocketMsg) (res PrivValidatorSocketMsg, err error) {
	b := wire.BinaryBytes(req)
	_, err = conn.Write(b)
	if err != nil {
		return nil, err
	}

	var n int
	b = wire.ReadByteSlice(conn, 0, &n, &err) //XXX: no max
	return decodeMsg(b)
}

func decodeMsg(bz []byte) (msg PrivValidatorSocketMsg, err error) {
	n := new(int)
	r := bytes.NewReader(bz)
	msgI := wire.ReadBinary(struct{ PrivValidatorSocketMsg }{}, r, 0, n, &err)
	msg = msgI.(struct{ PrivValidatorSocketMsg }).PrivValidatorSocketMsg
	return msg, err
}

// PubKeyMsg is a PrivValidatorSocket message containing the public key.
type PubKeyMsg struct {
	PubKey crypto.PubKey
}

// SignVoteMsg is a PrivValidatorSocket message containing a vote.
type SignVoteMsg struct {
	Vote *types.Vote
}

// SignProposalMsg is a PrivValidatorSocket message containing a Proposal.
type SignProposalMsg struct {
	Proposal *types.Proposal
}

// SignHeartbeatMsg is a PrivValidatorSocket message containing a Heartbeat.
type SignHeartbeatMsg struct {
	Heartbeat *types.Heartbeat
}
<|endoftext|>


<commit_before>package dex

// Very nearly all testing for dex is integration testing, sadly; this is inevitable since we're relying on exec to use git.

import (
	"io/ioutil"
	"os"
	"testing"
	"github.com/coocood/assrt"
)

func do(fn func()) {
	retreat, err := os.Getwd()
	if err != nil { panic(err); }

	defer os.Chdir(retreat)

	basedir := os.Getenv("BASEDIR")
	if len(basedir) != 0 {
		err = os.Chdir(basedir)
		if err != nil { panic(err); }
	}

	err = os.MkdirAll("target/test", 0755)
	if err != nil { panic(err); }
	tmpdir, err := ioutil.TempDir("target/test","")
	if err != nil { panic(err); }
	err = os.Chdir(tmpdir)
	if err != nil { panic(err); }

	fn()
}

func TestNoGraphLoading(t *testing.T) {
	do(func() {
		assert := assrt.NewAssert(t)

		assert.Equal(
			nil,
			nil,
		)
	})
}
<commit_msg>tests for basic graph initialization<commit_after>package dex

// Very nearly all testing for dex is integration testing, sadly; this is inevitable since we're relying on exec to use git.

import (
	"io/ioutil"
	"os"
	"testing"
	"github.com/coocood/assrt"
)

func do(fn func()) {
	retreat, err := os.Getwd()
	if err != nil { panic(err); }

	defer os.Chdir(retreat)

	basedir := os.Getenv("BASEDIR")
	if len(basedir) != 0 {
		err = os.Chdir(basedir)
		if err != nil { panic(err); }
	}

	err = os.MkdirAll("target/test", 0755)
	if err != nil { panic(err); }
	tmpdir, err := ioutil.TempDir("target/test","")
	if err != nil { panic(err); }
	err = os.Chdir(tmpdir)
	if err != nil { panic(err); }

	fn()
}

func TestLoadGraphAbsentIsNil(t *testing.T) {
	do(func() {
		assert := assrt.NewAssert(t)

		assert.Nil(LoadGraph("."))

		assert.Nil(LoadGraph("notadir"))
	})
}

func TestNewGraphInit(t *testing.T) {
	do(func() {
		assert := assrt.NewAssert(t)

		g := NewGraph(".")

		assert.NotNil(g)

		gstat, _ := os.Stat(".git")
		assert.True(gstat.IsDir())

		assert.True(g.HasBranch("docket/init"))

		assert.Equal(
			"",
			g.cmd("ls-tree")("HEAD").Output(),
		)
	})
}
<|endoftext|>


<commit_before>package gocd

import (
	"context"
	"net/url"
	"strings"
)

// EnvironmentsService exposes calls for interacting with Environment objects in the GoCD API.
type EnvironmentsService service

// EnvironmentsResponseLinks describes the HAL _link resource for the api response object for a collection of environment
// objects
//go:generate gocd-response-links-generator -type=EnvironmentsResponseLinks,EnvironmentLinks
type EnvironmentsResponseLinks struct {
	Self *url.URL `json:"self"`
	Doc  *url.URL `json:"doc"`
}

// EnvironmentLinks describes the HAL _link resource for the api response object for a collection of environment objects.
type EnvironmentLinks struct {
	Self *url.URL `json:"self"`
	Doc  *url.URL `json:"doc"`
	Find *url.URL `json:"find"`
}

// EnvironmentsResponse describes the response obejct for a plugin API call.
type EnvironmentsResponse struct {
	Links *EnvironmentsResponseLinks `json:"_links"`
	Embedded struct {
		Environments []*Environment `json:"environments"`
	} `json:"_embedded"`
}

// Environment describes a group of pipelines and agents
type Environment struct {
	Links                *EnvironmentLinks      `json:"_links,omitempty"`
	Name                 string                 `json:"name"`
	Pipelines            []*Pipeline            `json:"pipelines,omitempty"`
	Agents               []*Agent               `json:"agents,omitempty"`
	EnvironmentVariables []*EnvironmentVariable `json:"environment_variables,omitempty"`
	Version              string                 `json:"version"`
}

// EnvironmentPatchRequest describes the actions to perform on an environment
type EnvironmentPatchRequest struct {
	Pipelines            *PatchStringAction          `json:"pipelines"`
	Agents               *PatchStringAction          `json:"agents"`
	EnvironmentVariables *EnvironmentVariablesAction `json:"environment_variables"`
}

// EnvironmentVariablesAction describes a collection of Environment Variables to add or remove.
type EnvironmentVariablesAction struct {
	Add    []*EnvironmentVariable `json:"add"`
	Remove []*EnvironmentVariable `json:"remove"`
}

// PatchStringAction describes a collection of resources to add or remove.
type PatchStringAction struct {
	Add    []string `json:"add"`
	Remove []string `json:"remove"`
}

// List all environments
func (es *EnvironmentsService) List(ctx context.Context) (*EnvironmentsResponse, *APIResponse, error) {
	e := EnvironmentsResponse{}
	_, resp, err := es.client.getAction(ctx, &APIClientRequest{
		Path:         "admin/environments",
		ResponseBody: &e,
		APIVersion:   apiV2,
	})

	return &e, resp, err
}

// Get a single environment by name
func (es *EnvironmentsService) Get(ctx context.Context, name string) (*Environment, *APIResponse, error) {
	e := Environment{}
	_, resp, err := es.client.getAction(ctx, &APIClientRequest{
		Path:         "admin/environments/" + name,
		ResponseBody: &e,
		APIVersion:   apiV2,
	})
	if err == nil {
		e.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}

	return &e, resp, err
}

// Delete an environment
func (es *EnvironmentsService) Delete(ctx context.Context, name string) (string, *APIResponse, error) {
	return es.client.deleteAction(ctx, name, apiV2)
}

// Create an environment
func (es *EnvironmentsService) Create(ctx context.Context, name string) (*Environment, *APIResponse, error) {
	e := Environment{}
	_, resp, err := es.client.postAction(ctx, &APIClientRequest{
		Path: "admin/environments/" + name,
		RequestBody: Environment{
			Name: name,
		},
		ResponseBody: &e,
		APIVersion:   apiV2,
	})
	if err == nil {
		e.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}
	return &e, resp, err
}

// Patch an environments configuration by adding or removing pipelines, agents, environment variables
func (es *EnvironmentsService) Patch(ctx context.Context, name string, patch *EnvironmentPatchRequest) (*Environment, *APIResponse, error) {
	env := Environment{}
	_, resp, err := es.client.patchAction(ctx, &APIClientRequest{
		Path:         "admin/environments" + name,
		RequestBody:  patch,
		ResponseBody: &env,
		APIVersion:   apiV2,
	})
	if err == nil {
		env.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}

	return &env, resp, err
}
<commit_msg>Fixed formatting<commit_after>package gocd

import (
	"context"
	"net/url"
	"strings"
)

// EnvironmentsService exposes calls for interacting with Environment objects in the GoCD API.
type EnvironmentsService service

// EnvironmentsResponseLinks describes the HAL _link resource for the api response object for a collection of environment
// objects
//go:generate gocd-response-links-generator -type=EnvironmentsResponseLinks,EnvironmentLinks
type EnvironmentsResponseLinks struct {
	Self *url.URL `json:"self"`
	Doc  *url.URL `json:"doc"`
}

// EnvironmentLinks describes the HAL _link resource for the api response object for a collection of environment objects.
type EnvironmentLinks struct {
	Self *url.URL `json:"self"`
	Doc  *url.URL `json:"doc"`
	Find *url.URL `json:"find"`
}

// EnvironmentsResponse describes the response obejct for a plugin API call.
type EnvironmentsResponse struct {
	Links    *EnvironmentsResponseLinks `json:"_links"`
	Embedded struct {
		Environments []*Environment `json:"environments"`
	} `json:"_embedded"`
}

// Environment describes a group of pipelines and agents
type Environment struct {
	Links                *EnvironmentLinks      `json:"_links,omitempty"`
	Name                 string                 `json:"name"`
	Pipelines            []*Pipeline            `json:"pipelines,omitempty"`
	Agents               []*Agent               `json:"agents,omitempty"`
	EnvironmentVariables []*EnvironmentVariable `json:"environment_variables,omitempty"`
	Version              string                 `json:"version"`
}

// EnvironmentPatchRequest describes the actions to perform on an environment
type EnvironmentPatchRequest struct {
	Pipelines            *PatchStringAction          `json:"pipelines"`
	Agents               *PatchStringAction          `json:"agents"`
	EnvironmentVariables *EnvironmentVariablesAction `json:"environment_variables"`
}

// EnvironmentVariablesAction describes a collection of Environment Variables to add or remove.
type EnvironmentVariablesAction struct {
	Add    []*EnvironmentVariable `json:"add"`
	Remove []*EnvironmentVariable `json:"remove"`
}

// PatchStringAction describes a collection of resources to add or remove.
type PatchStringAction struct {
	Add    []string `json:"add"`
	Remove []string `json:"remove"`
}

// List all environments
func (es *EnvironmentsService) List(ctx context.Context) (*EnvironmentsResponse, *APIResponse, error) {
	e := EnvironmentsResponse{}
	_, resp, err := es.client.getAction(ctx, &APIClientRequest{
		Path:         "admin/environments",
		ResponseBody: &e,
		APIVersion:   apiV2,
	})

	return &e, resp, err
}

// Get a single environment by name
func (es *EnvironmentsService) Get(ctx context.Context, name string) (*Environment, *APIResponse, error) {
	e := Environment{}
	_, resp, err := es.client.getAction(ctx, &APIClientRequest{
		Path:         "admin/environments/" + name,
		ResponseBody: &e,
		APIVersion:   apiV2,
	})
	if err == nil {
		e.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}

	return &e, resp, err
}

// Delete an environment
func (es *EnvironmentsService) Delete(ctx context.Context, name string) (string, *APIResponse, error) {
	return es.client.deleteAction(ctx, name, apiV2)
}

// Create an environment
func (es *EnvironmentsService) Create(ctx context.Context, name string) (*Environment, *APIResponse, error) {
	e := Environment{}
	_, resp, err := es.client.postAction(ctx, &APIClientRequest{
		Path: "admin/environments/" + name,
		RequestBody: Environment{
			Name: name,
		},
		ResponseBody: &e,
		APIVersion:   apiV2,
	})
	if err == nil {
		e.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}
	return &e, resp, err
}

// Patch an environments configuration by adding or removing pipelines, agents, environment variables
func (es *EnvironmentsService) Patch(ctx context.Context, name string, patch *EnvironmentPatchRequest) (*Environment, *APIResponse, error) {
	env := Environment{}
	_, resp, err := es.client.patchAction(ctx, &APIClientRequest{
		Path:         "admin/environments" + name,
		RequestBody:  patch,
		ResponseBody: &env,
		APIVersion:   apiV2,
	})
	if err == nil {
		env.Version = strings.Replace(resp.HTTP.Header.Get("Etag"), "\"", "", -1)
	}

	return &env, resp, err
}
<|endoftext|>


<commit_before>package gonzo_test

import (
	"net"
	"testing"

	gc "gopkg.in/check.v1"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	//"gopkg.in/mgo.v2/bson"

	"github.com/cmars/gonzodb/gonzo"
)

func Test(t *testing.T) {
	gc.TestingT(t)
}

type gonzoSuite struct {
	server  *gonzo.Server
	session *mgo.Session
}

var _ = gc.Suite(&gonzoSuite{})

func (s *gonzoSuite) SetUpTest(c *gc.C) {
	addr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 0}
	l, err := net.ListenTCP("tcp", addr)
	c.Assert(err, gc.IsNil)
	addr = l.Addr().(*net.TCPAddr)

	s.server = gonzo.NewServer(l)
	s.server.Start()

	s.session, err = mgo.Dial(addr.String())
	c.Assert(err, gc.IsNil)
}

func (s *gonzoSuite) TearDownTest(c *gc.C) {
	s.session.Close()
	s.server.Stop()
}

func (s *gonzoSuite) TestInsertQuerySingle(c *gc.C) {
	err := s.session.DB("db1").C("c1").Insert(bson.D{{"foo", 1}, {"bar", 2}})
	c.Assert(err, gc.IsNil)

	var result []bson.M
	err = s.session.DB("db1").C("c1").Find(nil).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 1)
	c.Assert(result[0]["foo"], gc.DeepEquals, 1)
	c.Assert(result[0]["bar"], gc.DeepEquals, 2)
	_, ok := result[0]["_id"].(bson.ObjectId)
	c.Assert(ok, gc.Equals, true)
}

var queryMatchTestCases = []bson.D{
	bson.D{{"artist", "ed hall"}, {"label", "trance syndicate"}, {"venue", "liberty lunch"}},
	bson.D{{"artist", "cherubs"}, {"label", "trance syndicate"}, {"venue", "cavity club"}},
	bson.D{{"artist", "the jesus lizard"}, {"label", "touch & go"}, {"venue", "emo's"}},
}

func (s *gonzoSuite) TestInsertQueryMatch(c *gc.C) {
	for _, testCase := range queryMatchTestCases {
		err := s.session.DB("db1").C("c1").Insert(testCase)
		c.Assert(err, gc.IsNil)
	}

	var err error
	var result []bson.M
	err = s.session.DB("db1").C("c1").Find(bson.M{"artist": "ed hall"}).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 1)

	err = s.session.DB("db1").C("c1").Find(bson.M{"label": "trance syndicate"}).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 2)
	for i, m := range result {
		c.Assert(m["label"], gc.Equals, "trance syndicate")
		if i > 0 {
			c.Assert(m["artist"], gc.Not(gc.DeepEquals), result[i-1]["artist"])
			c.Assert(m["venue"], gc.Not(gc.DeepEquals), result[i-1]["venue"])
			c.Assert(m["_id"], gc.Not(gc.DeepEquals), result[i-1]["_id"])
		}
	}

	err = s.session.DB("db1").C("c1").Find(nil).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 3)
}

func (s *gonzoSuite) TestQueryIter(c *gc.C) {
	count := 1000
	for i := 0; i < count; i++ {
		err := s.session.DB("db1").C("c1").Insert(bson.M{"i": i})
		c.Assert(err, gc.IsNil)
	}

	i := s.session.DB("db1").C("c1").Find(nil).Iter()
	var m bson.M
	n := 0
	for i.Next(&m) {
		c.Assert(m, gc.HasLen, 2)
		_, ok := m["_id"]
		c.Assert(ok, gc.Equals, true)
		n++
	}
	c.Assert(n, gc.Equals, count)
	c.Assert(i.Err(), gc.IsNil)
	c.Assert(i.Close(), gc.IsNil)
}

func (s *gonzoSuite) TestGridFSrt(c *gc.C) {
	gfs := s.session.DB("whatfs").GridFS("whatroot")

	fooFile, err := gfs.Create("foo")
	c.Assert(err, gc.IsNil)
	_, err = fooFile.Write([]byte("this file contains foo"))
	c.Assert(err, gc.IsNil)
	c.Assert(fooFile.Close(), gc.IsNil)

	fooFile, err = gfs.Open("foo")
	c.Assert(err, gc.IsNil)
	buf := make([]byte, 200)
	n, err := fooFile.Read(buf)
	c.Assert(err, gc.IsNil)
	c.Assert(string(buf[:n]), gc.Equals, "this file contains foo")

	_, err = gfs.Open("bar")
	c.Assert(err, gc.ErrorMatches, "not found")
}
<commit_msg>Remove commented out import.<commit_after>package gonzo_test

import (
	"net"
	"testing"

	gc "gopkg.in/check.v1"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"

	"github.com/cmars/gonzodb/gonzo"
)

func Test(t *testing.T) {
	gc.TestingT(t)
}

type gonzoSuite struct {
	server  *gonzo.Server
	session *mgo.Session
}

var _ = gc.Suite(&gonzoSuite{})

func (s *gonzoSuite) SetUpTest(c *gc.C) {
	addr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 0}
	l, err := net.ListenTCP("tcp", addr)
	c.Assert(err, gc.IsNil)
	addr = l.Addr().(*net.TCPAddr)

	s.server = gonzo.NewServer(l)
	s.server.Start()

	s.session, err = mgo.Dial(addr.String())
	c.Assert(err, gc.IsNil)
}

func (s *gonzoSuite) TearDownTest(c *gc.C) {
	s.session.Close()
	s.server.Stop()
}

func (s *gonzoSuite) TestInsertQuerySingle(c *gc.C) {
	err := s.session.DB("db1").C("c1").Insert(bson.D{{"foo", 1}, {"bar", 2}})
	c.Assert(err, gc.IsNil)

	var result []bson.M
	err = s.session.DB("db1").C("c1").Find(nil).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 1)
	c.Assert(result[0]["foo"], gc.DeepEquals, 1)
	c.Assert(result[0]["bar"], gc.DeepEquals, 2)
	_, ok := result[0]["_id"].(bson.ObjectId)
	c.Assert(ok, gc.Equals, true)
}

var queryMatchTestCases = []bson.D{
	bson.D{{"artist", "ed hall"}, {"label", "trance syndicate"}, {"venue", "liberty lunch"}},
	bson.D{{"artist", "cherubs"}, {"label", "trance syndicate"}, {"venue", "cavity club"}},
	bson.D{{"artist", "the jesus lizard"}, {"label", "touch & go"}, {"venue", "emo's"}},
}

func (s *gonzoSuite) TestInsertQueryMatch(c *gc.C) {
	for _, testCase := range queryMatchTestCases {
		err := s.session.DB("db1").C("c1").Insert(testCase)
		c.Assert(err, gc.IsNil)
	}

	var err error
	var result []bson.M
	err = s.session.DB("db1").C("c1").Find(bson.M{"artist": "ed hall"}).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 1)

	err = s.session.DB("db1").C("c1").Find(bson.M{"label": "trance syndicate"}).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 2)
	for i, m := range result {
		c.Assert(m["label"], gc.Equals, "trance syndicate")
		if i > 0 {
			c.Assert(m["artist"], gc.Not(gc.DeepEquals), result[i-1]["artist"])
			c.Assert(m["venue"], gc.Not(gc.DeepEquals), result[i-1]["venue"])
			c.Assert(m["_id"], gc.Not(gc.DeepEquals), result[i-1]["_id"])
		}
	}

	err = s.session.DB("db1").C("c1").Find(nil).All(&result)
	c.Assert(err, gc.IsNil)
	c.Assert(result, gc.HasLen, 3)
}

func (s *gonzoSuite) TestQueryIter(c *gc.C) {
	count := 1000
	for i := 0; i < count; i++ {
		err := s.session.DB("db1").C("c1").Insert(bson.M{"i": i})
		c.Assert(err, gc.IsNil)
	}

	i := s.session.DB("db1").C("c1").Find(nil).Iter()
	var m bson.M
	n := 0
	for i.Next(&m) {
		c.Assert(m, gc.HasLen, 2)
		_, ok := m["_id"]
		c.Assert(ok, gc.Equals, true)
		n++
	}
	c.Assert(n, gc.Equals, count)
	c.Assert(i.Err(), gc.IsNil)
	c.Assert(i.Close(), gc.IsNil)
}

func (s *gonzoSuite) TestGridFSrt(c *gc.C) {
	gfs := s.session.DB("whatfs").GridFS("whatroot")

	fooFile, err := gfs.Create("foo")
	c.Assert(err, gc.IsNil)
	_, err = fooFile.Write([]byte("this file contains foo"))
	c.Assert(err, gc.IsNil)
	c.Assert(fooFile.Close(), gc.IsNil)

	fooFile, err = gfs.Open("foo")
	c.Assert(err, gc.IsNil)
	buf := make([]byte, 200)
	n, err := fooFile.Read(buf)
	c.Assert(err, gc.IsNil)
	c.Assert(string(buf[:n]), gc.Equals, "this file contains foo")

	_, err = gfs.Open("bar")
	c.Assert(err, gc.ErrorMatches, "not found")
}
<|endoftext|>


<commit_before>// Copyright ©2014 The gonum 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 topo

import (
	"github.com/gonum/graph"
	"github.com/gonum/graph/traverse"
)

// IsPath returns true for a connected path within a graph.
//
// IsPath returns true if, starting at path[0] and ending at path[len(path)-1], all nodes between
// are valid neighbors. That is, for each element path[i], path[i+1] is a valid successor.
//
// As special cases, IsPath returns true for a nil or zero length path, and for a path of length 1
// (only one node) but only if the node listed in path exists within the graph.
//
// Graph must be non-nil.
func IsPathIn(g graph.Graph, path []graph.Node) bool {
	var canReach func(u, v graph.Node) bool
	switch g := g.(type) {
	case graph.Directed:
		canReach = g.HasEdgeFromTo
	default:
		canReach = g.HasEdge
	}

	if path == nil || len(path) == 0 {
		return true
	} else if len(path) == 1 {
		return g.Has(path[0])
	}

	for i := 0; i < len(path)-1; i++ {
		if !canReach(path[i], path[i+1]) {
			return false
		}
	}

	return true
}

// ConnectedComponents returns the connected components of the graph g. All
// edges are treated as undirected.
func ConnectedComponents(g graph.Undirected) [][]graph.Node {
	var (
		w  traverse.DepthFirst
		c  []graph.Node
		cc [][]graph.Node
	)
	during := func(n graph.Node) {
		c = append(c, n)
	}
	after := func() {
		cc = append(cc, []graph.Node(nil))
		cc[len(cc)-1] = append(cc[len(cc)-1], c...)
		c = c[:0]
	}
	w.WalkAll(g, nil, after, during)

	return cc
}
<commit_msg>topo: fix IsPathIn doc comments<commit_after>// Copyright ©2014 The gonum 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 topo

import (
	"github.com/gonum/graph"
	"github.com/gonum/graph/traverse"
)

// IsPathIn returns whether path is a path in g.
//
// As special cases, IsPathIn returns true for a zero length path or for
// a path of length 1 when the node in path exists in the graph.
func IsPathIn(g graph.Graph, path []graph.Node) bool {
	var canReach func(u, v graph.Node) bool
	switch g := g.(type) {
	case graph.Directed:
		canReach = g.HasEdgeFromTo
	default:
		canReach = g.HasEdge
	}

	if path == nil || len(path) == 0 {
		return true
	} else if len(path) == 1 {
		return g.Has(path[0])
	}

	for i := 0; i < len(path)-1; i++ {
		if !canReach(path[i], path[i+1]) {
			return false
		}
	}

	return true
}

// ConnectedComponents returns the connected components of the graph g. All
// edges are treated as undirected.
func ConnectedComponents(g graph.Undirected) [][]graph.Node {
	var (
		w  traverse.DepthFirst
		c  []graph.Node
		cc [][]graph.Node
	)
	during := func(n graph.Node) {
		c = append(c, n)
	}
	after := func() {
		cc = append(cc, []graph.Node(nil))
		cc[len(cc)-1] = append(cc[len(cc)-1], c...)
		c = c[:0]
	}
	w.WalkAll(g, nil, after, during)

	return cc
}
<|endoftext|>