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 }