github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/system/useenvironment_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package system_test
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/cmd"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils"
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"github.com/juju/juju/api/base"
    15  	"github.com/juju/juju/apiserver/common"
    16  	"github.com/juju/juju/cmd/envcmd"
    17  	"github.com/juju/juju/cmd/juju/system"
    18  	"github.com/juju/juju/environs/configstore"
    19  	"github.com/juju/juju/testing"
    20  )
    21  
    22  const (
    23  	serverUUID = "0dbfe161-de6c-47ad-9283-5e3ea64e1dd3"
    24  	env1UUID   = "ebf03329-cdad-44a5-9f10-fe318efda3ce"
    25  	env2UUID   = "b366cdd5-82da-49a1-ac18-001f26bb59a3"
    26  	env3UUID   = "fd0f57a3-eb94-4095-9ab0-d1f6042f942a"
    27  	env4UUID   = "1e45141b-85cb-4a0a-96ef-0aa6bbeac45a"
    28  )
    29  
    30  type UseEnvironmentSuite struct {
    31  	testing.FakeJujuHomeSuite
    32  	api      *fakeEnvMgrAPIClient
    33  	creds    configstore.APICredentials
    34  	endpoint configstore.APIEndpoint
    35  }
    36  
    37  var _ = gc.Suite(&UseEnvironmentSuite{})
    38  
    39  func (s *UseEnvironmentSuite) SetUpTest(c *gc.C) {
    40  	s.FakeJujuHomeSuite.SetUpTest(c)
    41  
    42  	err := envcmd.WriteCurrentSystem("fake")
    43  	c.Assert(err, jc.ErrorIsNil)
    44  
    45  	envs := []base.UserEnvironment{{
    46  		Name:  "unique",
    47  		Owner: "tester@local",
    48  		UUID:  "some-uuid",
    49  	}, {
    50  		Name:  "test",
    51  		Owner: "tester@local",
    52  		UUID:  env1UUID,
    53  	}, {
    54  		Name:  "test",
    55  		Owner: "bob@local",
    56  		UUID:  env2UUID,
    57  	}, {
    58  		Name:  "other",
    59  		Owner: "bob@local",
    60  		UUID:  env3UUID,
    61  	}, {
    62  		Name:  "other",
    63  		Owner: "bob@remote",
    64  		UUID:  env4UUID,
    65  	}}
    66  	s.api = &fakeEnvMgrAPIClient{envs: envs}
    67  	s.creds = configstore.APICredentials{User: "tester", Password: "password"}
    68  	s.endpoint = configstore.APIEndpoint{
    69  		Addresses:  []string{"127.0.0.1:12345"},
    70  		Hostnames:  []string{"localhost:12345"},
    71  		CACert:     testing.CACert,
    72  		ServerUUID: serverUUID,
    73  	}
    74  }
    75  
    76  func (s *UseEnvironmentSuite) run(c *gc.C, args ...string) (*cmd.Context, error) {
    77  	command := system.NewUseEnvironmentCommand(s.api, &s.creds, &s.endpoint)
    78  	return testing.RunCommand(c, envcmd.WrapSystem(command), args...)
    79  }
    80  
    81  func (s *UseEnvironmentSuite) TestInit(c *gc.C) {
    82  	for i, test := range []struct {
    83  		args        []string
    84  		errorString string
    85  		localName   string
    86  		owner       string
    87  		envName     string
    88  		envUUID     string
    89  	}{{
    90  		errorString: "no environment supplied",
    91  	}, {
    92  		args:        []string{""},
    93  		errorString: "no environment supplied",
    94  	}, {
    95  		args:    []string{"env-name"},
    96  		envName: "env-name",
    97  	}, {
    98  		args:      []string{"env-name", "--name", "foo"},
    99  		localName: "foo",
   100  		envName:   "env-name",
   101  	}, {
   102  		args:    []string{"user/foobar"},
   103  		envName: "foobar",
   104  		owner:   "user",
   105  	}, {
   106  		args:    []string{"user@local/foobar"},
   107  		envName: "foobar",
   108  		owner:   "user@local",
   109  	}, {
   110  		args:    []string{"user@remote/foobar"},
   111  		envName: "foobar",
   112  		owner:   "user@remote",
   113  	}, {
   114  		args:        []string{"+user+name/foobar"},
   115  		errorString: `"\+user\+name" is not a valid user`,
   116  	}, {
   117  		args:    []string{env1UUID},
   118  		envUUID: env1UUID,
   119  	}, {
   120  		args:    []string{"user/" + env1UUID},
   121  		owner:   "user",
   122  		envUUID: env1UUID,
   123  	}} {
   124  		c.Logf("test %d", i)
   125  		command := &system.UseEnvironmentCommand{}
   126  		err := testing.InitCommand(command, test.args)
   127  		if test.errorString == "" {
   128  			c.Check(command.LocalName, gc.Equals, test.localName)
   129  			c.Check(command.EnvName, gc.Equals, test.envName)
   130  			c.Check(command.EnvUUID, gc.Equals, test.envUUID)
   131  			c.Check(command.Owner, gc.Equals, test.owner)
   132  		} else {
   133  			c.Check(err, gc.ErrorMatches, test.errorString)
   134  		}
   135  	}
   136  }
   137  
   138  func (s *UseEnvironmentSuite) TestEnvironmentsError(c *gc.C) {
   139  	s.api.err = common.ErrPerm
   140  	_, err := s.run(c, "ignored-but-needed")
   141  	c.Assert(err, gc.ErrorMatches, "cannot list environments: permission denied")
   142  }
   143  
   144  func (s *UseEnvironmentSuite) TestNameNotFound(c *gc.C) {
   145  	_, err := s.run(c, "missing")
   146  	c.Assert(err, gc.ErrorMatches, "matching environment not found")
   147  }
   148  
   149  func (s *UseEnvironmentSuite) TestUUID(c *gc.C) {
   150  	_, err := s.run(c, env3UUID)
   151  	c.Assert(err, gc.IsNil)
   152  
   153  	s.assertCurrentEnvironment(c, "bob-other", env3UUID)
   154  }
   155  
   156  func (s *UseEnvironmentSuite) TestUUIDCorrectOwner(c *gc.C) {
   157  	_, err := s.run(c, "bob/"+env3UUID)
   158  	c.Assert(err, gc.IsNil)
   159  
   160  	s.assertCurrentEnvironment(c, "bob-other", env3UUID)
   161  }
   162  
   163  func (s *UseEnvironmentSuite) TestUUIDWrongOwner(c *gc.C) {
   164  	ctx, err := s.run(c, "charles/"+env3UUID)
   165  	c.Assert(err, gc.IsNil)
   166  	expected := "Specified environment owned by bob@local, not charles@local"
   167  	c.Assert(testing.Stderr(ctx), jc.Contains, expected)
   168  
   169  	s.assertCurrentEnvironment(c, "bob-other", env3UUID)
   170  }
   171  
   172  func (s *UseEnvironmentSuite) TestUniqueName(c *gc.C) {
   173  	_, err := s.run(c, "unique")
   174  	c.Assert(err, gc.IsNil)
   175  
   176  	s.assertCurrentEnvironment(c, "unique", "some-uuid")
   177  }
   178  
   179  func (s *UseEnvironmentSuite) TestMultipleNameMatches(c *gc.C) {
   180  	ctx, err := s.run(c, "test")
   181  	c.Assert(err, gc.ErrorMatches, "multiple environments matched")
   182  
   183  	message := strings.TrimSpace(testing.Stderr(ctx))
   184  	lines := strings.Split(message, "\n")
   185  	c.Assert(lines, gc.HasLen, 4)
   186  	c.Assert(lines[0], gc.Equals, `Multiple environments matched name "test":`)
   187  	c.Assert(lines[1], gc.Equals, "  "+env1UUID+", owned by tester@local")
   188  	c.Assert(lines[2], gc.Equals, "  "+env2UUID+", owned by bob@local")
   189  	c.Assert(lines[3], gc.Equals, `Please specify either the environment UUID or the owner to disambiguate.`)
   190  }
   191  
   192  func (s *UseEnvironmentSuite) TestUserOwnerOfEnvironment(c *gc.C) {
   193  	_, err := s.run(c, "tester/test")
   194  	c.Assert(err, gc.IsNil)
   195  
   196  	s.assertCurrentEnvironment(c, "test", env1UUID)
   197  }
   198  
   199  func (s *UseEnvironmentSuite) TestOtherUsersEnvironment(c *gc.C) {
   200  	_, err := s.run(c, "bob/test")
   201  	c.Assert(err, gc.IsNil)
   202  
   203  	s.assertCurrentEnvironment(c, "bob-test", env2UUID)
   204  }
   205  
   206  func (s *UseEnvironmentSuite) TestRemoteUsersEnvironmentName(c *gc.C) {
   207  	_, err := s.run(c, "bob@remote/other")
   208  	c.Assert(err, gc.IsNil)
   209  
   210  	s.assertCurrentEnvironment(c, "bob-other", env4UUID)
   211  }
   212  
   213  func (s *UseEnvironmentSuite) TestDisambiguateWrongOwner(c *gc.C) {
   214  	_, err := s.run(c, "wrong/test")
   215  	c.Assert(err, gc.ErrorMatches, "matching environment not found")
   216  }
   217  
   218  func (s *UseEnvironmentSuite) TestUseEnvAlreadyExisting(c *gc.C) {
   219  	s.makeLocalEnvironment(c, "unique", "", "")
   220  	ctx, err := s.run(c, "unique")
   221  	c.Assert(err, gc.ErrorMatches, "existing environment")
   222  	expected := `You have an existing environment called "unique", use --name to specify a different local name.`
   223  	c.Assert(testing.Stderr(ctx), jc.Contains, expected)
   224  }
   225  
   226  func (s *UseEnvironmentSuite) TestUseEnvAlreadyExistingSameEnv(c *gc.C) {
   227  	s.makeLocalEnvironment(c, "unique", "some-uuid", "tester")
   228  	ctx, err := s.run(c, "unique")
   229  	c.Assert(err, gc.IsNil)
   230  
   231  	message := strings.TrimSpace(testing.Stderr(ctx))
   232  	lines := strings.Split(message, "\n")
   233  	c.Assert(lines, gc.HasLen, 2)
   234  
   235  	expected := `You already have environment details for "unique" cached locally.`
   236  	c.Assert(lines[0], gc.Equals, expected)
   237  	c.Assert(lines[1], gc.Equals, `fake (system) -> unique`)
   238  
   239  	current, err := envcmd.ReadCurrentEnvironment()
   240  	c.Assert(err, gc.IsNil)
   241  	c.Assert(current, gc.Equals, "unique")
   242  }
   243  
   244  func (s *UseEnvironmentSuite) assertCurrentEnvironment(c *gc.C, name, uuid string) {
   245  	current, err := envcmd.ReadCurrentEnvironment()
   246  	c.Assert(err, gc.IsNil)
   247  	c.Assert(current, gc.Equals, name)
   248  
   249  	store, err := configstore.Default()
   250  	c.Assert(err, gc.IsNil)
   251  
   252  	info, err := store.ReadInfo(name)
   253  	c.Assert(err, gc.IsNil)
   254  	c.Assert(info.APIEndpoint(), jc.DeepEquals, configstore.APIEndpoint{
   255  		Addresses:   []string{"127.0.0.1:12345"},
   256  		Hostnames:   []string{"localhost:12345"},
   257  		CACert:      testing.CACert,
   258  		EnvironUUID: uuid,
   259  		ServerUUID:  serverUUID,
   260  	})
   261  	c.Assert(info.APICredentials(), jc.DeepEquals, s.creds)
   262  }
   263  
   264  func (s *UseEnvironmentSuite) makeLocalEnvironment(c *gc.C, name, uuid, owner string) {
   265  	store, err := configstore.Default()
   266  	c.Assert(err, gc.IsNil)
   267  
   268  	if uuid == "" {
   269  		uuid = utils.MustNewUUID().String()
   270  	}
   271  	if owner == "" {
   272  		owner = "random@person"
   273  	}
   274  	info := store.CreateInfo(name)
   275  	info.SetAPIEndpoint(configstore.APIEndpoint{
   276  		EnvironUUID: uuid,
   277  	})
   278  	info.SetAPICredentials(configstore.APICredentials{
   279  		User: owner,
   280  	})
   281  	err = info.Write()
   282  	c.Assert(err, gc.IsNil)
   283  }