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