github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/provider/common/state_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"os"
    11  	"path/filepath"
    12  
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  	goyaml "gopkg.in/yaml.v1"
    16  
    17  	"github.com/juju/juju/environs"
    18  	"github.com/juju/juju/environs/storage"
    19  	envtesting "github.com/juju/juju/environs/testing"
    20  	"github.com/juju/juju/instance"
    21  	"github.com/juju/juju/provider/common"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  type StateSuite struct {
    26  	coretesting.BaseSuite
    27  }
    28  
    29  var _ = gc.Suite(&StateSuite{})
    30  
    31  func (suite *StateSuite) newStorageWithDataDir(c *gc.C) (storage.Storage, string) {
    32  	closer, stor, dataDir := envtesting.CreateLocalTestStorage(c)
    33  	suite.AddCleanup(func(*gc.C) { closer.Close() })
    34  	envtesting.UploadFakeTools(c, stor, "released", "released")
    35  	return stor, dataDir
    36  }
    37  
    38  func (suite *StateSuite) newStorage(c *gc.C) storage.Storage {
    39  	stor, _ := suite.newStorageWithDataDir(c)
    40  	return stor
    41  }
    42  
    43  // testingHTTPSServer creates a tempdir backed https server with internal
    44  // self-signed certs that will not be accepted as valid.
    45  func (suite *StateSuite) testingHTTPSServer(c *gc.C) (string, string) {
    46  	dataDir := c.MkDir()
    47  	mux := http.NewServeMux()
    48  	mux.Handle("/", http.FileServer(http.Dir(dataDir)))
    49  	server := httptest.NewTLSServer(mux)
    50  	suite.AddCleanup(func(*gc.C) { server.Close() })
    51  	return server.URL, dataDir
    52  }
    53  
    54  func (suite *StateSuite) TestCreateStateFileWritesEmptyStateFile(c *gc.C) {
    55  	stor := suite.newStorage(c)
    56  
    57  	url, err := common.CreateStateFile(stor)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  
    60  	reader, err := storage.Get(stor, common.StateFile)
    61  	c.Assert(err, jc.ErrorIsNil)
    62  	data, err := ioutil.ReadAll(reader)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	c.Check(string(data), gc.Equals, "")
    65  	c.Assert(url, gc.NotNil)
    66  	expectedURL, err := stor.URL(common.StateFile)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  	c.Check(url, gc.Equals, expectedURL)
    69  }
    70  
    71  func (suite *StateSuite) TestDeleteStateFile(c *gc.C) {
    72  	closer, stor, dataDir := envtesting.CreateLocalTestStorage(c)
    73  	defer closer.Close()
    74  
    75  	err := common.DeleteStateFile(stor)
    76  	c.Assert(err, jc.ErrorIsNil) // doesn't exist, juju don't care
    77  
    78  	_, err = common.CreateStateFile(stor)
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	_, err = os.Stat(filepath.Join(dataDir, common.StateFile))
    81  	c.Assert(err, jc.ErrorIsNil)
    82  
    83  	err = common.DeleteStateFile(stor)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	_, err = os.Stat(filepath.Join(dataDir, common.StateFile))
    86  	c.Assert(err, jc.Satisfies, os.IsNotExist)
    87  }
    88  
    89  func (suite *StateSuite) TestSaveStateWritesStateFile(c *gc.C) {
    90  	stor := suite.newStorage(c)
    91  	state := common.BootstrapState{
    92  		StateInstances: []instance.Id{instance.Id("an-instance-id")},
    93  	}
    94  	marshaledState, err := goyaml.Marshal(state)
    95  	c.Assert(err, jc.ErrorIsNil)
    96  
    97  	err = common.SaveState(stor, &state)
    98  	c.Assert(err, jc.ErrorIsNil)
    99  
   100  	loadedState, err := storage.Get(stor, common.StateFile)
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	content, err := ioutil.ReadAll(loadedState)
   103  	c.Assert(err, jc.ErrorIsNil)
   104  	c.Check(content, gc.DeepEquals, marshaledState)
   105  }
   106  
   107  func (suite *StateSuite) setUpSavedState(c *gc.C, dataDir string) common.BootstrapState {
   108  	state := common.BootstrapState{
   109  		StateInstances: []instance.Id{instance.Id("an-instance-id")},
   110  	}
   111  	content, err := goyaml.Marshal(state)
   112  	c.Assert(err, jc.ErrorIsNil)
   113  	err = ioutil.WriteFile(filepath.Join(dataDir, common.StateFile), []byte(content), 0644)
   114  	c.Assert(err, jc.ErrorIsNil)
   115  	return state
   116  }
   117  
   118  func (suite *StateSuite) TestLoadStateReadsStateFile(c *gc.C) {
   119  	storage, dataDir := suite.newStorageWithDataDir(c)
   120  	state := suite.setUpSavedState(c, dataDir)
   121  	storedState, err := common.LoadState(storage)
   122  	c.Assert(err, jc.ErrorIsNil)
   123  	c.Check(*storedState, gc.DeepEquals, state)
   124  }
   125  
   126  func (suite *StateSuite) TestLoadStateMissingFile(c *gc.C) {
   127  	stor := suite.newStorage(c)
   128  	_, err := common.LoadState(stor)
   129  	c.Check(err, gc.Equals, environs.ErrNotBootstrapped)
   130  }
   131  
   132  func (suite *StateSuite) TestLoadStateIntegratesWithSaveState(c *gc.C) {
   133  	storage := suite.newStorage(c)
   134  	state := common.BootstrapState{
   135  		StateInstances: []instance.Id{instance.Id("an-instance-id")},
   136  	}
   137  	err := common.SaveState(storage, &state)
   138  	c.Assert(err, jc.ErrorIsNil)
   139  	storedState, err := common.LoadState(storage)
   140  	c.Assert(err, jc.ErrorIsNil)
   141  
   142  	c.Check(*storedState, gc.DeepEquals, state)
   143  }
   144  
   145  func (suite *StateSuite) TestAddStateInstance(c *gc.C) {
   146  	storage := suite.newStorage(c)
   147  	for _, str := range []string{"a", "b", "c"} {
   148  		id := instance.Id(str)
   149  		err := common.AddStateInstance(storage, instance.Id(id))
   150  		c.Assert(err, jc.ErrorIsNil)
   151  	}
   152  
   153  	storedState, err := common.LoadState(storage)
   154  	c.Assert(err, jc.ErrorIsNil)
   155  	c.Check(storedState, gc.DeepEquals, &common.BootstrapState{
   156  		StateInstances: []instance.Id{
   157  			instance.Id("a"),
   158  			instance.Id("b"),
   159  			instance.Id("c"),
   160  		},
   161  	})
   162  }
   163  
   164  func (suite *StateSuite) TestRemoveStateInstancesPartial(c *gc.C) {
   165  	storage := suite.newStorage(c)
   166  	state := common.BootstrapState{
   167  		StateInstances: []instance.Id{
   168  			instance.Id("a"),
   169  			instance.Id("b"),
   170  			instance.Id("c"),
   171  		},
   172  	}
   173  	err := common.SaveState(storage, &state)
   174  	c.Assert(err, jc.ErrorIsNil)
   175  
   176  	err = common.RemoveStateInstances(
   177  		storage,
   178  		state.StateInstances[0],
   179  		instance.Id("not-there"),
   180  		state.StateInstances[2],
   181  	)
   182  	c.Assert(err, jc.ErrorIsNil)
   183  
   184  	storedState, err := common.LoadState(storage)
   185  	c.Assert(storedState, gc.DeepEquals, &common.BootstrapState{
   186  		StateInstances: []instance.Id{
   187  			state.StateInstances[1],
   188  		},
   189  	})
   190  }
   191  
   192  func (suite *StateSuite) TestRemoveStateInstancesNone(c *gc.C) {
   193  	storage := suite.newStorage(c)
   194  	state := common.BootstrapState{
   195  		StateInstances: []instance.Id{instance.Id("an-instance-id")},
   196  	}
   197  	err := common.SaveState(storage, &state)
   198  	c.Assert(err, jc.ErrorIsNil)
   199  
   200  	err = common.RemoveStateInstances(
   201  		storage,
   202  		instance.Id("not-there"),
   203  	)
   204  	c.Assert(err, jc.ErrorIsNil)
   205  
   206  	storedState, err := common.LoadState(storage)
   207  	c.Assert(storedState, gc.DeepEquals, &state)
   208  }
   209  
   210  func (suite *StateSuite) TestRemoveStateInstancesNoProviderState(c *gc.C) {
   211  	storage := suite.newStorage(c)
   212  	err := common.RemoveStateInstances(storage, instance.Id("id"))
   213  	// No error if the id is missing, so no error if the entire
   214  	// provider-state file is missing. This is the case if
   215  	// bootstrap failed.
   216  	c.Assert(err, jc.ErrorIsNil)
   217  }