func (s *EntrySuite) TestEntries(c *gc.C) { initial := ft.Entries{ ft.File{"some-file", "content", 0600}, ft.Dir{"some-dir", 0750}, ft.Symlink{"some-link", "target"}, ft.Removed{"missing"}, } expectRemoveds := ft.Entries{ ft.Removed{"some-file"}, ft.Removed{"some-dir"}, ft.Removed{"some-link"}, ft.Removed{"missing"}, } removeds := initial.AsRemoveds() c.Assert(removeds, jc.DeepEquals, expectRemoveds) expectPaths := []string{"some-file", "some-dir", "some-link", "missing"} c.Assert(initial.Paths(), jc.DeepEquals, expectPaths) c.Assert(removeds.Paths(), jc.DeepEquals, expectPaths) chainRemoveds := initial.Create(c, s.basePath).Check(c, s.basePath).AsRemoveds() c.Assert(chainRemoveds, jc.DeepEquals, expectRemoveds) chainRemoveds = chainRemoveds.Create(c, s.basePath).Check(c, s.basePath) c.Assert(chainRemoveds, jc.DeepEquals, expectRemoveds) }
func (s *ManifestDeployerSuite) TestUpgradeConflictResolveRetrySameCharm(c *gc.C) { // Create base install. s.deployCharm(c, 1, ft.File{"shared-file", "old", 0755}, ft.File{"old-file", "old", 0644}, ) // Create mock upgrade charm that can (claim to) fail to expand... failDeploy := true upgradeContent := ft.Entries{ ft.File{"shared-file", "new", 0755}, ft.File{"new-file", "new", 0644}, } mockCharm := mockBundle{ paths: set.NewStrings(upgradeContent.Paths()...), expand: func(targetPath string) error { upgradeContent.Create(c, targetPath) if failDeploy { return fmt.Errorf("oh noes") } return nil }, } info := s.addMockCharm(c, 2, mockCharm) err := s.deployer.Stage(info, nil) c.Assert(err, gc.IsNil) // ...and see it fail to expand. We're not too bothered about the actual // content of the target dir at this stage, but we do want to check it's // still marked as based on the original charm... err = s.deployer.Deploy() c.Assert(err, gc.Equals, charm.ErrConflict) s.assertCharm(c, 1) // ...and we want to verify that if we "fix the errors" and redeploy the // same charm... failDeploy = false err = s.deployer.NotifyResolved() c.Assert(err, gc.IsNil) err = s.deployer.Deploy() c.Assert(err, gc.IsNil) // ...we end up with the right stuff in play. s.assertCharm(c, 2, upgradeContent...) ft.Removed{"old-file"}.Check(c, s.targetPath) }
func (s *ManifestDeployerSuite) TestUpgradeConflictRevertRetryDifferentCharm(c *gc.C) { // Create base install and add a user file. s.deployCharm(c, 1, ft.File{"shared-file", "old", 0755}, ft.File{"old-file", "old", 0644}, ) userFile := ft.File{"user-file", "user", 0644}.Create(c, s.targetPath) // Create a charm upgrade that never works (but still writes a bunch of files), // and deploy it. badUpgradeContent := ft.Entries{ ft.File{"shared-file", "bad", 0644}, ft.File{"bad-file", "bad", 0644}, } badCharm := mockBundle{ paths: set.NewStrings(badUpgradeContent.Paths()...), expand: func(targetPath string) error { badUpgradeContent.Create(c, targetPath) return fmt.Errorf("oh noes") }, } badInfo := s.addMockCharm(c, 2, badCharm) err := s.deployer.Stage(badInfo, nil) c.Assert(err, gc.IsNil) err = s.deployer.Deploy() c.Assert(err, gc.Equals, charm.ErrConflict) // Notify the Deployer that it'll be expected to revert the changes from // the last attempt. err = s.deployer.NotifyRevert() c.Assert(err, gc.IsNil) // Create a charm upgrade that creates a bunch of different files, without // error, and deploy it; check user files are preserved, and nothing from // charm 1 or 2 is. s.deployCharm(c, 3, ft.File{"shared-file", "new", 0755}, ft.File{"new-file", "new", 0644}, ) userFile.Check(c, s.targetPath) ft.Removed{"old-file"}.Check(c, s.targetPath) ft.Removed{"bad-file"}.Check(c, s.targetPath) }