<commit_before>package commitgraph

import (
	"path"

	. "gopkg.in/check.v1"
	fixtures "gopkg.in/src-d/go-git-fixtures.v3"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/cache"
	"gopkg.in/src-d/go-git.v4/plumbing/format/commitgraph"
	"gopkg.in/src-d/go-git.v4/plumbing/format/packfile"
	"gopkg.in/src-d/go-git.v4/storage/filesystem"
)

type CommitNodeSuite struct {
	fixtures.Suite
}

var _ = Suite(&CommitNodeSuite{})

func unpackRepositry(f *fixtures.Fixture) *filesystem.Storage {
	storer := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
	p := f.Packfile()
	defer p.Close()
	packfile.UpdateObjectStorage(storer, p)
	return storer
}

func testWalker(c *C, nodeIndex CommitNodeIndex) {
	head, err := nodeIndex.Get(plumbing.NewHash("b9d69064b190e7aedccf84731ca1d917871f8a1c"))
	c.Assert(err, IsNil)

	iter := NewCommitNodeIterCTime(
		head,
		nil,
		nil,
	)

	var commits []CommitNode
	iter.ForEach(func(c CommitNode) error {
		commits = append(commits, c)
		return nil
	})

	c.Assert(commits, HasLen, 9)

	expected := []string{
		"b9d69064b190e7aedccf84731ca1d917871f8a1c",
		"6f6c5d2be7852c782be1dd13e36496dd7ad39560",
		"a45273fe2d63300e1962a9e26a6b15c276cd7082",
		"c0edf780dd0da6a65a7a49a86032fcf8a0c2d467",
		"bb13916df33ed23004c3ce9ed3b8487528e655c1",
		"03d2c021ff68954cf3ef0a36825e194a4b98f981",
		"ce275064ad67d51e99f026084e20827901a8361c",
		"e713b52d7e13807e87a002e812041f248db3f643",
		"347c91919944a68e9413581a1bc15519550a3afe",
	}
	for i, commit := range commits {
		c.Assert(commit.ID().String(), Equals, expected[i])
	}
}

func testParents(c *C, nodeIndex CommitNodeIndex) {
	merge3, err := nodeIndex.Get(plumbing.NewHash("6f6c5d2be7852c782be1dd13e36496dd7ad39560"))
	c.Assert(err, IsNil)

	var parents []CommitNode
	merge3.ParentNodes().ForEach(func(c CommitNode) error {
		parents = append(parents, c)
		return nil
	})

	c.Assert(parents, HasLen, 3)

	expected := []string{
		"ce275064ad67d51e99f026084e20827901a8361c",
		"bb13916df33ed23004c3ce9ed3b8487528e655c1",
		"a45273fe2d63300e1962a9e26a6b15c276cd7082",
	}
	for i, parent := range parents {
		c.Assert(parent.ID().String(), Equals, expected[i])
	}
}

func testCommitAndTree(c *C, nodeIndex CommitNodeIndex) {
	merge3node, err := nodeIndex.Get(plumbing.NewHash("6f6c5d2be7852c782be1dd13e36496dd7ad39560"))
	c.Assert(err, IsNil)
	merge3commit, err := merge3node.Commit()
	c.Assert(err, IsNil)
	c.Assert(merge3node.ID().String(), Equals, merge3commit.ID().String())
	tree, err := merge3node.Tree()
	c.Assert(err, IsNil)
	c.Assert(tree.ID().String(), Equals, merge3commit.TreeHash.String())
}

func (s *CommitNodeSuite) TestObjectGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)

	nodeIndex := NewObjectCommitNodeIndex(storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}

func (s *CommitNodeSuite) TestCommitGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)
	reader, err := storer.Filesystem().Open(path.Join("objects", "info", "commit-graph"))
	c.Assert(err, IsNil)
	defer reader.Close()
	index, err := commitgraph.OpenFileIndex(reader)
	c.Assert(err, IsNil)

	nodeIndex := NewGraphCommitNodeIndex(index, storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}

func (s *CommitNodeSuite) TestMixedGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)

	// Take the commit-graph file and copy it to memory index without the last commit
	reader, err := storer.Filesystem().Open(path.Join("objects", "info", "commit-graph"))
	c.Assert(err, IsNil)
	defer reader.Close()
	fileIndex, err := commitgraph.OpenFileIndex(reader)
	c.Assert(err, IsNil)
	memoryIndex := commitgraph.NewMemoryIndex()
	for i, hash := range fileIndex.Hashes() {
		if hash.String() != "b9d69064b190e7aedccf84731ca1d917871f8a1c" {
			node, err := fileIndex.GetCommitDataByIndex(i)
			c.Assert(err, IsNil)
			memoryIndex.Add(hash, node)
		}
	}

	nodeIndex := NewGraphCommitNodeIndex(memoryIndex, storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}
<commit_msg>Fix object/commitgraph tests<commit_after>package commitgraph

import (
	"path"
	"testing"

	. "gopkg.in/check.v1"
	fixtures "gopkg.in/src-d/go-git-fixtures.v3"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/cache"
	"gopkg.in/src-d/go-git.v4/plumbing/format/commitgraph"
	"gopkg.in/src-d/go-git.v4/plumbing/format/packfile"
	"gopkg.in/src-d/go-git.v4/storage/filesystem"
)

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

type CommitNodeSuite struct {
	fixtures.Suite
}

var _ = Suite(&CommitNodeSuite{})

func unpackRepositry(f *fixtures.Fixture) *filesystem.Storage {
	storer := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
	p := f.Packfile()
	defer p.Close()
	packfile.UpdateObjectStorage(storer, p)
	return storer
}

func testWalker(c *C, nodeIndex CommitNodeIndex) {
	head, err := nodeIndex.Get(plumbing.NewHash("b9d69064b190e7aedccf84731ca1d917871f8a1c"))
	c.Assert(err, IsNil)

	iter := NewCommitNodeIterCTime(
		head,
		nil,
		nil,
	)

	var commits []CommitNode
	iter.ForEach(func(c CommitNode) error {
		commits = append(commits, c)
		return nil
	})

	c.Assert(commits, HasLen, 9)

	expected := []string{
		"b9d69064b190e7aedccf84731ca1d917871f8a1c",
		"6f6c5d2be7852c782be1dd13e36496dd7ad39560",
		"a45273fe2d63300e1962a9e26a6b15c276cd7082",
		"c0edf780dd0da6a65a7a49a86032fcf8a0c2d467",
		"bb13916df33ed23004c3ce9ed3b8487528e655c1",
		"03d2c021ff68954cf3ef0a36825e194a4b98f981",
		"ce275064ad67d51e99f026084e20827901a8361c",
		"e713b52d7e13807e87a002e812041f248db3f643",
		"347c91919944a68e9413581a1bc15519550a3afe",
	}
	for i, commit := range commits {
		c.Assert(commit.ID().String(), Equals, expected[i])
	}
}

func testParents(c *C, nodeIndex CommitNodeIndex) {
	merge3, err := nodeIndex.Get(plumbing.NewHash("6f6c5d2be7852c782be1dd13e36496dd7ad39560"))
	c.Assert(err, IsNil)

	var parents []CommitNode
	merge3.ParentNodes().ForEach(func(c CommitNode) error {
		parents = append(parents, c)
		return nil
	})

	c.Assert(parents, HasLen, 3)

	expected := []string{
		"ce275064ad67d51e99f026084e20827901a8361c",
		"bb13916df33ed23004c3ce9ed3b8487528e655c1",
		"a45273fe2d63300e1962a9e26a6b15c276cd7082",
	}
	for i, parent := range parents {
		c.Assert(parent.ID().String(), Equals, expected[i])
	}
}

func testCommitAndTree(c *C, nodeIndex CommitNodeIndex) {
	merge3node, err := nodeIndex.Get(plumbing.NewHash("6f6c5d2be7852c782be1dd13e36496dd7ad39560"))
	c.Assert(err, IsNil)
	merge3commit, err := merge3node.Commit()
	c.Assert(err, IsNil)
	c.Assert(merge3node.ID().String(), Equals, merge3commit.ID().String())
	tree, err := merge3node.Tree()
	c.Assert(err, IsNil)
	c.Assert(tree.ID().String(), Equals, merge3commit.TreeHash.String())
}

func (s *CommitNodeSuite) TestObjectGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)

	nodeIndex := NewObjectCommitNodeIndex(storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}

func (s *CommitNodeSuite) TestCommitGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)
	reader, err := storer.Filesystem().Open(path.Join("objects", "info", "commit-graph"))
	c.Assert(err, IsNil)
	defer reader.Close()
	index, err := commitgraph.OpenFileIndex(reader)
	c.Assert(err, IsNil)

	nodeIndex := NewGraphCommitNodeIndex(index, storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}

func (s *CommitNodeSuite) TestMixedGraph(c *C) {
	f := fixtures.ByTag("commit-graph").One()
	storer := unpackRepositry(f)

	// Take the commit-graph file and copy it to memory index without the last commit
	reader, err := storer.Filesystem().Open(path.Join("objects", "info", "commit-graph"))
	c.Assert(err, IsNil)
	defer reader.Close()
	fileIndex, err := commitgraph.OpenFileIndex(reader)
	c.Assert(err, IsNil)
	memoryIndex := commitgraph.NewMemoryIndex()
	for i, hash := range fileIndex.Hashes() {
		if hash.String() != "b9d69064b190e7aedccf84731ca1d917871f8a1c" {
			node, err := fileIndex.GetCommitDataByIndex(i)
			c.Assert(err, IsNil)
			memoryIndex.Add(hash, node)
		}
	}

	nodeIndex := NewGraphCommitNodeIndex(memoryIndex, storer)
	testWalker(c, nodeIndex)
	testParents(c, nodeIndex)
	testCommitAndTree(c, nodeIndex)
}
<|endoftext|>


<commit_before>package pipelineserver

import (
	"errors"
	"sync"
	"time"

	"go.pachyderm.com/pachyderm/src/pfs"
	"go.pachyderm.com/pachyderm/src/pps"
	"go.pachyderm.com/pachyderm/src/pps/persist"
	"go.pedge.io/google-protobuf"
	"go.pedge.io/proto/rpclog"
	"go.pedge.io/protolog"
	"golang.org/x/net/context"
)

type apiServer struct {
	protorpclog.Logger
	pfsAPIClient     pfs.APIClient
	jobAPIClient     pps.JobAPIClient
	persistAPIClient persist.APIClient

	started                          bool
	pipelineNameToPipelineController map[string]*pipelineController
	lock                             *sync.Mutex
}

func newAPIServer(
	pfsAPIClient pfs.APIClient,
	jobAPIClient pps.JobAPIClient,
	persistAPIClient persist.APIClient,
) *apiServer {
	return &apiServer{
		protorpclog.NewLogger("pachyderm.pps.PipelineAPI"),
		pfsAPIClient,
		jobAPIClient,
		persistAPIClient,
		false,
		make(map[string]*pipelineController),
		&sync.Mutex{},
	}
}

func (a *apiServer) Start() error {
	a.lock.Lock()
	defer a.lock.Unlock()
	// TODO(pedge): volatile bool?
	if a.started {
		// TODO(pedge): abstract error to public variable
		return errors.New("pachyderm.pps.pipelineserver: already started")
	}
	a.started = true
	pipelineInfos, err := a.ListPipeline(context.Background(), &pps.ListPipelineRequest{})
	if err != nil {
		return err
	}
	for _, pipelineInfo := range pipelineInfos.PipelineInfo {
		if err := a.addPipelineController(pipelineInfo); err != nil {
			return err
		}
	}
	return nil
}

func (a *apiServer) CreatePipeline(ctx context.Context, request *pps.CreatePipelineRequest) (response *google_protobuf.Empty, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfo := &persist.PipelineInfo{
		PipelineName: request.Pipeline.Name,
		Transform:    request.Transform,
		Input:        request.Input,
		Output:       request.Output,
	}
	if _, err := a.persistAPIClient.CreatePipelineInfo(ctx, persistPipelineInfo); err != nil {
		return nil, err
	}
	a.lock.Lock()
	defer a.lock.Unlock()
	if err := a.addPipelineController(persistPipelineInfoToPipelineInfo(persistPipelineInfo)); err != nil {
		// TODO(pedge): need to roll back the db create
		return nil, err
	}
	return google_protobuf.EmptyInstance, nil
}

func (a *apiServer) InspectPipeline(ctx context.Context, request *pps.InspectPipelineRequest) (response *pps.PipelineInfo, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfo, err := a.persistAPIClient.GetPipelineInfo(ctx, request.Pipeline)
	if err != nil {
		return nil, err
	}
	return persistPipelineInfoToPipelineInfo(persistPipelineInfo), nil
}

func (a *apiServer) ListPipeline(ctx context.Context, request *pps.ListPipelineRequest) (response *pps.PipelineInfos, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfos, err := a.persistAPIClient.ListPipelineInfos(ctx, google_protobuf.EmptyInstance)
	if err != nil {
		return nil, err
	}
	pipelineInfos := make([]*pps.PipelineInfo, len(persistPipelineInfos.PipelineInfo))
	for i, persistPipelineInfo := range persistPipelineInfos.PipelineInfo {
		pipelineInfos[i] = persistPipelineInfoToPipelineInfo(persistPipelineInfo)
	}
	return &pps.PipelineInfos{
		PipelineInfo: pipelineInfos,
	}, nil
}

func (a *apiServer) DeletePipeline(ctx context.Context, request *pps.DeletePipelineRequest) (response *google_protobuf.Empty, err error) {
	if _, err := a.persistAPIClient.DeletePipelineInfo(ctx, request.Pipeline); err != nil {
		return nil, err
	}
	a.lock.Lock()
	defer a.lock.Unlock()
	if err := a.removePipelineController(request.Pipeline.Name); err != nil {
		return nil, err
	}
	return google_protobuf.EmptyInstance, nil
}

func persistPipelineInfoToPipelineInfo(persistPipelineInfo *persist.PipelineInfo) *pps.PipelineInfo {
	return &pps.PipelineInfo{
		Pipeline: &pps.Pipeline{
			Name: persistPipelineInfo.PipelineName,
		},
		Transform: persistPipelineInfo.Transform,
		Input:     persistPipelineInfo.Input,
		Output:    persistPipelineInfo.Output,
	}
}

func (a *apiServer) addPipelineController(pipelineInfo *pps.PipelineInfo) error {
	if _, ok := a.pipelineNameToPipelineController[pipelineInfo.Pipeline.Name]; ok {
		protolog.Warnf("pachyderm.pps.pipelineserver: had a create change event for an existing pipeline: %v", pipelineInfo)
		if err := a.removePipelineController(pipelineInfo.Pipeline.Name); err != nil {
			return err
		}
	}
	pipelineController := newPipelineController(
		a.pfsAPIClient,
		a.jobAPIClient,
		pps.NewLocalPipelineAPIClient(a),
		pipelineInfo,
	)
	a.pipelineNameToPipelineController[pipelineInfo.Pipeline.Name] = pipelineController
	return pipelineController.Start()
}

func (a *apiServer) removePipelineController(name string) error {
	pipelineController, ok := a.pipelineNameToPipelineController[name]
	if !ok {
		protolog.Warnf("pachyderm.pps.pipelineserver: no pipeline registered for name: %s", name)
	} else {
		pipelineController.Cancel()
	}
	return nil
}
<commit_msg>delete pipeline info if add pipeline controller fails<commit_after>package pipelineserver

import (
	"errors"
	"fmt"
	"sync"
	"time"

	"go.pachyderm.com/pachyderm/src/pfs"
	"go.pachyderm.com/pachyderm/src/pps"
	"go.pachyderm.com/pachyderm/src/pps/persist"
	"go.pedge.io/google-protobuf"
	"go.pedge.io/proto/rpclog"
	"go.pedge.io/protolog"
	"golang.org/x/net/context"
)

type apiServer struct {
	protorpclog.Logger
	pfsAPIClient     pfs.APIClient
	jobAPIClient     pps.JobAPIClient
	persistAPIClient persist.APIClient

	started                          bool
	pipelineNameToPipelineController map[string]*pipelineController
	lock                             *sync.Mutex
}

func newAPIServer(
	pfsAPIClient pfs.APIClient,
	jobAPIClient pps.JobAPIClient,
	persistAPIClient persist.APIClient,
) *apiServer {
	return &apiServer{
		protorpclog.NewLogger("pachyderm.pps.PipelineAPI"),
		pfsAPIClient,
		jobAPIClient,
		persistAPIClient,
		false,
		make(map[string]*pipelineController),
		&sync.Mutex{},
	}
}

func (a *apiServer) Start() error {
	a.lock.Lock()
	defer a.lock.Unlock()
	// TODO(pedge): volatile bool?
	if a.started {
		// TODO(pedge): abstract error to public variable
		return errors.New("pachyderm.pps.pipelineserver: already started")
	}
	a.started = true
	pipelineInfos, err := a.ListPipeline(context.Background(), &pps.ListPipelineRequest{})
	if err != nil {
		return err
	}
	for _, pipelineInfo := range pipelineInfos.PipelineInfo {
		if err := a.addPipelineController(pipelineInfo); err != nil {
			return err
		}
	}
	return nil
}

func (a *apiServer) CreatePipeline(ctx context.Context, request *pps.CreatePipelineRequest) (response *google_protobuf.Empty, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfo := &persist.PipelineInfo{
		PipelineName: request.Pipeline.Name,
		Transform:    request.Transform,
		Input:        request.Input,
		Output:       request.Output,
	}
	if _, err := a.persistAPIClient.CreatePipelineInfo(ctx, persistPipelineInfo); err != nil {
		return nil, err
	}
	a.lock.Lock()
	defer a.lock.Unlock()
	if err := a.addPipelineController(persistPipelineInfoToPipelineInfo(persistPipelineInfo)); err != nil {
		// TODO(pedge): proper create/rollback (do not commit transaction with create)
		if _, rollbackErr := a.persistAPIClient.DeletePipelineInfo(ctx, request.Pipeline); rollbackErr != nil {
			return nil, fmt.Errorf("%v", err, rollbackErr)
		}
		return nil, err
	}
	return google_protobuf.EmptyInstance, nil
}

func (a *apiServer) InspectPipeline(ctx context.Context, request *pps.InspectPipelineRequest) (response *pps.PipelineInfo, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfo, err := a.persistAPIClient.GetPipelineInfo(ctx, request.Pipeline)
	if err != nil {
		return nil, err
	}
	return persistPipelineInfoToPipelineInfo(persistPipelineInfo), nil
}

func (a *apiServer) ListPipeline(ctx context.Context, request *pps.ListPipelineRequest) (response *pps.PipelineInfos, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	persistPipelineInfos, err := a.persistAPIClient.ListPipelineInfos(ctx, google_protobuf.EmptyInstance)
	if err != nil {
		return nil, err
	}
	pipelineInfos := make([]*pps.PipelineInfo, len(persistPipelineInfos.PipelineInfo))
	for i, persistPipelineInfo := range persistPipelineInfos.PipelineInfo {
		pipelineInfos[i] = persistPipelineInfoToPipelineInfo(persistPipelineInfo)
	}
	return &pps.PipelineInfos{
		PipelineInfo: pipelineInfos,
	}, nil
}

func (a *apiServer) DeletePipeline(ctx context.Context, request *pps.DeletePipelineRequest) (response *google_protobuf.Empty, err error) {
	if _, err := a.persistAPIClient.DeletePipelineInfo(ctx, request.Pipeline); err != nil {
		return nil, err
	}
	a.lock.Lock()
	defer a.lock.Unlock()
	if err := a.removePipelineController(request.Pipeline.Name); err != nil {
		return nil, err
	}
	return google_protobuf.EmptyInstance, nil
}

func persistPipelineInfoToPipelineInfo(persistPipelineInfo *persist.PipelineInfo) *pps.PipelineInfo {
	return &pps.PipelineInfo{
		Pipeline: &pps.Pipeline{
			Name: persistPipelineInfo.PipelineName,
		},
		Transform: persistPipelineInfo.Transform,
		Input:     persistPipelineInfo.Input,
		Output:    persistPipelineInfo.Output,
	}
}

func (a *apiServer) addPipelineController(pipelineInfo *pps.PipelineInfo) error {
	if _, ok := a.pipelineNameToPipelineController[pipelineInfo.Pipeline.Name]; ok {
		protolog.Warnf("pachyderm.pps.pipelineserver: had a create change event for an existing pipeline: %v", pipelineInfo)
		if err := a.removePipelineController(pipelineInfo.Pipeline.Name); err != nil {
			return err
		}
	}
	pipelineController := newPipelineController(
		a.pfsAPIClient,
		a.jobAPIClient,
		pps.NewLocalPipelineAPIClient(a),
		pipelineInfo,
	)
	a.pipelineNameToPipelineController[pipelineInfo.Pipeline.Name] = pipelineController
	return pipelineController.Start()
}

func (a *apiServer) removePipelineController(name string) error {
	pipelineController, ok := a.pipelineNameToPipelineController[name]
	if !ok {
		protolog.Warnf("pachyderm.pps.pipelineserver: no pipeline registered for name: %s", name)
	} else {
		pipelineController.Cancel()
	}
	return nil
}
<|endoftext|>


<commit_before>package test

// Acceptance tests for GraphQL Schema

// There is a helper struct called GraphQLResult that helps to navigate through the output,
// and a few helper functions to access the GraphQL endpoint.
// See the end of this file for more details on how those work.

import (
	"testing"

	"github.com/go-openapi/runtime"

	"github.com/creativesoftwarefdn/weaviate/models"

	"github.com/stretchr/testify/assert"

	graphql_client "github.com/creativesoftwarefdn/weaviate/client/graphql"
	"github.com/creativesoftwarefdn/weaviate/test/acceptance/helper"
)

<<<<<<< HEAD
// Checks if the types defined in the schema are also in the actual schema
func TestStaticTypeNames(t *testing.T) {
=======
// Test that the types we expect there to be are actually generated.
func TestGettingTypeNames(t *testing.T) {
>>>>>>> 3a7036163aec9950a429ceab8173ff346911f5c5
	t.Parallel()

	query := `{
    __schema {
      types {
        name
      }
    }
  }`

	expectedTypes := []string{"WeaviateObj", "WeaviateLocalObj", "WeaviateLocalConvertedFetchFilterInpObj", "FetchFilterANDInpObj", "FetchFilterORInpObj", "FetchFilterEQInpObj", "FetchFilterFieldANDInpObj", "FetchFilterFieldORInpObj", "FetchFilterNEQInpObj", "FetchFilterIEInpObj", "WeaviateLocalConvertedFetchObj", "WeaviateLocalConvertedFetchThingsObj", "WeaviateLocalConvertedFetchActionsObj", "WeaviateLocalMetaFetchFilterInpObj", "WeaviateLocalMetaFetchObj", "WeaviateLocalMetaFetchGenericsObj", "WeaviateLocalMetaFetchGenericsThingsObj", "WeaviateLocalMetaFetchGenericsActionsObj"}

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)

	for _, expected := range expectedTypes {
		found := false

		// Check if this expected type is in the response
		for _, type_ := range response.AssertKey(t, "__schema").AssertKey(t, "types").AssertSlice(t) {
			foundType := type_.AssertKey(t, "name").AssertString(t)
			if expected == foundType {
				found = true
				break
			}
		}
		if !found {
			t.Errorf("Could not find expected type '%s'", expected)
		}
	}
}

// Checks if root query type is as expected
func TestRootType(t *testing.T) {
	t.Parallel()

	query := `{
		__schema {
		  queryType {
			name
		  }
		}
	  }`

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)

	assert.Equal(t, response.AssertKey(t, "__schema").AssertKey(t, "queryType").AsserKey(t, "name"), "WeaviateObj", "Root type should be the same as expected.")
}

// Checks if root query type is correctly defined
func TestRootQueryType(t *testing.T) {
	t.Parallel()

	response := queryGraphqlTypeIntrospection(t, helper.RootAuth, "WeaviateObj")

	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "kind"), "OBJECT", "Root query type object kind should be same as expected.")
	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "name"), "WeaviateObj", "Root query type name should be same as expected.")
	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "description"), "Location of the root query", "Root query type description should be same as expected.")
}

// Checks schema types are generated as expected
func TestSchemaTypes(t *testing.T) {
	t.Parallel()

	// Read entire grapql schema descriptions file into an array of bytes
	expected_schema_file, err := ioutil.ReadFile("../graphql_schema/schema_design.json")
	if (err != nil) {
		fmt.Fprintf(os.Stderr, "Failed read file: %s\n", err)
		os.Exit(1)
	}
	var f interface{}
	err = json.Unmarshal(expected_schema_file, &f)
	if (err != nil) {
		fmt.Fprintf(os.Stderr, "Failed to parse JSON: %s\n", err)
		os.Exit(1)
	}
	// Type-cast `expected_schema_file` to a map by means of type assertion.
	expected_schema := f.(map[string]interface{})

	// loop through all expected types
	for expected_type := range expected_schema.AssertKey(t, "data").AssertKey(t, "__schema").AssertKey(t, "types").AssertSlice(t) {
		// introspect the type in the actual schema
		response := queryGraphqlTypeIntrospection(t, helper.RootAuth, expected_type.AssertKey(t, "name"))

		// assert the actual type
		assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "kind"), expected_type.AssertKey(t, "kind"), "The object's kind type should be the same as expected.")
		assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "description"), expected_type.AssertKey(t, "description"), "The object's description should be the same as expected.")

		fields := false
		if response.AssertKey(t, "__type").AssertKey(t, "kind") == "OBJECT" {
			fields := "fields"
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "INPUT_OBJECT" {
			fields := "inputFields"
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "ENUM" {
			// assert the enumValues
			for expectedEnumValue := range expected_type.AssertKey(t, "enumValues").AssertSlice(t) {
				found := false
				for actualEnumValue := range response.AssertKey(t, "__type").AssertKey(t, "kind").AssertKey(t, "enumValues").AssertSlice(t) {
					if expectedEnumValue.AssertKey(t, "name") == actualEnumValue.AssertKey(t, "name") {
						found = true
						// assert description
						assert.Equal(t, actualEnumValue.AssertKey(t, "description"), expectedEnumValue.AssertKey(t, "description"), "The enum description should be the same as expected.")
						break
			}
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "UNION" {
			// assert type
			for expected_possible_type := range expected_type.AssertKey(t, fields).AssertSlice(t) {
				found := false
				for actual_possible_type := range response.AssertKey(t, "__type").AssertKey(t, "fields").AssertSlice(t) {
					if expected_possible_type.AssertKey(t, "name") == actual_possible_type.AssertKey(t, "name") {
						found = true
						// possible type is found

						// assert field type
						name := actual_possible_type.AssertKey(t, "name")
						ofType := actual_possible_type.AssertKey(t, "ofType")
						if name {
							assert.Equal(t, name, expected_possible_type.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
						}
						if ofType {
							for true {
								assert.Equal(t, actual_possible_type(t, "ofType").AssertKey(t, "name"), expected_possible_type.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
								actual_possible_type := actual_possible_type.AssertKey(t, "ofType")
								name := actual_possible_type.AssertKey(t, "name")
								if name != nil {
									break
								}
							}
						}
						break
					}
				}
			}
		}

		if fields {
			for expected_field := range expected_type.AssertKey(t, fields).AssertSlice(t) {
				found := false
				for actual_field := range response.AssertKey(t, "__type").AssertKey(t, "fields").AssertSlice(t) {
					if expected_field.AssertKey(t, "name") == actual_field.AssertKey(t, "name") {
						// field is found
						found = true

						// assert field description
						assert.Equal(t, actual_field.AssertKey(t, "description"), expected_field.AssertKey(t, "description"), "The fields description should be the same as expected.")

						// assert field type
						actual_field_type := actual_field.AssertKey(t, "type")
						name := actual_field_type.AssertKey(t, "name")
						ofType := actual_field_type.AssertKey(t, "ofType")
						if name {
							assert.Equal(t, name, expected_field.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
						}
						if ofType {
							for true {
								assert.Equal(t, actual_field_type(t, "ofType").AssertKey(t, "name"), expected_field.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
								actual_field_type := actual_field_type.AssertKey(t, "ofType")
								name := actual_field_type.AssertKey(t, "name")
								if name != nil {
									break
								}
							}
						}

						// assert field args
						for expected_arg := range expected_field.AssertKey(t, "args").AssertSlice(t) {
							found := false
							for actual_arg := range actual_field.AssertKey(t, "args").AssertSlice(t) {
								if expected_arg.AssertKey(t, "name") == actual_arg.AssertKey(t, "name") {
									found = true

									// assert arg description
									assert.Equal(t, actual_arg.AssertKey(t, "description"), expected_arg.AssertKey(t, "description"), "the arg's description should be the same as expected.")

									// assert arg type
									actual_arg_type := actual_arg.AssertKey(t, "type")
									name := actual_arg_type.AssertKey(t, "name")
									ofType := actual_arg_type.AssertKey(t, "ofType")
									if name {
										assert.Equal(t, name, expected_arg.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
									}
									if ofType {
										for true {
											assert.Equal(t, actual_arg_type(t, "ofType").AssertKey(t, "name"), expected_arg.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
											actual_arg_type := actual_arg_type.AssertKey(t, "ofType")
											name := actual_arg_type.AssertKey(t, "name")
											if name != nil {
												break
											}
										}
									}

									break
								}
							}
						}

						break
					}
				}
			}
		}
	}
}

// TO DO
// Test naming convention camel case
// func TestSchemaNamingConvention(t *testing.T) {
// 	t.Parallel()

///////////////////////////////////////////////////////////////////////////////////////////////////
// Helper functions

type GraphQLResult struct {
	Result interface{}
}

// Asserts that the result is a map, and index in this key
func (g *GraphQLResult) AssertKey(t *testing.T, key string) *GraphQLResult {
	m, ok := g.Result.(map[string]interface{})
	if !ok {
		t.Fatalf("Can't index into key %s, because this is not a map", key)
	}

	x, ok := m[key]
	if !ok {
		t.Fatalf("Can't index into key %s, because no such key exists", key)
	}

	return &GraphQLResult{Result: x}
}

// Assert that this is a slice.
// Wraps a GraphQLResult over all children too.
func (g *GraphQLResult) AssertSlice(t *testing.T) []*GraphQLResult {
	m, ok := g.Result.([]interface{})
	if !ok {
		t.Fatalf("This is not a slice!")
	}

	var result []*GraphQLResult

	for _, s := range m {
		result = append(result, &GraphQLResult{Result: s})
	}

	return result
}

// Assert that this is a string
func (g *GraphQLResult) AssertString(t *testing.T) string {
	str, ok := g.Result.(string)
	if !ok {
		t.Fatalf("This is not a string!")
	}
	return str
}

// Perform a GraphQL query
func queryGraphql(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation string, query string, variables map[string]interface{}) (*models.GraphQLResponse, error) {
	var vars interface{} = variables
	params := graphql_client.NewWeaviateGraphqlPostParams().WithBody(&models.GraphQLQuery{OperationName: operation, Query: query, Variables: vars})
	response, err := helper.Client(t).Graphql.WeaviateGraphqlPost(params, auth)

	if err != nil {
		return nil, err
	}

	return response.Payload, nil
}

// Perform a query and assert that it is successful
func queryGraphqlAssertOK(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) *GraphQLResult {
	response, err := queryGraphql(t, auth, "", query, nil)
	if err != nil {
		t.Fatalf("Expected the query to succeed, but failed due to: %#v", err)
	}

	data := make(map[string]interface{})

	// get rid of models.JSONData
	for key, value := range response.Data {
		data[key] = value
	}

	return &GraphQLResult{Result: data}
}

// Perform a query and assert that it is incorrect
func queryGraphqlAssertFail(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) ([]*models.GraphQLError, error) {
	response, err := queryGraphql(t, auth, "", query, nil)
	if err == nil {
		t.Fatalf("Expected the query to fail, but it succeeded %#v", response)
	}

	return response.Errors, err
}

// Perform a GraphQL introspection query for a specific type
func queryGraphqlTypeIntrospection(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, typeName string) *GraphQLResult {
	query := fmt.Sprintf(`{
		__type(name: %s) {
		  kind
		  name
		  description
		  fields {
			name
			description
			args {
			  ...InputValue
			}
			type {
			  ...TypeRef
			}
		  }
		  inputFields {
			...InputValue
		  }
		  interfaces {
			...TypeRef
		  }
		  enumValues {
			name
			description
		  }
		  possibleTypes {
			...TypeRef
		  }
		}
	  }

	  fragment InputValue on __InputValue {
		name
		description
		type {
		  ...TypeRef
		}
	  }

	  fragment TypeRef on __Type {
		kind
		name
		ofType {
		  kind
		  name
		  ofType {
			kind
			name
			ofType {
			  kind
			  name
			  ofType {
				kind
				name
				ofType {
				  kind
				  name
				  ofType {
					kind
					name
					ofType {
					  kind
					  name
					}
				  }
				}
			  }
			}
		  }
		}
	  }`, typeName)

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)
	return response
}<commit_msg>gh-431: fix merge conflict<commit_after>package test

// Acceptance tests for GraphQL Schema

// There is a helper struct called GraphQLResult that helps to navigate through the output,
// and a few helper functions to access the GraphQL endpoint.
// See the end of this file for more details on how those work.

import (
	"testing"

	"github.com/go-openapi/runtime"

	"github.com/creativesoftwarefdn/weaviate/models"

	"github.com/stretchr/testify/assert"

	graphql_client "github.com/creativesoftwarefdn/weaviate/client/graphql"
	"github.com/creativesoftwarefdn/weaviate/test/acceptance/helper"
)

// Test that the types we expect there to be are actually generated.
func TestGettingTypeNames(t *testing.T) {
	t.Parallel()

	query := `{
    __schema {
      types {
        name
      }
    }
  }`

	expectedTypes := []string{"WeaviateObj", "WeaviateLocalObj", "WeaviateLocalConvertedFetchFilterInpObj", "FetchFilterANDInpObj", "FetchFilterORInpObj", "FetchFilterEQInpObj", "FetchFilterFieldANDInpObj", "FetchFilterFieldORInpObj", "FetchFilterNEQInpObj", "FetchFilterIEInpObj", "WeaviateLocalConvertedFetchObj", "WeaviateLocalConvertedFetchThingsObj", "WeaviateLocalConvertedFetchActionsObj", "WeaviateLocalMetaFetchFilterInpObj", "WeaviateLocalMetaFetchObj", "WeaviateLocalMetaFetchGenericsObj", "WeaviateLocalMetaFetchGenericsThingsObj", "WeaviateLocalMetaFetchGenericsActionsObj"}

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)

	for _, expected := range expectedTypes {
		found := false

		// Check if this expected type is in the response
		for _, type_ := range response.AssertKey(t, "__schema").AssertKey(t, "types").AssertSlice(t) {
			foundType := type_.AssertKey(t, "name").AssertString(t)
			if expected == foundType {
				found = true
				break
			}
		}
		if !found {
			t.Errorf("Could not find expected type '%s'", expected)
		}
	}
}

// Checks if root query type is as expected
func TestRootType(t *testing.T) {
	t.Parallel()

	query := `{
		__schema {
		  queryType {
			name
		  }
		}
	  }`

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)

	assert.Equal(t, response.AssertKey(t, "__schema").AssertKey(t, "queryType").AsserKey(t, "name"), "WeaviateObj", "Root type should be the same as expected.")
}

// Checks if root query type is correctly defined
func TestRootQueryType(t *testing.T) {
	t.Parallel()

	response := queryGraphqlTypeIntrospection(t, helper.RootAuth, "WeaviateObj")

	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "kind"), "OBJECT", "Root query type object kind should be same as expected.")
	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "name"), "WeaviateObj", "Root query type name should be same as expected.")
	assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "description"), "Location of the root query", "Root query type description should be same as expected.")
}

// Checks schema types are generated as expected
func TestSchemaTypes(t *testing.T) {
	t.Parallel()

	// Read entire grapql schema descriptions file into an array of bytes
	expected_schema_file, err := ioutil.ReadFile("../graphql_schema/schema_design.json")
	if (err != nil) {
		fmt.Fprintf(os.Stderr, "Failed read file: %s\n", err)
		os.Exit(1)
	}
	var f interface{}
	err = json.Unmarshal(expected_schema_file, &f)
	if (err != nil) {
		fmt.Fprintf(os.Stderr, "Failed to parse JSON: %s\n", err)
		os.Exit(1)
	}
	// Type-cast `expected_schema_file` to a map by means of type assertion.
	expected_schema := f.(map[string]interface{})

	// loop through all expected types
	for expected_type := range expected_schema.AssertKey(t, "data").AssertKey(t, "__schema").AssertKey(t, "types").AssertSlice(t) {
		// introspect the type in the actual schema
		response := queryGraphqlTypeIntrospection(t, helper.RootAuth, expected_type.AssertKey(t, "name"))

		// assert the actual type
		assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "kind"), expected_type.AssertKey(t, "kind"), "The object's kind type should be the same as expected.")
		assert.Equal(t, response.AssertKey(t, "__type").AssertKey(t, "description"), expected_type.AssertKey(t, "description"), "The object's description should be the same as expected.")

		fields := false
		if response.AssertKey(t, "__type").AssertKey(t, "kind") == "OBJECT" {
			fields := "fields"
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "INPUT_OBJECT" {
			fields := "inputFields"
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "ENUM" {
			// assert the enumValues
			for expectedEnumValue := range expected_type.AssertKey(t, "enumValues").AssertSlice(t) {
				found := false
				for actualEnumValue := range response.AssertKey(t, "__type").AssertKey(t, "kind").AssertKey(t, "enumValues").AssertSlice(t) {
					if expectedEnumValue.AssertKey(t, "name") == actualEnumValue.AssertKey(t, "name") {
						found = true
						// assert description
						assert.Equal(t, actualEnumValue.AssertKey(t, "description"), expectedEnumValue.AssertKey(t, "description"), "The enum description should be the same as expected.")
						break
			}
		} else if response.AssertKey(t, "__type").AssertKey(t, "kind") == "UNION" {
			// assert type
			for expected_possible_type := range expected_type.AssertKey(t, fields).AssertSlice(t) {
				found := false
				for actual_possible_type := range response.AssertKey(t, "__type").AssertKey(t, "fields").AssertSlice(t) {
					if expected_possible_type.AssertKey(t, "name") == actual_possible_type.AssertKey(t, "name") {
						found = true
						// possible type is found

						// assert field type
						name := actual_possible_type.AssertKey(t, "name")
						ofType := actual_possible_type.AssertKey(t, "ofType")
						if name {
							assert.Equal(t, name, expected_possible_type.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
						}
						if ofType {
							for true {
								assert.Equal(t, actual_possible_type(t, "ofType").AssertKey(t, "name"), expected_possible_type.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
								actual_possible_type := actual_possible_type.AssertKey(t, "ofType")
								name := actual_possible_type.AssertKey(t, "name")
								if name != nil {
									break
								}
							}
						}
						break
					}
				}
			}
		}

		if fields {
			for expected_field := range expected_type.AssertKey(t, fields).AssertSlice(t) {
				found := false
				for actual_field := range response.AssertKey(t, "__type").AssertKey(t, "fields").AssertSlice(t) {
					if expected_field.AssertKey(t, "name") == actual_field.AssertKey(t, "name") {
						// field is found
						found = true

						// assert field description
						assert.Equal(t, actual_field.AssertKey(t, "description"), expected_field.AssertKey(t, "description"), "The fields description should be the same as expected.")

						// assert field type
						actual_field_type := actual_field.AssertKey(t, "type")
						name := actual_field_type.AssertKey(t, "name")
						ofType := actual_field_type.AssertKey(t, "ofType")
						if name {
							assert.Equal(t, name, expected_field.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
						}
						if ofType {
							for true {
								assert.Equal(t, actual_field_type(t, "ofType").AssertKey(t, "name"), expected_field.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
								actual_field_type := actual_field_type.AssertKey(t, "ofType")
								name := actual_field_type.AssertKey(t, "name")
								if name != nil {
									break
								}
							}
						}

						// assert field args
						for expected_arg := range expected_field.AssertKey(t, "args").AssertSlice(t) {
							found := false
							for actual_arg := range actual_field.AssertKey(t, "args").AssertSlice(t) {
								if expected_arg.AssertKey(t, "name") == actual_arg.AssertKey(t, "name") {
									found = true

									// assert arg description
									assert.Equal(t, actual_arg.AssertKey(t, "description"), expected_arg.AssertKey(t, "description"), "the arg's description should be the same as expected.")

									// assert arg type
									actual_arg_type := actual_arg.AssertKey(t, "type")
									name := actual_arg_type.AssertKey(t, "name")
									ofType := actual_arg_type.AssertKey(t, "ofType")
									if name {
										assert.Equal(t, name, expected_arg.AssertKey(t, "type").AssertKey(t, "name"), "The field type's name should be the same as expected.")
									}
									if ofType {
										for true {
											assert.Equal(t, actual_arg_type(t, "ofType").AssertKey(t, "name"), expected_arg.AssertKey(t, "ofType").AssertKey(t, "name"), "The field type's name should be the same as expected.")
											actual_arg_type := actual_arg_type.AssertKey(t, "ofType")
											name := actual_arg_type.AssertKey(t, "name")
											if name != nil {
												break
											}
										}
									}

									break
								}
							}
						}

						break
					}
				}
			}
		}
	}
}

// TO DO
// Test naming convention camel case
// func TestSchemaNamingConvention(t *testing.T) {
// 	t.Parallel()

///////////////////////////////////////////////////////////////////////////////////////////////////
// Helper functions

type GraphQLResult struct {
	Result interface{}
}

// Asserts that the result is a map, and index in this key
func (g *GraphQLResult) AssertKey(t *testing.T, key string) *GraphQLResult {
	m, ok := g.Result.(map[string]interface{})
	if !ok {
		t.Fatalf("Can't index into key %s, because this is not a map", key)
	}

	x, ok := m[key]
	if !ok {
		t.Fatalf("Can't index into key %s, because no such key exists", key)
	}

	return &GraphQLResult{Result: x}
}

// Assert that this is a slice.
// Wraps a GraphQLResult over all children too.
func (g *GraphQLResult) AssertSlice(t *testing.T) []*GraphQLResult {
	m, ok := g.Result.([]interface{})
	if !ok {
		t.Fatalf("This is not a slice!")
	}

	var result []*GraphQLResult

	for _, s := range m {
		result = append(result, &GraphQLResult{Result: s})
	}

	return result
}

// Assert that this is a string
func (g *GraphQLResult) AssertString(t *testing.T) string {
	str, ok := g.Result.(string)
	if !ok {
		t.Fatalf("This is not a string!")
	}
	return str
}

// Perform a GraphQL query
func queryGraphql(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, operation string, query string, variables map[string]interface{}) (*models.GraphQLResponse, error) {
	var vars interface{} = variables
	params := graphql_client.NewWeaviateGraphqlPostParams().WithBody(&models.GraphQLQuery{OperationName: operation, Query: query, Variables: vars})
	response, err := helper.Client(t).Graphql.WeaviateGraphqlPost(params, auth)

	if err != nil {
		return nil, err
	}

	return response.Payload, nil
}

// Perform a query and assert that it is successful
func queryGraphqlAssertOK(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) *GraphQLResult {
	response, err := queryGraphql(t, auth, "", query, nil)
	if err != nil {
		t.Fatalf("Expected the query to succeed, but failed due to: %#v", err)
	}

	data := make(map[string]interface{})

	// get rid of models.JSONData
	for key, value := range response.Data {
		data[key] = value
	}

	return &GraphQLResult{Result: data}
}

// Perform a query and assert that it is incorrect
func queryGraphqlAssertFail(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, query string) ([]*models.GraphQLError, error) {
	response, err := queryGraphql(t, auth, "", query, nil)
	if err == nil {
		t.Fatalf("Expected the query to fail, but it succeeded %#v", response)
	}

	return response.Errors, err
}

// Perform a GraphQL introspection query for a specific type
func queryGraphqlTypeIntrospection(t *testing.T, auth runtime.ClientAuthInfoWriterFunc, typeName string) *GraphQLResult {
	query := fmt.Sprintf(`{
		__type(name: %s) {
		  kind
		  name
		  description
		  fields {
			name
			description
			args {
			  ...InputValue
			}
			type {
			  ...TypeRef
			}
		  }
		  inputFields {
			...InputValue
		  }
		  interfaces {
			...TypeRef
		  }
		  enumValues {
			name
			description
		  }
		  possibleTypes {
			...TypeRef
		  }
		}
	  }

	  fragment InputValue on __InputValue {
		name
		description
		type {
		  ...TypeRef
		}
	  }

	  fragment TypeRef on __Type {
		kind
		name
		ofType {
		  kind
		  name
		  ofType {
			kind
			name
			ofType {
			  kind
			  name
			  ofType {
				kind
				name
				ofType {
				  kind
				  name
				  ofType {
					kind
					name
					ofType {
					  kind
					  name
					}
				  }
				}
			  }
			}
		  }
		}
	  }`, typeName)

	response := queryGraphqlAssertOK(t, helper.RootAuth, query)
	return response
}<|endoftext|>


<commit_before>package service

import (
	"context"
	"fmt"
	inet "gx/ipfs/QmXfkENeeBvh3zYA51MaSdGUdBjhQ99cP5WQe8zgr6wchG/go-libp2p-net"
	ggio "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/io"
	"gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer"
	"math/rand"
	"sync"
	"time"

	"github.com/OpenBazaar/openbazaar-go/pb"
)

type messageSender struct {
	s         inet.Stream
	w         ggio.WriteCloser
	r         ggio.ReadCloser
	lk        sync.Mutex
	p         peer.ID
	service   *OpenBazaarService
	singleMes int
	invalid   bool
	requests  map[int32]chan *pb.Message
	requestlk sync.Mutex
}

var ReadMessageTimeout = time.Minute * 5
var ErrReadTimeout = fmt.Errorf("timed out reading response")
var ErrWriteTimeout = fmt.Errorf("timed out writing message")

func (service *OpenBazaarService) messageSenderForPeer(ctx context.Context, p peer.ID) (*messageSender, error) {
	service.senderlk.Lock()
	ms, ok := service.sender[p]
	if ok {
		service.senderlk.Unlock()
		return ms, nil
	}
	ms = &messageSender{p: p, service: service, requests: make(map[int32]chan *pb.Message, 2)}
	service.sender[p] = ms
	service.senderlk.Unlock()

	if err := ms.ctxPrepOrInvalidate(ctx); err != nil {
		service.senderlk.Lock()
		defer service.senderlk.Unlock()

		if msCur, ok := service.sender[p]; ok {
			// Changed. Use the new one, old one is invalid and
			// not in the map so we can just throw it away.
			if ms != msCur {
				return msCur, nil
			}
			// Not changed, remove the now invalid stream from the
			// map.
			delete(service.sender, p)
		}
		// Invalid but not in map. Must have been removed by a disconnect.
		return nil, err
	}
	// All ready to go.
	return ms, nil
}

// invalidate is called before this messageSender is removed from the strmap.
// It prevents the messageSender from being reused/reinitialized and then
// forgotten (leaving the stream open).
func (ms *messageSender) invalidate() {
	ms.invalid = true
	if ms.s != nil {
		ms.s.Reset()
		ms.s = nil
	}
}

func (ms *messageSender) ctxPrepOrInvalidate(ctx context.Context) error {
	ms.lk.Lock()
	defer ms.lk.Unlock()

	errCh := make(chan error)
	go func() {
		errCh <- ms.prep()
	}()

	select {
	case err := <-errCh:
		ms.invalidate()
		return err
	case <-ctx.Done():
		ms.invalidate()
		return ErrWriteTimeout
	}
}

func (ms *messageSender) prep() error {
	if ms.invalid {
		return fmt.Errorf("message sender has been invalidated")
	}
	if ms.s != nil {
		return nil
	}

	nstr, err := ms.service.host.NewStream(ms.service.ctx, ms.p, ProtocolOpenBazaar)
	if err != nil {
		return err
	}

	ms.r = ggio.NewDelimitedReader(nstr, inet.MessageSizeMax)
	ms.w = ggio.NewDelimitedWriter(nstr)
	ms.s = nstr

	return nil
}

// streamReuseTries is the number of times we will try to reuse a stream to a
// given peer before giving up and reverting to the old one-message-per-stream
// behavior.
const streamReuseTries = 3

func (ms *messageSender) SendMessage(ctx context.Context, pmes *pb.Message) error {
	ms.lk.Lock()
	defer ms.lk.Unlock()
	retry := false
	for {
		if err := ms.prep(); err != nil {
			return err
		}

		err := ms.ctxWriteMsg(ctx, pmes)
		switch err {
		case ErrWriteTimeout:
			ms.s.Reset()
			ms.s = nil
			return err
		case nil:
			break
		default:
			ms.s.Reset()
			ms.s = nil

			if retry {
				return err
			} else {
				retry = true
				continue
			}
		}

		if ms.singleMes > streamReuseTries {
			ms.s.Close()
			ms.s = nil
		} else if retry {
			ms.singleMes++
		}

		return nil
	}
}

func (ms *messageSender) SendRequest(ctx context.Context, pmes *pb.Message) (*pb.Message, error) {
	pmes.RequestId = rand.Int31()
	returnChan := make(chan *pb.Message)
	ms.requestlk.Lock()
	ms.requests[pmes.RequestId] = returnChan
	ms.requestlk.Unlock()

	defer ms.closeRequest(pmes.RequestId)

	ms.lk.Lock()
	defer ms.lk.Unlock()
	retry := false
	for {
		if err := ms.prep(); err != nil {
			return nil, err
		}

		err := ms.ctxWriteMsg(ctx, pmes)
		switch err {
		case ErrWriteTimeout:
			ms.s.Reset()
			ms.s = nil
			return nil, err
		case nil:
			break
		default:
			ms.s.Reset()
			ms.s = nil

			if retry {
				return nil, err
			} else {
				retry = true
				continue
			}
		}

		mes, err := ms.ctxReadMsg(ctx, returnChan)
		if err != nil {
			ms.s.Reset()
			ms.s = nil
			return nil, err
		}

		if ms.singleMes > streamReuseTries {
			ms.s.Close()
			ms.s = nil
		} else if retry {
			ms.singleMes++
		}

		return mes, nil
	}
}

// stop listening for responses
func (ms *messageSender) closeRequest(id int32) {
	ms.requestlk.Lock()
	ch, ok := ms.requests[id]
	if ok {
		close(ch)
		delete(ms.requests, id)
	}
	ms.requestlk.Unlock()
}

func (ms *messageSender) ctxReadMsg(ctx context.Context, returnChan chan *pb.Message) (*pb.Message, error) {
	t := time.NewTimer(ReadMessageTimeout)
	defer t.Stop()

	select {
	case mes := <-returnChan:
		return mes, nil
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-t.C:
		return nil, ErrReadTimeout
	}
}

func (ms *messageSender) ctxWriteMsg(ctx context.Context, pmes *pb.Message) error {
	errCh := make(chan error)
	go func() {
		errCh <- ms.w.WriteMsg(pmes)
	}()

	select {
	case err := <-errCh:
		return err
	case <-ctx.Done():
		return ErrWriteTimeout
	}
}
<commit_msg>Fix bug in prepOrInvalidate<commit_after>package service

import (
	"context"
	"fmt"
	inet "gx/ipfs/QmXfkENeeBvh3zYA51MaSdGUdBjhQ99cP5WQe8zgr6wchG/go-libp2p-net"
	ggio "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/io"
	"gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer"
	"math/rand"
	"sync"
	"time"

	"github.com/OpenBazaar/openbazaar-go/pb"
)

type messageSender struct {
	s         inet.Stream
	w         ggio.WriteCloser
	r         ggio.ReadCloser
	lk        sync.Mutex
	p         peer.ID
	service   *OpenBazaarService
	singleMes int
	invalid   bool
	requests  map[int32]chan *pb.Message
	requestlk sync.Mutex
}

var ReadMessageTimeout = time.Minute * 5
var ErrReadTimeout = fmt.Errorf("timed out reading response")
var ErrWriteTimeout = fmt.Errorf("timed out writing message")

func (service *OpenBazaarService) messageSenderForPeer(ctx context.Context, p peer.ID) (*messageSender, error) {
	service.senderlk.Lock()
	ms, ok := service.sender[p]
	if ok {
		service.senderlk.Unlock()
		return ms, nil
	}
	ms = &messageSender{p: p, service: service, requests: make(map[int32]chan *pb.Message, 2)}
	service.sender[p] = ms
	service.senderlk.Unlock()

	if err := ms.ctxPrepOrInvalidate(ctx); err != nil {
		service.senderlk.Lock()
		defer service.senderlk.Unlock()

		if msCur, ok := service.sender[p]; ok {
			// Changed. Use the new one, old one is invalid and
			// not in the map so we can just throw it away.
			if ms != msCur {
				return msCur, nil
			}
			// Not changed, remove the now invalid stream from the
			// map.
			delete(service.sender, p)
		}
		// Invalid but not in map. Must have been removed by a disconnect.
		return nil, err
	}
	// All ready to go.
	return ms, nil
}

// invalidate is called before this messageSender is removed from the strmap.
// It prevents the messageSender from being reused/reinitialized and then
// forgotten (leaving the stream open).
func (ms *messageSender) invalidate() {
	ms.invalid = true
	if ms.s != nil {
		ms.s.Reset()
		ms.s = nil
	}
}

func (ms *messageSender) ctxPrepOrInvalidate(ctx context.Context) error {
	ms.lk.Lock()
	defer ms.lk.Unlock()

	errCh := make(chan error)
	go func() {
		errCh <- ms.prep()
	}()

	select {
	case err := <-errCh:
		if err != nil {
			ms.invalidate()
		}
		return err
	case <-ctx.Done():
		ms.invalidate()
		return ErrWriteTimeout
	}
}

func (ms *messageSender) prep() error {
	if ms.invalid {
		return fmt.Errorf("message sender has been invalidated")
	}
	if ms.s != nil {
		return nil
	}

	nstr, err := ms.service.host.NewStream(ms.service.ctx, ms.p, ProtocolOpenBazaar)
	if err != nil {
		return err
	}

	ms.r = ggio.NewDelimitedReader(nstr, inet.MessageSizeMax)
	ms.w = ggio.NewDelimitedWriter(nstr)
	ms.s = nstr

	return nil
}

// streamReuseTries is the number of times we will try to reuse a stream to a
// given peer before giving up and reverting to the old one-message-per-stream
// behavior.
const streamReuseTries = 3

func (ms *messageSender) SendMessage(ctx context.Context, pmes *pb.Message) error {
	ms.lk.Lock()
	defer ms.lk.Unlock()
	retry := false
	for {
		if err := ms.prep(); err != nil {
			return err
		}

		err := ms.ctxWriteMsg(ctx, pmes)
		switch err {
		case ErrWriteTimeout:
			ms.s.Reset()
			ms.s = nil
			return err
		case nil:
			break
		default:
			ms.s.Reset()
			ms.s = nil

			if retry {
				return err
			} else {
				retry = true
				continue
			}
		}

		if ms.singleMes > streamReuseTries {
			ms.s.Close()
			ms.s = nil
		} else if retry {
			ms.singleMes++
		}

		return nil
	}
}

func (ms *messageSender) SendRequest(ctx context.Context, pmes *pb.Message) (*pb.Message, error) {
	pmes.RequestId = rand.Int31()
	returnChan := make(chan *pb.Message)
	ms.requestlk.Lock()
	ms.requests[pmes.RequestId] = returnChan
	ms.requestlk.Unlock()

	defer ms.closeRequest(pmes.RequestId)

	ms.lk.Lock()
	defer ms.lk.Unlock()
	retry := false
	for {
		if err := ms.prep(); err != nil {
			return nil, err
		}

		err := ms.ctxWriteMsg(ctx, pmes)
		switch err {
		case ErrWriteTimeout:
			ms.s.Reset()
			ms.s = nil
			return nil, err
		case nil:
			break
		default:
			ms.s.Reset()
			ms.s = nil

			if retry {
				return nil, err
			} else {
				retry = true
				continue
			}
		}

		mes, err := ms.ctxReadMsg(ctx, returnChan)
		if err != nil {
			ms.s.Reset()
			ms.s = nil
			return nil, err
		}

		if ms.singleMes > streamReuseTries {
			ms.s.Close()
			ms.s = nil
		} else if retry {
			ms.singleMes++
		}

		return mes, nil
	}
}

// stop listening for responses
func (ms *messageSender) closeRequest(id int32) {
	ms.requestlk.Lock()
	ch, ok := ms.requests[id]
	if ok {
		close(ch)
		delete(ms.requests, id)
	}
	ms.requestlk.Unlock()
}

func (ms *messageSender) ctxReadMsg(ctx context.Context, returnChan chan *pb.Message) (*pb.Message, error) {
	t := time.NewTimer(ReadMessageTimeout)
	defer t.Stop()

	select {
	case mes := <-returnChan:
		return mes, nil
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-t.C:
		return nil, ErrReadTimeout
	}
}

func (ms *messageSender) ctxWriteMsg(ctx context.Context, pmes *pb.Message) error {
	errCh := make(chan error)
	go func() {
		errCh <- ms.w.WriteMsg(pmes)
	}()

	select {
	case err := <-errCh:
		return err
	case <-ctx.Done():
		return ErrWriteTimeout
	}
}
<|endoftext|>


<commit_before>package network_test

import (
	"bufio"
	"bytes"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"net/url"
	"strings"

	"github.com/pivotal-cf/om/network"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("OAuthClient", func() {
	var (
		receivedRequest []byte
		authHeader      string
		callCount       int
		server          *httptest.Server
	)

	BeforeEach(func() {
		server = httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			switch req.URL.Path {
			case "/uaa/oauth/token":
				callCount++
				var err error
				receivedRequest, err = httputil.DumpRequest(req, true)
				Expect(err).NotTo(HaveOccurred())

				w.Header().Set("Content-Type", "application/json")
				w.Write([]byte(`{
					"access_token": "some-opsman-token",
					"token_type": "bearer",
					"expires_in": 3600
					}`))
			default:
				authHeader = req.Header.Get("Authorization")

				w.WriteHeader(http.StatusNoContent)
				w.Write([]byte("response"))
			}
		}))
	})

	Describe("Do", func() {
		It("makes a request with authentication", func() {
			client, err := network.NewOAuthClient(server.URL, "opsman-username", "opsman-password", true)
			Expect(err).NotTo(HaveOccurred())

			Expect(callCount).To(Equal(0))

			req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
			Expect(err).NotTo(HaveOccurred())

			resp, err := client.Do(req)
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.StatusCode).To(Equal(http.StatusNoContent))

			Expect(authHeader).To(Equal("Bearer some-opsman-token"))

			req, err = http.ReadRequest(bufio.NewReader(bytes.NewReader(receivedRequest)))
			Expect(req.Method).To(Equal("POST"))
			Expect(req.URL.Path).To(Equal("/uaa/oauth/token"))
			username, password, ok := req.BasicAuth()
			Expect(ok).To(BeTrue())
			Expect(username).To(Equal("opsman"))
			Expect(password).To(BeEmpty())

			err = req.ParseForm()
			Expect(err).NotTo(HaveOccurred())
			Expect(req.Form).To(Equal(url.Values{
				"client_id":  []string{"opsman"},
				"grant_type": []string{"password"},
				"username":   []string{"opsman-username"},
				"password":   []string{"opsman-password"},
			}))
		})

		Context("when an error occurs", func() {
			Context("when the initial token cannot be retrieved", func() {
				It("returns an error", func() {
					client, err := network.NewOAuthClient("%%%", "username", "password", false)
					Expect(err).NotTo(HaveOccurred())

					req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
					Expect(err).NotTo(HaveOccurred())

					_, err = client.Do(req)
					Expect(err).To(MatchError("token could not be retrieved from target url: parse %%%/uaa/oauth/token: invalid URL escape \"%%%\""))
				})
			})
		})
	})

	Describe("RoundTrip", func() {
		It("makes a request with authentication", func() {
			client, err := network.NewOAuthClient(server.URL, "opsman-username", "opsman-password", true)
			Expect(err).NotTo(HaveOccurred())

			req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
			Expect(err).NotTo(HaveOccurred())

			resp, err := client.RoundTrip(req)
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.StatusCode).To(Equal(http.StatusNoContent))

			Expect(authHeader).To(Equal("Bearer some-opsman-token"))

			req, err = http.ReadRequest(bufio.NewReader(bytes.NewReader(receivedRequest)))
			Expect(req.Method).To(Equal("POST"))
			Expect(req.URL.Path).To(Equal("/uaa/oauth/token"))
			username, password, ok := req.BasicAuth()
			Expect(ok).To(BeTrue())
			Expect(username).To(Equal("opsman"))
			Expect(password).To(BeEmpty())

			err = req.ParseForm()
			Expect(err).NotTo(HaveOccurred())
			Expect(req.Form).To(Equal(url.Values{
				"client_id":  []string{"opsman"},
				"grant_type": []string{"password"},
				"username":   []string{"opsman-username"},
				"password":   []string{"opsman-password"},
			}))
		})
	})

	Context("when an error occurs", func() {
		Context("when the initial token cannot be retrieved", func() {
			It("returns an error", func() {
				client, err := network.NewOAuthClient("%%%", "username", "password", false)
				Expect(err).NotTo(HaveOccurred())

				req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
				Expect(err).NotTo(HaveOccurred())

				_, err = client.RoundTrip(req)
				Expect(err).To(MatchError("token could not be retrieved from target url: parse %%%/uaa/oauth/token: invalid URL escape \"%%%\""))
			})
		})
	})
})
<commit_msg>need to make sure to reset call count<commit_after>package network_test

import (
	"bufio"
	"bytes"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"net/url"
	"strings"

	"github.com/pivotal-cf/om/network"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("OAuthClient", func() {
	var (
		receivedRequest []byte
		authHeader      string
		callCount       int
		server          *httptest.Server
	)

	BeforeEach(func() {
		callCount = 0
		server = httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			switch req.URL.Path {
			case "/uaa/oauth/token":
				callCount++
				var err error
				receivedRequest, err = httputil.DumpRequest(req, true)
				Expect(err).NotTo(HaveOccurred())

				w.Header().Set("Content-Type", "application/json")
				w.Write([]byte(`{
					"access_token": "some-opsman-token",
					"token_type": "bearer",
					"expires_in": 3600
					}`))
			default:
				authHeader = req.Header.Get("Authorization")

				w.WriteHeader(http.StatusNoContent)
				w.Write([]byte("response"))
			}
		}))
	})

	Describe("Do", func() {
		It("makes a request with authentication", func() {
			client, err := network.NewOAuthClient(server.URL, "opsman-username", "opsman-password", true)
			Expect(err).NotTo(HaveOccurred())

			Expect(callCount).To(Equal(0))

			req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
			Expect(err).NotTo(HaveOccurred())

			resp, err := client.Do(req)
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.StatusCode).To(Equal(http.StatusNoContent))

			Expect(authHeader).To(Equal("Bearer some-opsman-token"))

			req, err = http.ReadRequest(bufio.NewReader(bytes.NewReader(receivedRequest)))
			Expect(req.Method).To(Equal("POST"))
			Expect(req.URL.Path).To(Equal("/uaa/oauth/token"))
			username, password, ok := req.BasicAuth()
			Expect(ok).To(BeTrue())
			Expect(username).To(Equal("opsman"))
			Expect(password).To(BeEmpty())

			err = req.ParseForm()
			Expect(err).NotTo(HaveOccurred())
			Expect(req.Form).To(Equal(url.Values{
				"client_id":  []string{"opsman"},
				"grant_type": []string{"password"},
				"username":   []string{"opsman-username"},
				"password":   []string{"opsman-password"},
			}))
		})

		Context("when an error occurs", func() {
			Context("when the initial token cannot be retrieved", func() {
				It("returns an error", func() {
					client, err := network.NewOAuthClient("%%%", "username", "password", false)
					Expect(err).NotTo(HaveOccurred())

					req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
					Expect(err).NotTo(HaveOccurred())

					_, err = client.Do(req)
					Expect(err).To(MatchError("token could not be retrieved from target url: parse %%%/uaa/oauth/token: invalid URL escape \"%%%\""))
				})
			})
		})
	})

	Describe("RoundTrip", func() {
		It("makes a request with authentication", func() {
			client, err := network.NewOAuthClient(server.URL, "opsman-username", "opsman-password", true)
			Expect(err).NotTo(HaveOccurred())

			req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
			Expect(err).NotTo(HaveOccurred())

			resp, err := client.RoundTrip(req)
			Expect(err).NotTo(HaveOccurred())

			Expect(resp.StatusCode).To(Equal(http.StatusNoContent))

			Expect(authHeader).To(Equal("Bearer some-opsman-token"))

			req, err = http.ReadRequest(bufio.NewReader(bytes.NewReader(receivedRequest)))
			Expect(req.Method).To(Equal("POST"))
			Expect(req.URL.Path).To(Equal("/uaa/oauth/token"))
			username, password, ok := req.BasicAuth()
			Expect(ok).To(BeTrue())
			Expect(username).To(Equal("opsman"))
			Expect(password).To(BeEmpty())

			err = req.ParseForm()
			Expect(err).NotTo(HaveOccurred())
			Expect(req.Form).To(Equal(url.Values{
				"client_id":  []string{"opsman"},
				"grant_type": []string{"password"},
				"username":   []string{"opsman-username"},
				"password":   []string{"opsman-password"},
			}))
		})
	})

	Context("when an error occurs", func() {
		Context("when the initial token cannot be retrieved", func() {
			It("returns an error", func() {
				client, err := network.NewOAuthClient("%%%", "username", "password", false)
				Expect(err).NotTo(HaveOccurred())

				req, err := http.NewRequest("GET", "/some/path", strings.NewReader("request-body"))
				Expect(err).NotTo(HaveOccurred())

				_, err = client.RoundTrip(req)
				Expect(err).To(MatchError("token could not be retrieved from target url: parse %%%/uaa/oauth/token: invalid URL escape \"%%%\""))
			})
		})
	})
})
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
	iog.Debugf("Writing %+v to data channel", bytes)
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package transport

import (
	log "github.com/Sirupsen/logrus"
	"time"

	"github.com/runtimeinc/gatt"

	"mynewt.apache.org/newt/newtmgr/config"
	"mynewt.apache.org/newt/util"
)

/* This is used by different command handlers */
var BleMTU uint16 = 180

var rxBLEPkt = make(chan []byte)
var CharDisc = make(chan bool)

var newtmgrServiceId = gatt.MustParseUUID("59462f12-9543-9999-12c8-58b459a27120")
var newtmgrServiceCharId = gatt.MustParseUUID("5c3a659e-897e-45e1-b016-007107c96d00")
var deviceName string

type ConnBLE struct {
	connProfile   config.NewtmgrConnProfile
	currentPacket *Packet

	bleDevice gatt.Device
}

var deviceChar *gatt.Characteristic
var devicePerph gatt.Peripheral

var bleTxData []byte

func onStateChanged(d gatt.Device, s gatt.State) {
	log.Debugf("State:%+v", s)
	switch s {
	case gatt.StatePoweredOn:
		log.Debugf("scanning...")
		d.Scan([]gatt.UUID{}, false)
		return
	default:
		d.StopScanning()
	}
}

func onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
	if a.LocalName == deviceName {
		log.Debugf("Peripheral Discovered: %s", p.Name())
		p.Device().StopScanning()
		p.Device().Connect(p)
	}
}

func newtmgrNotifyCB(c *gatt.Characteristic, incomingDatabuf []byte, err error) {
	log.Debugf("BLE Newtmgr rx data:%+v", incomingDatabuf)
        err = nil
        rxBLEPkt <- incomingDatabuf
        return
}

func onPeriphConnected(p gatt.Peripheral, err error) {
	log.Debugf("Peripheral Connected")

	services, err := p.DiscoverServices(nil)
	if err != nil {
		log.Debugf("Failed to discover services, err: %s", err)
		return
	}

	for _, service := range services {

		if service.UUID().Equal(newtmgrServiceId) {
			log.Debugf("Newtmgr Service Found %s", service.Name())

			cs, _ := p.DiscoverCharacteristics(nil, service)

			for _, c := range cs {
				if c.UUID().Equal(newtmgrServiceCharId) {
					log.Debugf("Newtmgr Characteristic Found")
					p.SetNotifyValue(c, newtmgrNotifyCB)
					deviceChar = c
					devicePerph = p
					p.SetMTU(BleMTU)
					<-CharDisc
				}
			}
		}
	}
}

func onPeriphDisconnected(p gatt.Peripheral, err error) {
	log.Debugf("Disconnected", err)
}

func (cb *ConnBLE) Open(cp config.NewtmgrConnProfile, readTimeout time.Duration) error {
	var err error

	var DefaultClientOptions = []gatt.Option{
		gatt.LnxMaxConnections(1),
		gatt.LnxDeviceID(-1, false),
	}

	deviceName = cp.ConnString()
	cb.bleDevice, err = gatt.NewDevice(DefaultClientOptions...)
	if err != nil {
		return util.NewNewtError(err.Error())
	}

	cb.bleDevice.Handle(
		gatt.PeripheralDiscovered(onPeriphDiscovered),
		gatt.PeripheralConnected(onPeriphConnected),
		gatt.PeripheralDisconnected(onPeriphDisconnected),
	)
	cb.bleDevice.Init(onStateChanged)
	CharDisc <- true

	return nil
}

func (cb *ConnBLE) ReadPacket() (*Packet, error) {
	var err error

	bleRxData := <-rxBLEPkt

	cb.currentPacket, err = NewPacket(uint16(len(bleRxData)))
	if err != nil {
		return nil, err
	}

	cb.currentPacket.AddBytes(bleRxData)
	log.Debugf("Read BLE Packet:buf::%+v len::%+v", cb.currentPacket.buffer,
                   cb.currentPacket.expectedLen)
        bleRxData = bleRxData[:0]
	pkt := cb.currentPacket
	cb.currentPacket = nil
	return pkt, err
}

func (cb *ConnBLE) writeData() error {
	devicePerph.WriteCharacteristic(deviceChar, bleTxData, true)
	return nil
}

func (cb *ConnBLE) WritePacket(pkt *Packet) error {
	log.Debugf("Write BLE Packet:buf::%+v len::%+v", pkt.buffer,
                   pkt.expectedLen)
	bleTxData = pkt.GetBytes()
	cb.writeData()
	return nil
}

func (cb *ConnBLE) Close () error {
	log.Debugf("Closing Connection %+v", cb)
        cb.bleDevice.CancelConnection(devicePerph)
	return nil
}
<commit_msg>MYNEWT-266 newtmgr over BLE<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
	iog.Debugf("Writing %+v to data channel", bytes)
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package transport

import (
	log "github.com/Sirupsen/logrus"
	"time"

	"github.com/runtimeinc/gatt"

	"mynewt.apache.org/newt/newtmgr/config"
	"mynewt.apache.org/newt/util"
)

/* This is used by different command handlers */
var BleMTU uint16 = 180

var rxBLEPkt = make(chan []byte)
var CharDisc = make(chan bool)

var newtmgrServiceId = gatt.MustParseUUID("8D53DC1D-1DB7-4CD3-868B-8A527460AA84")
var newtmgrServiceCharId = gatt.MustParseUUID("DA2E7828-FBCE-4E01-AE9E-261174997C48")
var deviceName string

type ConnBLE struct {
	connProfile   config.NewtmgrConnProfile
	currentPacket *Packet

	bleDevice gatt.Device
}

var deviceChar *gatt.Characteristic
var devicePerph gatt.Peripheral

var bleTxData []byte

func onStateChanged(d gatt.Device, s gatt.State) {
	log.Debugf("State:%+v", s)
	switch s {
	case gatt.StatePoweredOn:
		log.Debugf("scanning...")
		d.Scan([]gatt.UUID{}, false)
		return
	default:
		d.StopScanning()
	}
}

func onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
	if a.LocalName == deviceName {
		log.Debugf("Peripheral Discovered: %s", p.Name())
		p.Device().StopScanning()
		p.Device().Connect(p)
	}
}

func newtmgrNotifyCB(c *gatt.Characteristic, incomingDatabuf []byte, err error) {
	log.Debugf("BLE Newtmgr rx data:%+v", incomingDatabuf)
        err = nil
        rxBLEPkt <- incomingDatabuf
        return
}

func onPeriphConnected(p gatt.Peripheral, err error) {
	log.Debugf("Peripheral Connected")

	services, err := p.DiscoverServices(nil)
	if err != nil {
		log.Debugf("Failed to discover services, err: %s", err)
		return
	}

	for _, service := range services {

		if service.UUID().Equal(newtmgrServiceId) {
			log.Debugf("Newtmgr Service Found %s", service.Name())

			cs, _ := p.DiscoverCharacteristics(nil, service)

			for _, c := range cs {
				if c.UUID().Equal(newtmgrServiceCharId) {
					log.Debugf("Newtmgr Characteristic Found")
					p.SetNotifyValue(c, newtmgrNotifyCB)
					deviceChar = c
					devicePerph = p
					p.SetMTU(BleMTU)
					<-CharDisc
				}
			}
		}
	}
}

func onPeriphDisconnected(p gatt.Peripheral, err error) {
	log.Debugf("Disconnected", err)
}

func (cb *ConnBLE) Open(cp config.NewtmgrConnProfile, readTimeout time.Duration) error {
	var err error

	var DefaultClientOptions = []gatt.Option{
		gatt.LnxMaxConnections(1),
		gatt.LnxDeviceID(-1, false),
	}

	deviceName = cp.ConnString()
	cb.bleDevice, err = gatt.NewDevice(DefaultClientOptions...)
	if err != nil {
		return util.NewNewtError(err.Error())
	}

	cb.bleDevice.Handle(
		gatt.PeripheralDiscovered(onPeriphDiscovered),
		gatt.PeripheralConnected(onPeriphConnected),
		gatt.PeripheralDisconnected(onPeriphDisconnected),
	)
	cb.bleDevice.Init(onStateChanged)
	CharDisc <- true

	return nil
}

func (cb *ConnBLE) ReadPacket() (*Packet, error) {
	var err error

	bleRxData := <-rxBLEPkt

	cb.currentPacket, err = NewPacket(uint16(len(bleRxData)))
	if err != nil {
		return nil, err
	}

	cb.currentPacket.AddBytes(bleRxData)
	log.Debugf("Read BLE Packet:buf::%+v len::%+v", cb.currentPacket.buffer,
                   cb.currentPacket.expectedLen)
        bleRxData = bleRxData[:0]
	pkt := cb.currentPacket
	cb.currentPacket = nil
	return pkt, err
}

func (cb *ConnBLE) writeData() error {
	devicePerph.WriteCharacteristic(deviceChar, bleTxData, true)
	return nil
}

func (cb *ConnBLE) WritePacket(pkt *Packet) error {
	log.Debugf("Write BLE Packet:buf::%+v len::%+v", pkt.buffer,
                   pkt.expectedLen)
	bleTxData = pkt.GetBytes()
	cb.writeData()
	return nil
}

func (cb *ConnBLE) Close () error {
	log.Debugf("Closing Connection %+v", cb)
        cb.bleDevice.CancelConnection(devicePerph)
	return nil
}
<|endoftext|>


<commit_before>/* Taken from the Go Tour (Exercise: Loops and Functions)
 *
 * As a simple way to play with functions and loops, implement the square root function using
 * Newton's method.
 *
 * In this case, Newton's method is to approximate Sqrt(x) by picking a starting point z and then
 * repeating:
 *
 * z = z - (z*z-x)/(2*z)
 *
 * To begin with, just repeat that calculation 10 times and see how close you get to the answer for
 * various values (1, 2, 3, ...).
 *
 * Next, change the loop condition to stop once the value has stopped changing (or only changes by
 * a very small delta). See if that's more or fewer iterations. How close are you to the math.Sqrt?
 *
 * Hint: to declare and initialize a floating point value, give it floating point syntax or use a
 * conversion:
 *
 * z := float64(1)
 * z := 1.0
 *
 */

package main

import (
	"fmt"
	"math"
)

func Sqrt(x float64) (z float64) {
	z = 1.0

	for i := 0; i < 10; i++ {
		z -= (z*z-x)/(2*z)
	}

	return
}

func print_sqrt(n int) {
	fmt.Printf("sqrt(%v) = %v\n", n, Sqrt(float64(n)))
	fmt.Printf("math.Sqrt(%v) = %v\n", n, math.Sqrt(float64(n)))
}

func main() {
	for i := 0; i < 10; i++ {
		print_sqrt(i)
	}
}
<commit_msg>Added special case for x = 0 in Sqrt<commit_after>/* Taken from the Go Tour (Exercise: Loops and Functions)
 *
 * As a simple way to play with functions and loops, implement the square root function using
 * Newton's method.
 *
 * In this case, Newton's method is to approximate Sqrt(x) by picking a starting point z and then
 * repeating:
 *
 * z = z - (z*z-x)/(2*z)
 *
 * To begin with, just repeat that calculation 10 times and see how close you get to the answer for
 * various values (1, 2, 3, ...).
 *
 * Next, change the loop condition to stop once the value has stopped changing (or only changes by
 * a very small delta). See if that's more or fewer iterations. How close are you to the math.Sqrt?
 *
 * Hint: to declare and initialize a floating point value, give it floating point syntax or use a
 * conversion:
 *
 * z := float64(1)
 * z := 1.0
 *
 */

package main

import (
	"fmt"
	"math"
)

func Sqrt(x float64) (z float64) {

	if x == 0 {
		return 0
	}

	z = 1.0
	for i := 0; i < 10; i++ {
		z -= (z*z-x)/(2*z)
	}

	return
}

func print_sqrt(n int) {
	fmt.Printf("sqrt(%v) = %v\n", n, Sqrt(float64(n)))
	fmt.Printf("math.Sqrt(%v) = %v\n", n, math.Sqrt(float64(n)))
}

func main() {
	for i := 0; i < 10; i++ {
		print_sqrt(i)
	}
}
<|endoftext|>


<commit_before>package gonumbers

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func Test_NumberToPercentage(t *testing.T) {

	a := assert.New(t)
	a.Equal("100.000%", NumberToPercentage(100))
	a.Equal("98.000%", NumberToPercentage("98"))
	a.Equal("100%", NumberToPercentage(100, "precision:0"))
	a.Equal("1,000.000%", NumberToPercentage(1000))
	a.Equal("1.000,000%", NumberToPercentage(1000, "delimiter:.", "separator:,"))
	a.Equal("302.24399%", NumberToPercentage(302.24398923423, "precision:5"))

}
<commit_msg>add test for wrong argument<commit_after>package gonumbers

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func Test_NumberToPercentage(t *testing.T) {

	a := assert.New(t)
	a.Equal("100.000%", NumberToPercentage(100))
	a.Equal("98.000%", NumberToPercentage("98"))
	a.Equal("100%", NumberToPercentage(100, "precision:0"))
	a.Equal("1,000.000%", NumberToPercentage(1000))
	a.Equal("1.000,000%", NumberToPercentage(1000, "delimiter:.", "separator:,"))
	a.Equal("302.24399%", NumberToPercentage(302.24398923423, "precision:5"))
	a.Equal("0.000%", NumberToPercentage("hahahah"))

}
<|endoftext|>


<commit_before>package client

import (
	"fmt"
	"text/tabwriter"

	Cli "github.com/docker/docker/cli"
	"github.com/docker/docker/opts"
	flag "github.com/docker/docker/pkg/mflag"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
)

// CmdVolume is the parent subcommand for all volume commands
//
// Usage: docker volume <COMMAND> <OPTS>
func (cli *DockerCli) CmdVolume(args ...string) error {
	description := Cli.DockerCommands["volume"].Description + "\n\nCommands:\n"
	commands := [][]string{
		{"create", "Create a volume"},
		{"inspect", "Return low-level information on a volume"},
		{"ls", "List volumes"},
		{"rm", "Remove a volume"},
	}

	for _, cmd := range commands {
		description += fmt.Sprintf("  %-25.25s%s\n", cmd[0], cmd[1])
	}

	description += "\nRun 'docker volume COMMAND --help' for more information on a command"
	cmd := Cli.Subcmd("volume", []string{"[COMMAND]"}, description, false)

	cmd.Require(flag.Exact, 0)
	err := cmd.ParseFlags(args, true)
	cmd.Usage()
	return err
}

// CmdVolumeLs outputs a list of Docker volumes.
//
// Usage: docker volume ls [OPTIONS]
func (cli *DockerCli) CmdVolumeLs(args ...string) error {
	cmd := Cli.Subcmd("volume ls", nil, "List volumes", true)

	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names")
	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")

	cmd.Require(flag.Exact, 0)
	cmd.ParseFlags(args, true)

	volFilterArgs := filters.NewArgs()
	for _, f := range flFilter.GetAll() {
		var err error
		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
		if err != nil {
			return err
		}
	}

	volumes, err := cli.client.VolumeList(volFilterArgs)
	if err != nil {
		return err
	}

	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
	if !*quiet {
		for _, warn := range volumes.Warnings {
			fmt.Fprintln(cli.err, warn)
		}
		fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
		fmt.Fprintf(w, "\n")
	}

	for _, vol := range volumes.Volumes {
		if *quiet {
			fmt.Fprintln(w, vol.Name)
			continue
		}
		fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
	}
	w.Flush()
	return nil
}

// CmdVolumeInspect displays low-level information on one or more volumes.
//
// Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
	cmd := Cli.Subcmd("volume inspect", []string{"VOLUME [VOLUME...]"}, "Return low-level information on a volume", true)
	tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template")

	cmd.Require(flag.Min, 1)
	cmd.ParseFlags(args, true)

	if err := cmd.Parse(args); err != nil {
		return nil
	}

	inspectSearcher := func(name string) (interface{}, []byte, error) {
		i, err := cli.client.VolumeInspect(name)
		return i, nil, err
	}

	return cli.inspectElements(*tmplStr, cmd.Args(), inspectSearcher)
}

// CmdVolumeCreate creates a new volume.
//
// Usage: docker volume create [OPTIONS]
func (cli *DockerCli) CmdVolumeCreate(args ...string) error {
	cmd := Cli.Subcmd("volume create", nil, "Create a volume", true)
	flDriver := cmd.String([]string{"d", "-driver"}, "cinder", "Specify volume driver name")
	flName := cmd.String([]string{"-name"}, "", "Specify volume name")
	flSnapshot := cmd.String([]string{"-snapshot"}, "", "Specify snapshot to create volume")
	flSize := cmd.Int([]string{"-size"}, 10, "Specify volume size")

	flDriverOpts := opts.NewMapOpts(nil, nil)
	cmd.Var(flDriverOpts, []string{"o", "-opt"}, "Set driver specific options")

	cmd.Require(flag.Exact, 0)
	cmd.ParseFlags(args, true)

	volReq := types.VolumeCreateRequest{
		Driver:     *flDriver,
		DriverOpts: flDriverOpts.GetAll(),
		Name:       *flName,
	}

	volReq.DriverOpts["size"] = fmt.Sprintf("%d", *flSize)
	if *flSnapshot != "" {
		volReq.DriverOpts["snapshot"] = *flSnapshot
		if *flSize == 10 {
			volReq.DriverOpts["size"] = ""
		}
	}

	vol, err := cli.client.VolumeCreate(volReq)
	if err != nil {
		return err
	}

	fmt.Fprintf(cli.out, "%s\n", vol.Name)
	return nil
}

// CmdVolumeRm removes one or more volumes.
//
// Usage: docker volume rm VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeRm(args ...string) error {
	cmd := Cli.Subcmd("volume rm", []string{"VOLUME [VOLUME...]"}, "Remove a volume", true)
	cmd.Require(flag.Min, 1)
	cmd.ParseFlags(args, true)

	var status = 0

	for _, name := range cmd.Args() {
		if err := cli.client.VolumeRemove(name); err != nil {
			fmt.Fprintf(cli.err, "%s\n", err)
			status = 1
			continue
		}
		fmt.Fprintf(cli.out, "%s\n", name)
	}

	if status != 0 {
		return Cli.StatusError{StatusCode: status}
	}
	return nil
}
<commit_msg>Update volume.go<commit_after>package client

import (
	"fmt"
	"text/tabwriter"

	Cli "github.com/docker/docker/cli"
	"github.com/docker/docker/opts"
	flag "github.com/docker/docker/pkg/mflag"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/filters"
)

// CmdVolume is the parent subcommand for all volume commands
//
// Usage: docker volume <COMMAND> <OPTS>
func (cli *DockerCli) CmdVolume(args ...string) error {
	description := Cli.DockerCommands["volume"].Description + "\n\nCommands:\n"
	commands := [][]string{
		{"create", "Create a volume"},
		{"inspect", "Return low-level information on a volume"},
		{"ls", "List volumes"},
		{"rm", "Remove a volume"},
	}

	for _, cmd := range commands {
		description += fmt.Sprintf("  %-25.25s%s\n", cmd[0], cmd[1])
	}

	description += "\nRun 'docker volume COMMAND --help' for more information on a command"
	cmd := Cli.Subcmd("volume", []string{"[COMMAND]"}, description, false)

	cmd.Require(flag.Exact, 0)
	err := cmd.ParseFlags(args, true)
	cmd.Usage()
	return err
}

// CmdVolumeLs outputs a list of Docker volumes.
//
// Usage: docker volume ls [OPTIONS]
func (cli *DockerCli) CmdVolumeLs(args ...string) error {
	cmd := Cli.Subcmd("volume ls", nil, "List volumes", true)

	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names")
	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")

	cmd.Require(flag.Exact, 0)
	cmd.ParseFlags(args, true)

	volFilterArgs := filters.NewArgs()
	for _, f := range flFilter.GetAll() {
		var err error
		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
		if err != nil {
			return err
		}
	}

	volumes, err := cli.client.VolumeList(volFilterArgs)
	if err != nil {
		return err
	}

	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
	if !*quiet {
		for _, warn := range volumes.Warnings {
			fmt.Fprintln(cli.err, warn)
		}
		fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
		fmt.Fprintf(w, "\n")
	}

	for _, vol := range volumes.Volumes {
		if *quiet {
			fmt.Fprintln(w, vol.Name)
			continue
		}
		fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
	}
	w.Flush()
	return nil
}

// CmdVolumeInspect displays low-level information on one or more volumes.
//
// Usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeInspect(args ...string) error {
	cmd := Cli.Subcmd("volume inspect", []string{"VOLUME [VOLUME...]"}, "Return low-level information on a volume", true)
	tmplStr := cmd.String([]string{"f", "-format"}, "", "Format the output using the given go template")

	cmd.Require(flag.Min, 1)
	cmd.ParseFlags(args, true)

	if err := cmd.Parse(args); err != nil {
		return nil
	}

	inspectSearcher := func(name string) (interface{}, []byte, error) {
		i, err := cli.client.VolumeInspect(name)
		return i, nil, err
	}

	return cli.inspectElements(*tmplStr, cmd.Args(), inspectSearcher)
}

// CmdVolumeCreate creates a new volume.
//
// Usage: docker volume create [OPTIONS]
func (cli *DockerCli) CmdVolumeCreate(args ...string) error {
	cmd := Cli.Subcmd("volume create", nil, "Create a volume", true)
	flDriver := cmd.String([]string{}, "hyper", "Specify volume driver name")
	flName := cmd.String([]string{"-name"}, "", "Specify volume name")
	flSnapshot := cmd.String([]string{"-snapshot"}, "", "Specify snapshot to create volume")
	flSize := cmd.Int([]string{"-size"}, 10, "Specify volume size")

	flDriverOpts := opts.NewMapOpts(nil, nil)
	cmd.Var(flDriverOpts, []string{"o", "-opt"}, "Set driver specific options")

	cmd.Require(flag.Exact, 0)
	cmd.ParseFlags(args, true)

	volReq := types.VolumeCreateRequest{
		Driver:     *flDriver,
		DriverOpts: flDriverOpts.GetAll(),
		Name:       *flName,
	}

	volReq.DriverOpts["size"] = fmt.Sprintf("%d", *flSize)
	if *flSnapshot != "" {
		volReq.DriverOpts["snapshot"] = *flSnapshot
		if *flSize == 10 {
			volReq.DriverOpts["size"] = ""
		}
	}

	vol, err := cli.client.VolumeCreate(volReq)
	if err != nil {
		return err
	}

	fmt.Fprintf(cli.out, "%s\n", vol.Name)
	return nil
}

// CmdVolumeRm removes one or more volumes.
//
// Usage: docker volume rm VOLUME [VOLUME...]
func (cli *DockerCli) CmdVolumeRm(args ...string) error {
	cmd := Cli.Subcmd("volume rm", []string{"VOLUME [VOLUME...]"}, "Remove a volume", true)
	cmd.Require(flag.Min, 1)
	cmd.ParseFlags(args, true)

	var status = 0

	for _, name := range cmd.Args() {
		if err := cli.client.VolumeRemove(name); err != nil {
			fmt.Fprintf(cli.err, "%s\n", err)
			status = 1
			continue
		}
		fmt.Fprintf(cli.out, "%s\n", name)
	}

	if status != 0 {
		return Cli.StatusError{StatusCode: status}
	}
	return nil
}
<|endoftext|>


<commit_before>// Package millipede provides a framework for creating millipedes.
// millipede is designed to be easy to understand and write, the most simple
// application can be written as follow:
//   func main() {
//     fmt.Println(millipede.New(20))
//   }
package millipede

import (
	"bytes"
	"fmt"
	"math"
	"strings"
	"unicode/utf8"

	"github.com/getmillipede/millipede-go/vendor/github.com/Sirupsen/logrus"
	"github.com/getmillipede/millipede-go/vendor/github.com/kortschak/zalgo"
	"github.com/getmillipede/millipede-go/vendor/github.com/mgutz/ansi"
)

// Millipede defines a millipede configuration
type Millipede struct {
	// Size is the amount of feet pairs
	Size uint64
	// Reverse is the flag that indicates the direction (up/down)
	Reverse bool
	// Skin is the current millipede skin (template)
	Skin string
	// Opposite is the flag that indicates the direction (left/right)
	Opposite bool
	// Width is the width of the millipede (depending on its age and the food it consumes)
	Width uint64
	// Curve is the size of the curve
	Curve uint64
	// Chameleon is the flag that indicates the millipede share its environment color
	Chameleon bool
	// Rainbow is the flag that indicates the millipede live with care bears
	Rainbow bool
	// Zalgo is the flag that invoke the hive-mind representing chaos
	Zalgo bool
	// Step is the amount of steps done by the millipede (useful for animations)
	Steps uint64

	// PadRight is the flag that indicates the need to add spacing on the right of the output
	PadRight bool
}

// Skin defines the different parts of a millipede body
type Skin struct {
	// Head is used by the millipede to think about its life
	Head string
	// Pede are what make this arthropod so special
	Pede string
	// Reverse is the reverse skin of the millipede
	Reverse *Skin
}

// String returns a string representing a millipede
func (m *Millipede) String() string {
	paddingOffsets := []string{""}
	if m.Curve > 0 {
		for n := uint64(1); n < m.Curve*2; n++ {
			size := int(math.Min(float64(n%(m.Curve*2)), float64(m.Curve*2-n%(m.Curve*2))))
			paddingOffsets = append(paddingOffsets, strings.Repeat(" ", size))
		}
		// --opposite support
		if m.Opposite {
			paddingOffsets = append(paddingOffsets[m.Curve:], paddingOffsets[:m.Curve]...)
		}
	}

	skins := map[string]Skin{
		"default": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(███)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(███)═╗",
			},
		},
		"frozen": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(❄❄❄)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(❄❄❄)═╗",
			},
		},
		"corporate": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(©©©)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(©©©)═╗",
			},
		},
		"love": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(♥♥♥)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(♥♥♥)═╗",
			},
		},
		"musician": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(♫♩♬)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(♫♩♬)═╗",
			},
		},
		"bocal": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(🐟🐟🐟)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(🐟🐟🐟)═╗",
			},
		},
		"ascii": {
			Head: "  \\o o/  ",
			Pede: "|=(###)=|",
			Reverse: &Skin{
				Head: "  /o o\\  ",
				Pede: "|=(###)=|",
			},
		},
		"inception": {
			Head: "    👀    ",
			Pede: "╚═(🐛🐛🐛)═╝",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "╔═(🐛🐛🐛)═╗",
			},
		},
		"humancentipede": {
			Head: "    👀    ",
			Pede: "╚═(😷😷😷)═╝",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "╔═(😷😷😷)═╗",
			},
		},
		"finger": {
			Head: "    👀    ",
			Pede: "👈~~~  ~~~👉",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "👈~~~~~~~~👉",
			},
		},
	}

	// --skin support
	skin := skins[m.Skin]
	if skin.Head == "" {
		logrus.Fatalf("no such skin: '%s'", m.Skin)
	}

	// --reverse support
	if m.Reverse && skin.Reverse != nil && skin.Reverse.Head != "" {
		skin = *skin.Reverse
	}

	// --width support
	if m.Width < 3 {
		logrus.Fatalf("millipede cannot have a witch < 3")
	}
	if m.Width > 3 {
		w := utf8.RuneCountInString(skin.Head)
		head := StringToRuneSlice(skin.Head)
		skin.Head = string(head[:w/2]) + strings.Repeat(string(head[w/2:w/2+1]), int(m.Width-2)) + string(head[w/2+1:])
		pede := StringToRuneSlice(skin.Pede)
		skin.Pede = string(pede[:w/2]) + strings.Repeat(string(pede[w/2:w/2+1]), int(m.Width-2)) + string(pede[w/2+1:])
	}

	// build the millipede body
	var body []string
	if m.Curve > 0 {
		body = []string{paddingOffsets[m.Steps%(m.Curve*2)] + strings.TrimRight(skin.Head, " ")}
	} else {
		body = []string{strings.TrimRight(skin.Head, " ")}
	}
	var x uint64
	for x = 0; x < m.Size; x++ {
		var line string
		if m.Curve > 0 {
			line = paddingOffsets[(m.Steps+x)%(m.Curve*2)] + skin.Pede
		} else {
			line = "" + skin.Pede
		}
		body = append(body, line)
	}

	// --reverse support
	if m.Reverse {
		for i, j := 0, len(body)-1; i < j; i, j = i+1, j-1 {
			body[i], body[j] = body[j], body[i]
		}
	}

	// --chameleon and --rainbow support
	for idx, line := range body {
		colors := []string{"red", "green", "yellow", "blue", "magenta", "cyan", "white"}

		fgColor := ""
		bgColor := ""

		// --chameleon support
		if m.Chameleon {
			fgColor = "black"
		}

		// --rainbow
		if m.Rainbow {
			bgColor = colors[idx%len(colors)]
			if m.Chameleon {
				fgColor = bgColor
				fgColor = "black"
			}
		}

		if fgColor != "" || bgColor != "" {
			paddingSize := len(line) - len(strings.TrimSpace(line))
			line = strings.Repeat(" ", paddingSize) + ansi.Color(line[paddingSize:], fgColor+":"+bgColor)
		}

		if m.PadRight {
			line = line + strings.Repeat(" ", int(m.Curve))
		}

		body[idx] = line
	}

	output := strings.Join(body, "\n")

	// --zalgo support
	if m.Zalgo {
		buf := new(bytes.Buffer)

		z := zalgo.NewCorrupter(buf)
		z.Zalgo = func(n int, r rune, z *zalgo.Corrupter) bool {
			if string(r) == " " || r == 10 {
				z.Up = 0
				z.Middle = 0
				z.Down = 0
			} else {
				if z.Up == 0 {
					z.Up = complex(0, 0.2)
					z.Middle = complex(0, 0.2)
					z.Down = complex(0.001, 0.3)
				}
				z.Up += 0.1
				z.Middle += complex(0.1, 0.2)
				z.Down += 0.1
			}
			return false
		}
		fmt.Fprintln(z, output)
		output = buf.String()
	}

	return output
}

// New returns a millipede
func New(size uint64) *Millipede {
	return &Millipede{
		Size:      size,
		Reverse:   false,
		Skin:      "default",
		Opposite:  false,
		Width:     3,
		Curve:     4,
		Chameleon: false,
		Rainbow:   false,
		Zalgo:     false,
		Steps:     0,
	}
}

// StringToRuneSlice converts a string to a slice of runes
func StringToRuneSlice(input string) []rune {
	output := make([]rune, utf8.RuneCountInString(input))
	n := 0
	for _, r := range input {
		output[n] = r
		n++
	}
	return output
}
<commit_msg>Added a new skin: handy<commit_after>// Package millipede provides a framework for creating millipedes.
// millipede is designed to be easy to understand and write, the most simple
// application can be written as follow:
//   func main() {
//     fmt.Println(millipede.New(20))
//   }
package millipede

import (
	"bytes"
	"fmt"
	"math"
	"strings"
	"unicode/utf8"

	"github.com/getmillipede/millipede-go/vendor/github.com/Sirupsen/logrus"
	"github.com/getmillipede/millipede-go/vendor/github.com/kortschak/zalgo"
	"github.com/getmillipede/millipede-go/vendor/github.com/mgutz/ansi"
)

// Millipede defines a millipede configuration
type Millipede struct {
	// Size is the amount of feet pairs
	Size uint64
	// Reverse is the flag that indicates the direction (up/down)
	Reverse bool
	// Skin is the current millipede skin (template)
	Skin string
	// Opposite is the flag that indicates the direction (left/right)
	Opposite bool
	// Width is the width of the millipede (depending on its age and the food it consumes)
	Width uint64
	// Curve is the size of the curve
	Curve uint64
	// Chameleon is the flag that indicates the millipede share its environment color
	Chameleon bool
	// Rainbow is the flag that indicates the millipede live with care bears
	Rainbow bool
	// Zalgo is the flag that invoke the hive-mind representing chaos
	Zalgo bool
	// Step is the amount of steps done by the millipede (useful for animations)
	Steps uint64

	// PadRight is the flag that indicates the need to add spacing on the right of the output
	PadRight bool
}

// Skin defines the different parts of a millipede body
type Skin struct {
	// Head is used by the millipede to think about its life
	Head string
	// Pede are what make this arthropod so special
	Pede string
	// Reverse is the reverse skin of the millipede
	Reverse *Skin
}

// String returns a string representing a millipede
func (m *Millipede) String() string {
	paddingOffsets := []string{""}
	if m.Curve > 0 {
		for n := uint64(1); n < m.Curve*2; n++ {
			size := int(math.Min(float64(n%(m.Curve*2)), float64(m.Curve*2-n%(m.Curve*2))))
			paddingOffsets = append(paddingOffsets, strings.Repeat(" ", size))
		}
		// --opposite support
		if m.Opposite {
			paddingOffsets = append(paddingOffsets[m.Curve:], paddingOffsets[:m.Curve]...)
		}
	}

	skins := map[string]Skin{
		"default": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(███)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(███)═╗",
			},
		},
		"frozen": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(❄❄❄)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(❄❄❄)═╗",
			},
		},
		"corporate": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(©©©)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(©©©)═╗",
			},
		},
		"love": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(♥♥♥)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(♥♥♥)═╗",
			},
		},
		"musician": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(♫♩♬)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(♫♩♬)═╗",
			},
		},
		"bocal": {
			Head: "  ╚⊙ ⊙╝  ",
			Pede: "╚═(🐟🐟🐟)═╝",
			Reverse: &Skin{
				Head: "  ╔⊙ ⊙╗  ",
				Pede: "╔═(🐟🐟🐟)═╗",
			},
		},
		"ascii": {
			Head: "  \\o o/  ",
			Pede: "|=(###)=|",
			Reverse: &Skin{
				Head: "  /o o\\  ",
				Pede: "|=(###)=|",
			},
		},
		"inception": {
			Head: "    👀    ",
			Pede: "╚═(🐛🐛🐛)═╝",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "╔═(🐛🐛🐛)═╗",
			},
		},
		"humancentipede": {
			Head: "    👀    ",
			Pede: "╚═(😷😷😷)═╝",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "╔═(😷😷😷)═╗",
			},
		},
		"finger": {
			Head: "    👀    ",
			Pede: "👈~~~  ~~~👉",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "👈~~~~~~~~👉",
			},
		},
		"handy": {
			Head: "    👀    ",
			Pede: "╚═(👌 👌 👌 )═╝",
			Reverse: &Skin{
				Head: "    👀    ",
				Pede: "╔═(👌 👌 👌 )═╗",
			},
		},
	}

	// --skin support
	skin := skins[m.Skin]
	if skin.Head == "" {
		logrus.Fatalf("no such skin: '%s'", m.Skin)
	}

	// --reverse support
	if m.Reverse && skin.Reverse != nil && skin.Reverse.Head != "" {
		skin = *skin.Reverse
	}

	// --width support
	if m.Width < 3 {
		logrus.Fatalf("millipede cannot have a witch < 3")
	}
	if m.Width > 3 {
		w := utf8.RuneCountInString(skin.Head)
		head := StringToRuneSlice(skin.Head)
		skin.Head = string(head[:w/2]) + strings.Repeat(string(head[w/2:w/2+1]), int(m.Width-2)) + string(head[w/2+1:])
		pede := StringToRuneSlice(skin.Pede)
		skin.Pede = string(pede[:w/2]) + strings.Repeat(string(pede[w/2:w/2+1]), int(m.Width-2)) + string(pede[w/2+1:])
	}

	// build the millipede body
	var body []string
	if m.Curve > 0 {
		body = []string{paddingOffsets[m.Steps%(m.Curve*2)] + strings.TrimRight(skin.Head, " ")}
	} else {
		body = []string{strings.TrimRight(skin.Head, " ")}
	}
	var x uint64
	for x = 0; x < m.Size; x++ {
		var line string
		if m.Curve > 0 {
			line = paddingOffsets[(m.Steps+x)%(m.Curve*2)] + skin.Pede
		} else {
			line = "" + skin.Pede
		}
		body = append(body, line)
	}

	// --reverse support
	if m.Reverse {
		for i, j := 0, len(body)-1; i < j; i, j = i+1, j-1 {
			body[i], body[j] = body[j], body[i]
		}
	}

	// --chameleon and --rainbow support
	for idx, line := range body {
		colors := []string{"red", "green", "yellow", "blue", "magenta", "cyan", "white"}

		fgColor := ""
		bgColor := ""

		// --chameleon support
		if m.Chameleon {
			fgColor = "black"
		}

		// --rainbow
		if m.Rainbow {
			bgColor = colors[idx%len(colors)]
			if m.Chameleon {
				fgColor = bgColor
				fgColor = "black"
			}
		}

		if fgColor != "" || bgColor != "" {
			paddingSize := len(line) - len(strings.TrimSpace(line))
			line = strings.Repeat(" ", paddingSize) + ansi.Color(line[paddingSize:], fgColor+":"+bgColor)
		}

		if m.PadRight {
			line = line + strings.Repeat(" ", int(m.Curve))
		}

		body[idx] = line
	}

	output := strings.Join(body, "\n")

	// --zalgo support
	if m.Zalgo {
		buf := new(bytes.Buffer)

		z := zalgo.NewCorrupter(buf)
		z.Zalgo = func(n int, r rune, z *zalgo.Corrupter) bool {
			if string(r) == " " || r == 10 {
				z.Up = 0
				z.Middle = 0
				z.Down = 0
			} else {
				if z.Up == 0 {
					z.Up = complex(0, 0.2)
					z.Middle = complex(0, 0.2)
					z.Down = complex(0.001, 0.3)
				}
				z.Up += 0.1
				z.Middle += complex(0.1, 0.2)
				z.Down += 0.1
			}
			return false
		}
		fmt.Fprintln(z, output)
		output = buf.String()
	}

	return output
}

// New returns a millipede
func New(size uint64) *Millipede {
	return &Millipede{
		Size:      size,
		Reverse:   false,
		Skin:      "default",
		Opposite:  false,
		Width:     3,
		Curve:     4,
		Chameleon: false,
		Rainbow:   false,
		Zalgo:     false,
		Steps:     0,
	}
}

// StringToRuneSlice converts a string to a slice of runes
func StringToRuneSlice(input string) []rune {
	output := make([]rune, utf8.RuneCountInString(input))
	n := 0
	for _, r := range input {
		output[n] = r
		n++
	}
	return output
}
<|endoftext|>