Example #1
0
func (*diskStoreSuite) TestNewDisk(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(filepath.Join(dir, "foo"))
	c.Assert(err, jc.Satisfies, os.IsNotExist)
	c.Assert(store, gc.IsNil)

	store, err = configstore.NewDisk(filepath.Join(dir))
	c.Assert(err, gc.IsNil)
	c.Assert(store, gc.NotNil)
}
Example #2
0
func (*diskStoreSuite) TestRead(c *gc.C) {
	dir := c.MkDir()
	err := os.Mkdir(storePath(dir, ""), 0700)
	c.Assert(err, gc.IsNil)
	err = ioutil.WriteFile(storePath(dir, "someenv"), []byte(sampleInfo), 0666)
	c.Assert(err, gc.IsNil)
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)
	info, err := store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	c.Assert(info.Initialized(), jc.IsTrue)
	c.Assert(info.APICredentials(), gc.DeepEquals, configstore.APICredentials{
		User:     "******",
		Password: "******",
	})
	c.Assert(info.APIEndpoint(), gc.DeepEquals, configstore.APIEndpoint{
		Addresses: []string{"example.com", "kremvax.ru"},
		CACert:    "first line\nsecond line",
	})
	c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", dir+"/environments/someenv.jenv"))
	c.Assert(info.BootstrapConfig(), gc.DeepEquals, map[string]interface{}{
		"secret": "blah",
		"arble":  "bletch",
	})
}
Example #3
0
func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)
	info := store.CreateInfo("somemodel")
	endpoint := configstore.APIEndpoint{
		Addresses: []string{"this", "is", "never", "validated", "here"},
		Hostnames: []string{"neither", "is", "this"},
		ModelUUID: testing.ModelTag.Id(),
	}
	info.SetAPIEndpoint(endpoint)
	err = info.Write()
	c.Assert(err, jc.ErrorIsNil)

	newInfo, err := store.ReadInfo("somemodel")
	c.Assert(err, jc.ErrorIsNil)
	// Now change the number of addresses to be shorter.
	endpoint.Addresses = []string{"just one"}
	endpoint.Hostnames = []string{"just this"}
	newInfo.SetAPIEndpoint(endpoint)
	err = newInfo.Write()
	c.Assert(err, jc.ErrorIsNil)

	// We should be able to read in in fine.
	yaInfo, err := store.ReadInfo("somemodel")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"})
	c.Assert(yaInfo.APIEndpoint().Hostnames, gc.DeepEquals, []string{"just this"})
}
Example #4
0
func (*diskStoreSuite) TestCreate(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)

	// Create some new environment info.
	info, err := store.CreateInfo("someenv")
	c.Assert(err, gc.IsNil)
	c.Assert(info.APIEndpoint(), gc.DeepEquals, configstore.APIEndpoint{})
	c.Assert(info.APICredentials(), gc.DeepEquals, configstore.APICredentials{})
	c.Assert(info.Initialized(), jc.IsFalse)
	data, err := ioutil.ReadFile(storePath(dir, "someenv"))
	c.Assert(err, gc.IsNil)
	c.Assert(data, gc.HasLen, 0)

	// Check that we can't create it twice.
	info, err = store.CreateInfo("someenv")
	c.Assert(err, gc.Equals, configstore.ErrEnvironInfoAlreadyExists)
	c.Assert(info, gc.IsNil)

	// Check that we can read it again.
	info, err = store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	c.Assert(info.Initialized(), jc.IsFalse)
}
Example #5
0
func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)
	info := store.CreateInfo("someenv")
	endpoint := configstore.APIEndpoint{
		Addresses:   []string{"this", "is", "never", "validated", "here"},
		EnvironUUID: "90168e4c-2f10-4e9c-83c2-feedfacee5a9",
	}
	info.SetAPIEndpoint(endpoint)
	err = info.Write()
	c.Assert(err, gc.IsNil)

	newInfo, err := store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	// Now change the number of addresses to be shorter.
	endpoint.Addresses = []string{"just one"}
	newInfo.SetAPIEndpoint(endpoint)
	err = newInfo.Write()
	c.Assert(err, gc.IsNil)

	// We should be able to read in in fine.
	yaInfo, err := store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"})
}
Example #6
0
func (*diskStoreSuite) TestConcurrentAccess(c *gc.C) {
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("test-log", &tw, loggo.DEBUG), gc.IsNil)

	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	envDir := storePath(dir, "")
	lock, err := configstore.AcquireEnvironmentLock(envDir, "blocking-op")
	c.Assert(err, jc.ErrorIsNil)
	defer lock.Unlock()

	_, err = store.ReadInfo("someenv")
	c.Assert(errors.Cause(err), gc.Equals, fslock.ErrTimeout)

	// Using . between environments and env.lock so we don't have to care
	// about forward vs. backwards slash separator.
	messages := []jc.SimpleMessage{
		{loggo.WARNING, `configstore lock held, lock dir: .*environments.env\.lock`},
		{loggo.WARNING, `lock holder message: pid: \d+, operation: blocking-op`},
	}

	c.Check(tw.Log(), jc.LogMatches, messages)
}
Example #7
0
func (s *diskInterfaceSuite) SetUpTest(c *gc.C) {
	s.dir = c.MkDir()
	s.NewStore = func(c *gc.C) configstore.Storage {
		store, err := configstore.NewDisk(s.dir)
		c.Assert(err, gc.IsNil)
		return store
	}
}
Example #8
0
func (*diskStoreSuite) TestReadNotFound(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)
	info, err := store.ReadInfo("someenv")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)
	c.Assert(info, gc.IsNil)
}
Example #9
0
func (s *cacheFileInterfaceSuite) SetUpTest(c *gc.C) {
	s.interfaceSuite.SetUpTest(c)
	s.dir = c.MkDir()
	s.NewStore = func(c *gc.C) configstore.Storage {
		store, err := configstore.NewDisk(s.dir)
		c.Assert(err, jc.ErrorIsNil)
		return store
	}
	s.store = s.NewStore(c)
}
Example #10
0
func (*diskStoreSuite) TestRenameFails(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)

	// Replace the file by an directory which can't be renamed over.
	path := storePath(dir, "someenv")
	err = os.Mkdir(path, 0777)
	c.Assert(err, gc.IsNil)

	info := store.CreateInfo("someenv")
	err = info.Write()
	c.Assert(err, gc.ErrorMatches, "environment info already exists")
}
Example #11
0
func (*diskStoreSuite) TestRenameFails(c *gc.C) {
	if runtime.GOOS == "windows" {
		c.Skip("issue 1403084: the way the error is checked doesn't work on windows")
	}
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	// Replace the file by an directory which can't be renamed over.
	path := storePath(dir, "somemodel")
	err = os.Mkdir(path, 0777)
	c.Assert(err, jc.ErrorIsNil)

	info := store.CreateInfo("somemodel")
	err = info.Write()
	c.Assert(err, gc.ErrorMatches, "model info already exists")
}
Example #12
0
func (*diskStoreSuite) TestWriteFails(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)

	info := store.CreateInfo("someenv")

	// Make the directory non-writable
	err = os.Chmod(storePath(dir, ""), 0555)
	c.Assert(err, gc.IsNil)

	err = info.Write()
	c.Assert(err, gc.ErrorMatches, ".* permission denied")

	// Make the directory writable again so that gocheck can clean it up.
	err = os.Chmod(storePath(dir, ""), 0777)
	c.Assert(err, gc.IsNil)
}
Example #13
0
func (*diskStoreSuite) TestDestroyRemovesFiles(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)

	info, err := store.CreateInfo("someenv")
	c.Assert(err, gc.IsNil)

	_, err = os.Stat(storePath(dir, "someenv"))
	c.Assert(err, gc.IsNil)

	err = info.Destroy()
	c.Assert(err, gc.IsNil)

	_, err = os.Stat(storePath(dir, "someenv"))
	c.Assert(err, jc.Satisfies, os.IsNotExist)

	err = info.Destroy()
	c.Assert(err, gc.ErrorMatches, "environment info has already been removed")
}
Example #14
0
func (*diskStoreSuite) TestWriteFails(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	info := store.CreateInfo("somemodel")

	// Make the directory non-writable
	err = os.Chmod(storePath(dir, ""), 0555)
	c.Assert(err, jc.ErrorIsNil)

	// Cannot use permissions properly on windows for now
	if runtime.GOOS != "windows" {
		err = info.Write()
		c.Assert(err, gc.ErrorMatches, ".* permission denied")
	}

	// Make the directory writable again so that gocheck can clean it up.
	err = os.Chmod(storePath(dir, ""), 0777)
	c.Assert(err, jc.ErrorIsNil)
}
Example #15
0
func (s *diskStoreSuite) TestCreatePermissions(c *gc.C) {
	// Even though it doesn't test the actual chown, it does test the code path.
	user, err := user.Current()
	c.Assert(err, gc.IsNil)
	s.PatchEnvironment("SUDO_UID", user.Uid)
	s.PatchEnvironment("SUDO_GID", user.Gid)

	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)

	// Create some new environment info.
	_, err = store.CreateInfo("someenv")
	c.Assert(err, gc.IsNil)

	checkPath := func(path string) {
		stat, err := os.Stat(path)
		c.Assert(err, gc.IsNil)
		c.Assert(fmt.Sprint(stat.Sys().(*syscall.Stat_t).Uid), gc.Equals, user.Uid)
		c.Assert(fmt.Sprint(stat.Sys().(*syscall.Stat_t).Gid), gc.Equals, user.Gid)
	}
	checkPath(storePath(dir, ""))
	checkPath(storePath(dir, "someenv"))
}
Example #16
0
func (*diskStoreSuite) TestConcurrentAccessBreaksIfTimeExceeded(c *gc.C) {
	var tw loggo.TestWriter
	c.Assert(loggo.RegisterWriter("test-log", &tw, loggo.DEBUG), gc.IsNil)

	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)

	envDir := storePath(dir, "")
	_, err = configstore.AcquireEnvironmentLock(envDir, "blocking-op")
	c.Assert(err, jc.ErrorIsNil)

	_, err = store.ReadInfo("somemodel")
	c.Check(err, jc.Satisfies, errors.IsNotFound)

	// Using . between environments and env.lock so we don't have to care
	// about forward vs. backwards slash separator.
	messages := []jc.SimpleMessage{
		{loggo.WARNING, `breaking configstore lock, lock dir: .*models.env\.lock`},
		{loggo.WARNING, `lock holder message: pid: \d+, operation: blocking-op`},
	}

	c.Check(tw.Log(), jc.LogMatches, messages)
}