github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/environs/configstore/disk_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package configstore_test
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  	"strings"
    13  
    14  	"github.com/juju/errors"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/environs/configstore"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  var _ = gc.Suite(&diskInterfaceSuite{})
    23  
    24  type diskInterfaceSuite struct {
    25  	interfaceSuite
    26  	dir string
    27  }
    28  
    29  func (s *diskInterfaceSuite) SetUpTest(c *gc.C) {
    30  	s.interfaceSuite.SetUpTest(c)
    31  	s.dir = c.MkDir()
    32  	s.NewStore = func(c *gc.C) configstore.Storage {
    33  		store, err := configstore.NewDisk(s.dir)
    34  		c.Assert(err, jc.ErrorIsNil)
    35  		return store
    36  	}
    37  }
    38  
    39  // storePath returns the path to the environment info
    40  // for the named environment in the given directory.
    41  // If envName is empty, it returns the path
    42  // to the info files' containing directory.
    43  func storePath(dir string, envName string) string {
    44  	path := filepath.Join(dir, "environments")
    45  	if envName != "" {
    46  		path = filepath.Join(path, envName+".jenv")
    47  	}
    48  	return path
    49  }
    50  
    51  func (s *diskInterfaceSuite) TearDownTest(c *gc.C) {
    52  	s.NewStore = nil
    53  	// Check that no stray temp files have been left behind
    54  	entries, err := ioutil.ReadDir(storePath(s.dir, ""))
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	for _, entry := range entries {
    57  		if !strings.HasSuffix(entry.Name(), ".jenv") {
    58  			c.Errorf("found possible stray temp file %q", entry.Name())
    59  		}
    60  	}
    61  	s.interfaceSuite.TearDownTest(c)
    62  }
    63  
    64  var _ = gc.Suite(&diskStoreSuite{})
    65  
    66  type diskStoreSuite struct {
    67  	testing.BaseSuite
    68  }
    69  
    70  func (*diskStoreSuite) TestNewDisk(c *gc.C) {
    71  	dir := c.MkDir()
    72  	store, err := configstore.NewDisk(filepath.Join(dir, "foo"))
    73  	c.Assert(err, jc.Satisfies, os.IsNotExist)
    74  	c.Assert(store, gc.IsNil)
    75  
    76  	store, err = configstore.NewDisk(filepath.Join(dir))
    77  	c.Assert(err, jc.ErrorIsNil)
    78  	c.Assert(store, gc.NotNil)
    79  }
    80  
    81  var sampleInfo = `
    82    user: rog
    83    password: guessit
    84    state-servers:
    85    - 10.0.0.1
    86    - 127.0.0.1
    87    server-hostnames:
    88    - example.com
    89    - kremvax.ru
    90    ca-cert: 'first line
    91  
    92      second line'
    93    bootstrap-config:
    94      secret: blah
    95      arble: bletch
    96  `[1:]
    97  
    98  func (*diskStoreSuite) TestRead(c *gc.C) {
    99  	dir := c.MkDir()
   100  	err := os.Mkdir(storePath(dir, ""), 0700)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	err = ioutil.WriteFile(storePath(dir, "someenv"), []byte(sampleInfo), 0666)
   103  	c.Assert(err, jc.ErrorIsNil)
   104  	store, err := configstore.NewDisk(dir)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  	info, err := store.ReadInfo("someenv")
   107  	c.Assert(err, jc.ErrorIsNil)
   108  	c.Assert(info.Initialized(), jc.IsTrue)
   109  	c.Assert(info.APICredentials(), gc.DeepEquals, configstore.APICredentials{
   110  		User:     "rog",
   111  		Password: "guessit",
   112  	})
   113  	c.Assert(info.APIEndpoint(), gc.DeepEquals, configstore.APIEndpoint{
   114  		Addresses: []string{"10.0.0.1", "127.0.0.1"},
   115  		Hostnames: []string{"example.com", "kremvax.ru"},
   116  		CACert:    "first line\nsecond line",
   117  	})
   118  	c.Assert(info.Location(), gc.Equals, fmt.Sprintf("file %q", filepath.Join(dir, "environments", "someenv.jenv")))
   119  	c.Assert(info.BootstrapConfig(), gc.DeepEquals, map[string]interface{}{
   120  		"secret": "blah",
   121  		"arble":  "bletch",
   122  	})
   123  }
   124  
   125  func (*diskStoreSuite) TestReadNotFound(c *gc.C) {
   126  	dir := c.MkDir()
   127  	store, err := configstore.NewDisk(dir)
   128  	c.Assert(err, jc.ErrorIsNil)
   129  	info, err := store.ReadInfo("someenv")
   130  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   131  	c.Assert(info, gc.IsNil)
   132  }
   133  
   134  func (*diskStoreSuite) TestWriteFails(c *gc.C) {
   135  	dir := c.MkDir()
   136  	store, err := configstore.NewDisk(dir)
   137  	c.Assert(err, jc.ErrorIsNil)
   138  
   139  	info := store.CreateInfo("someenv")
   140  
   141  	// Make the directory non-writable
   142  	err = os.Chmod(storePath(dir, ""), 0555)
   143  	c.Assert(err, jc.ErrorIsNil)
   144  
   145  	// Cannot use permissions properly on windows for now
   146  	if runtime.GOOS != "windows" {
   147  		err = info.Write()
   148  		c.Assert(err, gc.ErrorMatches, ".* permission denied")
   149  	}
   150  
   151  	// Make the directory writable again so that gocheck can clean it up.
   152  	err = os.Chmod(storePath(dir, ""), 0777)
   153  	c.Assert(err, jc.ErrorIsNil)
   154  }
   155  
   156  func (*diskStoreSuite) TestRenameFails(c *gc.C) {
   157  	if runtime.GOOS == "windows" {
   158  		c.Skip("issue 1403084: the way the error is checked doesn't work on windows")
   159  	}
   160  	dir := c.MkDir()
   161  	store, err := configstore.NewDisk(dir)
   162  	c.Assert(err, jc.ErrorIsNil)
   163  
   164  	// Replace the file by an directory which can't be renamed over.
   165  	path := storePath(dir, "someenv")
   166  	err = os.Mkdir(path, 0777)
   167  	c.Assert(err, jc.ErrorIsNil)
   168  
   169  	info := store.CreateInfo("someenv")
   170  	err = info.Write()
   171  	c.Assert(err, gc.ErrorMatches, "environment info already exists")
   172  }
   173  
   174  func (*diskStoreSuite) TestDestroyRemovesFiles(c *gc.C) {
   175  	dir := c.MkDir()
   176  	store, err := configstore.NewDisk(dir)
   177  	c.Assert(err, jc.ErrorIsNil)
   178  
   179  	info := store.CreateInfo("someenv")
   180  	err = info.Write()
   181  	c.Assert(err, jc.ErrorIsNil)
   182  
   183  	_, err = os.Stat(storePath(dir, "someenv"))
   184  	c.Assert(err, jc.ErrorIsNil)
   185  
   186  	err = info.Destroy()
   187  	c.Assert(err, jc.ErrorIsNil)
   188  
   189  	_, err = os.Stat(storePath(dir, "someenv"))
   190  	c.Assert(err, jc.Satisfies, os.IsNotExist)
   191  
   192  	err = info.Destroy()
   193  	c.Assert(err, gc.ErrorMatches, "environment info has already been removed")
   194  }
   195  
   196  func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) {
   197  	dir := c.MkDir()
   198  	store, err := configstore.NewDisk(dir)
   199  	c.Assert(err, jc.ErrorIsNil)
   200  	info := store.CreateInfo("someenv")
   201  	endpoint := configstore.APIEndpoint{
   202  		Addresses:   []string{"this", "is", "never", "validated", "here"},
   203  		Hostnames:   []string{"neither", "is", "this"},
   204  		EnvironUUID: testing.EnvironmentTag.Id(),
   205  	}
   206  	info.SetAPIEndpoint(endpoint)
   207  	err = info.Write()
   208  	c.Assert(err, jc.ErrorIsNil)
   209  
   210  	newInfo, err := store.ReadInfo("someenv")
   211  	c.Assert(err, jc.ErrorIsNil)
   212  	// Now change the number of addresses to be shorter.
   213  	endpoint.Addresses = []string{"just one"}
   214  	endpoint.Hostnames = []string{"just this"}
   215  	newInfo.SetAPIEndpoint(endpoint)
   216  	err = newInfo.Write()
   217  	c.Assert(err, jc.ErrorIsNil)
   218  
   219  	// We should be able to read in in fine.
   220  	yaInfo, err := store.ReadInfo("someenv")
   221  	c.Assert(err, jc.ErrorIsNil)
   222  	c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"})
   223  	c.Assert(yaInfo.APIEndpoint().Hostnames, gc.DeepEquals, []string{"just this"})
   224  }