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  }