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

package git

import (
	"testing"

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

func TestTreeEntry(t *testing.T) {
	id := MustIDFromString("0eedd79eba4394bbef888c804e899731644367fe")
	e := &TreeEntry{
		mode: EntrySymlink,
		typ:  ObjectTree,
		id:   id,
		name: "go.mod",
	}

	assert.False(t, e.IsTree())
	assert.False(t, e.IsBlob())
	assert.False(t, e.IsExec())
	assert.True(t, e.IsSymlink())
	assert.False(t, e.IsCommit())

	assert.Equal(t, ObjectTree, e.Type())
	assert.Equal(t, e.id, e.ID())
	assert.Equal(t, "go.mod", e.Name())
}

func TestEntries_Sort(t *testing.T) {
	tree, err := testrepo.LsTree("0eedd79eba4394bbef888c804e899731644367fe")
	if err != nil {
		t.Fatal(err)
	}

	es, err := tree.Entries()
	if err != nil {
		t.Fatal(err)
	}

	es.Sort()

	expEntries := []*TreeEntry{
		{
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("fcf7087e732bfe3c25328248a9bf8c3ccd85bed4"),
			name: "gogs",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("a41a5a6cfd2d5ec3c0c1101e7cc05c9dedc3e11d"),
			name: "img",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("aaa0af6b82db99c660b169962524e2201ac7079c"),
			name: "resources",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("007cb92318c7bd3b56908ea8c2e54370245562f8"),
			name: "src",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("021a721a61a1de65865542c405796d1eb985f784"),
			name: ".DS_Store",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("412eeda78dc9de1186c2e0e1526764af82ab3431"),
			name: ".gitattributes",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("7c820833a9ad5fbfc96efd533d55f5edc65dc977"),
			name: ".gitignore",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("6abde17f49a6d43df40366e57d8964fee0dfda11"),
			name: ".gitmodules",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("17eccd68b7cafa718d53c8b4db666194646e2bd9"),
			name: ".travis.yml",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("adfd6da3c0a3fb038393144becbf37f14f780087"),
			name: "README.txt",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("6058be211566308428ca6dcab3f08cf270cd9568"),
			name: "build.gradle",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("99975710477a65b89233b2d12bf60f7c0ffc1f5c"),
			name: "pom.xml",
		}, {
			mode: EntryExec,
			typ:  ObjectBlob,
			id:   MustIDFromString("fb4bd4ec9220ed4fe0d9526d1b77147490ce8842"),
			name: "run.sh",
		},
	}
	for i := range expEntries {
		assert.Equal(t, expEntries[i].Mode(), es[i].Mode(), "idx: %d", i)
		assert.Equal(t, expEntries[i].Type(), es[i].Type(), "idx: %d", i)
		assert.Equal(t, expEntries[i].ID().String(), es[i].ID().String(), "idx: %d", i)
		assert.Equal(t, expEntries[i].Name(), es[i].Name(), "idx: %d", i)
	}
}

func TestEntries_CommitsInfo(t *testing.T) {
	tree, err := testrepo.LsTree("0eedd79eba4394bbef888c804e899731644367fe")
	if err != nil {
		t.Fatal(err)
	}

	c, err := testrepo.CatFileCommit(tree.id.String())
	if err != nil {
		t.Fatal(err)
	}

	t.Run("", func(t *testing.T) {
		es, err := tree.Entries()
		if err != nil {
			t.Fatal(err)
		}

		infos, err := es.CommitsInfo(c)
		if err != nil {
			t.Fatal(err)
		}

		expInfos := []*EntryCommitInfo{
			{
				Entry: &TreeEntry{
					name: ".DS_Store",
				},
				Commit: &Commit{
					ID: MustIDFromString("4eaa8d4b05e731e950e2eaf9e8b92f522303ab41"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitattributes",
				},
				Commit: &Commit{
					ID: MustIDFromString("bf7a9a5ee025edee0e610bd7ba23c0704b53c6db"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitignore",
				},
				Commit: &Commit{
					ID: MustIDFromString("d2280d000c84f1e595e4dec435ae6c1e6c245367"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitmodules",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".travis.yml",
				},
				Commit: &Commit{
					ID: MustIDFromString("9805760644754c38d10a9f1522a54a4bdc00fa8a"),
				},
			}, {
				Entry: &TreeEntry{
					name: "README.txt",
				},
				Commit: &Commit{
					ID: MustIDFromString("a13dba1e469944772490909daa58c53ac8fa4b0d"),
				},
			}, {
				Entry: &TreeEntry{
					name: "build.gradle",
				},
				Commit: &Commit{
					ID: MustIDFromString("c59479302142d79e46f84d11438a41b39ba51a1f"),
				},
			}, {
				Entry: &TreeEntry{
					name: "gogs",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			}, {
				Entry: &TreeEntry{
					name: "img",
				},
				Commit: &Commit{
					ID: MustIDFromString("4eaa8d4b05e731e950e2eaf9e8b92f522303ab41"),
				},
			}, {
				Entry: &TreeEntry{
					name: "pom.xml",
				},
				Commit: &Commit{
					ID: MustIDFromString("ef7bebf8bdb1919d947afe46ab4b2fb4278039b3"),
				},
			}, {
				Entry: &TreeEntry{
					name: "resources",
				},
				Commit: &Commit{
					ID: MustIDFromString("755fd577edcfd9209d0ac072eed3b022cbe4d39b"),
				},
			}, {
				Entry: &TreeEntry{
					name: "run.sh",
				},
				Commit: &Commit{
					ID: MustIDFromString("0eedd79eba4394bbef888c804e899731644367fe"),
				},
			}, {
				Entry: &TreeEntry{
					name: "src",
				},
				Commit: &Commit{
					ID: MustIDFromString("ebbbf773431ba07510251bb03f9525c7bab2b13a"),
				},
			},
		}
		for i := range expInfos {
			assert.Equal(t, expInfos[i].Entry.Name(), infos[i].Entry.Name(), "idx: %d", i)
			assert.Equal(t, expInfos[i].Commit.ID.String(), infos[i].Commit.ID.String(), "idx: %d", i)
		}
	})

	t.Run("", func(t *testing.T) {
		subtree, err := tree.Subtree("gogs")
		if err != nil {
			t.Fatal(err)
		}

		es, err := subtree.Entries()
		if err != nil {
			t.Fatal(err)
		}

		infos, err := es.CommitsInfo(c, CommitsInfoOptions{
			Path: "gogs",
		})
		if err != nil {
			t.Fatal(err)
		}

		expInfos := []*EntryCommitInfo{
			{
				Entry: &TreeEntry{
					name: "docs-api",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			},
		}
		for i := range expInfos {
			assert.Equal(t, expInfos[i].Entry.Name(), infos[i].Entry.Name(), "idx: %d", i)
			assert.Equal(t, expInfos[i].Commit.ID.String(), infos[i].Commit.ID.String(), "idx: %d", i)
		}
	})
}
<commit_msg>tree_entry: add tests for #59 (#60)<commit_after>// Copyright 2020 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package git

import (
	"testing"

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

func TestTreeEntry(t *testing.T) {
	id := MustIDFromString("0eedd79eba4394bbef888c804e899731644367fe")
	e := &TreeEntry{
		mode: EntrySymlink,
		typ:  ObjectTree,
		id:   id,
		name: "go.mod",
	}

	assert.False(t, e.IsTree())
	assert.False(t, e.IsBlob())
	assert.False(t, e.IsExec())
	assert.True(t, e.IsSymlink())
	assert.False(t, e.IsCommit())

	assert.Equal(t, ObjectTree, e.Type())
	assert.Equal(t, e.id, e.ID())
	assert.Equal(t, "go.mod", e.Name())
}

func TestEntries_Sort(t *testing.T) {
	tree, err := testrepo.LsTree("0eedd79eba4394bbef888c804e899731644367fe")
	if err != nil {
		t.Fatal(err)
	}

	es, err := tree.Entries()
	if err != nil {
		t.Fatal(err)
	}

	es.Sort()

	expEntries := []*TreeEntry{
		{
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("fcf7087e732bfe3c25328248a9bf8c3ccd85bed4"),
			name: "gogs",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("a41a5a6cfd2d5ec3c0c1101e7cc05c9dedc3e11d"),
			name: "img",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("aaa0af6b82db99c660b169962524e2201ac7079c"),
			name: "resources",
		}, {
			mode: EntryTree,
			typ:  ObjectTree,
			id:   MustIDFromString("007cb92318c7bd3b56908ea8c2e54370245562f8"),
			name: "src",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("021a721a61a1de65865542c405796d1eb985f784"),
			name: ".DS_Store",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("412eeda78dc9de1186c2e0e1526764af82ab3431"),
			name: ".gitattributes",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("7c820833a9ad5fbfc96efd533d55f5edc65dc977"),
			name: ".gitignore",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("6abde17f49a6d43df40366e57d8964fee0dfda11"),
			name: ".gitmodules",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("17eccd68b7cafa718d53c8b4db666194646e2bd9"),
			name: ".travis.yml",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("adfd6da3c0a3fb038393144becbf37f14f780087"),
			name: "README.txt",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("6058be211566308428ca6dcab3f08cf270cd9568"),
			name: "build.gradle",
		}, {
			mode: EntryBlob,
			typ:  ObjectBlob,
			id:   MustIDFromString("99975710477a65b89233b2d12bf60f7c0ffc1f5c"),
			name: "pom.xml",
		}, {
			mode: EntryExec,
			typ:  ObjectBlob,
			id:   MustIDFromString("fb4bd4ec9220ed4fe0d9526d1b77147490ce8842"),
			name: "run.sh",
		},
	}
	for i := range expEntries {
		assert.Equal(t, expEntries[i].Mode(), es[i].Mode(), "idx: %d", i)
		assert.Equal(t, expEntries[i].Type(), es[i].Type(), "idx: %d", i)
		assert.Equal(t, expEntries[i].ID().String(), es[i].ID().String(), "idx: %d", i)
		assert.Equal(t, expEntries[i].Name(), es[i].Name(), "idx: %d", i)
	}
}

func TestEntries_CommitsInfo(t *testing.T) {
	tree, err := testrepo.LsTree("cfc3b2993f74726356887a5ec093de50486dc617")
	if err != nil {
		t.Fatal(err)
	}

	c, err := testrepo.CatFileCommit(tree.id.String())
	if err != nil {
		t.Fatal(err)
	}

	t.Run("general directory", func(t *testing.T) {
		es, err := tree.Entries()
		if err != nil {
			t.Fatal(err)
		}

		infos, err := es.CommitsInfo(c)
		if err != nil {
			t.Fatal(err)
		}

		expInfos := []*EntryCommitInfo{
			{
				Entry: &TreeEntry{
					name: ".DS_Store",
				},
				Commit: &Commit{
					ID: MustIDFromString("4eaa8d4b05e731e950e2eaf9e8b92f522303ab41"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitattributes",
				},
				Commit: &Commit{
					ID: MustIDFromString("bf7a9a5ee025edee0e610bd7ba23c0704b53c6db"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitignore",
				},
				Commit: &Commit{
					ID: MustIDFromString("d2280d000c84f1e595e4dec435ae6c1e6c245367"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".gitmodules",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			}, {
				Entry: &TreeEntry{
					name: ".travis.yml",
				},
				Commit: &Commit{
					ID: MustIDFromString("9805760644754c38d10a9f1522a54a4bdc00fa8a"),
				},
			}, {
				Entry: &TreeEntry{
					name: "README.txt",
				},
				Commit: &Commit{
					ID: MustIDFromString("a13dba1e469944772490909daa58c53ac8fa4b0d"),
				},
			}, {
				Entry: &TreeEntry{
					name: "build.gradle",
				},
				Commit: &Commit{
					ID: MustIDFromString("c59479302142d79e46f84d11438a41b39ba51a1f"),
				},
			}, {
				Entry: &TreeEntry{
					name: "gogs",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			}, {
				Entry: &TreeEntry{
					name: "img",
				},
				Commit: &Commit{
					ID: MustIDFromString("4eaa8d4b05e731e950e2eaf9e8b92f522303ab41"),
				},
			}, {
				Entry: &TreeEntry{
					name: "pom.xml",
				},
				Commit: &Commit{
					ID: MustIDFromString("ef7bebf8bdb1919d947afe46ab4b2fb4278039b3"),
				},
			}, {
				Entry: &TreeEntry{
					name: "resources",
				},
				Commit: &Commit{
					ID: MustIDFromString("755fd577edcfd9209d0ac072eed3b022cbe4d39b"),
				},
			}, {
				Entry: &TreeEntry{
					name: "run.sh",
				},
				Commit: &Commit{
					ID: MustIDFromString("0eedd79eba4394bbef888c804e899731644367fe"),
				},
			}, {
				Entry: &TreeEntry{
					name: "sameSHAs",
				},
				Commit: &Commit{
					ID: MustIDFromString("cfc3b2993f74726356887a5ec093de50486dc617"),
				},
			}, {
				Entry: &TreeEntry{
					name: "src",
				},
				Commit: &Commit{
					ID: MustIDFromString("ebbbf773431ba07510251bb03f9525c7bab2b13a"),
				},
			},
		}
		for i := range expInfos {
			assert.Equal(t, expInfos[i].Entry.Name(), infos[i].Entry.Name(), "idx: %d", i)
			assert.Equal(t, expInfos[i].Commit.ID.String(), infos[i].Commit.ID.String(), "idx: %d", i)
		}
	})

	t.Run("directory with submodule", func(t *testing.T) {
		subtree, err := tree.Subtree("gogs")
		if err != nil {
			t.Fatal(err)
		}

		es, err := subtree.Entries()
		if err != nil {
			t.Fatal(err)
		}

		infos, err := es.CommitsInfo(c, CommitsInfoOptions{
			Path: "gogs",
		})
		if err != nil {
			t.Fatal(err)
		}

		expInfos := []*EntryCommitInfo{
			{
				Entry: &TreeEntry{
					name: "docs-api",
				},
				Commit: &Commit{
					ID: MustIDFromString("4e59b72440188e7c2578299fc28ea425fbe9aece"),
				},
			},
		}
		for i := range expInfos {
			assert.Equal(t, expInfos[i].Entry.Name(), infos[i].Entry.Name(), "idx: %d", i)
			assert.Equal(t, expInfos[i].Commit.ID.String(), infos[i].Commit.ID.String(), "idx: %d", i)
		}
	})

	t.Run("direcotry with files have same SHA", func(t *testing.T) {
		subtree, err := tree.Subtree("sameSHAs")
		if err != nil {
			t.Fatal(err)
		}

		es, err := subtree.Entries()
		if err != nil {
			t.Fatal(err)
		}

		infos, err := es.CommitsInfo(c, CommitsInfoOptions{
			Path: "sameSHAs",
		})
		if err != nil {
			t.Fatal(err)
		}

		expInfos := []*EntryCommitInfo{
			{
				Entry: &TreeEntry{
					name: "file1.txt",
				},
				Commit: &Commit{
					ID: MustIDFromString("cfc3b2993f74726356887a5ec093de50486dc617"),
				},
			}, {
				Entry: &TreeEntry{
					name: "file2.txt",
				},
				Commit: &Commit{
					ID: MustIDFromString("cfc3b2993f74726356887a5ec093de50486dc617"),
				},
			},
		}
		for i := range expInfos {
			assert.Equal(t, expInfos[i].Entry.Name(), infos[i].Entry.Name(), "idx: %d", i)
			assert.Equal(t, expInfos[i].Commit.ID.String(), infos[i].Commit.ID.String(), "idx: %d", i)
		}
	})
}
<|endoftext|>


<commit_before>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"
	"code.cloudfoundry.org/cli/integration/helpers/servicebrokerstub"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("update-service-broker command", func() {
	When("logged in", func() {
		var (
			org        string
			cfUsername string
		)

		BeforeEach(func() {
			org = helpers.SetupCFWithGeneratedOrgAndSpaceNames()
			cfUsername, _ = helpers.GetCredentials()
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(org)
		})

		It("updates the service broker", func() {
			broker1 := servicebrokerstub.Register()
			broker2 := servicebrokerstub.Create()
			defer broker1.Forget()
			defer broker2.Forget()

			session := helpers.CF("update-service-broker", broker1.Name, broker2.Username, broker2.Password, broker2.URL)

			Eventually(session.Wait().Out).Should(SatisfyAll(
				Say("Updating service broker %s as %s...", broker1.Name, cfUsername),
				Say("OK"),
			))
			Eventually(session).Should(Exit(0))
			session = helpers.CF("service-brokers")
			Eventually(session.Out).Should(Say("%s[[:space:]]+%s", broker1.Name, broker2.URL))
		})

		When("the service broker was updated but warnings happened", func() {
			var (
				serviceInstance string
				broker          *servicebrokerstub.ServiceBrokerStub
			)

			BeforeEach(func() {
				broker = servicebrokerstub.EnableServiceAccess()

				serviceInstance = helpers.NewServiceInstanceName()
				session := helpers.CF("create-service", broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstance, "-b", broker.Name)
				Eventually(session).Should(Exit(0))

				broker.Services[0].Plans[0].Name = "different-plan-name"
				broker.Services[0].Plans[0].ID = "different-plan-id"
				broker.Configure()
			})

			AfterEach(func() {
				helpers.CF("delete-service", "-f", serviceInstance)
				broker.Forget()
			})

			It("should yield a warning", func() {
				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, broker.URL)

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("OK"),
				))
				Eventually(session.Err).Should(Say("Warning: Service plans are missing from the broker's catalog"))
			})
		})

		When("the service broker doesn't exist", func() {
			It("prints an error message", func() {
				session := helpers.CF("update-service-broker", "does-not-exist", "test-user", "test-password", "http://test.com")

				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(SatisfyAll(
					Say("Service broker 'does-not-exist' not found"),
				))
				Eventually(session).Should(Exit(1))
			})
		})

		When("the update fails before starting a synchronization job", func() {
			It("prints an error message", func() {
				broker := servicebrokerstub.Register()

				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, "not-a-valid-url")

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("FAILED"),
				))

				Eventually(session.Err).Should(
					Say("must be a valid url"),
				)

				Eventually(session).Should(Exit(1))
			})
		})

		When("the update fails after starting a synchronization job", func() {
			var broker *servicebrokerstub.ServiceBrokerStub

			BeforeEach(func() {
				broker = servicebrokerstub.Register()
				broker.WithCatalogResponse(500).Configure()
			})

			AfterEach(func() {
				broker.Forget()
			})

			It("prints an error message and the job guid", func() {
				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, broker.URL)

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("FAILED"),
				))

				Eventually(session.Err).Should(SatisfyAll(
					Say("Job (.*) failed"),
					Say("The service broker returned an invalid response for the request "),
					Say("Status Code: 500 Internal Server Error"),
				))

				Eventually(session).Should(Exit(1))
			})
		})
	})

	When("passing incorrect parameters", func() {
		It("prints an error message", func() {
			session := helpers.CF("update-service-broker", "b1")

			Eventually(session.Err).Should(Say("Incorrect Usage: the required arguments `USERNAME`, `PASSWORD` and `URL` were not provided"))
			eventuallyRendersUpdateServiceBrokerHelp(session)
			Eventually(session).Should(Exit(1))
		})
	})

	When("the environment is not targeted correctly", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(false, false, ReadOnlyOrg, "update-service-broker", "broker-name", "username", "password", "https://test.com")
		})
	})

	When("passing --help", func() {
		It("displays command usage to output", func() {
			session := helpers.CF("update-service-broker", "--help")

			eventuallyRendersUpdateServiceBrokerHelp(session)
			Eventually(session).Should(Exit(0))
		})
	})
})

func eventuallyRendersUpdateServiceBrokerHelp(s *Session) {
	Eventually(s).Should(Say("NAME:"))
	Eventually(s).Should(Say("update-service-broker - Update a service broker"))
	Eventually(s).Should(Say("USAGE:"))
	Eventually(s).Should(Say("cf update-service-broker SERVICE_BROKER USERNAME PASSWORD URL"))
	Eventually(s).Should(Say("SEE ALSO:"))
	Eventually(s).Should(Say("rename-service-broker, service-brokers"))
}
<commit_msg>Change expected error message from broker<commit_after>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"
	"code.cloudfoundry.org/cli/integration/helpers/servicebrokerstub"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("update-service-broker command", func() {
	When("logged in", func() {
		var (
			org        string
			cfUsername string
		)

		BeforeEach(func() {
			org = helpers.SetupCFWithGeneratedOrgAndSpaceNames()
			cfUsername, _ = helpers.GetCredentials()
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(org)
		})

		It("updates the service broker", func() {
			broker1 := servicebrokerstub.Register()
			broker2 := servicebrokerstub.Create()
			defer broker1.Forget()
			defer broker2.Forget()

			session := helpers.CF("update-service-broker", broker1.Name, broker2.Username, broker2.Password, broker2.URL)

			Eventually(session.Wait().Out).Should(SatisfyAll(
				Say("Updating service broker %s as %s...", broker1.Name, cfUsername),
				Say("OK"),
			))
			Eventually(session).Should(Exit(0))
			session = helpers.CF("service-brokers")
			Eventually(session.Out).Should(Say("%s[[:space:]]+%s", broker1.Name, broker2.URL))
		})

		When("the service broker was updated but warnings happened", func() {
			var (
				serviceInstance string
				broker          *servicebrokerstub.ServiceBrokerStub
			)

			BeforeEach(func() {
				broker = servicebrokerstub.EnableServiceAccess()

				serviceInstance = helpers.NewServiceInstanceName()
				session := helpers.CF("create-service", broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstance, "-b", broker.Name)
				Eventually(session).Should(Exit(0))

				broker.Services[0].Plans[0].Name = "different-plan-name"
				broker.Services[0].Plans[0].ID = "different-plan-id"
				broker.Configure()
			})

			AfterEach(func() {
				helpers.CF("delete-service", "-f", serviceInstance)
				broker.Forget()
			})

			It("should yield a warning", func() {
				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, broker.URL)

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("OK"),
				))
				Eventually(session.Err).Should(Say("Warning: Service plans are missing from the broker's catalog"))
			})
		})

		When("the service broker doesn't exist", func() {
			It("prints an error message", func() {
				session := helpers.CF("update-service-broker", "does-not-exist", "test-user", "test-password", "http://test.com")

				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(SatisfyAll(
					Say("Service broker 'does-not-exist' not found"),
				))
				Eventually(session).Should(Exit(1))
			})
		})

		When("the update fails before starting a synchronization job", func() {
			It("prints an error message", func() {
				broker := servicebrokerstub.Register()

				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, "not-a-valid-url")

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("FAILED"),
				))

				Eventually(session.Err).Should(
					Say("must be a valid url"),
				)

				Eventually(session).Should(Exit(1))
			})
		})

		When("the update fails after starting a synchronization job", func() {
			var broker *servicebrokerstub.ServiceBrokerStub

			BeforeEach(func() {
				broker = servicebrokerstub.Register()
				broker.WithCatalogResponse(500).Configure()
			})

			AfterEach(func() {
				broker.Forget()
			})

			It("prints an error message and the job guid", func() {
				session := helpers.CF("update-service-broker", broker.Name, broker.Username, broker.Password, broker.URL)

				Eventually(session.Wait().Out).Should(SatisfyAll(
					Say("Updating service broker %s as %s...", broker.Name, cfUsername),
					Say("FAILED"),
				))

				Eventually(session.Err).Should(SatisfyAll(
					Say("Job (.*) failed"),
					Say("The service broker returned an invalid response"),
					Say("Status Code: 500 Internal Server Error"),
				))

				Eventually(session).Should(Exit(1))
			})
		})
	})

	When("passing incorrect parameters", func() {
		It("prints an error message", func() {
			session := helpers.CF("update-service-broker", "b1")

			Eventually(session.Err).Should(Say("Incorrect Usage: the required arguments `USERNAME`, `PASSWORD` and `URL` were not provided"))
			eventuallyRendersUpdateServiceBrokerHelp(session)
			Eventually(session).Should(Exit(1))
		})
	})

	When("the environment is not targeted correctly", func() {
		It("fails with the appropriate errors", func() {
			helpers.CheckEnvironmentTargetedCorrectly(false, false, ReadOnlyOrg, "update-service-broker", "broker-name", "username", "password", "https://test.com")
		})
	})

	When("passing --help", func() {
		It("displays command usage to output", func() {
			session := helpers.CF("update-service-broker", "--help")

			eventuallyRendersUpdateServiceBrokerHelp(session)
			Eventually(session).Should(Exit(0))
		})
	})
})

func eventuallyRendersUpdateServiceBrokerHelp(s *Session) {
	Eventually(s).Should(Say("NAME:"))
	Eventually(s).Should(Say("update-service-broker - Update a service broker"))
	Eventually(s).Should(Say("USAGE:"))
	Eventually(s).Should(Say("cf update-service-broker SERVICE_BROKER USERNAME PASSWORD URL"))
	Eventually(s).Should(Say("SEE ALSO:"))
	Eventually(s).Should(Say("rename-service-broker, service-brokers"))
}
<|endoftext|>


<commit_before>// twitter service for 9p
package main

import (
	"flag"
	"github.com/Leimy/rx-go/twit"
	"github.com/mortdeus/go9p"
	"github.com/mortdeus/go9p/srv"
	"log"
	"os"
	"strings"
)

// Describes the file system we serve up to host
// Twitter capabilities for the metabot
type Twitfs struct {
	srv   *srv.Fsrv
	user  go9p.User
	group go9p.Group
}

// Describes an individual file we serve in the
// file system.
type TweetFile struct {
	srv.File
	data []byte
	tweeter twit.Tweeter
}

// A data structure to track the state of the
// "creator" file which exists to set up other files.
type TweetFileFactory struct {
	srv.File
	data []byte
}

// The common functions that are involved with creating
// a regular tweeting endpoint.
func NewTweetFile(name string, user go9p.User, group go9p.Group, mode uint32, template string) (error, *TweetFile) {
	twitterentry := new(TweetFile)
	twitterentry.tweeter = twit.MakeTweeter(template)
	err := twitterentry.Add(root, name, user, group, mode, twitterentry)
	if err != nil {
		return err, nil
	}
	return nil, twitterentry
}

// Just a constant for metadata
const METADATA_SFX string = "on @radioxenu http://tunein.com/radio/Radio-Xenu-s118981/"

// Command line argument parsing and defaults
var addr = flag.String("a", "./crustysock", "unix domain socket path")
var debug = flag.Int("d", 0, "debuglevel")
var logsz = flag.Int("l", 2048, "log size")
var tsrv Twitfs
var root *srv.File

// Runs one time when the module loads... initializes stuff (hence the name)
func init () {
	flag.Parse()
	tsrv.user = go9p.OsUsers.Uid2User(os.Geteuid())
	tsrv.group = go9p.OsUsers.Gid2Group(os.Getegid())
	root = new(srv.File)
	if err := root.Add(nil, "/", tsrv.user, nil, go9p.DMDIR|0555, nil); err != nil {
		log.Panic(err)
	}
}

// When a client writes to a tweet file, we capture the bytes, and handle them
// in Clunk
func (t *TweetFile) Write(fid *srv.FFid, buf []byte, offset uint64) (int, error) {
	t.data = append(t.data, buf...)
	return len(buf), nil
}

// When the client decides it's done with this TweetFile, we run this action
// It run the set up tweeter function on the stringified form of the bytes
// it has collected.
func (t *TweetFile) Clunk(fid *srv.FFid) error {
	go func () {
		if err := t.tweeter(string(t.data)); err != nil {
			log.Printf("Error tweeting: %s\n", err)
		}
	}()
	log.Printf("Clunk: %p\n", fid)
	return nil
}

// This simply says "we'll allow you to delete this file"
func (t *TweetFile) Remove(fid *srv.FFid) error {
	return nil
}

// When someone writes to the creator file, we capture the bytes
// we'll deal with them in Clunk
func (tff *TweetFileFactory) Write(fid *srv.FFid, buf []byte, offset uint64) (int, error) {
	tff.data = append(tff.data, buf...)
	return len(buf), nil
}

// When the creator is Clunk'd by the client, we try to process the formatted string
// newfilename|suffix string for tweet
// And if successful, you get a new TweetFile you can write to that appends "suffix string for tweet"
// to the message before sending to twitter.
func (tff *TweetFileFactory) Clunk(fid *srv.FFid) error {
	s := string(tff.data)
	all := strings.SplitN(s, "|", 2)

	if len(all) != 2 {
		log.Printf("Illegal request, ignoring: %s\n", s)
	} else {
		if err, _ := NewTweetFile(all[0], tsrv.user, tsrv.group, 0600, all[1]); err != nil {
			log.Printf("Failed to allocate: %s for %s\n", all[0], all[1])
		}
	}
	return nil
}

func start_service () {
	l := go9p.NewLogger(*logsz)

	tsrv.srv = srv.NewFileSrv(root)
	tsrv.srv.Dotu = true // 9p2000.u
	tsrv.srv.Debuglevel = *debug

	tsrv.srv.Start(tsrv.srv)
	tsrv.srv.Id = "tweetfs"
	tsrv.srv.Log = l

	err := tsrv.srv.StartNetListener("unix", *addr)
	if err != nil {
		log.Panic(err)
	}
}

func main() {

	tff := new(TweetFileFactory)
	if err := tff.Add(root, "creator", tsrv.user, tsrv.group, 0600, tff); err != nil {
		log.Panicf("Failed to create the creator: %v\n", err)
	}

	if err, _ := NewTweetFile(root, "metadata", tsrv.user, tsrv.group, 0600, METADATA_SFX); err != nil {
		log.Panicf("Failed to allocate metadata endpoint: %v\n", err)
	}

	start_service()

	return
}
<commit_msg>Clear out buffer on clunk<commit_after>// twitter service for 9p
package main

import (
	"flag"
	"github.com/Leimy/rx-go/twit"
	"github.com/mortdeus/go9p"
	"github.com/mortdeus/go9p/srv"
	"log"
	"os"
	"strings"
	"fmt"
	"errors"
)

// Describes the file system we serve up to host
// Twitter capabilities for the metabot
type Twitfs struct {
	srv   *srv.Fsrv
	user  go9p.User
	group go9p.Group
}

// Describes an individual file we serve in the
// file system.
type TweetFile struct {
	srv.File
	data []byte
	tweeter twit.Tweeter
}

// A data structure to track the state of the
// "creator" file which exists to set up other files.
type TweetFileFactory struct {
	srv.File
	data []byte
}

// The common functions that are involved with creating
// a regular tweeting endpoint.
func NewTweetFile(name string, user go9p.User, group go9p.Group, mode uint32, template string) (error, *TweetFile) {
	twitterentry := new(TweetFile)
	twitterentry.tweeter = twit.MakeTweeter(template)
	err := twitterentry.Add(root, name, user, group, mode, twitterentry)
	if err != nil {
		return err, nil
	}
	return nil, twitterentry
}

// Just a constant for metadata
const METADATA_SFX string = "on @radioxenu http://tunein.com/radio/Radio-Xenu-s118981/"

// Command line argument parsing and defaults
var addr = flag.String("a", "./crustysock", "unix domain socket path")
var debug = flag.Int("d", 0, "debuglevel")
var logsz = flag.Int("l", 2048, "log size")
var tsrv Twitfs
var root *srv.File

// Runs one time when the module loads... initializes stuff (hence the name)
func init () {
	flag.Parse()
	tsrv.user = go9p.OsUsers.Uid2User(os.Geteuid())
	tsrv.group = go9p.OsUsers.Gid2Group(os.Getegid())
	root = new(srv.File)
	if err := root.Add(nil, "/", tsrv.user, nil, go9p.DMDIR|0555, nil); err != nil {
		log.Panic(err)
	}
}

// When a client writes to a tweet file, we capture the bytes, and handle them
// in Clunk
func (t *TweetFile) Write(fid *srv.FFid, buf []byte, offset uint64) (int, error) {
	t.data = append(t.data, buf...)
	return len(buf), nil
}

// When the client decides it's done with this TweetFile, we run this action
// It run the set up tweeter function on the stringified form of the bytes
// it has collected.
func (t *TweetFile) Clunk(fid *srv.FFid) error {
	go func () {
		if err := t.tweeter(string(t.data)); err != nil {
			log.Printf("Error tweeting: %s\n", err)
		}
	}()
	log.Printf("Clunk: %p\n", fid)
	t.data = []byte{}
	return nil
}

// This simply says "we'll allow you to delete this file"
func (t *TweetFile) Remove(fid *srv.FFid) error {
	return nil
}

// When someone writes to the creator file, we capture the bytes
// we'll deal with them in Clunk
func (tff *TweetFileFactory) Write(fid *srv.FFid, buf []byte, offset uint64) (int, error) {
	tff.data = append(tff.data, buf...)
	return len(buf), nil
}

// When the creator is Clunk'd by the client, we try to process the formatted string
// newfilename|suffix string for tweet
// And if successful, you get a new TweetFile you can write to that appends "suffix string for tweet"
// to the message before sending to twitter.
func (tff *TweetFileFactory) Clunk(fid *srv.FFid) (err error) {
	s := string(tff.data)
	all := strings.SplitN(s, "|", 2)

	if len(all) != 2 {
		s := fmt.Sprintf("Illegal reqeust, ignoring: %s", s)
		log.Printf("%s\n", s)
		err = errors.New(s)
	} else {
		if err, _ := NewTweetFile(all[0], tsrv.user, tsrv.group, 0600, all[1]); err != nil {
			log.Printf("Failed to allocate: %s for %s\n", all[0], all[1])
		}
	}
	tff.data = []byte{}
	return err
}

func start_service () {
	l := go9p.NewLogger(*logsz)

	tsrv.srv = srv.NewFileSrv(root)
	tsrv.srv.Dotu = true // 9p2000.u
	tsrv.srv.Debuglevel = *debug

	tsrv.srv.Start(tsrv.srv)
	tsrv.srv.Id = "tweetfs"
	tsrv.srv.Log = l

	err := tsrv.srv.StartNetListener("unix", *addr)
	if err != nil {
		log.Panic(err)
	}
}

func main() {

	tff := new(TweetFileFactory)
	if err := tff.Add(root, "creator", tsrv.user, tsrv.group, 0600, tff); err != nil {
		log.Panicf("Failed to create the creator: %v\n", err)
	}

	if err, _ := NewTweetFile("metadata", tsrv.user, tsrv.group, 0600, METADATA_SFX); err != nil {
		log.Panicf("Failed to allocate metadata endpoint: %v\n", err)
	}

	start_service()

	return
}
<|endoftext|>


<commit_before>package main

import (
	"a-star/utils"
	"fmt"
	"math"
	"os"
)

var origin, dest utils.Point
var openList, closeList, path []utils.Point

// Set the origin point
func setOrig(s *Scene) {
	origin = utils.Point{utils.GetRandInt(s.rows-2) + 1, utils.GetRandInt(s.cols-2) + 1, 0, 0, 0, nil}
	if s.scene[origin.X][origin.Y] == ' ' {
		s.scene[origin.X][origin.Y] = 'A'
	} else {
		setOrig(s)
	}
}

// Set the destination point
func setDest(s *Scene) {
	dest = utils.Point{utils.GetRandInt(s.rows-2) + 1, utils.GetRandInt(s.cols-2) + 1, 0, 0, 0, nil}

	if s.scene[dest.X][dest.Y] == ' ' {
		s.scene[dest.X][dest.Y] = 'B'
	} else {
		setDest(s)
	}
}

// Init origin, destination. Put the origin point into the openlist by the way
func initAstar(s *Scene) {
	setOrig(s)
	setDest(s)
	openList = append(openList, origin)
}

func findPath(s *Scene) {
	current := getFMin()
	addToCloseList(current, s)
	walkable := getWalkable(current, s)
	for _, p := range walkable {
		addToOpenList(p)
	}
}

func getFMin() utils.Point {
	if len(openList) == 0 {
		fmt.Println("No way!!!")
		os.Exit(-1)
	}
	index := 0
	for i, p := range openList {
		if (i > 0) && (p.F <= openList[index].F) {
			index = i
		}
	}
	return openList[index]
}

func getWalkable(p utils.Point, s *Scene) []utils.Point {
	var around []utils.Point
	row, col := p.X, p.Y
	left := s.scene[row][col-1]
	up := s.scene[row-1][col]
	right := s.scene[row][col+1]
	down := s.scene[row+1][col]
	leftup := s.scene[row-1][col-1]
	rightup := s.scene[row-1][col+1]
	leftdown := s.scene[row+1][col-1]
	rightdown := s.scene[row+1][col+1]
	if (left == ' ') || (left == 'B') {
		around = append(around, utils.Point{row, col - 1, 0, 0, 0, &p})
	}
	if (leftup == ' ') || (leftup == 'B') {
		around = append(around, utils.Point{row - 1, col - 1, 0, 0, 0, &p})
	}
	if (up == ' ') || (up == 'B') {
		around = append(around, utils.Point{row - 1, col, 0, 0, 0, &p})
	}
	if (rightup == ' ') || (rightup == 'B') {
		around = append(around, utils.Point{row - 1, col + 1, 0, 0, 0, &p})
	}
	if (right == ' ') || (right == 'B') {
		around = append(around, utils.Point{row, col + 1, 0, 0, 0, &p})
	}
	if (rightdown == ' ') || (rightdown == 'B') {
		around = append(around, utils.Point{row + 1, col + 1, 0, 0, 0, &p})
	}
	if (down == ' ') || (down == 'B') {
		around = append(around, utils.Point{row + 1, col, 0, 0, 0, &p})
	}
	if (leftdown == ' ') || (leftdown == 'B') {
		around = append(around, utils.Point{row + 1, col - 1, 0, 0, 0, &p})
	}
	return around
}

func addToOpenList(p utils.Point) {
	updateWeight(&p)
	if checkExist(p, closeList) {
		return
	}
	if !checkExist(p, openList) {
		openList = append(openList, p)
	} else {
		if openList[findPoint(p, openList)].F > p.F { //New path found
			openList[findPoint(p, openList)].Parent = p.Parent
		}
	}
}

// Update G, H, F of the point
func updateWeight(p *utils.Point) {
	if checkRelativePos(*p) == 1 {
		p.G = p.Parent.G + 10
	} else {
		p.G = p.Parent.G + 14
	}
	absx := (int)(math.Abs((float64)(dest.X - p.X)))
	absy := (int)(math.Abs((float64)(dest.Y - p.Y)))
	p.H = (absx + absy) * 10
	p.F = p.G + p.H
}

func removeFromOpenList(p utils.Point) {
	index := findPoint(p, openList)
	if index == -1 {
		os.Exit(0)
	}
	openList = append(openList[:index], openList[index+1:]...)
}

func addToCloseList(p utils.Point, s *Scene) {
	removeFromOpenList(p)
	if (p.X == dest.X) && (p.Y == dest.Y) {
		generatePath(p, s)
		s.draw()
		os.Exit(1)
	}
	// if (p.Parent != nil) && (checkRelativePos(p) == 2) {
	// 	parent := p.Parent
	// 	//rdblck := s.scene[p.X][parent.Y] | s.scene[parent.X][p.Y]
	// 	//fmt.Printf("%c\n", rdblck)
	// 	if (s.scene[p.X][parent.Y] == '#') || (s.scene[parent.X][p.Y] == '#') {
	// 		return
	// 	}
	// }
	if s.scene[p.X][p.Y] != 'A' {
		s.scene[p.X][p.Y] = '·'
	}
	closeList = append(closeList, p)
}

func checkExist(p utils.Point, arr []utils.Point) bool {
	for _, point := range arr {
		if p.X == point.X && p.Y == point.Y {
			return true
		}
	}
	return false
}

func findPoint(p utils.Point, arr []utils.Point) int {
	for index, point := range arr {
		if p.X == point.X && p.Y == point.Y {
			return index
		}
	}

	return -1
}

func checkRelativePos(p utils.Point) int {
	parent := p.Parent
	hor := (int)(math.Abs((float64)(p.X - parent.X)))
	ver := (int)(math.Abs((float64)(p.Y - parent.Y)))
	return hor + ver
}

func generatePath(p utils.Point, s *Scene) {
	if (s.scene[p.X][p.Y] != 'A') && (s.scene[p.X][p.Y] != 'B') {
		s.scene[p.X][p.Y] = '*'
	}
	if p.Parent != nil {
		generatePath(*(p.Parent), s)
	}
}
<commit_msg>import path fix<commit_after>package main

import (
	"fmt"
	"github.com/dyzdyz010/Golang-AStar/utils"
	"math"
	"os"
)

var origin, dest utils.Point
var openList, closeList, path []utils.Point

// Set the origin point
func setOrig(s *Scene) {
	origin = utils.Point{utils.GetRandInt(s.rows-2) + 1, utils.GetRandInt(s.cols-2) + 1, 0, 0, 0, nil}
	if s.scene[origin.X][origin.Y] == ' ' {
		s.scene[origin.X][origin.Y] = 'A'
	} else {
		setOrig(s)
	}
}

// Set the destination point
func setDest(s *Scene) {
	dest = utils.Point{utils.GetRandInt(s.rows-2) + 1, utils.GetRandInt(s.cols-2) + 1, 0, 0, 0, nil}

	if s.scene[dest.X][dest.Y] == ' ' {
		s.scene[dest.X][dest.Y] = 'B'
	} else {
		setDest(s)
	}
}

// Init origin, destination. Put the origin point into the openlist by the way
func initAstar(s *Scene) {
	setOrig(s)
	setDest(s)
	openList = append(openList, origin)
}

func findPath(s *Scene) {
	current := getFMin()
	addToCloseList(current, s)
	walkable := getWalkable(current, s)
	for _, p := range walkable {
		addToOpenList(p)
	}
}

func getFMin() utils.Point {
	if len(openList) == 0 {
		fmt.Println("No way!!!")
		os.Exit(-1)
	}
	index := 0
	for i, p := range openList {
		if (i > 0) && (p.F <= openList[index].F) {
			index = i
		}
	}
	return openList[index]
}

func getWalkable(p utils.Point, s *Scene) []utils.Point {
	var around []utils.Point
	row, col := p.X, p.Y
	left := s.scene[row][col-1]
	up := s.scene[row-1][col]
	right := s.scene[row][col+1]
	down := s.scene[row+1][col]
	leftup := s.scene[row-1][col-1]
	rightup := s.scene[row-1][col+1]
	leftdown := s.scene[row+1][col-1]
	rightdown := s.scene[row+1][col+1]
	if (left == ' ') || (left == 'B') {
		around = append(around, utils.Point{row, col - 1, 0, 0, 0, &p})
	}
	if (leftup == ' ') || (leftup == 'B') {
		around = append(around, utils.Point{row - 1, col - 1, 0, 0, 0, &p})
	}
	if (up == ' ') || (up == 'B') {
		around = append(around, utils.Point{row - 1, col, 0, 0, 0, &p})
	}
	if (rightup == ' ') || (rightup == 'B') {
		around = append(around, utils.Point{row - 1, col + 1, 0, 0, 0, &p})
	}
	if (right == ' ') || (right == 'B') {
		around = append(around, utils.Point{row, col + 1, 0, 0, 0, &p})
	}
	if (rightdown == ' ') || (rightdown == 'B') {
		around = append(around, utils.Point{row + 1, col + 1, 0, 0, 0, &p})
	}
	if (down == ' ') || (down == 'B') {
		around = append(around, utils.Point{row + 1, col, 0, 0, 0, &p})
	}
	if (leftdown == ' ') || (leftdown == 'B') {
		around = append(around, utils.Point{row + 1, col - 1, 0, 0, 0, &p})
	}
	return around
}

func addToOpenList(p utils.Point) {
	updateWeight(&p)
	if checkExist(p, closeList) {
		return
	}
	if !checkExist(p, openList) {
		openList = append(openList, p)
	} else {
		if openList[findPoint(p, openList)].F > p.F { //New path found
			openList[findPoint(p, openList)].Parent = p.Parent
		}
	}
}

// Update G, H, F of the point
func updateWeight(p *utils.Point) {
	if checkRelativePos(*p) == 1 {
		p.G = p.Parent.G + 10
	} else {
		p.G = p.Parent.G + 14
	}
	absx := (int)(math.Abs((float64)(dest.X - p.X)))
	absy := (int)(math.Abs((float64)(dest.Y - p.Y)))
	p.H = (absx + absy) * 10
	p.F = p.G + p.H
}

func removeFromOpenList(p utils.Point) {
	index := findPoint(p, openList)
	if index == -1 {
		os.Exit(0)
	}
	openList = append(openList[:index], openList[index+1:]...)
}

func addToCloseList(p utils.Point, s *Scene) {
	removeFromOpenList(p)
	if (p.X == dest.X) && (p.Y == dest.Y) {
		generatePath(p, s)
		s.draw()
		os.Exit(1)
	}
	// if (p.Parent != nil) && (checkRelativePos(p) == 2) {
	// 	parent := p.Parent
	// 	//rdblck := s.scene[p.X][parent.Y] | s.scene[parent.X][p.Y]
	// 	//fmt.Printf("%c\n", rdblck)
	// 	if (s.scene[p.X][parent.Y] == '#') || (s.scene[parent.X][p.Y] == '#') {
	// 		return
	// 	}
	// }
	if s.scene[p.X][p.Y] != 'A' {
		s.scene[p.X][p.Y] = '·'
	}
	closeList = append(closeList, p)
}

func checkExist(p utils.Point, arr []utils.Point) bool {
	for _, point := range arr {
		if p.X == point.X && p.Y == point.Y {
			return true
		}
	}
	return false
}

func findPoint(p utils.Point, arr []utils.Point) int {
	for index, point := range arr {
		if p.X == point.X && p.Y == point.Y {
			return index
		}
	}

	return -1
}

func checkRelativePos(p utils.Point) int {
	parent := p.Parent
	hor := (int)(math.Abs((float64)(p.X - parent.X)))
	ver := (int)(math.Abs((float64)(p.Y - parent.Y)))
	return hor + ver
}

func generatePath(p utils.Point, s *Scene) {
	if (s.scene[p.X][p.Y] != 'A') && (s.scene[p.X][p.Y] != 'B') {
		s.scene[p.X][p.Y] = '*'
	}
	if p.Parent != nil {
		generatePath(*(p.Parent), s)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 Beego Authors
// Copyright 2014 The Macaron Authors
//
// Licensed 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 captcha a middleware that provides captcha service for Macaron.
package captcha

import (
	"fmt"
	"html/template"
	"path"
	"strings"

	"github.com/Unknwon/com"
	"github.com/go-macaron/cache"
	"gopkg.in/macaron.v1"
)

const _VERSION = "0.1.0"

func Version() string {
	return _VERSION
}

var (
	defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
)

// Captcha represents a captcha service.
type Captcha struct {
	store            cache.Cache
	SubURL           string
	URLPrefix        string
	FieldIdName      string
	FieldCaptchaName string
	StdWidth         int
	StdHeight        int
	ChallengeNums    int
	Expiration       int64
	CachePrefix      string
}

// generate key string
func (c *Captcha) key(id string) string {
	return c.CachePrefix + id
}

// generate rand chars with default chars
func (c *Captcha) genRandChars() string {
	return string(com.RandomCreateBytes(c.ChallengeNums, defaultChars...))
}

// tempalte func for output html
func (c *Captcha) CreateHtml() template.HTML {
	value, err := c.CreateCaptcha()
	if err != nil {
		panic(fmt.Errorf("fail to create captcha: %v", err))
	}
	return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">

	`, c.FieldIdName, value, c.SubURL, c.URLPrefix, value, c.SubURL, c.URLPrefix, value))
}

// create a new captcha id
func (c *Captcha) CreateCaptcha() (string, error) {
	id := string(com.RandomCreateBytes(15))
	if err := c.store.Put(c.key(id), c.genRandChars(), c.Expiration); err != nil {
		return "", err
	}
	return id, nil
}

// verify from a request
func (c *Captcha) VerifyReq(req macaron.Request) bool {
	req.ParseForm()
	return c.Verify(req.Form.Get(c.FieldIdName), req.Form.Get(c.FieldCaptchaName))
}

// direct verify id and challenge string
func (c *Captcha) Verify(id string, challenge string) bool {
	if len(challenge) == 0 || len(id) == 0 {
		return false
	}

	var chars string

	key := c.key(id)

	if v, ok := c.store.Get(key).(string); ok {
		chars = v
	} else {
		return false
	}

	defer c.store.Delete(key)

	if len(chars) != len(challenge) {
		return false
	}

	// verify challenge
	for i, c := range []byte(chars) {
		if c != challenge[i]-48 {
			return false
		}
	}

	return true
}

type Options struct {
	// Suburl path. Default is empty.
	SubURL string
	// URL prefix of getting captcha pictures. Default is "/captcha/".
	URLPrefix string
	// Hidden input element ID. Default is "captcha_id".
	FieldIdName string
	// User input value element name in request form. Default is "captcha".
	FieldCaptchaName string
	// Challenge number. Default is 6.
	ChallengeNums int
	// Captcha image width. Default is 240.
	Width int
	// Captcha image height. Default is 80.
	Height int
	// Captcha expiration time in seconds. Default is 600.
	Expiration int64
	// Cache key prefix captcha characters. Default is "captcha_".
	CachePrefix string
}

func prepareOptions(options []Options) Options {
	var opt Options
	if len(options) > 0 {
		opt = options[0]
	}

	opt.SubURL = strings.TrimSuffix(opt.SubURL, "/")

	// Defaults.
	if len(opt.URLPrefix) == 0 {
		opt.URLPrefix = "/captcha/"
	} else if opt.URLPrefix[len(opt.URLPrefix)-1] != '/' {
		opt.URLPrefix += "/"
	}
	if len(opt.FieldIdName) == 0 {
		opt.FieldIdName = "captcha_id"
	}
	if len(opt.FieldCaptchaName) == 0 {
		opt.FieldCaptchaName = "captcha"
	}
	if opt.ChallengeNums == 0 {
		opt.ChallengeNums = 6
	}
	if opt.Width == 0 {
		opt.Width = stdWidth
	}
	if opt.Height == 0 {
		opt.Height = stdHeight
	}
	if opt.Expiration == 0 {
		opt.Expiration = 600
	}
	if len(opt.CachePrefix) == 0 {
		opt.CachePrefix = "captcha_"
	}

	return opt
}

// NewCaptcha initializes and returns a captcha with given options.
func NewCaptcha(opt Options) *Captcha {
	return &Captcha{
		SubURL:           opt.SubURL,
		URLPrefix:        opt.URLPrefix,
		FieldIdName:      opt.FieldIdName,
		FieldCaptchaName: opt.FieldCaptchaName,
		StdWidth:         opt.Width,
		StdHeight:        opt.Height,
		ChallengeNums:    opt.ChallengeNums,
		Expiration:       opt.Expiration,
		CachePrefix:      opt.CachePrefix,
	}
}

// Captchaer is a middleware that maps a captcha.Captcha service into the Macaron handler chain.
// An single variadic captcha.Options struct can be optionally provided to configure.
// This should be register after cache.Cacher.
func Captchaer(options ...Options) macaron.Handler {
	return func(ctx *macaron.Context, cache cache.Cache) {
		cpt := NewCaptcha(prepareOptions(options))
		cpt.store = cache

		if strings.HasPrefix(ctx.Req.URL.Path, cpt.URLPrefix) {
			var chars string
			id := path.Base(ctx.Req.URL.Path)
			if i := strings.Index(id, "."); i > -1 {
				id = id[:i]
			}
			key := cpt.key(id)

			// Reload captcha.
			if len(ctx.Query("reload")) > 0 {
				chars = cpt.genRandChars()
				if err := cpt.store.Put(key, chars, cpt.Expiration); err != nil {
					ctx.Status(500)
					ctx.Write([]byte("captcha reload error"))
					panic(fmt.Errorf("reload captcha: %v", err))
				}
			} else {
				if v, ok := cpt.store.Get(key).(string); ok {
					chars = v
				} else {
					ctx.Status(404)
					ctx.Write([]byte("captcha not found"))
					return
				}
			}

			if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight).WriteTo(ctx.Resp); err != nil {
				panic(fmt.Errorf("write captcha: %v", err))
			}
			return
		}

		ctx.Data["Captcha"] = cpt
		ctx.Map(cpt)
	}
}
<commit_msg>skip tabindex<commit_after>// Copyright 2013 Beego Authors
// Copyright 2014 The Macaron Authors
//
// Licensed 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 captcha a middleware that provides captcha service for Macaron.
package captcha

import (
	"fmt"
	"html/template"
	"path"
	"strings"

	"github.com/Unknwon/com"
	"github.com/go-macaron/cache"
	"gopkg.in/macaron.v1"
)

const _VERSION = "0.1.0"

func Version() string {
	return _VERSION
}

var (
	defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
)

// Captcha represents a captcha service.
type Captcha struct {
	store            cache.Cache
	SubURL           string
	URLPrefix        string
	FieldIdName      string
	FieldCaptchaName string
	StdWidth         int
	StdHeight        int
	ChallengeNums    int
	Expiration       int64
	CachePrefix      string
}

// generate key string
func (c *Captcha) key(id string) string {
	return c.CachePrefix + id
}

// generate rand chars with default chars
func (c *Captcha) genRandChars() string {
	return string(com.RandomCreateBytes(c.ChallengeNums, defaultChars...))
}

// tempalte func for output html
func (c *Captcha) CreateHtml() template.HTML {
	value, err := c.CreateCaptcha()
	if err != nil {
		panic(fmt.Errorf("fail to create captcha: %v", err))
	}
	return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">

	`, c.FieldIdName, value, c.SubURL, c.URLPrefix, value, c.SubURL, c.URLPrefix, value))
}

// create a new captcha id
func (c *Captcha) CreateCaptcha() (string, error) {
	id := string(com.RandomCreateBytes(15))
	if err := c.store.Put(c.key(id), c.genRandChars(), c.Expiration); err != nil {
		return "", err
	}
	return id, nil
}

// verify from a request
func (c *Captcha) VerifyReq(req macaron.Request) bool {
	req.ParseForm()
	return c.Verify(req.Form.Get(c.FieldIdName), req.Form.Get(c.FieldCaptchaName))
}

// direct verify id and challenge string
func (c *Captcha) Verify(id string, challenge string) bool {
	if len(challenge) == 0 || len(id) == 0 {
		return false
	}

	var chars string

	key := c.key(id)

	if v, ok := c.store.Get(key).(string); ok {
		chars = v
	} else {
		return false
	}

	defer c.store.Delete(key)

	if len(chars) != len(challenge) {
		return false
	}

	// verify challenge
	for i, c := range []byte(chars) {
		if c != challenge[i]-48 {
			return false
		}
	}

	return true
}

type Options struct {
	// Suburl path. Default is empty.
	SubURL string
	// URL prefix of getting captcha pictures. Default is "/captcha/".
	URLPrefix string
	// Hidden input element ID. Default is "captcha_id".
	FieldIdName string
	// User input value element name in request form. Default is "captcha".
	FieldCaptchaName string
	// Challenge number. Default is 6.
	ChallengeNums int
	// Captcha image width. Default is 240.
	Width int
	// Captcha image height. Default is 80.
	Height int
	// Captcha expiration time in seconds. Default is 600.
	Expiration int64
	// Cache key prefix captcha characters. Default is "captcha_".
	CachePrefix string
}

func prepareOptions(options []Options) Options {
	var opt Options
	if len(options) > 0 {
		opt = options[0]
	}

	opt.SubURL = strings.TrimSuffix(opt.SubURL, "/")

	// Defaults.
	if len(opt.URLPrefix) == 0 {
		opt.URLPrefix = "/captcha/"
	} else if opt.URLPrefix[len(opt.URLPrefix)-1] != '/' {
		opt.URLPrefix += "/"
	}
	if len(opt.FieldIdName) == 0 {
		opt.FieldIdName = "captcha_id"
	}
	if len(opt.FieldCaptchaName) == 0 {
		opt.FieldCaptchaName = "captcha"
	}
	if opt.ChallengeNums == 0 {
		opt.ChallengeNums = 6
	}
	if opt.Width == 0 {
		opt.Width = stdWidth
	}
	if opt.Height == 0 {
		opt.Height = stdHeight
	}
	if opt.Expiration == 0 {
		opt.Expiration = 600
	}
	if len(opt.CachePrefix) == 0 {
		opt.CachePrefix = "captcha_"
	}

	return opt
}

// NewCaptcha initializes and returns a captcha with given options.
func NewCaptcha(opt Options) *Captcha {
	return &Captcha{
		SubURL:           opt.SubURL,
		URLPrefix:        opt.URLPrefix,
		FieldIdName:      opt.FieldIdName,
		FieldCaptchaName: opt.FieldCaptchaName,
		StdWidth:         opt.Width,
		StdHeight:        opt.Height,
		ChallengeNums:    opt.ChallengeNums,
		Expiration:       opt.Expiration,
		CachePrefix:      opt.CachePrefix,
	}
}

// Captchaer is a middleware that maps a captcha.Captcha service into the Macaron handler chain.
// An single variadic captcha.Options struct can be optionally provided to configure.
// This should be register after cache.Cacher.
func Captchaer(options ...Options) macaron.Handler {
	return func(ctx *macaron.Context, cache cache.Cache) {
		cpt := NewCaptcha(prepareOptions(options))
		cpt.store = cache

		if strings.HasPrefix(ctx.Req.URL.Path, cpt.URLPrefix) {
			var chars string
			id := path.Base(ctx.Req.URL.Path)
			if i := strings.Index(id, "."); i > -1 {
				id = id[:i]
			}
			key := cpt.key(id)

			// Reload captcha.
			if len(ctx.Query("reload")) > 0 {
				chars = cpt.genRandChars()
				if err := cpt.store.Put(key, chars, cpt.Expiration); err != nil {
					ctx.Status(500)
					ctx.Write([]byte("captcha reload error"))
					panic(fmt.Errorf("reload captcha: %v", err))
				}
			} else {
				if v, ok := cpt.store.Get(key).(string); ok {
					chars = v
				} else {
					ctx.Status(404)
					ctx.Write([]byte("captcha not found"))
					return
				}
			}

			if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight).WriteTo(ctx.Resp); err != nil {
				panic(fmt.Errorf("write captcha: %v", err))
			}
			return
		}

		ctx.Data["Captcha"] = cpt
		ctx.Map(cpt)
	}
}
<|endoftext|>


<commit_before>package car

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"github.com/micro/cli"
	"github.com/micro/go-micro"
	"github.com/micro/go-micro/cmd"
	"github.com/micro/go-micro/registry"
	"github.com/micro/micro/internal/handler"
	"github.com/micro/micro/internal/helper"
	"github.com/micro/micro/internal/server"
	"github.com/micro/micro/internal/stats"
	"github.com/micro/micro/plugin"
	"github.com/pborman/uuid"
)

type sidecar struct {
	name    string
	address string
	hcUrl   string
}

type srv struct {
	*mux.Router
}

var (
	Address      = ":8081"
	RootPath     = "/"
	BrokerPath   = "/broker"
	HealthPath   = "/health"
	RegistryPath = "/registry"
	RPCPath      = "/rpc"
	CORS         = map[string]bool{"*": true}
	Namespace    string
)

func (s *srv) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if origin := r.Header.Get("Origin"); CORS[origin] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	} else if len(origin) > 0 && CORS["*"] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	}

	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	w.Header().Set("Access-Control-Allow-Credentials", "true")

	if r.Method == "OPTIONS" {
		return
	}

	s.Router.ServeHTTP(w, r)
}

func newSidecar(name, address, hcUrl string) *sidecar {
	return &sidecar{
		name:    name,
		address: address,
		hcUrl:   hcUrl,
	}
}

func run(ctx *cli.Context, car *sidecar) {
	if len(ctx.String("address")) > 0 {
		Address = ctx.String("address")
	}
	if len(ctx.String("cors")) > 0 {
		origins := make(map[string]bool)
		for _, origin := range strings.Split(ctx.String("cors"), ",") {
			origins[origin] = true
		}
		CORS = origins
	}
	if len(ctx.String("namespace")) > 0 {
		Namespace = ctx.String("namespace")
	}

	// Init plugins
	for _, p := range Plugins() {
		p.Init(ctx)
	}

	var opts []server.Option

	if ctx.GlobalBool("enable_tls") {
		config, err := helper.TLSConfig(ctx)
		if err != nil {
			fmt.Println(err.Error())
			return
		}

		opts = append(opts, server.EnableTLS(true))
		opts = append(opts, server.TLSConfig(config))
	}

	r := mux.NewRouter()
	s := &srv{r}

	// new server
	srv := server.NewServer(Address)
	srv.Init(opts...)

	// register handlers
	if car != nil {
		log.Printf("Registering Health handler at %s", HealthPath)
		r.Handle(HealthPath, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if c, err := car.hc(); err != nil {
				http.Error(w, err.Error(), c)
				return
			}
		}))
	}

	log.Printf("Registering Root Handler at %s", RootPath)
	r.PathPrefix(RootPath).Handler(handler.RPCX(Namespace))

	log.Printf("Registering Registry handler at %s", RegistryPath)
	r.Handle(RegistryPath, http.HandlerFunc(handler.Registry))

	log.Printf("Registering RPC handler at %s", RPCPath)
	r.Handle(RPCPath, http.HandlerFunc(handler.RPC))

	log.Printf("Registering Broker handler at %s", BrokerPath)
	r.Handle(BrokerPath, http.HandlerFunc(handler.Broker))

	var h http.Handler = s

	if ctx.GlobalBool("enable_stats") {
		st := stats.New()
		r.Handle("/stats", http.HandlerFunc(st.StatsHandler))
		h = st.ServeHTTP(r)
		st.Start()
		defer st.Stop()
	}

	// reverse wrap handler
	plugins := append(Plugins(), plugin.Plugins()...)
	for i := len(plugins); i > 0; i-- {
		h = plugins[i-1].Handler()(h)
	}

	srv.Handle("/", h)

	// Initialise Server
	service := micro.NewService(
		micro.Name("go.micro.sidecar"),
		micro.RegisterTTL(
			time.Duration(ctx.GlobalInt("register_ttl"))*time.Second,
		),
		micro.RegisterInterval(
			time.Duration(ctx.GlobalInt("register_interval"))*time.Second,
		),
	)

	if err := srv.Start(); err != nil {
		log.Fatal(err)
	}

	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}

	if err := srv.Stop(); err != nil {
		log.Fatal(err)
	}
}

func (s *sidecar) hc() (int, error) {
	if len(s.hcUrl) == 0 {
		return 200, nil
	}
	rsp, err := http.Get(s.hcUrl)
	if err != nil {
		return 500, err
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != 200 {
		return rsp.StatusCode, fmt.Errorf("Non 200 response: %d", rsp.StatusCode)
	}
	return 200, nil
}

func (s *sidecar) hcLoop(service *registry.Service, exitCh chan bool) {
	tick := time.NewTicker(time.Second * 30)
	registered := true

	for {
		select {
		case <-tick.C:
			_, err := s.hc()
			if err != nil && registered {
				log.Printf("Healthcheck error. Deregistering %v", service.Nodes[0].Id)
				(*cmd.DefaultOptions().Registry).Deregister(service)
				registered = false
			} else if err == nil && !registered {
				log.Printf("Healthcheck success. Registering %v", service.Nodes[0].Id)
				(*cmd.DefaultOptions().Registry).Register(service)
				registered = true
			}
		case <-exitCh:
			return
		}
	}
}

// run healthchecker
func (s *sidecar) run(exit chan bool) {
	parts := strings.Split(s.address, ":")
	host := strings.Join(parts[:len(parts)-1], ":")
	port, _ := strconv.Atoi(parts[len(parts)-1])

	id := s.name + "-" + uuid.NewUUID().String()
	node := &registry.Node{
		Id:      id,
		Address: host,
		Port:    port,
	}

	service := &registry.Service{
		Name:  s.name,
		Nodes: []*registry.Node{node},
	}

	log.Printf("Registering %s", node.Id)
	(*cmd.DefaultOptions().Registry).Register(service)

	if len(s.hcUrl) == 0 {
		return
	}

	log.Print("Starting sidecar healthchecker")
	go s.hcLoop(service, exit)
	<-exit
}

func Commands() []cli.Command {
	command := cli.Command{
		Name:  "sidecar",
		Usage: "Run the micro sidecar",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "address",
				Usage:  "Set the sidecar address e.g 0.0.0.0:8081",
				EnvVar: "MICRO_SIDECAR_ADDRESS",
			},
			cli.StringFlag{
				Name:   "cors",
				Usage:  "Comma separated whitelist of allowed origins for CORS",
				EnvVar: "MICRO_SIDECAR_CORS",
			},
			cli.StringFlag{
				Name:   "namespace",
				Usage:  "Set the namespace used by the sidecar e.g. com.example.srv",
				EnvVar: "MICRO_SIDECAR_NAMESPACE",
			},
			cli.StringFlag{
				Name:  "server_name",
				Usage: "Server name of the app",
			},
			cli.StringFlag{
				Name:  "server_address",
				Usage: "Server address and port of the app",
			},
			cli.StringFlag{
				Name:  "healthcheck_url",
				Usage: "URL to check health of the app",
			},
		},
		Action: func(c *cli.Context) {
			name := c.String("server_name")
			address := c.String("server_address")
			hcUrl := c.String("healthcheck_url")

			if len(name) == 0 && len(address) == 0 {
				run(c, nil)
				return
			}

			if len(name) == 0 {
				fmt.Println("Require server name")
				return
			}

			if len(address) == 0 {
				fmt.Println("Require server address")
				return
			}

			// exit chan
			exit := make(chan bool)

			// start the healthchecker
			car := newSidecar(name, address, hcUrl)
			go car.run(exit)

			// run the server
			run(c, car)

			// kill healthchecker
			close(exit)
		},
	}

	for _, p := range Plugins() {
		if cmds := p.Commands(); len(cmds) > 0 {
			command.Subcommands = append(command.Subcommands, cmds...)
		}

		if flags := p.Flags(); len(flags) > 0 {
			command.Flags = append(command.Flags, flags...)
		}
	}

	return []cli.Command{command}
}
<commit_msg>We should set the namespace<commit_after>package car

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/gorilla/mux"
	"github.com/micro/cli"
	"github.com/micro/go-micro"
	"github.com/micro/go-micro/cmd"
	"github.com/micro/go-micro/registry"
	"github.com/micro/micro/internal/handler"
	"github.com/micro/micro/internal/helper"
	"github.com/micro/micro/internal/server"
	"github.com/micro/micro/internal/stats"
	"github.com/micro/micro/plugin"
	"github.com/pborman/uuid"
)

type sidecar struct {
	name    string
	address string
	hcUrl   string
}

type srv struct {
	*mux.Router
}

var (
	Address      = ":8081"
	RootPath     = "/"
	BrokerPath   = "/broker"
	HealthPath   = "/health"
	RegistryPath = "/registry"
	RPCPath      = "/rpc"
	CORS         = map[string]bool{"*": true}
	Namespace    = "go.micro.srv"
)

func (s *srv) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if origin := r.Header.Get("Origin"); CORS[origin] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	} else if len(origin) > 0 && CORS["*"] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	}

	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	w.Header().Set("Access-Control-Allow-Credentials", "true")

	if r.Method == "OPTIONS" {
		return
	}

	s.Router.ServeHTTP(w, r)
}

func newSidecar(name, address, hcUrl string) *sidecar {
	return &sidecar{
		name:    name,
		address: address,
		hcUrl:   hcUrl,
	}
}

func run(ctx *cli.Context, car *sidecar) {
	if len(ctx.String("address")) > 0 {
		Address = ctx.String("address")
	}
	if len(ctx.String("cors")) > 0 {
		origins := make(map[string]bool)
		for _, origin := range strings.Split(ctx.String("cors"), ",") {
			origins[origin] = true
		}
		CORS = origins
	}
	if len(ctx.String("namespace")) > 0 {
		Namespace = ctx.String("namespace")
	}

	// Init plugins
	for _, p := range Plugins() {
		p.Init(ctx)
	}

	var opts []server.Option

	if ctx.GlobalBool("enable_tls") {
		config, err := helper.TLSConfig(ctx)
		if err != nil {
			fmt.Println(err.Error())
			return
		}

		opts = append(opts, server.EnableTLS(true))
		opts = append(opts, server.TLSConfig(config))
	}

	r := mux.NewRouter()
	s := &srv{r}

	// new server
	srv := server.NewServer(Address)
	srv.Init(opts...)

	// register handlers
	if car != nil {
		log.Printf("Registering Health handler at %s", HealthPath)
		r.Handle(HealthPath, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if c, err := car.hc(); err != nil {
				http.Error(w, err.Error(), c)
				return
			}
		}))
	}

	log.Printf("Registering Root Handler at %s", RootPath)
	r.PathPrefix(RootPath).Handler(handler.RPCX(Namespace))

	log.Printf("Registering Registry handler at %s", RegistryPath)
	r.Handle(RegistryPath, http.HandlerFunc(handler.Registry))

	log.Printf("Registering RPC handler at %s", RPCPath)
	r.Handle(RPCPath, http.HandlerFunc(handler.RPC))

	log.Printf("Registering Broker handler at %s", BrokerPath)
	r.Handle(BrokerPath, http.HandlerFunc(handler.Broker))

	var h http.Handler = s

	if ctx.GlobalBool("enable_stats") {
		st := stats.New()
		r.Handle("/stats", http.HandlerFunc(st.StatsHandler))
		h = st.ServeHTTP(r)
		st.Start()
		defer st.Stop()
	}

	// reverse wrap handler
	plugins := append(Plugins(), plugin.Plugins()...)
	for i := len(plugins); i > 0; i-- {
		h = plugins[i-1].Handler()(h)
	}

	srv.Handle("/", h)

	// Initialise Server
	service := micro.NewService(
		micro.Name("go.micro.sidecar"),
		micro.RegisterTTL(
			time.Duration(ctx.GlobalInt("register_ttl"))*time.Second,
		),
		micro.RegisterInterval(
			time.Duration(ctx.GlobalInt("register_interval"))*time.Second,
		),
	)

	if err := srv.Start(); err != nil {
		log.Fatal(err)
	}

	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}

	if err := srv.Stop(); err != nil {
		log.Fatal(err)
	}
}

func (s *sidecar) hc() (int, error) {
	if len(s.hcUrl) == 0 {
		return 200, nil
	}
	rsp, err := http.Get(s.hcUrl)
	if err != nil {
		return 500, err
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != 200 {
		return rsp.StatusCode, fmt.Errorf("Non 200 response: %d", rsp.StatusCode)
	}
	return 200, nil
}

func (s *sidecar) hcLoop(service *registry.Service, exitCh chan bool) {
	tick := time.NewTicker(time.Second * 30)
	registered := true

	for {
		select {
		case <-tick.C:
			_, err := s.hc()
			if err != nil && registered {
				log.Printf("Healthcheck error. Deregistering %v", service.Nodes[0].Id)
				(*cmd.DefaultOptions().Registry).Deregister(service)
				registered = false
			} else if err == nil && !registered {
				log.Printf("Healthcheck success. Registering %v", service.Nodes[0].Id)
				(*cmd.DefaultOptions().Registry).Register(service)
				registered = true
			}
		case <-exitCh:
			return
		}
	}
}

// run healthchecker
func (s *sidecar) run(exit chan bool) {
	parts := strings.Split(s.address, ":")
	host := strings.Join(parts[:len(parts)-1], ":")
	port, _ := strconv.Atoi(parts[len(parts)-1])

	id := s.name + "-" + uuid.NewUUID().String()
	node := &registry.Node{
		Id:      id,
		Address: host,
		Port:    port,
	}

	service := &registry.Service{
		Name:  s.name,
		Nodes: []*registry.Node{node},
	}

	log.Printf("Registering %s", node.Id)
	(*cmd.DefaultOptions().Registry).Register(service)

	if len(s.hcUrl) == 0 {
		return
	}

	log.Print("Starting sidecar healthchecker")
	go s.hcLoop(service, exit)
	<-exit
}

func Commands() []cli.Command {
	command := cli.Command{
		Name:  "sidecar",
		Usage: "Run the micro sidecar",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "address",
				Usage:  "Set the sidecar address e.g 0.0.0.0:8081",
				EnvVar: "MICRO_SIDECAR_ADDRESS",
			},
			cli.StringFlag{
				Name:   "cors",
				Usage:  "Comma separated whitelist of allowed origins for CORS",
				EnvVar: "MICRO_SIDECAR_CORS",
			},
			cli.StringFlag{
				Name:   "namespace",
				Usage:  "Set the namespace used by the sidecar e.g. com.example.srv",
				EnvVar: "MICRO_SIDECAR_NAMESPACE",
			},
			cli.StringFlag{
				Name:  "server_name",
				Usage: "Server name of the app",
			},
			cli.StringFlag{
				Name:  "server_address",
				Usage: "Server address and port of the app",
			},
			cli.StringFlag{
				Name:  "healthcheck_url",
				Usage: "URL to check health of the app",
			},
		},
		Action: func(c *cli.Context) {
			name := c.String("server_name")
			address := c.String("server_address")
			hcUrl := c.String("healthcheck_url")

			if len(name) == 0 && len(address) == 0 {
				run(c, nil)
				return
			}

			if len(name) == 0 {
				fmt.Println("Require server name")
				return
			}

			if len(address) == 0 {
				fmt.Println("Require server address")
				return
			}

			// exit chan
			exit := make(chan bool)

			// start the healthchecker
			car := newSidecar(name, address, hcUrl)
			go car.run(exit)

			// run the server
			run(c, car)

			// kill healthchecker
			close(exit)
		},
	}

	for _, p := range Plugins() {
		if cmds := p.Commands(); len(cmds) > 0 {
			command.Subcommands = append(command.Subcommands, cmds...)
		}

		if flags := p.Flags(); len(flags) > 0 {
			command.Flags = append(command.Flags, flags...)
		}
	}

	return []cli.Command{command}
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 Intel Corporation
//
// Licensed 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 virtcontainers

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
)

type ccShim struct{}

// CCShimConfig is the structure providing specific configuration
// for ccShim implementation.
type CCShimConfig struct {
	Path string
}

var consoleFileMode = os.FileMode(0660)

// start is the ccShim start implementation.
// It starts the cc-shim binary with URL and token flags provided by
// the proxy.
func (s *ccShim) start(pod Pod, params ShimParams) (int, error) {
	if pod.config == nil {
		return -1, fmt.Errorf("Pod config cannot be nil")
	}

	config, ok := newShimConfig(*(pod.config)).(CCShimConfig)
	if !ok {
		return -1, fmt.Errorf("Wrong shim config type, should be CCShimConfig type")
	}

	if config.Path == "" {
		return -1, fmt.Errorf("Shim path cannot be empty")
	}

	if params.Token == "" {
		return -1, fmt.Errorf("Token cannot be empty")
	}

	if params.URL == "" {
		return -1, fmt.Errorf("URL cannot be empty")
	}

	cmd := exec.Command(config.Path, "-t", params.Token, "-u", params.URL)
	cmd.Env = os.Environ()

	if !params.Detach {
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
	}

	var f *os.File
	var err error
	if params.Console != "" {
		f, err = os.OpenFile(params.Console, os.O_RDWR, consoleFileMode)
		if err != nil {
			return -1, err
		}

		cmd.Stdin = f
		cmd.Stdout = f
		cmd.Stderr = f
		cmd.SysProcAttr = &syscall.SysProcAttr{
			// Create Session
			Setsid: true,

			// Set Controlling terminal to Ctty
			Setctty: true,
			Ctty:    int(f.Fd()),
		}

	}
	defer func() {
		if f != nil {
			f.Close()
		}
	}()

	if err := cmd.Start(); err != nil {
		return -1, err
	}

	return cmd.Process.Pid, nil
}
<commit_msg>shim: Add ability to enable debug output<commit_after>//
// Copyright (c) 2017 Intel Corporation
//
// Licensed 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 virtcontainers

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
)

type ccShim struct{}

// CCShimConfig is the structure providing specific configuration
// for ccShim implementation.
type CCShimConfig struct {
	Path  string
	Debug bool
}

var consoleFileMode = os.FileMode(0660)

// start is the ccShim start implementation.
// It starts the cc-shim binary with URL and token flags provided by
// the proxy.
func (s *ccShim) start(pod Pod, params ShimParams) (int, error) {
	if pod.config == nil {
		return -1, fmt.Errorf("Pod config cannot be nil")
	}

	config, ok := newShimConfig(*(pod.config)).(CCShimConfig)
	if !ok {
		return -1, fmt.Errorf("Wrong shim config type, should be CCShimConfig type")
	}

	if config.Path == "" {
		return -1, fmt.Errorf("Shim path cannot be empty")
	}

	if params.Token == "" {
		return -1, fmt.Errorf("Token cannot be empty")
	}

	if params.URL == "" {
		return -1, fmt.Errorf("URL cannot be empty")
	}

	args := []string{config.Path, "-t", params.Token, "-u", params.URL}
	if config.Debug {
		args = append(args, "-d")
	}

	cmd := exec.Command(args[0], args[1:]...)
	cmd.Env = os.Environ()

	if !params.Detach {
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
	}

	var f *os.File
	var err error
	if params.Console != "" {
		f, err = os.OpenFile(params.Console, os.O_RDWR, consoleFileMode)
		if err != nil {
			return -1, err
		}

		cmd.Stdin = f
		cmd.Stdout = f
		cmd.Stderr = f
		cmd.SysProcAttr = &syscall.SysProcAttr{
			// Create Session
			Setsid: true,

			// Set Controlling terminal to Ctty
			Setctty: true,
			Ctty:    int(f.Fd()),
		}

	}
	defer func() {
		if f != nil {
			f.Close()
		}
	}()

	if err := cmd.Start(); err != nil {
		return -1, err
	}

	return cmd.Process.Pid, nil
}
<|endoftext|>


<commit_before>package cc

import (
	"testing"
)

var solveTests = []struct {
	c   int     // columns on board
	r   int     // rows on board
	p   []Piece // The pieces to use
	out int     // The number of solutions
}{
	{2, 2, []Piece{Rook, Rook}, 2},
	{2, 2, []Piece{King, King}, 0},
	{3, 2, []Piece{Bishop, Bishop}, 11},
	{3, 3, []Piece{Rook, King, King}, 4},
	{4, 4, []Piece{Rook, Rook, Knight, Knight, Knight, Knight}, 8},
	{1, 1, []Piece{Queen}, 1},
	{2, 2, []Piece{Queen, Queen}, 0},
	{4, 4, []Piece{Queen, Queen, Queen, Queen}, 2},
	{5, 5, []Piece{Queen, Queen, Queen, Queen, Queen}, 10},
	{6, 6, []Piece{Queen, Queen, Queen, Queen, Queen, Queen}, 4},
	{7, 7, []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen}, 40},
	//{8, 8, []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen, Queen}, 92},
	//{7, 7, []Piece{Queen, Queen, Bishop, Bishop, Knight, King, King}, 3062636},
}

func TestSolve(t *testing.T) {
	for _, tc := range solveTests {
		solutions := make([]Board, 0)
		Solve(tc.c, tc.r, tc.p, &solutions)
		if len(solutions) != tc.out {
			t.Errorf("Expected %d got %d: %+v", tc.out, len(solutions), tc)
			t.Errorf("Solutions:\n")
			for i, s := range solutions {
				t.Errorf("[%d]\n%s\n", i, s.Notation())
				t.Errorf("[%d]\n%s\n", i, s.Ascii())
			}
		}
	}
}

// Benchmarks

func Benchmark2x2R2(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, Rook}
		Solve(2, 2, p, &solutions)
		if len(solutions) != 2 {
			b.Errorf("Expected %d got %d", 2, len(solutions))
		}
	}
}

func Benchmark3x3R1K2(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, King, King}
		Solve(3, 3, p, &solutions)
		if len(solutions) != 4 {
			b.Errorf("Expected %d got %d", 4, len(solutions))
		}
	}
}

func Benchmark4x4R2N4(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, Rook, Knight, Knight, Knight, Knight}
		Solve(4, 4, p, &solutions)
		if len(solutions) != 8 {
			b.Errorf("Expected %d got %d", 8, len(solutions))
		}
	}
}

func Benchmark2Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen}
		Solve(2, 2, p, &solutions)
		if len(solutions) != 0 {
			b.Errorf("Expected %d got %d", 0, len(solutions))
		}
	}
}

func Benchmark4Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen}
		Solve(4, 4, p, &solutions)
		if len(solutions) != 2 {
			b.Errorf("Expected %d got %d", 2, len(solutions))
		}
	}
}

func Benchmark5Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen}
		Solve(5, 5, p, &solutions)
		if len(solutions) != 10 {
			b.Errorf("Expected %d got %d", 10, len(solutions))
		}
	}
}

func Benchmark6Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(6, 6, p, &solutions)
		if len(solutions) != 4 {
			b.Errorf("Expected %d got %d", 4, len(solutions))
		}
	}
}

func Benchmark7Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(7, 7, p, &solutions)
		if len(solutions) != 40 {
			b.Errorf("Expected %d got %d", 40, len(solutions))
		}
	}
}

func Benchmark8Q(b *testing.B) {
	b.Skip("Slow test")
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(8, 8, p, &solutions)
		if len(solutions) != 92 {
			b.Errorf("Expected %d got %d", 92, len(solutions))
		}
	}
}

func Benchmark7x7Q2B2N1K2(b *testing.B) {
	b.Skip("Slow test")
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Bishop, Bishop, Knight, King, King}
		Solve(7, 7, p, &solutions)
		if len(solutions) != 3062636 {
			b.Errorf("Expected %d got %d", 3062636, len(solutions))
		}
	}
}
<commit_msg>Add tests<commit_after>package cc

import (
	"testing"
)

var solveTests = []struct {
	c   int     // columns on board
	r   int     // rows on board
	p   []Piece // The pieces to use
	out int     // The number of solutions
}{
	{2, 2, []Piece{Rook, Rook}, 2},
	{2, 2, []Piece{King, King}, 0},
	{3, 2, []Piece{Bishop, Bishop}, 11},
	{3, 3, []Piece{Rook, King, King}, 4},
	{4, 4, []Piece{Rook, Rook, Knight, Knight, Knight, Knight}, 8},
	{1, 1, []Piece{Queen}, 1},
	{2, 2, []Piece{Queen, Queen}, 0},
	{4, 4, []Piece{Queen, Queen, Queen, Queen}, 2},
	{5, 5, []Piece{Queen, Queen, Queen, Queen, Queen}, 10},
	{6, 6, []Piece{Queen, Queen, Queen, Queen, Queen, Queen}, 4},
	{7, 7, []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen}, 40},
	{2, 2, []Piece{Rook, Rook, Rook}, 0},
	{3, 3, []Piece{Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop}, 0},
	//{8, 8, []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen, Queen}, 92},
	//{7, 7, []Piece{Queen, Queen, Bishop, Bishop, Knight, King, King}, 3062636},
}

func TestSolve(t *testing.T) {
	for _, tc := range solveTests {
		solutions := make([]Board, 0)
		Solve(tc.c, tc.r, tc.p, &solutions)
		if len(solutions) != tc.out {
			t.Errorf("Expected %d got %d: %+v", tc.out, len(solutions), tc)
			t.Errorf("Solutions:\n")
			for i, s := range solutions {
				t.Errorf("[%d]\n%s\n", i, s.Notation())
				t.Errorf("[%d]\n%s\n", i, s.Ascii())
			}
		}
	}
}

// Benchmarks

func Benchmark2x2R2(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, Rook}
		Solve(2, 2, p, &solutions)
		if len(solutions) != 2 {
			b.Errorf("Expected %d got %d", 2, len(solutions))
		}
	}
}

func Benchmark3x3R1K2(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, King, King}
		Solve(3, 3, p, &solutions)
		if len(solutions) != 4 {
			b.Errorf("Expected %d got %d", 4, len(solutions))
		}
	}
}

func Benchmark4x4R2N4(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Rook, Rook, Knight, Knight, Knight, Knight}
		Solve(4, 4, p, &solutions)
		if len(solutions) != 8 {
			b.Errorf("Expected %d got %d", 8, len(solutions))
		}
	}
}

func Benchmark2Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen}
		Solve(2, 2, p, &solutions)
		if len(solutions) != 0 {
			b.Errorf("Expected %d got %d", 0, len(solutions))
		}
	}
}

func Benchmark4Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen}
		Solve(4, 4, p, &solutions)
		if len(solutions) != 2 {
			b.Errorf("Expected %d got %d", 2, len(solutions))
		}
	}
}

func Benchmark5Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen}
		Solve(5, 5, p, &solutions)
		if len(solutions) != 10 {
			b.Errorf("Expected %d got %d", 10, len(solutions))
		}
	}
}

func Benchmark6Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(6, 6, p, &solutions)
		if len(solutions) != 4 {
			b.Errorf("Expected %d got %d", 4, len(solutions))
		}
	}
}

func Benchmark7Q(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(7, 7, p, &solutions)
		if len(solutions) != 40 {
			b.Errorf("Expected %d got %d", 40, len(solutions))
		}
	}
}

func Benchmark8Q(b *testing.B) {
	b.Skip("Slow test")
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Queen, Queen, Queen, Queen, Queen, Queen}
		Solve(8, 8, p, &solutions)
		if len(solutions) != 92 {
			b.Errorf("Expected %d got %d", 92, len(solutions))
		}
	}
}

func Benchmark7x7Q2B2N1K2(b *testing.B) {
	b.Skip("Slow test")
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Queen, Queen, Bishop, Bishop, Knight, King, King}
		Solve(7, 7, p, &solutions)
		if len(solutions) != 3062636 {
			b.Errorf("Expected %d got %d", 3062636, len(solutions))
		}
	}
}

func Benchmark3x3B10(b *testing.B) {
	for n := 0; n < b.N; n++ {
		solutions := make([]Board, 0)
		p := []Piece{Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop, Bishop}
		Solve(3, 3, p, &solutions)
		if len(solutions) != 0 {
			b.Errorf("Expected %d got %d", 0, len(solutions))
		}
	}
}
<|endoftext|>


<commit_before>package dicom

import (
	"bytes"
	"errors"
)

type DicomFile struct {
	NumberOfItems int
	Elements      []DicomElement
	PixelBuffer   []uint16
}

// Errors
var (
	ErrIllegalTag = errors.New("Illegal tag found in PixelData")
	ErrTagNotFound = errors.New("Could not find tag in dicom dictionary")
	ErrWrongNumberSize = errors.New("Not a valid byte size for readNumber")
	ErrBrokenFile = errors.New("Invalid DICOM file")
)

const (
	magic_word = "DICM"
)

// Parse a byte array, returns a DICOM file struct
func Parse(buff []byte) (*DicomFile, error) {
	buffer := bytes.NewBuffer(buff)

	buffer.Next(128) // skip preamble

	// check for magic word
	if magicWord := string(buffer.Next(4)); magicWord != magic_word {
		return nil, ErrBrokenFile
	}

	file := &DicomFile{}

	// (0002,0000) MetaElementGroupLength
	metaElem := readDataElement(buffer, false)
	metaLength := int(metaElem.Value.(uint32))
	file.appendDataElement(metaElem)

	// Read meta tags
	start := buffer.Len()
	for start-buffer.Len() < metaLength {
		elem := readDataElement(buffer, false)
		file.appendDataElement(elem)
	}

	startedPixelData := false

	// Start with image meta data
	for buffer.Len() != 0 {

		elem := readDataElement(buffer, false)
		name := elem.Name
		file.appendDataElement(elem)

		if startedPixelData == true {

			// TODO: refactor this in separate function
			if name == "Item" {
				if len(elem.Value.([]byte)) == 4 {
					break // Skip Basic Offset Table
				} else {
					// TODO: concat multiple pixel data images
					elem.Value = "..."
				}
			} else if name == "SequenceDelimitationItem" {
				startedPixelData = false
			} else {
				panic(ErrIllegalTag)
			}
		}

		if name == "PixelData" {
			startedPixelData = true
			file.PixelBuffer = elem.Value.([]uint16)
			elem.Value = "..."
		}

	}

	return file, nil
}

// Append a dataElement to the DicomFile
func (file *DicomFile) appendDataElement(elem *DicomElement) {
	file.Elements = append(file.Elements, *elem)
}

// Lookup a tag by name
func (file *DicomFile) lookupElement(name string) (*DicomElement, error) {

	for _, elem := range file.Elements {
		if elem.Name == name {
			return &elem, nil
		}
	}

	return nil, ErrTagNotFound
}
<commit_msg>Public LookupElement function<commit_after>package dicom

import (
	"bytes"
	"errors"
)

type DicomFile struct {
	NumberOfItems int
	Elements      []DicomElement
	PixelBuffer   []uint16
}

// Errors
var (
	ErrIllegalTag = errors.New("Illegal tag found in PixelData")
	ErrTagNotFound = errors.New("Could not find tag in dicom dictionary")
	ErrWrongNumberSize = errors.New("Not a valid byte size for readNumber")
	ErrBrokenFile = errors.New("Invalid DICOM file")
)

const (
	magic_word = "DICM"
)

// Parse a byte array, returns a DICOM file struct
func Parse(buff []byte) (*DicomFile, error) {
	buffer := bytes.NewBuffer(buff)

	buffer.Next(128) // skip preamble

	// check for magic word
	if magicWord := string(buffer.Next(4)); magicWord != magic_word {
		return nil, ErrBrokenFile
	}

	file := &DicomFile{}

	// (0002,0000) MetaElementGroupLength
	metaElem := readDataElement(buffer, false)
	metaLength := int(metaElem.Value.(uint32))
	file.appendDataElement(metaElem)

	// Read meta tags
	start := buffer.Len()
	for start-buffer.Len() < metaLength {
		elem := readDataElement(buffer, false)
		file.appendDataElement(elem)
	}

	startedPixelData := false

	// Start with image meta data
	for buffer.Len() != 0 {

		elem := readDataElement(buffer, false)
		name := elem.Name
		file.appendDataElement(elem)

		if startedPixelData == true {

			// TODO: refactor this in separate function
			if name == "Item" {
				if len(elem.Value.([]byte)) == 4 {
					break // Skip Basic Offset Table
				} else {
					// TODO: concat multiple pixel data images
					elem.Value = "..."
				}
			} else if name == "SequenceDelimitationItem" {
				startedPixelData = false
			} else {
				panic(ErrIllegalTag)
			}
		}

		if name == "PixelData" {
			startedPixelData = true
			file.PixelBuffer = elem.Value.([]uint16)
			elem.Value = "..."
		}

	}

	return file, nil
}

// Append a dataElement to the DicomFile
func (file *DicomFile) appendDataElement(elem *DicomElement) {
	file.Elements = append(file.Elements, *elem)
}

// Lookup a tag by name
func (file *DicomFile) LookupElement(name string) (*DicomElement, error) {

	for _, elem := range file.Elements {
		if elem.Name == name {
			return &elem, nil
		}
	}

	return nil, ErrTagNotFound
}
<|endoftext|>


<commit_before>package gapi

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"

	"github.com/grafana/grafana/pkg/api/dtos"
)

func (c *Client) CreateUserForm(settings dtos.AdminCreateUserForm) error {
	data, err := json.Marshal(settings)
	req, err := c.newRequest("POST", "/api/admin/users", bytes.NewBuffer(data))
	if err != nil {
		return err
	}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	data, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return errors.New(resp.Status)
	}
	return err
}

func (c *Client) DeleteUser(id int64) error {
	req, err := c.newRequest("DELETE", fmt.Sprintf("/api/admin/users/%d", id), nil)
	if err != nil {
		return err
	}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return errors.New(resp.Status)
	}
	return err
}
<commit_msg>Add generic method to create a new user<commit_after>package gapi

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"

	"github.com/grafana/grafana/pkg/api/dtos"
)

func (c *Client) CreateUserForm(settings dtos.AdminCreateUserForm) error {
	data, err := json.Marshal(settings)
	req, err := c.newRequest("POST", "/api/admin/users", bytes.NewBuffer(data))
	if err != nil {
		return err
	}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	data, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return errors.New(resp.Status)
	}
	return err
}

func (c *Client) CreateUser(email, login, name, password string) error {
	return c.CreateUserForm(dtos.AdminCreateUserForm{email, login, name, password})
}

func (c *Client) DeleteUser(id int64) error {
	req, err := c.newRequest("DELETE", fmt.Sprintf("/api/admin/users/%d", id), nil)
	if err != nil {
		return err
	}
	resp, err := c.Do(req)
	if err != nil {
		return err
	}
	if resp.StatusCode != 200 {
		return errors.New(resp.Status)
	}
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/hawx/persona"
	"github.com/hawx/riviera-admin/actions"
	"github.com/hawx/riviera-admin/views"
	"github.com/hawx/serve"

	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
)

const HELP = `Usage: riviera-admin [options]

  An admin panel for riviera

    --port <num>        # Port to bind to (default: 8081)
    --socket <path>     # Serve using a unix socket instead
    --riviera <url>     # Url to riviera (default: http://localhost:8080/)

    --audience <host>   # Host and port site is running under (default: http://localhost:8081)
    --user <email>      # User who can access the admin panel
    --secret <str>      # String to use as cookie secret
    --path-prefix <p>   # Path prefix serving on

    --help              # Display help message
`

var (
	port       = flag.String("port", "8081", "")
	socket     = flag.String("socket", "", "")
	riviera    = flag.String("riviera", "http://localhost:8080/", "")
	audience   = flag.String("audience", "http://localhost:8081", "")
	user       = flag.String("user", "", "")
	secret     = flag.String("secret", "some-secret", "")
	pathPrefix = flag.String("path-prefix", "", "")
	help       = flag.Bool("help", false, "")
)

var Login = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "text/html")
	views.Login.Execute(w, struct{
		PathPrefix string
	}{*pathPrefix})
})

var List = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(*riviera + "-/list")
	if err != nil {
		log.Print("list", err)
		w.WriteHeader(500)
		return
	}

	var list []string
	json.NewDecoder(resp.Body).Decode(&list)

	w.Header().Add("Content-Type", "text/html")

	views.Index.Execute(w, struct {
		Url string
		PathPrefix string
		Feeds []string
	}{*audience, *pathPrefix, list})
})

var Subscribe = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	url := r.FormValue("url")

	err := actions.Subscribe(*riviera, url)
	if err != nil {
		log.Println("subscribe:", err)
		w.WriteHeader(500)
		return
	}

	if r.FormValue("redirect") == "origin" {
		http.Redirect(w, r, url, 301)
		return
	}

	http.Redirect(w, r, "/", 301)
})

var Unsubscribe = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	err := actions.Unsubscribe(*riviera, r.FormValue("url"))
	if err != nil {
		log.Println(err)
		return
	}

	http.Redirect(w, r, "/", 301)
})

func main() {
	flag.Parse()

	if *help {
		fmt.Println(HELP)
		return
	}

	store := persona.NewStore(*secret)
	persona := persona.New(store, *audience, []string{*user})

	r := mux.NewRouter()

	r.Methods("GET").Path("/").Handler(persona.Switch(List, Login))
	r.Methods("GET").Path("/subscribe").Handler(persona.Protect(Subscribe))
	r.Methods("GET").Path("/unsubscribe").Handler(persona.Protect(Unsubscribe))
	r.Methods("POST").Path("/sign-in").Handler(persona.SignIn)
	r.Methods("GET").Path("/sign-out").Handler(persona.SignOut)

	http.Handle("/", r)

	serve.Serve(*port, *socket, context.ClearHandler(http.DefaultServeMux))
}
<commit_msg>log method+path<commit_after>package main

import (
	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/hawx/persona"
	"github.com/hawx/riviera-admin/actions"
	"github.com/hawx/riviera-admin/views"
	"github.com/hawx/serve"

	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
)

const HELP = `Usage: riviera-admin [options]

  An admin panel for riviera

    --port <num>        # Port to bind to (default: 8081)
    --socket <path>     # Serve using a unix socket instead
    --riviera <url>     # Url to riviera (default: http://localhost:8080/)

    --audience <host>   # Host and port site is running under (default: http://localhost:8081)
    --user <email>      # User who can access the admin panel
    --secret <str>      # String to use as cookie secret
    --path-prefix <p>   # Path prefix serving on

    --help              # Display help message
`

var (
	port       = flag.String("port", "8081", "")
	socket     = flag.String("socket", "", "")
	riviera    = flag.String("riviera", "http://localhost:8080/", "")
	audience   = flag.String("audience", "http://localhost:8081", "")
	user       = flag.String("user", "", "")
	secret     = flag.String("secret", "some-secret", "")
	pathPrefix = flag.String("path-prefix", "", "")
	help       = flag.Bool("help", false, "")
)

func Log(handler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s %s", r.Method, r.URL)
		handler.ServeHTTP(w, r)
	})
}

var Login = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "text/html")
	views.Login.Execute(w, struct{
		PathPrefix string
	}{*pathPrefix})
})

var List = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(*riviera + "-/list")
	if err != nil {
		log.Print("list", err)
		w.WriteHeader(500)
		return
	}

	var list []string
	json.NewDecoder(resp.Body).Decode(&list)

	w.Header().Add("Content-Type", "text/html")

	views.Index.Execute(w, struct {
		Url string
		PathPrefix string
		Feeds []string
	}{*audience, *pathPrefix, list})
})

var Subscribe = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	url := r.FormValue("url")

	err := actions.Subscribe(*riviera, url)
	if err != nil {
		log.Println("subscribe:", err)
		w.WriteHeader(500)
		return
	}

	if r.FormValue("redirect") == "origin" {
		http.Redirect(w, r, url, 301)
		return
	}

	http.Redirect(w, r, "/", 301)
})

var Unsubscribe = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	err := actions.Unsubscribe(*riviera, r.FormValue("url"))
	if err != nil {
		log.Println(err)
		return
	}

	http.Redirect(w, r, "/", 301)
})

func main() {
	flag.Parse()

	if *help {
		fmt.Println(HELP)
		return
	}

	store := persona.NewStore(*secret)
	persona := persona.New(store, *audience, []string{*user})

	r := mux.NewRouter()

	r.Methods("GET").Path("/").Handler(persona.Switch(List, Login))
	r.Methods("GET").Path("/subscribe").Handler(persona.Protect(Subscribe))
	r.Methods("GET").Path("/unsubscribe").Handler(persona.Protect(Unsubscribe))
	r.Methods("POST").Path("/sign-in").Handler(persona.SignIn)
	r.Methods("GET").Path("/sign-out").Handler(persona.SignOut)

	http.Handle("/", r)

	serve.Serve(*port, *socket, context.ClearHandler(Log(http.DefaultServeMux)))
}
<|endoftext|>