Пример #1
0
func TestInvokeRectifyDryruns(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	testDryRun := func(which string) (sous.Deployer, sous.Registry) {
		exe := justCommand(t, []string{`sous`, `rectify`, `-dry-run`, which, `-repo`, `github.com/somewhere`})
		assert.Len(exe.Args, 0)
		require.IsType(&SousRectify{}, exe.Cmd)
		rect := exe.Cmd.(*SousRectify)
		// currently no easy way to tell if the deploy client is live or dummy
		return nil, rect.Resolver.Registry
	}

	_, r := testDryRun("both")
	assert.IsType(&sous.DummyRegistry{}, r)

	_, r = testDryRun("none")
	assert.IsType(&docker.NameCache{}, r)

	_, r = testDryRun("scheduler")
	assert.IsType(&docker.NameCache{}, r)

	_, r = testDryRun("registry")
	assert.IsType(&sous.DummyRegistry{}, r)
}
Пример #2
0
func TestInvokeManifestSet(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)
	exe := justCommand(t, []string{`sous`, `manifest`, `set`, `-repo`, `github.com/opentable/sous`})
	assert.NotNil(exe)
	maniSet, good := exe.Cmd.(*SousManifestSet)
	require.True(good)
	assert.NotNil(maniSet.StateWriter)
}
Пример #3
0
func TestInvokeMetadataSet(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)
	exe := justCommand(t, []string{`sous`, `metadata`, `set`, `-repo`, `github.com/opentable/sous`, `BuildBranch`, `master`})
	assert.NotNil(exe)
	metaSet, good := exe.Cmd.(*SousMetadataSet)
	require.True(good)
	assert.NotNil(metaSet.State)
}
Пример #4
0
func TestInvokeDeploy(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	exe := justCommand(t, []string{`sous`, `deploy`, `-cluster`, `ci-sf`, `-tag`, `1.2.3`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 0)
	deploy, good := exe.Cmd.(*SousDeploy)
	require.True(good)
	assert.Equal(deploy.DeployFilterFlags.Cluster, `ci-sf`)
	assert.Equal(deploy.DeployFilterFlags.Tag, `1.2.3`)
}
Пример #5
0
func TestGitReadState(t *testing.T) {
	require := require.New(t)

	gsm := NewGitStateManager(NewDiskStateManager("testdata/in"))

	actual, err := gsm.ReadState()
	require.NoError(err)

	expected := exampleState()

	sameYAML(t, actual, expected)
}
Пример #6
0
/*
usage: sous <command>

sous is a tool to help speed up the build/test/deploy cycle at your organisation

subcommands:
  build    build your project
  config   view and edit sous configuration
  context  show the current build context
  deploy   initialise a new sous project
  help     get help with sous
  init     initialise a new sous project
  query    build your project
  rectify  force Sous to make the deployment match the contents of the local state directory
  version  print the version of sous

options:
  -d	debug: output detailed logs of internal operations
  -q	quiet: output only essential error messages
  -s	silent: silence all non-essential output
  -v	loud: output extra info, including all shell commands
*/
func TestInvokeBareSous(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	log.SetFlags(log.Flags() | log.Lshortfile)
	c, exe, _, _ := prepareCommand(t, []string{`sous`})
	assert.Len(exe.Args, 0)

	var r cmdr.Result
	c.InvokeWithoutPrinting([]string{"sous", "help"})
	require.NotPanics(func() { r = c.InvokeWithoutPrinting([]string{"sous", "help"}) })
	assert.IsType(cmdr.SuccessResult{}, r)
}
Пример #7
0
func TestHandlesManifestGetNotKnown(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	q, err := url.ParseQuery("repo=gh")
	require.NoError(err)

	th := &GETManifestHandler{
		State:       sous.NewState(),
		QueryValues: &QueryValues{q},
	}
	_, status := th.Exchange()
	assert.Equal(404, status)
}
Пример #8
0
func TestBuildDeployRequest(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	di := "dockerImage"
	rID := "reqID"
	env := sous.Env{"test": "yes"}
	rez := sous.Resources{"cpus": "0.1"}
	vols := sous.Volumes{&sous.Volume{}}

	dr, err := buildDeployRequest(di, env, rez, rID, vols)
	require.NoError(err)
	assert.NotNil(dr)
	assert.Equal(dr.Deploy.RequestId, rID)
}
Пример #9
0
func TestInvokeWithUnknownFlags(t *testing.T) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	assert := assert.New(t)
	require := require.New(t)

	stdin := &bytes.Buffer{}
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}

	s := &Sous{Version: semv.MustParse(`1.2.3`)}
	c, err := NewSousCLI(s, stdin, stdout, stderr)
	require.NoError(err)

	c.Invoke([]string{`sous`, `-cobblers`})
	assert.Regexp(`flag provided but not defined`, stderr.String())
}
Пример #10
0
func prepareCommand(t *testing.T, cl []string) (*CLI, *cmdr.PreparedExecution, fmt.Stringer, fmt.Stringer) {
	require := require.New(t)

	stdin := &bytes.Buffer{}
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}

	s := &Sous{Version: semv.MustParse(`1.2.3`)}
	c, err := NewSousCLI(s, stdin, stdout, stderr)
	require.NoError(err)

	exe, err := c.Prepare(cl)
	require.NoError(err)

	return c, exe, stdout, stderr
}
Пример #11
0
func TestInvokeRectifyWithoutFilterFlags(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	_, exe, _, _ := prepareCommand(t, []string{`sous`, `rectify`})
	assert.Len(exe.Args, 0)
	require.IsType(&SousRectify{}, exe.Cmd)

	rect := exe.Cmd.(*SousRectify)

	assert.NotNil(rect.Config)
	assert.NotNil(rect.GDM)
	require.NotNil(rect.SourceFlags)
	assert.Equal(rect.SourceFlags.All, false)
	require.NotNil(rect.Resolver.ResolveFilter)
	assert.Equal(rect.Resolver.ResolveFilter.All(), true)
}
Пример #12
0
func TestGitPushes(t *testing.T) {
	require := require.New(t)
	gsm, dsm := setupManagers(t)

	expected, err := gsm.ReadState()
	require.NoError(err)

	expected.Manifests.Add(&sous.Manifest{Source: sous.SourceLocation{Repo: "github.com/opentable/brandnew"}})
	require.NoError(gsm.WriteState(expected))
	expected, err = gsm.ReadState()
	require.NoError(err)

	runScript(t, `git reset --hard`, `testdata/origin`) //in order to reflect the change
	actual, err := dsm.ReadState()
	require.NoError(err)
	sameYAML(t, actual, expected)
}
Пример #13
0
func TestHandlesManifestGet(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	q, err := url.ParseQuery("repo=gh")
	require.NoError(err)
	state := sous.NewState()
	state.Manifests.Add(&sous.Manifest{Source: sous.SourceLocation{Repo: "gh"}})

	th := &GETManifestHandler{
		State:       state,
		QueryValues: &QueryValues{q},
	}
	_, status := th.Exchange()
	assert.Equal(status, 200)

}
Пример #14
0
func TestInvokeRectifyWithDebugFlags(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	_, exe, _, stderr := prepareCommand(t, []string{`sous`, `rectify`, `-d`, `-v`, `-all`})
	assert.Len(exe.Args, 0)
	require.IsType(&SousRectify{}, exe.Cmd)

	rect := exe.Cmd.(*SousRectify)

	assert.NotNil(rect.Config)
	assert.NotNil(rect.GDM)
	require.NotNil(rect.SourceFlags)
	assert.Equal(rect.SourceFlags.All, true)
	assert.Regexp(`Verbose debugging`, stderr.String())
	assert.Regexp(`Regular debugging`, stderr.String())
}
Пример #15
0
func TestHandlesManifestPut(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)

	q, err := url.ParseQuery("repo=gh")
	require.NoError(err)
	state := sous.NewState()
	state.Manifests.Add(&sous.Manifest{
		Source: sous.SourceLocation{Repo: "gh"},
		Kind:   sous.ManifestKindService,
	})
	writer := graph.StateWriter{StateWriter: &sous.DummyStateManager{State: state}}

	manifest := &sous.Manifest{
		Source: sous.SourceLocation{Repo: "gh"},
		Owners: []string{"sam", "judson"},
		Kind:   sous.ManifestKindService,
	}
	buf := &bytes.Buffer{}
	enc := json.NewEncoder(buf)
	enc.Encode(manifest)
	req, err := http.NewRequest("PUT", "", buf)
	require.NoError(err)

	th := &PUTManifestHandler{
		Request:     req,
		StateWriter: writer,
		State:       state,
		QueryValues: &QueryValues{q},
	}
	data, status := th.Exchange()
	assert.Equal(status, 200)
	require.IsType(&sous.Manifest{}, data)
	assert.Len(data.(*sous.Manifest).Owners, 2)
	assert.Equal(data.(*sous.Manifest).Owners[1], "judson")

	changed, found := state.Manifests.Get(sous.ManifestID{Source: sous.SourceLocation{Repo: "gh"}})
	require.True(found)
	assert.Len(changed.Owners, 2)
	assert.Equal(changed.Owners[1], "judson")

}
Пример #16
0
func TestGitWriteState(t *testing.T) {
	require := require.New(t)

	s := exampleState()

	if err := os.RemoveAll("testdata/out"); err != nil {
		t.Fatal(err)
	}

	gsm := NewGitStateManager(NewDiskStateManager("testdata/out"))

	require.NoError(gsm.WriteState(s))

	d := exec.Command("diff", "-r", "testdata/in", "testdata/out")
	out, err := d.CombinedOutput()
	if err != nil {
		t.Log("Output not as expected:")
		t.Log(string(out))
		t.Fatal("")
	}
}
Пример #17
0
func TestGitPulls(t *testing.T) {
	require := require.New(t)
	gsm, dsm := setupManagers(t)

	actual, err := gsm.ReadState()
	require.NoError(err)

	expected := exampleState()
	sameYAML(t, actual, expected)

	expected.Manifests.Add(&sous.Manifest{Source: sous.SourceLocation{Repo: "github.com/opentable/brandnew"}})
	dsm.WriteState(expected)
	expected, err = dsm.ReadState()
	require.NoError(err)
	runScript(t, `git add .
	git commit -m ""`, `testdata/origin`)

	actual, err = gsm.ReadState()
	require.NoError(err)
	sameYAML(t, actual, expected)
}
Пример #18
0
func sameYAML(t *testing.T, actual *sous.State, expected *sous.State) {
	assert := assert.New(t)
	require := require.New(t)

	actualManifests := actual.Manifests.Snapshot()
	expectedManifests := expected.Manifests.Snapshot()
	assert.Len(actualManifests, len(expectedManifests))
	for mid, manifest := range expectedManifests {
		actual := *actualManifests[mid]
		assert.Contains(actualManifests, mid)
		if !assert.Equal(actual, *manifest) {
			_, differences := actual.Diff(manifest)
			t.Logf("DIFFERENCES (%q): %#v", mid, differences)
		}
	}

	actualYAML, err := yaml.Marshal(actual)
	require.NoError(err)
	expectedYAML, err := yaml.Marshal(expected)
	require.NoError(err)
	assert.Equal(actualYAML, expectedYAML)
}
Пример #19
0
func TestRecordAdvisories(t *testing.T) {
	assert := assert.New(t)
	require := require.New(t)
	dc := docker_registry.NewDummyClient()
	host := "docker.repo.io"
	base := "ot/wackadoo"
	nc := NewNameCache(host, dc, inMemoryDB("advisories"))
	v := "1.2.3"
	sv := sous.MustNewSourceID("https://github.com/opentable/wackadoo", "nested/there", v)
	digest := "sha256:012345678901234567890123456789AB012345678901234567890123456789AB"
	cn := base + "@" + digest

	qs := []sous.Quality{{Name: "ephemeral_tag", Kind: "advisory"}}

	err := nc.Insert(sv, cn, digest, qs)
	assert.NoError(err)

	arty, err := nc.GetArtifact(sv)
	assert.NoError(err)
	require.NotNil(arty)
	require.Len(arty.Qualities, 1)
	assert.Equal(arty.Qualities[0].Name, `ephemeral_tag`)
}
Пример #20
0
func TestRealDiffConcentration(t *testing.T) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	assert := assert.New(t)
	require := require.New(t)

	intended := NewDeployments()
	existing := NewDeployments()
	defs := Defs{Clusters: map[string]*Cluster{"test": &Cluster{}}}

	makeDepl := func(repo, verstr string, num int) *Deployment {
		version := semv.MustParse(verstr)
		cl := defs.Clusters["test"]
		owners := OwnerSet{}
		owners.Add("judson")
		return &Deployment{
			SourceID: SourceID{
				Location: SourceLocation{
					Repo: repo,
				},
				Version: version,
			},
			Cluster:     cl,
			ClusterName: "test",
			DeployConfig: DeployConfig{
				NumInstances: num,
				Env:          map[string]string{},
				Resources: map[string]string{
					"cpu":    ".1",
					"memory": "100",
					"ports":  "1",
				},
			},
			Owners: owners,
		}
	}

	repoOne := "github.com/opentable/one"
	repoTwo := "github.com/opentable/two"
	repoThree := "github.com/opentable/three"
	repoFour := "github.com/opentable/four"
	repoFive := "github.com/opentable/five"

	existing.MustAdd(makeDepl(repoOne, "111.1.1", 1)) //remove
	//intended: gone

	existing.MustAdd(makeDepl(repoTwo, "1.0.0", 1)) //same
	intended.MustAdd(makeDepl(repoTwo, "1.0.0", 1)) //same

	// existing: doesn't yet
	intended.MustAdd(makeDepl(repoFour, "1.0.0", 1)) //create

	existing.MustAdd(makeDepl(repoThree, "1.0.0", 1)) //changed
	intended.MustAdd(makeDepl(repoThree, "1.0.0", 2)) //changed

	existing.MustAdd(makeDepl(repoFive, "1.0.0", 1)) //changed
	intended.MustAdd(makeDepl(repoFive, "2.0.0", 1)) //changed

	dc := existing.Diff(intended).Concentrate(defs)
	ds, err := dc.collect()
	require.NoError(err)

	if assert.Len(ds.Gone.Snapshot(), 1, "Should have one deleted item.") {
		it, _ := ds.Gone.Any(func(*Manifest) bool { return true })
		assert.Equal(string(it.Source.Repo), repoOne)
	}

	if assert.Len(ds.Same.Snapshot(), 1, "Should have one unchanged item.") {
		it, _ := ds.Same.Any(func(*Manifest) bool { return true })
		assert.Equal(string(it.Source.Repo), repoTwo)
	}

	if assert.Len(ds.Changed, 2, "Should have two modified items.") {
		chNum, chVer := ds.Changed[0], ds.Changed[1]
		if repoThree == chVer.name.Source.Repo {
			chNum, chVer = chVer, chNum
		}
		assert.Equal(repoThree, string(chNum.name.Source.Repo))
		assert.Equal(repoThree, string(chNum.Prior.Source.Repo))
		assert.Equal(repoThree, string(chNum.Post.Source.Repo))
		log.Printf("%+v", chNum)
		log.Printf("%+v", chNum.Prior)
		log.Printf("%+v", chNum.Post)
		assert.Equal(chNum.Prior.Deployments["test"].NumInstances, 1)
		assert.Equal(chNum.Post.Deployments["test"].NumInstances, 2)

		assert.Equal(repoFive, string(chVer.name.Source.Repo))
		assert.Equal(repoFive, string(chVer.Prior.Source.Repo))
		assert.Equal(repoFive, string(chVer.Post.Source.Repo))
		ver1 := semv.MustParse("1.0.0")
		ver2 := semv.MustParse("2.0.0")
		assert.Equal(ver1, chVer.Prior.Deployments["test"].Version)
		assert.Equal(ver2, chVer.Post.Deployments["test"].Version)
	}

	if assert.Equal(ds.New.Len(), 1, "Should have one added item.") {
		it, _ := ds.New.Any(func(*Manifest) bool { return true })
		assert.Equal(string(it.Source.Repo), repoFour)
	}

}