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