Beispiel #1
0
func TestModifyResources(t *testing.T) {
	assert := assert.New(t)
	version := "1.2.3-test"

	pair := baseDeployablePair()

	pair.Prior.Deployment.SourceID.Version = semv.MustParse(version)
	pair.Prior.Deployment.Resources["memory"] = "100"

	pair.Post.Deployment.SourceID.Version = semv.MustParse(version)
	pair.Post.Deployment.Resources["memory"] = "500"
	pair.Post.BuildArtifact.Name = "1.2.3"

	mods := make(chan *sous.DeployablePair, 1)
	errs := make(chan error, 10)

	client := sous.NewDummyRectificationClient()
	deployer := NewDeployer(client)

	mods <- pair
	close(mods)
	deployer.RectifyModifies(mods, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	assert.Len(client.Created, 0)

	if assert.Len(client.Deployed, 1) {
		assert.Regexp("1.2.3", client.Deployed[0].ImageName)
		assert.Regexp("500", client.Deployed[0].Res["memory"])
	}
}
Beispiel #2
0
func TestModifyImage(t *testing.T) {
	assert := assert.New(t)
	sous.Log.Warn.SetOutput(os.Stderr)
	Log.Debug.SetOutput(os.Stderr)

	before := "1.2.3-test"
	after := "2.3.4-new"
	pair := baseDeployablePair()
	pair.Prior.Deployment.SourceID.Version = semv.MustParse(before)
	pair.Post.Deployment.SourceID.Version = semv.MustParse(after)
	pair.Post.BuildArtifact.Name = "2.3.4"

	mods := make(chan *sous.DeployablePair, 1)
	errs := make(chan error, 10)

	client := sous.NewDummyRectificationClient()
	deployer := NewDeployer(client)

	mods <- pair
	close(mods)
	deployer.RectifyModifies(mods, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	assert.Len(client.Created, 0)

	if assert.Len(client.Deployed, 1) {
		assert.Regexp("2.3.4", client.Deployed[0].ImageName)
	}
}
Beispiel #3
0
func TestModifyScale(t *testing.T) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	assert := assert.New(t)
	mods := make(chan *sous.DeployablePair, 1)
	errs := make(chan error, 10)

	pair := baseDeployablePair()
	pair.Prior.Deployment.DeployConfig.NumInstances = 12
	pair.Post.Deployment.DeployConfig.NumInstances = 24

	client := sous.NewDummyRectificationClient()

	deployer := NewDeployer(client)

	mods <- pair
	close(mods)
	deployer.RectifyModifies(mods, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	assert.Len(client.Deployed, 0)
	if assert.Len(client.Created, 1) {
		assert.Equal(24, client.Created[0].Count)
	}
}
Beispiel #4
0
func TestValidateRepairResources(t *testing.T) {
	empty := make(Resources)

	flaws := empty.Validate()
	assert.Len(t, flaws, 3)

	flaws, es := RepairAll(flaws)
	assert.Len(t, flaws, 0)
	assert.Len(t, es, 0)
	assert.Equal(t, empty["cpus"], "0.1")
	assert.Equal(t, empty["memory"], "100")
	assert.Equal(t, empty["ports"], "1")
}
Beispiel #5
0
func TestCreates(t *testing.T) {
	assert := assert.New(t)

	created := &sous.Deployable{
		BuildArtifact: &sous.BuildArtifact{
			Type: "docker",
			Name: "reqid,0.0.0",
		},
		Deployment: &sous.Deployment{
			SourceID: sous.SourceID{
				Location: sous.SourceLocation{
					Repo: "reqid",
				},
			},
			DeployConfig: sous.DeployConfig{
				NumInstances: 12,
			},
			Cluster:     &sous.Cluster{BaseURL: "cluster"},
			ClusterName: "nick",
		},
	}

	crts := make(chan *sous.Deployable, 1)
	errs := make(chan error, 10)

	client := sous.NewDummyRectificationClient()
	deployer := NewDeployer(client)

	crts <- created
	close(crts)
	deployer.RectifyCreates(crts, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	if assert.Len(client.Deployed, 1) {
		dep := client.Deployed[0]
		assert.Equal("cluster", dep.Cluster)
		assert.Equal("reqid,0.0.0", dep.ImageName)
	}

	if assert.Len(client.Created, 1) {
		req := client.Created[0]
		assert.Equal("cluster", req.Cluster)
		assert.Equal("reqid::nick", req.ID)
		assert.Equal(12, req.Count)
	}
}
Beispiel #6
0
func TestDeletes(t *testing.T) {
	assert := assert.New(t)

	deleted := &sous.Deployable{
		Deployment: &sous.Deployment{
			SourceID: sous.SourceID{
				Location: sous.SourceLocation{
					Repo: "reqid",
				},
			},
			DeployConfig: sous.DeployConfig{
				NumInstances: 12,
			},
			ClusterName: "",
			Cluster: &sous.Cluster{
				BaseURL: "cluster",
			},
		},
	}

	dels := make(chan *sous.Deployable, 1)
	errs := make(chan error, 10)

	client := sous.NewDummyRectificationClient()
	deployer := NewDeployer(client)

	dels <- deleted
	close(dels)
	deployer.RectifyDeletes(dels, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	assert.Len(client.Deployed, 0)
	assert.Len(client.Created, 0)

	// We no longer expect any deletions; See deployer.RectifySingleDelete.
	//expectedDeletions := 1
	expectedDeletions := 0

	if assert.Len(client.Deleted, expectedDeletions) {
		// We no longer expect any deletions; See deployer.RectifySingleDelete.
		//req := client.Deleted[0]
		//assert.Equal("cluster", req.Cluster)
		//assert.Equal("reqid::", req.Reqid)
	}
}
Beispiel #7
0
func TestRealDiff(t *testing.T) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	assert := assert.New(t)

	intended := NewDeployments()
	existing := NewDeployments()

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

	intended.MustAdd(makeDepl(repoOne, 1)) //remove

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

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

	existing.MustAdd(makeDepl(repoFour, 1)) //create

	dc := intended.Diff(existing)
	ds := dc.collect()

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

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

	if assert.Len(ds.Changed, 1, "Should have one modified item.") {
		assert.Equal(repoThree, string(ds.Changed[0].name.ManifestID.Source.Repo))
		assert.Equal(repoThree, string(ds.Changed[0].Prior.SourceID.Location.Repo))
		assert.Equal(repoThree, string(ds.Changed[0].Post.SourceID.Location.Repo))
		assert.Equal(ds.Changed[0].Post.NumInstances, 1)
		assert.Equal(ds.Changed[0].Prior.NumInstances, 2)
	}

	if assert.Equal(ds.New.Len(), 1, "Should have one added item.") {
		it, _ := ds.New.Any(func(*Deployment) bool { return true })
		assert.Equal(string(it.SourceID.Location.Repo), repoFour)
	}
}
Beispiel #8
0
func TestBuildDeployment(t *testing.T) {
	assert := assert.New(t)
	m := &Manifest{
		Source: SourceLocation{},
		Owners: []string{"*****@*****.**"},
		Kind:   ManifestKindService,
	}
	sp := DeploySpec{
		DeployConfig: DeployConfig{
			Resources:    Resources{},
			Args:         []string{},
			Env:          Env{},
			NumInstances: 3,
			Volumes: Volumes{
				&Volume{"h", "c", "RO"},
			},
		},
		Version:     semv.MustParse("1.2.3"),
		clusterName: "cluster.name",
	}
	var ih []DeploySpec
	nick := "cn"

	state := &State{Defs: Defs{Clusters: Clusters{nick: &Cluster{BaseURL: "http://not"}}}}

	d, err := BuildDeployment(state, m, nick, sp, ih)

	if assert.NoError(err) {
		if assert.Len(d.DeployConfig.Volumes, 1) {
			assert.Equal("c", d.DeployConfig.Volumes[0].Container)
		}
		assert.Equal(nick, d.ClusterName)
	}
}
Beispiel #9
0
func TestInvokeHarvest(t *testing.T) {
	assert := assert.New(t)

	exe := justCommand(t, []string{`sous`, `harvest`, `sms-continual-test`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 1)
}
Beispiel #10
0
/*
usage: sous config Invoking sous config with no arguments lists all configuration key/value pairs.
If you pass just a single argument (a key) sous config will output just the
value of that key. You can set a key by providing both a key and a value.

usage: sous config [<key> [value]]

*/
func TestInvokeConfig(t *testing.T) {
	assert := assert.New(t)

	exe := justCommand(t, []string{`sous`, `config`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 0)

	exe = justCommand(t, []string{`sous`, `config`, `x`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 1)

	exe = justCommand(t, []string{`sous`, `config`, `x`, `7`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 2)

}
Beispiel #11
0
func TestInvokeUpdate(t *testing.T) {
	assert := assert.New(t)

	exe := justCommand(t, []string{`sous`, `update`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 0)
}
Beispiel #12
0
func TestProductionReady(t *testing.T) {
	assert := assert.New(t)

	bc := BuildConfig{
		Strict:   true,
		Tag:      "1.2.3",
		Repo:     "github.com/opentable/present",
		Revision: "abcdef",
		Context: &BuildContext{
			Sh: &shell.Sh{},
			Source: SourceContext{
				RemoteURL: "github.com/opentable/present",
				RemoteURLs: []string{
					"github.com/opentable/present",
					"github.com/opentable/also",
				},
				Revision:           "abcdef",
				NearestTagName:     "1.2.3",
				NearestTagRevision: "abcdef",
				Tags: []Tag{
					Tag{Name: "1.2.3"},
				},
			},
		},
	}

	ctx := bc.NewContext()
	assert.Len(ctx.Advisories, 0)
	assert.NoError(bc.GuardStrict(ctx))
}
Beispiel #13
0
/*
usage: sous context

context prints out sous's view of your current context
*/
func TestInvokeContext(t *testing.T) {
	assert := assert.New(t)

	exe := justCommand(t, []string{`sous`, `context`})
	assert.NotNil(exe)
	assert.Len(exe.Args, 0)
}
Beispiel #14
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)
}
Beispiel #15
0
func TestValidateRepair(t *testing.T) {
	dc := DeployConfig{
		Volumes:   Volumes{nil, &Volume{}},
		Resources: make(Resources),
	}
	dc.Resources["cpus"] = "0.25"
	dc.Resources["memory"] = "356"
	dc.Resources["ports"] = "2"

	assert.Len(t, dc.Volumes, 2)
	flaws := dc.Validate()
	assert.Len(t, flaws, 1)
	fs, es := RepairAll(flaws)
	assert.Len(t, fs, 0)
	assert.Len(t, es, 0)
	assert.Len(t, dc.Volumes, 1)
}
Beispiel #16
0
func TestModify(t *testing.T) {
	Log.Debug.SetOutput(os.Stderr)
	defer Log.Debug.SetOutput(ioutil.Discard)
	assert := assert.New(t)
	before := "1.2.3-test"
	after := "2.3.4-new"

	pair := baseDeployablePair()

	pair.Prior.Deployment.SourceID.Version = semv.MustParse(before)
	pair.Prior.Deployment.DeployConfig.NumInstances = 1
	pair.Prior.Deployment.DeployConfig.Volumes = sous.Volumes{{"host", "container", "RO"}}

	pair.Post.Deployment.SourceID.Version = semv.MustParse(after)
	pair.Post.Deployment.DeployConfig.NumInstances = 24
	pair.Post.Deployment.DeployConfig.Volumes = sous.Volumes{{"host", "container", "RW"}}
	pair.Post.BuildArtifact.Name = "2.3.4"

	mods := make(chan *sous.DeployablePair, 1)
	errs := make(chan error, 10)

	client := sous.NewDummyRectificationClient()
	deployer := NewDeployer(client)

	mods <- pair
	close(mods)
	deployer.RectifyModifies(mods, errs)
	close(errs)

	for e := range errs {
		t.Error(e)
	}

	if assert.Len(client.Created, 1) {
		assert.Equal(24, client.Created[0].Count)
	}

	if assert.Len(client.Deployed, 1) {
		assert.Regexp("2.3.4", client.Deployed[0].ImageName)
		log.Print(client.Deployed[0].Vols)
		assert.Equal("RW", string(client.Deployed[0].Vols[0].Mode))
	}

}
Beispiel #17
0
func TestOwnerSet(t *testing.T) {
	set := NewOwnerSet("one")
	set.Add("two")
	set.Add("one")
	slice := set.Slice()
	assert.Len(t, slice, 2)
	assert.Contains(t, slice, "one")
	assert.Contains(t, slice, "two")
	assert.True(t, set.Equal(NewOwnerSet("two", "one")))
}
Beispiel #18
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")

}
Beispiel #19
0
func TestHandlesGDMGet(t *testing.T) {
	assert := assert.New(t)

	th := &GDMHandler{graph.CurrentGDM{
		Deployments: sous.NewDeployments(),
	}}
	data, status := th.Exchange()
	assert.Equal(status, 200)
	assert.Len(data.(gdmWrapper).Deployments, 0)

}
Beispiel #20
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`)
}
Beispiel #21
0
func TestReharvest(t *testing.T) {
	assert := assert.New(t)

	dc := docker_registry.NewDummyClient()
	_, err := dc.GetImageMetadata("", "")
	assert.Error(err) //because channel starved

	host := "docker.repo.io"
	base := "ot/wackadoo"

	nc := NewNameCache(host, dc, inMemoryDB("reharvest"))

	vstr := "1.2.3"
	sv := sous.MustNewSourceID("https://github.com/opentable/wackadoo", "nested/there", vstr)
	in := base + ":version-" + vstr
	digest := "sha256:012345678901234567890123456789AB012345678901234567890123456789AB"
	cn := base + "@" + digest

	dc.FeedMetadata(docker_registry.Metadata{
		Registry:      host,
		Labels:        Labels(sv),
		Etag:          digest,
		CanonicalName: cn,
		AllNames:      []string{cn, in},
	})
	gotSV, err := nc.GetSourceID(NewBuildArtifact(host+"/"+in, nil)) // XXX Really prefix with host?
	if assert.Nil(err) {
		assert.Equal(gotSV, sv)
	}
	nc.dump(os.Stderr)

	nc.DB.Exec("update _database_metadata_ set value='' where name='fingerprint'")

	dc.FeedTags([]string{"version" + vstr})
	dc.FeedMetadata(docker_registry.Metadata{
		Registry:      host,
		Labels:        Labels(sv),
		Etag:          digest,
		CanonicalName: cn,
		AllNames:      []string{cn, in},
	})
	nc.dump(os.Stderr)
	Log.Debug.SetOutput(os.Stderr)
	Log.Vomit.SetOutput(os.Stderr)
	err = nc.GroomDatabase()
	assert.NoError(err)
	nc.dump(os.Stderr)

	_, err = dc.GetImageMetadata("", "")
	assert.Error(err) //because channel starved
	list, _ := dc.AllTags("")
	assert.Len(list, 0) //because channel starved
}
Beispiel #22
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)
}
Beispiel #23
0
/*
usage: sous build [path]

build builds the project in your current directory by default. If you pass it a
path, it will instead build the project at that path.

options:
  -offset string
    	source code relative repository offset
  -repo string
    	source code repository location
  -revision string
    	source code revision ID
  -strict
    	require that the build be pristine
  -tag string
    	source code revision tag

*/
func TestInvokeBuildWithRepoSelector(t *testing.T) {
	assert := assert.New(t)

	_, exe, _, _ := prepareCommand(t, []string{`sous`, `build`, `-repo`, `github.com/opentable/sous`})
	assert.Len(exe.Args, 0)

	build := exe.Cmd.(*SousBuild)

	assert.NotNil(build.Labeller)
	assert.NotNil(build.Registrar)
	assert.Equal(build.DeployFilterFlags.Repo, `github.com/opentable/sous`)

}
Beispiel #24
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)
}
Beispiel #25
0
func TestParseTags(t *testing.T) {
	assert := assert.New(t)

	lines := []string{
		"2f381f35ffcf57b21b4c2991635f7f825c29f003 2016-08-02T11:16:04-04:00 HEAD -> master, tag: 0.2.0, origin/master, origin/HEAD",
		"0a271b999974db8f37326e16c9027436098b251f 2016-08-01T10:54:53-04:00 tag: 0.1.6",
		"a83cebbdb1e06bc325f88d953120ac60dead7268 2016-07-26T15:32:24-04:00 tag: 0.1.5",
		"65017e8bcbeaf10d48ea677113a3d5d99ed03c45 2016-07-12T14:23:03-04:00 tag: 0.1.4",
		"6013d74276ac6a62f8fec3aee7c06162496b25a5 2016-07-12T13:14:52-04:00 tag: 0.1.3",
		"b779b60a13f0a3b8edbecf81b0b24b252202b3a2 2016-07-11T16:00:14-04:00 tag: 0.1.2",
		"612eec227ccdcdbe9d182ce830adb566930ca0c0 2016-07-07T14:41:18-04:00 2f381f35ffcf57b21b4c2991635f7f825c29f003",
	}

	tags := (&Client{}).parseTags(lines)
	assert.Len(tags, 6)
	assert.Contains(tags, sous.Tag{Name: "0.2.0", Revision: "2f381f35ffcf57b21b4c2991635f7f825c29f003"})
}
Beispiel #26
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())
}
Beispiel #27
0
func TestClusterMap(t *testing.T) {
	assert := assert.New(t)

	s := State{
		Defs: Defs{
			Clusters: Clusters{
				"one": &Cluster{},
				"two": &Cluster{},
			},
		},
	}

	m := s.ClusterMap()
	assert.Len(m, 2)
	assert.Contains(m, "one")
	assert.Contains(m, "two")
}
Beispiel #28
0
func TestHarvestGuessedRepo(t *testing.T) {
	assert := assert.New(t)

	dc := docker_registry.NewDummyClient()

	host := "docker.repo.io"
	nc := NewNameCache(host, dc, inMemoryDB("guessed_repo"))

	sl := sous.SourceLocation{
		Repo: "https://github.com/opentable/wackadoo",
		Dir:  "nested/there",
	}

	dc.FeedTags([]string{"something", "the other"})
	nc.harvest(sl)

	remainingTags, err := dc.AllTags("")
	assert.NoError(err)
	assert.Len(remainingTags, 0) // because all consumed by harvest
}
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)
}
func TestBuildDeployments(t *testing.T) {

	t.Skipf("Failing test on master preventing progress on other stories.")

	assert := assert.New(t)
	sous.Log.Debug.SetOutput(os.Stdout)

	ResetSingularity()
	defer ResetSingularity()

	drc := docker_registry.NewClient()
	drc.BecomeFoolishlyTrusting()

	db, err := docker.GetDatabase(&docker.DBConfig{
		Driver:     "sqlite3_sous",
		Connection: docker.InMemoryConnection("testresolve"),
	})
	if err != nil {
		panic(err)
	}

	appLocation := "testhelloreq"
	clusterNick := "tcluster"
	reqID := appLocation + clusterNick

	nc := docker.NewNameCache("", drc, db)

	singCl := sing.NewClient(SingularityURL)
	//singCl.Debug = true

	sr, err := singReqDep(
		SingularityURL,
		whitespace.CleanWS(`
		{
			"instances": 1,
			"id": "`+reqID+`",
			"requestType": "SERVICE",
			"owners": ["*****@*****.**", "*****@*****.**"]
		}`),
		whitespace.CleanWS(`
		{
			"deploy": {
				"id": "`+singularity.MakeDeployID(uuid.NewV4().String())+`",
				"requestId": "`+reqID+`",
				"resources": {
					"cpus": 0.1,
					"memoryMb": 32,
					"numPorts": 1
				},
				"containerInfo": {
					"type": "DOCKER",
					"docker": {
						"image": "`+BuildImageName("hello-server-labels", "latest")+`"
					},
					"volumes": [{"hostPath":"/tmp", "containerPath":"/tmp","mode":"RO"}]
				},
				"env": {
					"TEST": "yes"
				}
			}
		}`),
	)

	req := singularity.SingReq{
		SourceURL: SingularityURL,
		Sing:      singCl,
		ReqParent: sr,
	}

	if assert.NoError(err) {
		clusters := sous.Clusters{clusterNick: {BaseURL: SingularityURL}}
		dep, err := singularity.BuildDeployment(nc, clusters, req)

		if assert.NoError(err) {
			if assert.Len(dep.DeployConfig.Volumes, 1) {
				assert.Equal(dep.DeployConfig.Volumes[0].Host, "/tmp")
			}
			assert.Equal("github.com/docker/dockercloud-hello-world", dep.SourceID.Location.Repo)
		}
	}
}