github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/worker/uniter/charm/git_deployer_test.go (about) 1 // Copyright 2012-2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package charm_test 5 6 import ( 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 11 gc "launchpad.net/gocheck" 12 13 corecharm "github.com/juju/juju/charm" 14 "github.com/juju/juju/testing" 15 "github.com/juju/juju/worker/uniter/charm" 16 ) 17 18 type GitDeployerSuite struct { 19 testing.GitSuite 20 bundles *bundleReader 21 targetPath string 22 deployer charm.Deployer 23 } 24 25 var _ = gc.Suite(&GitDeployerSuite{}) 26 27 func (s *GitDeployerSuite) SetUpTest(c *gc.C) { 28 s.GitSuite.SetUpTest(c) 29 s.bundles = &bundleReader{} 30 s.targetPath = filepath.Join(c.MkDir(), "target") 31 deployerPath := filepath.Join(c.MkDir(), "deployer") 32 s.deployer = charm.NewGitDeployer(s.targetPath, deployerPath, s.bundles) 33 } 34 35 func (s *GitDeployerSuite) TestUnsetCharm(c *gc.C) { 36 err := s.deployer.Deploy() 37 c.Assert(err, gc.ErrorMatches, "charm deployment failed: no charm set") 38 } 39 40 func (s *GitDeployerSuite) TestInstall(c *gc.C) { 41 // Prepare. 42 info := s.bundles.AddCustomBundle(c, corecharm.MustParseURL("cs:s/c-1"), func(path string) { 43 err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644) 44 c.Assert(err, gc.IsNil) 45 }) 46 err := s.deployer.Stage(info, nil) 47 c.Assert(err, gc.IsNil) 48 checkCleanup(c, s.deployer) 49 50 // Install. 51 err = s.deployer.Deploy() 52 c.Assert(err, gc.IsNil) 53 checkCleanup(c, s.deployer) 54 55 // Check content. 56 data, err := ioutil.ReadFile(filepath.Join(s.targetPath, "some-file")) 57 c.Assert(err, gc.IsNil) 58 c.Assert(string(data), gc.Equals, "hello") 59 60 target := charm.NewGitDir(s.targetPath) 61 url, err := target.ReadCharmURL() 62 c.Assert(err, gc.IsNil) 63 c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-1")) 64 lines, err := target.Log() 65 c.Assert(err, gc.IsNil) 66 c.Assert(lines, gc.HasLen, 2) 67 c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Deployed charm "cs:s/c-1"\.`) 68 c.Assert(lines[1], gc.Matches, `[0-9a-f]{7} Imported charm "cs:s/c-1"\.`) 69 } 70 71 func (s *GitDeployerSuite) TestUpgrade(c *gc.C) { 72 // Install. 73 info1 := s.bundles.AddCustomBundle(c, corecharm.MustParseURL("cs:s/c-1"), func(path string) { 74 err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644) 75 c.Assert(err, gc.IsNil) 76 err = os.Symlink("./some-file", filepath.Join(path, "a-symlink")) 77 c.Assert(err, gc.IsNil) 78 }) 79 err := s.deployer.Stage(info1, nil) 80 c.Assert(err, gc.IsNil) 81 err = s.deployer.Deploy() 82 c.Assert(err, gc.IsNil) 83 84 // Upgrade. 85 info2 := s.bundles.AddCustomBundle(c, corecharm.MustParseURL("cs:s/c-2"), func(path string) { 86 err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644) 87 c.Assert(err, gc.IsNil) 88 err = ioutil.WriteFile(filepath.Join(path, "a-symlink"), []byte("not any more!"), 0644) 89 c.Assert(err, gc.IsNil) 90 }) 91 err = s.deployer.Stage(info2, nil) 92 c.Assert(err, gc.IsNil) 93 checkCleanup(c, s.deployer) 94 err = s.deployer.Deploy() 95 c.Assert(err, gc.IsNil) 96 checkCleanup(c, s.deployer) 97 98 // Check content. 99 data, err := ioutil.ReadFile(filepath.Join(s.targetPath, "some-file")) 100 c.Assert(err, gc.IsNil) 101 c.Assert(string(data), gc.Equals, "goodbye") 102 data, err = ioutil.ReadFile(filepath.Join(s.targetPath, "a-symlink")) 103 c.Assert(err, gc.IsNil) 104 c.Assert(string(data), gc.Equals, "not any more!") 105 106 target := charm.NewGitDir(s.targetPath) 107 url, err := target.ReadCharmURL() 108 c.Assert(err, gc.IsNil) 109 c.Assert(url, gc.DeepEquals, corecharm.MustParseURL("cs:s/c-2")) 110 lines, err := target.Log() 111 c.Assert(err, gc.IsNil) 112 c.Assert(lines, gc.HasLen, 5) 113 c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`) 114 } 115 116 func (s *GitDeployerSuite) TestConflictRevertResolve(c *gc.C) { 117 // Install. 118 info1 := s.bundles.AddCustomBundle(c, corecharm.MustParseURL("cs:s/c-1"), func(path string) { 119 err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644) 120 c.Assert(err, gc.IsNil) 121 }) 122 err := s.deployer.Stage(info1, nil) 123 c.Assert(err, gc.IsNil) 124 err = s.deployer.Deploy() 125 c.Assert(err, gc.IsNil) 126 127 // Mess up target. 128 err = ioutil.WriteFile(filepath.Join(s.targetPath, "some-file"), []byte("mu!"), 0644) 129 c.Assert(err, gc.IsNil) 130 131 // Upgrade. 132 info2 := s.bundles.AddCustomBundle(c, corecharm.MustParseURL("cs:s/c-2"), func(path string) { 133 err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644) 134 c.Assert(err, gc.IsNil) 135 }) 136 err = s.deployer.Stage(info2, nil) 137 c.Assert(err, gc.IsNil) 138 err = s.deployer.Deploy() 139 c.Assert(err, gc.Equals, charm.ErrConflict) 140 checkCleanup(c, s.deployer) 141 142 // Check state. 143 target := charm.NewGitDir(s.targetPath) 144 conflicted, err := target.Conflicted() 145 c.Assert(err, gc.IsNil) 146 c.Assert(conflicted, gc.Equals, true) 147 148 // Revert and check initial content. 149 err = s.deployer.NotifyRevert() 150 c.Assert(err, gc.IsNil) 151 data, err := ioutil.ReadFile(filepath.Join(s.targetPath, "some-file")) 152 c.Assert(err, gc.IsNil) 153 c.Assert(string(data), gc.Equals, "mu!") 154 conflicted, err = target.Conflicted() 155 c.Assert(err, gc.IsNil) 156 c.Assert(conflicted, gc.Equals, false) 157 158 // Try to upgrade again. 159 err = s.deployer.Deploy() 160 c.Assert(err, gc.Equals, charm.ErrConflict) 161 conflicted, err = target.Conflicted() 162 c.Assert(err, gc.IsNil) 163 c.Assert(conflicted, gc.Equals, true) 164 checkCleanup(c, s.deployer) 165 166 // And again. 167 err = s.deployer.Deploy() 168 c.Assert(err, gc.Equals, charm.ErrConflict) 169 conflicted, err = target.Conflicted() 170 c.Assert(err, gc.IsNil) 171 c.Assert(conflicted, gc.Equals, true) 172 checkCleanup(c, s.deployer) 173 174 // Manually resolve, and commit. 175 err = ioutil.WriteFile(filepath.Join(target.Path(), "some-file"), []byte("nu!"), 0644) 176 c.Assert(err, gc.IsNil) 177 err = s.deployer.NotifyResolved() 178 c.Assert(err, gc.IsNil) 179 conflicted, err = target.Conflicted() 180 c.Assert(err, gc.IsNil) 181 c.Assert(conflicted, gc.Equals, false) 182 183 // Try a final upgrade to the same charm and check it doesn't write anything 184 // except the upgrade log line. 185 err = s.deployer.Deploy() 186 c.Assert(err, gc.IsNil) 187 checkCleanup(c, s.deployer) 188 189 data, err = ioutil.ReadFile(filepath.Join(target.Path(), "some-file")) 190 c.Assert(err, gc.IsNil) 191 c.Assert(string(data), gc.Equals, "nu!") 192 conflicted, err = target.Conflicted() 193 c.Assert(err, gc.IsNil) 194 c.Assert(conflicted, gc.Equals, false) 195 lines, err := target.Log() 196 c.Assert(err, gc.IsNil) 197 c.Assert(lines[0], gc.Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`) 198 } 199 200 func checkCleanup(c *gc.C, d charm.Deployer) { 201 // Only one update dir should exist and be pointed to by the 'current' 202 // symlink since extra ones should have been cleaned up by 203 // cleanupOrphans. 204 deployerPath := charm.GitDeployerDataPath(d) 205 updateDirs, err := filepath.Glob(filepath.Join(deployerPath, "update-*")) 206 c.Assert(err, gc.IsNil) 207 c.Assert(updateDirs, gc.HasLen, 1) 208 deployerCurrent := charm.GitDeployerCurrent(d) 209 current, err := os.Readlink(deployerCurrent.Path()) 210 c.Assert(err, gc.IsNil) 211 c.Assert(updateDirs[0], gc.Equals, current) 212 213 // No install dirs should be left behind since the one created is 214 // renamed to the target path. 215 installDirs, err := filepath.Glob(filepath.Join(deployerPath, "install-*")) 216 c.Assert(err, gc.IsNil) 217 c.Assert(installDirs, gc.HasLen, 0) 218 }