github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/cmd/modelcmd/modelcommand_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package modelcmd_test
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/cmd/cmdtesting"
    12  	jc "github.com/juju/testing/checkers"
    13  	gc "gopkg.in/check.v1"
    14  	"gopkg.in/juju/names.v2"
    15  
    16  	apitesting "github.com/juju/juju/api/testing"
    17  	"github.com/juju/juju/cmd/modelcmd"
    18  	"github.com/juju/juju/juju/osenv"
    19  	"github.com/juju/juju/jujuclient"
    20  	"github.com/juju/juju/jujuclient/jujuclienttesting"
    21  	"github.com/juju/juju/permission"
    22  	"github.com/juju/juju/testing"
    23  )
    24  
    25  type ModelCommandSuite struct {
    26  	testing.FakeJujuXDGDataHomeSuite
    27  	store *jujuclienttesting.MemStore
    28  }
    29  
    30  func (s *ModelCommandSuite) SetUpTest(c *gc.C) {
    31  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    32  	s.PatchEnvironment("JUJU_CLI_VERSION", "")
    33  
    34  	s.store = jujuclienttesting.NewMemStore()
    35  	s.store.CurrentControllerName = "foo"
    36  	s.store.Controllers["foo"] = jujuclient.ControllerDetails{}
    37  	s.store.Accounts["foo"] = jujuclient.AccountDetails{
    38  		User: "bar", Password: "hunter2",
    39  	}
    40  }
    41  
    42  var _ = gc.Suite(&ModelCommandSuite{})
    43  
    44  func (s *ModelCommandSuite) TestGetCurrentModelNothingSet(c *gc.C) {
    45  	s.store.CurrentControllerName = ""
    46  	env, err := modelcmd.GetCurrentModel(s.store)
    47  	c.Assert(env, gc.Equals, "")
    48  	c.Assert(err, jc.ErrorIsNil)
    49  }
    50  
    51  func (s *ModelCommandSuite) TestGetCurrentModelCurrentControllerNoCurrentModel(c *gc.C) {
    52  	env, err := modelcmd.GetCurrentModel(s.store)
    53  	c.Assert(env, gc.Equals, "foo:")
    54  	c.Assert(err, jc.ErrorIsNil)
    55  }
    56  
    57  func (s *ModelCommandSuite) TestGetCurrentModelCurrentControllerModel(c *gc.C) {
    58  	err := s.store.UpdateModel("foo", "admin/mymodel", jujuclient.ModelDetails{"uuid"})
    59  	c.Assert(err, jc.ErrorIsNil)
    60  	err = s.store.SetCurrentModel("foo", "admin/mymodel")
    61  	c.Assert(err, jc.ErrorIsNil)
    62  
    63  	env, err := modelcmd.GetCurrentModel(s.store)
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	c.Assert(env, gc.Equals, "foo:admin/mymodel")
    66  }
    67  
    68  func (s *ModelCommandSuite) TestGetCurrentModelJujuEnvSet(c *gc.C) {
    69  	os.Setenv(osenv.JujuModelEnvKey, "admin/magic")
    70  	env, err := modelcmd.GetCurrentModel(s.store)
    71  	c.Assert(env, gc.Equals, "admin/magic")
    72  	c.Assert(err, jc.ErrorIsNil)
    73  }
    74  
    75  func (s *ModelCommandSuite) TestGetCurrentModelBothSet(c *gc.C) {
    76  	os.Setenv(osenv.JujuModelEnvKey, "admin/magic")
    77  
    78  	err := s.store.UpdateModel("foo", "admin/mymodel", jujuclient.ModelDetails{"uuid"})
    79  	c.Assert(err, jc.ErrorIsNil)
    80  	err = s.store.SetCurrentModel("foo", "admin/mymodel")
    81  	c.Assert(err, jc.ErrorIsNil)
    82  
    83  	env, err := modelcmd.GetCurrentModel(s.store)
    84  	c.Assert(err, jc.ErrorIsNil)
    85  	c.Assert(env, gc.Equals, "admin/magic")
    86  }
    87  
    88  func (s *ModelCommandSuite) TestModelCommandInitExplicit(c *gc.C) {
    89  	// Take model name from command line arg.
    90  	s.testEnsureModelName(c, "explicit", "-m", "explicit")
    91  }
    92  
    93  func (s *ModelCommandSuite) TestModelCommandInitExplicitLongForm(c *gc.C) {
    94  	// Take model name from command line arg.
    95  	s.testEnsureModelName(c, "explicit", "--model", "explicit")
    96  }
    97  
    98  func (s *ModelCommandSuite) TestModelCommandInitEnvFile(c *gc.C) {
    99  	err := s.store.UpdateModel("foo", "admin/mymodel", jujuclient.ModelDetails{"uuid"})
   100  	c.Assert(err, jc.ErrorIsNil)
   101  	err = s.store.SetCurrentModel("foo", "admin/mymodel")
   102  	c.Assert(err, jc.ErrorIsNil)
   103  	s.testEnsureModelName(c, "admin/mymodel")
   104  }
   105  
   106  func (s *ModelCommandSuite) TestBootstrapContext(c *gc.C) {
   107  	ctx := modelcmd.BootstrapContext(&cmd.Context{})
   108  	c.Assert(ctx.ShouldVerifyCredentials(), jc.IsTrue)
   109  }
   110  
   111  func (s *ModelCommandSuite) TestBootstrapContextNoVerify(c *gc.C) {
   112  	ctx := modelcmd.BootstrapContextNoVerify(&cmd.Context{})
   113  	c.Assert(ctx.ShouldVerifyCredentials(), jc.IsFalse)
   114  }
   115  
   116  func (s *ModelCommandSuite) TestWrapWithoutFlags(c *gc.C) {
   117  	cmd := new(testCommand)
   118  	wrapped := modelcmd.Wrap(cmd, modelcmd.WrapSkipModelFlags)
   119  	args := []string{"-m", "testenv"}
   120  	err := cmdtesting.InitCommand(wrapped, args)
   121  	// 1st position is always the flag
   122  	msg := fmt.Sprintf("flag provided but not defined: %v", args[0])
   123  	c.Assert(err, gc.ErrorMatches, msg)
   124  }
   125  
   126  func (*ModelCommandSuite) TestSplitModelName(c *gc.C) {
   127  	assert := func(in, controller, model string) {
   128  		outController, outModel := modelcmd.SplitModelName(in)
   129  		c.Assert(outController, gc.Equals, controller)
   130  		c.Assert(outModel, gc.Equals, model)
   131  	}
   132  	assert("model", "", "model")
   133  	assert("ctrl:model", "ctrl", "model")
   134  	assert("ctrl:", "ctrl", "")
   135  	assert(":model", "", "model")
   136  }
   137  
   138  func (*ModelCommandSuite) TestJoinModelName(c *gc.C) {
   139  	assert := func(controller, model, expect string) {
   140  		out := modelcmd.JoinModelName(controller, model)
   141  		c.Assert(out, gc.Equals, expect)
   142  	}
   143  	assert("ctrl", "", "ctrl:")
   144  	assert("", "model", ":model")
   145  	assert("ctrl", "model", "ctrl:model")
   146  }
   147  
   148  func (s *ModelCommandSuite) testEnsureModelName(c *gc.C, expect string, args ...string) {
   149  	cmd, err := initTestCommand(c, s.store, args...)
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	c.Assert(cmd.ConnectionName(), gc.Equals, expect)
   152  }
   153  
   154  type testCommand struct {
   155  	modelcmd.ModelCommandBase
   156  }
   157  
   158  func (c *testCommand) Info() *cmd.Info {
   159  	panic("should not be called")
   160  }
   161  
   162  func (c *testCommand) Run(ctx *cmd.Context) error {
   163  	panic("should not be called")
   164  }
   165  
   166  func initTestCommand(c *gc.C, store jujuclient.ClientStore, args ...string) (*testCommand, error) {
   167  	cmd := new(testCommand)
   168  	cmd.SetClientStore(store)
   169  	wrapped := modelcmd.Wrap(cmd)
   170  	return cmd, cmdtesting.InitCommand(wrapped, args)
   171  }
   172  
   173  type closer struct{}
   174  
   175  func (*closer) Close() error {
   176  	return nil
   177  }
   178  
   179  var _ = gc.Suite(&macaroonLoginSuite{})
   180  
   181  type macaroonLoginSuite struct {
   182  	apitesting.MacaroonSuite
   183  	store          *jujuclienttesting.MemStore
   184  	controllerName string
   185  	modelName      string
   186  }
   187  
   188  const testUser = "testuser@somewhere"
   189  
   190  func (s *macaroonLoginSuite) SetUpTest(c *gc.C) {
   191  	s.MacaroonSuite.SetUpTest(c)
   192  	s.MacaroonSuite.AddModelUser(c, testUser)
   193  	s.MacaroonSuite.AddControllerUser(c, testUser, permission.LoginAccess)
   194  
   195  	s.controllerName = "my-controller"
   196  	s.modelName = testUser + "/my-model"
   197  	modelTag := names.NewModelTag(s.State.ModelUUID())
   198  	apiInfo := s.APIInfo(c)
   199  
   200  	s.store = jujuclienttesting.NewMemStore()
   201  	s.store.Controllers[s.controllerName] = jujuclient.ControllerDetails{
   202  		APIEndpoints:   apiInfo.Addrs,
   203  		ControllerUUID: s.State.ControllerUUID(),
   204  		CACert:         apiInfo.CACert,
   205  	}
   206  	s.store.Accounts[s.controllerName] = jujuclient.AccountDetails{
   207  		// External user forces use of macaroons.
   208  		User: "me@external",
   209  	}
   210  	s.store.Models[s.controllerName] = &jujuclient.ControllerModels{
   211  		Models: map[string]jujuclient.ModelDetails{
   212  			s.modelName: {modelTag.Id()},
   213  		},
   214  	}
   215  }
   216  
   217  func (s *macaroonLoginSuite) TestsSuccessfulLogin(c *gc.C) {
   218  	s.DischargerLogin = func() string {
   219  		return testUser
   220  	}
   221  
   222  	cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.modelName)
   223  	_, err := cmd.NewAPIRoot()
   224  	c.Assert(err, jc.ErrorIsNil)
   225  }
   226  
   227  func (s *macaroonLoginSuite) TestsFailToObtainDischargeLogin(c *gc.C) {
   228  	s.DischargerLogin = func() string {
   229  		return ""
   230  	}
   231  
   232  	cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.modelName)
   233  	_, err := cmd.NewAPIRoot()
   234  	c.Assert(err, gc.ErrorMatches, "cannot get discharge.*")
   235  }
   236  
   237  func (s *macaroonLoginSuite) TestsUnknownUserLogin(c *gc.C) {
   238  	s.DischargerLogin = func() string {
   239  		return "testUnknown@nowhere"
   240  	}
   241  
   242  	cmd := modelcmd.NewModelCommandBase(s.store, s.controllerName, s.modelName)
   243  	_, err := cmd.NewAPIRoot()
   244  	c.Assert(err, gc.ErrorMatches, "invalid entity name or password \\(unauthorized access\\)")
   245  }