github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/cmd/juju/environment/create_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package environment_test
     5  
     6  import (
     7  	"io/ioutil"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/errors"
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/yaml.v1"
    15  
    16  	"github.com/juju/juju/apiserver/params"
    17  	"github.com/juju/juju/cmd/envcmd"
    18  	"github.com/juju/juju/cmd/juju/environment"
    19  	"github.com/juju/juju/environs/configstore"
    20  	"github.com/juju/juju/feature"
    21  	"github.com/juju/juju/testing"
    22  )
    23  
    24  type createSuite struct {
    25  	testing.FakeJujuHomeSuite
    26  	fake       *fakeCreateClient
    27  	store      configstore.Storage
    28  	serverUUID string
    29  	server     configstore.EnvironInfo
    30  }
    31  
    32  var _ = gc.Suite(&createSuite{})
    33  
    34  func (s *createSuite) SetUpTest(c *gc.C) {
    35  	s.FakeJujuHomeSuite.SetUpTest(c)
    36  	s.SetFeatureFlags(feature.JES)
    37  	s.fake = &fakeCreateClient{}
    38  	store := configstore.Default
    39  	s.AddCleanup(func(*gc.C) {
    40  		configstore.Default = store
    41  	})
    42  	s.store = configstore.NewMem()
    43  	configstore.Default = func() (configstore.Storage, error) {
    44  		return s.store, nil
    45  	}
    46  	// Set up the current environment, and write just enough info
    47  	// so we don't try to refresh
    48  	envName := "test-master"
    49  	s.serverUUID = "fake-server-uuid"
    50  	info := s.store.CreateInfo(envName)
    51  	info.SetAPIEndpoint(configstore.APIEndpoint{
    52  		Addresses:   []string{"localhost"},
    53  		CACert:      testing.CACert,
    54  		EnvironUUID: s.serverUUID,
    55  		ServerUUID:  s.serverUUID,
    56  	})
    57  	info.SetAPICredentials(configstore.APICredentials{User: "bob", Password: "sekrit"})
    58  	err := info.Write()
    59  	c.Assert(err, jc.ErrorIsNil)
    60  	s.server = info
    61  	err = envcmd.WriteCurrentEnvironment(envName)
    62  	c.Assert(err, jc.ErrorIsNil)
    63  }
    64  
    65  func (s *createSuite) run(c *gc.C, args ...string) (*cmd.Context, error) {
    66  	command := environment.NewCreateCommand(s.fake)
    67  	return testing.RunCommand(c, envcmd.Wrap(command), args...)
    68  }
    69  
    70  func (s *createSuite) TestInit(c *gc.C) {
    71  
    72  	for i, test := range []struct {
    73  		args   []string
    74  		err    string
    75  		name   string
    76  		path   string
    77  		values map[string]string
    78  	}{
    79  		{
    80  			err: "environment name is required",
    81  		}, {
    82  			args: []string{"new-env"},
    83  			name: "new-env",
    84  		}, {
    85  			args:   []string{"new-env", "key=value", "key2=value2"},
    86  			name:   "new-env",
    87  			values: map[string]string{"key": "value", "key2": "value2"},
    88  		}, {
    89  			args: []string{"new-env", "key=value", "key=value2"},
    90  			err:  `key "key" specified more than once`,
    91  		}, {
    92  			args: []string{"new-env", "another"},
    93  			err:  `expected "key=value", got "another"`,
    94  		}, {
    95  			args: []string{"new-env", "--config", "some-file"},
    96  			name: "new-env",
    97  			path: "some-file",
    98  		},
    99  	} {
   100  		c.Logf("test %d", i)
   101  		create := &environment.CreateCommand{}
   102  		err := testing.InitCommand(create, test.args)
   103  		if test.err != "" {
   104  			c.Assert(err, gc.ErrorMatches, test.err)
   105  		} else {
   106  			c.Assert(err, jc.ErrorIsNil)
   107  			c.Assert(create.Name, gc.Equals, test.name)
   108  			c.Assert(create.ConfigFile.Path, gc.Equals, test.path)
   109  			// The config value parse method returns an empty map
   110  			// if there were no values
   111  			if len(test.values) == 0 {
   112  				c.Assert(create.ConfValues, gc.HasLen, 0)
   113  			} else {
   114  				c.Assert(create.ConfValues, jc.DeepEquals, test.values)
   115  			}
   116  		}
   117  	}
   118  }
   119  
   120  func (s *createSuite) TestCreateExistingName(c *gc.C) {
   121  	// Make a configstore entry with the same name.
   122  	info := s.store.CreateInfo("test")
   123  	err := info.Write()
   124  	c.Assert(err, jc.ErrorIsNil)
   125  
   126  	_, err = s.run(c, "test")
   127  	c.Assert(err, gc.ErrorMatches, `environment "test" already exists`)
   128  }
   129  
   130  func (s *createSuite) TestComandLineConfigPassedThrough(c *gc.C) {
   131  	_, err := s.run(c, "test", "account=magic", "cloud=special")
   132  	c.Assert(err, jc.ErrorIsNil)
   133  
   134  	c.Assert(s.fake.config["account"], gc.Equals, "magic")
   135  	c.Assert(s.fake.config["cloud"], gc.Equals, "special")
   136  }
   137  
   138  func (s *createSuite) TestConfigFileValuesPassedThrough(c *gc.C) {
   139  	config := map[string]string{
   140  		"account": "magic",
   141  		"cloud":   "9",
   142  	}
   143  	bytes, err := yaml.Marshal(config)
   144  	c.Assert(err, jc.ErrorIsNil)
   145  	file, err := ioutil.TempFile(c.MkDir(), "")
   146  	c.Assert(err, jc.ErrorIsNil)
   147  	file.Write(bytes)
   148  	file.Close()
   149  
   150  	_, err = s.run(c, "test", "--config", file.Name())
   151  	c.Assert(err, jc.ErrorIsNil)
   152  	c.Assert(s.fake.config["account"], gc.Equals, "magic")
   153  	c.Assert(s.fake.config["cloud"], gc.Equals, "9")
   154  }
   155  
   156  func (s *createSuite) TestConfigFileFormatError(c *gc.C) {
   157  	file, err := ioutil.TempFile(c.MkDir(), "")
   158  	c.Assert(err, jc.ErrorIsNil)
   159  	file.Write(([]byte)("not: valid: yaml"))
   160  	file.Close()
   161  
   162  	_, err = s.run(c, "test", "--config", file.Name())
   163  	c.Assert(err, gc.ErrorMatches, `YAML error: .*`)
   164  }
   165  
   166  func (s *createSuite) TestConfigFileDoesntExist(c *gc.C) {
   167  	_, err := s.run(c, "test", "--config", "missing-file")
   168  	errMsg := ".*" + utils.NoSuchFileErrRegexp
   169  	c.Assert(err, gc.ErrorMatches, errMsg)
   170  }
   171  
   172  func (s *createSuite) TestConfigValuePrecedence(c *gc.C) {
   173  	config := map[string]string{
   174  		"account": "magic",
   175  		"cloud":   "9",
   176  	}
   177  	bytes, err := yaml.Marshal(config)
   178  	c.Assert(err, jc.ErrorIsNil)
   179  	file, err := ioutil.TempFile(c.MkDir(), "")
   180  	c.Assert(err, jc.ErrorIsNil)
   181  	file.Write(bytes)
   182  	file.Close()
   183  
   184  	_, err = s.run(c, "test", "--config", file.Name(), "account=magic", "cloud=special")
   185  	c.Assert(err, jc.ErrorIsNil)
   186  	c.Assert(s.fake.config["account"], gc.Equals, "magic")
   187  	c.Assert(s.fake.config["cloud"], gc.Equals, "special")
   188  }
   189  
   190  func (s *createSuite) TestCreateErrorRemoveConfigstoreInfo(c *gc.C) {
   191  	s.fake.err = errors.New("bah humbug")
   192  
   193  	_, err := s.run(c, "test")
   194  	c.Assert(err, gc.ErrorMatches, "bah humbug")
   195  
   196  	_, err = s.store.ReadInfo("test")
   197  	c.Assert(err, gc.ErrorMatches, `environment "test" not found`)
   198  }
   199  
   200  func (s *createSuite) TestCreateStoresValues(c *gc.C) {
   201  	s.fake.env = params.Environment{
   202  		Name:       "test",
   203  		UUID:       "fake-env-uuid",
   204  		OwnerTag:   "ignored-for-now",
   205  		ServerUUID: s.serverUUID,
   206  	}
   207  	_, err := s.run(c, "test")
   208  	c.Assert(err, jc.ErrorIsNil)
   209  
   210  	info, err := s.store.ReadInfo("test")
   211  	c.Assert(err, jc.ErrorIsNil)
   212  	// Stores the credentials of the original environment
   213  	c.Assert(info.APICredentials(), jc.DeepEquals, s.server.APICredentials())
   214  	endpoint := info.APIEndpoint()
   215  	expected := s.server.APIEndpoint()
   216  	c.Assert(endpoint.Addresses, jc.DeepEquals, expected.Addresses)
   217  	c.Assert(endpoint.Hostnames, jc.DeepEquals, expected.Hostnames)
   218  	c.Assert(endpoint.ServerUUID, gc.Equals, expected.ServerUUID)
   219  	c.Assert(endpoint.CACert, gc.Equals, expected.CACert)
   220  	c.Assert(endpoint.EnvironUUID, gc.Equals, "fake-env-uuid")
   221  }
   222  
   223  // fakeCreateClient is used to mock out the behavior of the real
   224  // CreateEnvironment command.
   225  type fakeCreateClient struct {
   226  	owner   string
   227  	account map[string]interface{}
   228  	config  map[string]interface{}
   229  	err     error
   230  	env     params.Environment
   231  }
   232  
   233  var _ environment.CreateEnvironmentAPI = (*fakeCreateClient)(nil)
   234  
   235  func (*fakeCreateClient) Close() error {
   236  	return nil
   237  }
   238  
   239  func (*fakeCreateClient) ConfigSkeleton(provider, region string) (params.EnvironConfig, error) {
   240  	return params.EnvironConfig{
   241  		"type":         "dummy",
   242  		"state-server": false,
   243  	}, nil
   244  }
   245  func (f *fakeCreateClient) CreateEnvironment(owner string, account, config map[string]interface{}) (params.Environment, error) {
   246  	var env params.Environment
   247  	if f.err != nil {
   248  		return env, f.err
   249  	}
   250  	f.owner = owner
   251  	f.account = account
   252  	f.config = config
   253  	return f.env, nil
   254  }