launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/cmd/juju/upgradecharm_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"bytes"
     8  	"io/ioutil"
     9  	"os"
    10  	"path"
    11  
    12  	gc "launchpad.net/gocheck"
    13  
    14  	"launchpad.net/juju-core/charm"
    15  	jujutesting "launchpad.net/juju-core/juju/testing"
    16  	"launchpad.net/juju-core/state"
    17  	"launchpad.net/juju-core/testing"
    18  )
    19  
    20  type UpgradeCharmErrorsSuite struct {
    21  	jujutesting.RepoSuite
    22  }
    23  
    24  var _ = gc.Suite(&UpgradeCharmErrorsSuite{})
    25  
    26  func runUpgradeCharm(c *gc.C, args ...string) error {
    27  	_, err := testing.RunCommand(c, &UpgradeCharmCommand{}, args)
    28  	return err
    29  }
    30  
    31  func (s *UpgradeCharmErrorsSuite) TestInvalidArgs(c *gc.C) {
    32  	err := runUpgradeCharm(c)
    33  	c.Assert(err, gc.ErrorMatches, "no service specified")
    34  	err = runUpgradeCharm(c, "invalid:name")
    35  	c.Assert(err, gc.ErrorMatches, `invalid service name "invalid:name"`)
    36  	err = runUpgradeCharm(c, "foo", "bar")
    37  	c.Assert(err, gc.ErrorMatches, `unrecognized args: \["bar"\]`)
    38  }
    39  
    40  func (s *UpgradeCharmErrorsSuite) TestWithInvalidRepository(c *gc.C) {
    41  	testing.Charms.ClonedDirPath(s.SeriesPath, "riak")
    42  	err := runDeploy(c, "local:riak", "riak")
    43  	c.Assert(err, gc.IsNil)
    44  
    45  	err = runUpgradeCharm(c, "riak", "--repository=blah")
    46  	c.Assert(err, gc.ErrorMatches, `no repository found at ".*blah"`)
    47  	// Reset JUJU_REPOSITORY explicitly, because repoSuite.SetUpTest
    48  	// overwrites it (TearDownTest will revert it again).
    49  	os.Setenv("JUJU_REPOSITORY", "")
    50  	err = runUpgradeCharm(c, "riak", "--repository=")
    51  	c.Assert(err, gc.ErrorMatches, `charm not found in ".*": local:precise/riak`)
    52  }
    53  
    54  func (s *UpgradeCharmErrorsSuite) TestInvalidService(c *gc.C) {
    55  	err := runUpgradeCharm(c, "phony")
    56  	c.Assert(err, gc.ErrorMatches, `service "phony" not found`)
    57  }
    58  
    59  func (s *UpgradeCharmErrorsSuite) deployService(c *gc.C) {
    60  	testing.Charms.ClonedDirPath(s.SeriesPath, "riak")
    61  	err := runDeploy(c, "local:riak", "riak")
    62  	c.Assert(err, gc.IsNil)
    63  }
    64  
    65  func (s *UpgradeCharmErrorsSuite) TestInvalidSwitchURL(c *gc.C) {
    66  	s.deployService(c)
    67  	err := runUpgradeCharm(c, "riak", "--switch=blah")
    68  	c.Assert(err, gc.ErrorMatches, "charm not found: cs:precise/blah")
    69  	err = runUpgradeCharm(c, "riak", "--switch=cs:missing/one")
    70  	c.Assert(err, gc.ErrorMatches, "charm not found: cs:missing/one")
    71  	// TODO(dimitern): add tests with incompatible charms
    72  }
    73  
    74  func (s *UpgradeCharmErrorsSuite) TestSwitchAndRevisionFails(c *gc.C) {
    75  	s.deployService(c)
    76  	err := runUpgradeCharm(c, "riak", "--switch=riak", "--revision=2")
    77  	c.Assert(err, gc.ErrorMatches, "--switch and --revision are mutually exclusive")
    78  }
    79  
    80  func (s *UpgradeCharmErrorsSuite) TestInvalidRevision(c *gc.C) {
    81  	s.deployService(c)
    82  	err := runUpgradeCharm(c, "riak", "--revision=blah")
    83  	c.Assert(err, gc.ErrorMatches, `invalid value "blah" for flag --revision: strconv.ParseInt: parsing "blah": invalid syntax`)
    84  }
    85  
    86  type UpgradeCharmSuccessSuite struct {
    87  	jujutesting.RepoSuite
    88  	path string
    89  	riak *state.Service
    90  }
    91  
    92  var _ = gc.Suite(&UpgradeCharmSuccessSuite{})
    93  
    94  func (s *UpgradeCharmSuccessSuite) SetUpTest(c *gc.C) {
    95  	s.RepoSuite.SetUpTest(c)
    96  	s.path = testing.Charms.ClonedDirPath(s.SeriesPath, "riak")
    97  	err := runDeploy(c, "local:riak", "riak")
    98  	c.Assert(err, gc.IsNil)
    99  	s.riak, err = s.State.Service("riak")
   100  	c.Assert(err, gc.IsNil)
   101  	ch, forced, err := s.riak.Charm()
   102  	c.Assert(err, gc.IsNil)
   103  	c.Assert(ch.Revision(), gc.Equals, 7)
   104  	c.Assert(forced, gc.Equals, false)
   105  }
   106  
   107  func (s *UpgradeCharmSuccessSuite) assertUpgraded(c *gc.C, revision int, forced bool) *charm.URL {
   108  	err := s.riak.Refresh()
   109  	c.Assert(err, gc.IsNil)
   110  	ch, force, err := s.riak.Charm()
   111  	c.Assert(err, gc.IsNil)
   112  	c.Assert(ch.Revision(), gc.Equals, revision)
   113  	c.Assert(force, gc.Equals, forced)
   114  	s.AssertCharmUploaded(c, ch.URL())
   115  	return ch.URL()
   116  }
   117  
   118  func (s *UpgradeCharmSuccessSuite) assertLocalRevision(c *gc.C, revision int, path string) {
   119  	dir, err := charm.ReadDir(path)
   120  	c.Assert(err, gc.IsNil)
   121  	c.Assert(dir.Revision(), gc.Equals, revision)
   122  }
   123  
   124  func (s *UpgradeCharmSuccessSuite) TestLocalRevisionUnchanged(c *gc.C) {
   125  	err := runUpgradeCharm(c, "riak")
   126  	c.Assert(err, gc.IsNil)
   127  	s.assertUpgraded(c, 8, false)
   128  	// Even though the remote revision is bumped, the local one should
   129  	// be unchanged.
   130  	s.assertLocalRevision(c, 7, s.path)
   131  }
   132  
   133  func (s *UpgradeCharmSuccessSuite) TestRespectsLocalRevisionWhenPossible(c *gc.C) {
   134  	dir, err := charm.ReadDir(s.path)
   135  	c.Assert(err, gc.IsNil)
   136  	err = dir.SetDiskRevision(42)
   137  	c.Assert(err, gc.IsNil)
   138  
   139  	err = runUpgradeCharm(c, "riak")
   140  	c.Assert(err, gc.IsNil)
   141  	s.assertUpgraded(c, 42, false)
   142  	s.assertLocalRevision(c, 42, s.path)
   143  }
   144  
   145  func (s *UpgradeCharmSuccessSuite) TestUpgradesWithBundle(c *gc.C) {
   146  	dir, err := charm.ReadDir(s.path)
   147  	c.Assert(err, gc.IsNil)
   148  	dir.SetRevision(42)
   149  	buf := &bytes.Buffer{}
   150  	err = dir.BundleTo(buf)
   151  	c.Assert(err, gc.IsNil)
   152  	bundlePath := path.Join(s.SeriesPath, "riak.charm")
   153  	err = ioutil.WriteFile(bundlePath, buf.Bytes(), 0644)
   154  	c.Assert(err, gc.IsNil)
   155  
   156  	err = runUpgradeCharm(c, "riak")
   157  	c.Assert(err, gc.IsNil)
   158  	s.assertUpgraded(c, 42, false)
   159  	s.assertLocalRevision(c, 7, s.path)
   160  }
   161  
   162  func (s *UpgradeCharmSuccessSuite) TestForcedUpgrade(c *gc.C) {
   163  	err := runUpgradeCharm(c, "riak", "--force")
   164  	c.Assert(err, gc.IsNil)
   165  	s.assertUpgraded(c, 8, true)
   166  	// Local revision is not changed.
   167  	s.assertLocalRevision(c, 7, s.path)
   168  }
   169  
   170  var myriakMeta = []byte(`
   171  name: myriak
   172  summary: "K/V storage engine"
   173  description: "Scalable K/V Store in Erlang with Clocks :-)"
   174  provides:
   175    endpoint:
   176      interface: http
   177    admin:
   178      interface: http
   179  peers:
   180    ring:
   181      interface: riak
   182  `)
   183  
   184  func (s *UpgradeCharmSuccessSuite) TestSwitch(c *gc.C) {
   185  	myriakPath := testing.Charms.RenamedClonedDirPath(s.SeriesPath, "riak", "myriak")
   186  	err := ioutil.WriteFile(path.Join(myriakPath, "metadata.yaml"), myriakMeta, 0644)
   187  	c.Assert(err, gc.IsNil)
   188  
   189  	// Test with local repo and no explicit revsion.
   190  	err = runUpgradeCharm(c, "riak", "--switch=local:myriak")
   191  	c.Assert(err, gc.IsNil)
   192  	curl := s.assertUpgraded(c, 7, false)
   193  	c.Assert(curl.String(), gc.Equals, "local:precise/myriak-7")
   194  	s.assertLocalRevision(c, 7, myriakPath)
   195  
   196  	// Now try the same with explicit revision - should fail.
   197  	err = runUpgradeCharm(c, "riak", "--switch=local:myriak-7")
   198  	c.Assert(err, gc.ErrorMatches, `already running specified charm "local:precise/myriak-7"`)
   199  
   200  	// Change the revision to 42 and upgrade to it with explicit revision.
   201  	err = ioutil.WriteFile(path.Join(myriakPath, "revision"), []byte("42"), 0644)
   202  	c.Assert(err, gc.IsNil)
   203  	err = runUpgradeCharm(c, "riak", "--switch=local:myriak-42")
   204  	c.Assert(err, gc.IsNil)
   205  	curl = s.assertUpgraded(c, 42, false)
   206  	c.Assert(curl.String(), gc.Equals, "local:precise/myriak-42")
   207  	s.assertLocalRevision(c, 42, myriakPath)
   208  }