github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cmd/juju/commands/cmd_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package commands
     5  
     6  import (
     7  	"os"
     8  
     9  	"github.com/juju/cmd"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/cmd/envcmd"
    14  	"github.com/juju/juju/cmd/juju/service"
    15  	"github.com/juju/juju/cmd/juju/status"
    16  	cmdtesting "github.com/juju/juju/cmd/testing"
    17  	"github.com/juju/juju/juju/osenv"
    18  	"github.com/juju/juju/juju/testing"
    19  	coretesting "github.com/juju/juju/testing"
    20  )
    21  
    22  func badrun(c *gc.C, exit int, args ...string) string {
    23  	args = append([]string{"juju"}, args...)
    24  	return cmdtesting.BadRun(c, exit, args...)
    25  }
    26  
    27  type CmdSuite struct {
    28  	testing.JujuConnSuite
    29  }
    30  
    31  var _ = gc.Suite(&CmdSuite{})
    32  
    33  const envConfig = `
    34  default:
    35      peckham
    36  environments:
    37      peckham:
    38          type: dummy
    39          state-server: false
    40          admin-secret: arble
    41          authorized-keys: i-am-a-key
    42          default-series: raring
    43      walthamstow:
    44          type: dummy
    45          state-server: false
    46          authorized-keys: i-am-a-key
    47      brokenenv:
    48          type: dummy
    49          broken: Bootstrap Destroy
    50          state-server: false
    51          authorized-keys: i-am-a-key
    52          agent-stream: proposed
    53      devenv:
    54          type: dummy
    55          state-server: false
    56          admin-secret: arble
    57          authorized-keys: i-am-a-key
    58          default-series: raring
    59          agent-stream: proposed
    60  `
    61  
    62  func (s *CmdSuite) SetUpTest(c *gc.C) {
    63  	s.JujuConnSuite.SetUpTest(c)
    64  	coretesting.WriteEnvironments(c, envConfig, "peckham", "walthamstow", "brokenenv")
    65  }
    66  
    67  func (s *CmdSuite) TearDownTest(c *gc.C) {
    68  	s.JujuConnSuite.TearDownTest(c)
    69  }
    70  
    71  // testInit checks that a command initialises correctly
    72  // with the given set of arguments.
    73  func testInit(c *gc.C, com cmd.Command, args []string, errPat string) {
    74  	err := coretesting.InitCommand(com, args)
    75  	if errPat != "" {
    76  		c.Assert(err, gc.ErrorMatches, errPat)
    77  	} else {
    78  		c.Assert(err, jc.ErrorIsNil)
    79  	}
    80  }
    81  
    82  type HasConnectionName interface {
    83  	ConnectionName() string
    84  }
    85  
    86  // assertEnvName asserts that the Command is using
    87  // the given environment name.
    88  // Since every command has a different type,
    89  // we use reflection to look at the value of the
    90  // Conn field in the value.
    91  func assertEnvName(c *gc.C, com cmd.Command, name string) {
    92  	i, ok := com.(HasConnectionName)
    93  	c.Assert(ok, jc.IsTrue)
    94  	c.Assert(i.ConnectionName(), gc.Equals, name)
    95  }
    96  
    97  // All members of EnvironmentInitTests are tested for the -environment and -e
    98  // flags, and that extra arguments will cause parsing to fail.
    99  var EnvironmentInitTests = []func() (envcmd.EnvironCommand, []string){
   100  	func() (envcmd.EnvironCommand, []string) { return new(BootstrapCommand), nil },
   101  	func() (envcmd.EnvironCommand, []string) {
   102  		return new(DeployCommand), []string{"charm-name", "service-name"}
   103  	},
   104  	func() (envcmd.EnvironCommand, []string) { return new(status.StatusCommand), nil },
   105  }
   106  
   107  // TestEnvironmentInit tests that all commands which accept
   108  // the --environment variable initialise their
   109  // environment name correctly.
   110  func (*CmdSuite) TestEnvironmentInit(c *gc.C) {
   111  	for i, cmdFunc := range EnvironmentInitTests {
   112  		c.Logf("test %d", i)
   113  		com, args := cmdFunc()
   114  		testInit(c, envcmd.Wrap(com), args, "")
   115  		assertEnvName(c, com, "peckham")
   116  
   117  		com, args = cmdFunc()
   118  		testInit(c, envcmd.Wrap(com), append(args, "-e", "walthamstow"), "")
   119  		assertEnvName(c, com, "walthamstow")
   120  
   121  		com, args = cmdFunc()
   122  		testInit(c, envcmd.Wrap(com), append(args, "--environment", "walthamstow"), "")
   123  		assertEnvName(c, com, "walthamstow")
   124  
   125  		// JUJU_ENV is the final place the environment can be overriden
   126  		com, args = cmdFunc()
   127  		oldenv := os.Getenv(osenv.JujuEnvEnvKey)
   128  		os.Setenv(osenv.JujuEnvEnvKey, "walthamstow")
   129  		testInit(c, envcmd.Wrap(com), args, "")
   130  		os.Setenv(osenv.JujuEnvEnvKey, oldenv)
   131  		assertEnvName(c, com, "walthamstow")
   132  	}
   133  }
   134  
   135  var deployTests = []struct {
   136  	args []string
   137  	com  *DeployCommand
   138  }{
   139  	{
   140  		[]string{"charm-name"},
   141  		&DeployCommand{},
   142  	}, {
   143  		[]string{"charm-name", "service-name"},
   144  		&DeployCommand{ServiceName: "service-name"},
   145  	}, {
   146  		[]string{"--repository", "/path/to/another-repo", "charm-name"},
   147  		&DeployCommand{RepoPath: "/path/to/another-repo"},
   148  	}, {
   149  		[]string{"--upgrade", "charm-name"},
   150  		&DeployCommand{BumpRevision: true},
   151  	}, {
   152  		[]string{"-u", "charm-name"},
   153  		&DeployCommand{BumpRevision: true},
   154  	}, {
   155  		[]string{"--num-units", "33", "charm-name"},
   156  		&DeployCommand{UnitCommandBase: service.UnitCommandBase{NumUnits: 33}},
   157  	}, {
   158  		[]string{"-n", "104", "charm-name"},
   159  		&DeployCommand{UnitCommandBase: service.UnitCommandBase{NumUnits: 104}},
   160  	},
   161  }
   162  
   163  func initExpectations(com *DeployCommand) {
   164  	if com.CharmName == "" {
   165  		com.CharmName = "charm-name"
   166  	}
   167  	if com.NumUnits == 0 {
   168  		com.NumUnits = 1
   169  	}
   170  	if com.RepoPath == "" {
   171  		com.RepoPath = "/path/to/repo"
   172  	}
   173  	com.SetEnvName("peckham")
   174  }
   175  
   176  func initDeployCommand(args ...string) (*DeployCommand, error) {
   177  	com := &DeployCommand{}
   178  	return com, coretesting.InitCommand(envcmd.Wrap(com), args)
   179  }
   180  
   181  func (*CmdSuite) TestDeployCommandInit(c *gc.C) {
   182  	defer os.Setenv(osenv.JujuRepositoryEnvKey, os.Getenv(osenv.JujuRepositoryEnvKey))
   183  	os.Setenv(osenv.JujuRepositoryEnvKey, "/path/to/repo")
   184  
   185  	for _, t := range deployTests {
   186  		initExpectations(t.com)
   187  		com, err := initDeployCommand(t.args...)
   188  		c.Assert(err, jc.ErrorIsNil)
   189  		c.Assert(com, gc.DeepEquals, t.com)
   190  	}
   191  
   192  	// test relative --config path
   193  	ctx := coretesting.Context(c)
   194  	expected := []byte("test: data")
   195  	path := ctx.AbsPath("testconfig.yaml")
   196  	file, err := os.Create(path)
   197  	c.Assert(err, jc.ErrorIsNil)
   198  	_, err = file.Write(expected)
   199  	c.Assert(err, jc.ErrorIsNil)
   200  	file.Close()
   201  
   202  	com, err := initDeployCommand("--config", "testconfig.yaml", "charm-name")
   203  	c.Assert(err, jc.ErrorIsNil)
   204  	actual, err := com.Config.Read(ctx)
   205  	c.Assert(err, jc.ErrorIsNil)
   206  	c.Assert(expected, gc.DeepEquals, actual)
   207  
   208  	// missing args
   209  	_, err = initDeployCommand()
   210  	c.Assert(err, gc.ErrorMatches, "no charm specified")
   211  
   212  	// bad unit count
   213  	_, err = initDeployCommand("charm-name", "--num-units", "0")
   214  	c.Assert(err, gc.ErrorMatches, "--num-units must be a positive integer")
   215  	_, err = initDeployCommand("charm-name", "-n", "0")
   216  	c.Assert(err, gc.ErrorMatches, "--num-units must be a positive integer")
   217  
   218  	// environment tested elsewhere
   219  }
   220  
   221  func initExposeCommand(args ...string) (*ExposeCommand, error) {
   222  	com := &ExposeCommand{}
   223  	return com, coretesting.InitCommand(com, args)
   224  }
   225  
   226  func (*CmdSuite) TestExposeCommandInit(c *gc.C) {
   227  	// missing args
   228  	_, err := initExposeCommand()
   229  	c.Assert(err, gc.ErrorMatches, "no service name specified")
   230  
   231  	// environment tested elsewhere
   232  }
   233  
   234  func initUnexposeCommand(args ...string) (*UnexposeCommand, error) {
   235  	com := &UnexposeCommand{}
   236  	return com, coretesting.InitCommand(com, args)
   237  }
   238  
   239  func (*CmdSuite) TestUnexposeCommandInit(c *gc.C) {
   240  	// missing args
   241  	_, err := initUnexposeCommand()
   242  	c.Assert(err, gc.ErrorMatches, "no service name specified")
   243  
   244  	// environment tested elsewhere
   245  }
   246  
   247  func initSSHCommand(args ...string) (*SSHCommand, error) {
   248  	com := &SSHCommand{}
   249  	return com, coretesting.InitCommand(com, args)
   250  }
   251  
   252  func (*CmdSuite) TestSSHCommandInit(c *gc.C) {
   253  	// missing args
   254  	_, err := initSSHCommand()
   255  	c.Assert(err, gc.ErrorMatches, "no target name specified")
   256  }
   257  
   258  func initSCPCommand(args ...string) (*SCPCommand, error) {
   259  	com := &SCPCommand{}
   260  	return com, coretesting.InitCommand(com, args)
   261  }
   262  
   263  func (*CmdSuite) TestSCPCommandInit(c *gc.C) {
   264  	// missing args
   265  	_, err := initSCPCommand()
   266  	c.Assert(err, gc.ErrorMatches, "at least two arguments required")
   267  
   268  	// not enough args
   269  	_, err = initSCPCommand("mysql/0:foo")
   270  	c.Assert(err, gc.ErrorMatches, "at least two arguments required")
   271  }
   272  
   273  func initRemoveUnitCommand(args ...string) (*RemoveUnitCommand, error) {
   274  	com := &RemoveUnitCommand{}
   275  	return com, coretesting.InitCommand(com, args)
   276  }
   277  
   278  func (*CmdSuite) TestRemoveUnitCommandInit(c *gc.C) {
   279  	// missing args
   280  	_, err := initRemoveUnitCommand()
   281  	c.Assert(err, gc.ErrorMatches, "no units specified")
   282  	// not a unit
   283  	_, err = initRemoveUnitCommand("seven/nine")
   284  	c.Assert(err, gc.ErrorMatches, `invalid unit name "seven/nine"`)
   285  }