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  }