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