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) }
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", }) }
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"}) }
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) }
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"}) }
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) }
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 } }
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) }
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) }
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") }
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") }
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) }
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") }
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) }
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")) }
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) }