github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/worker/uniter/uniter_old_test.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"strconv"
    12  
    13  	jc "github.com/juju/testing/checkers"
    14  	ft "github.com/juju/testing/filetesting"
    15  	gc "launchpad.net/gocheck"
    16  
    17  	"github.com/juju/juju/state"
    18  	"github.com/juju/juju/state/api/params"
    19  )
    20  
    21  // These tests are copies of the old git-deployer-related tests, to test that
    22  // the uniter with the manifest-deployer work patched out still works how it
    23  // used to; thus demonstrating that the *other* tests that verify manifest
    24  // deployer behaviour in the presence of an old git deployer are working against
    25  // an accurate representation of the base state.
    26  // The only actual behaviour change is that we no longer commit changes after
    27  // each hook execution; this is reflected by checking that it's dirty in a couple
    28  // of places where we once checked it was not.
    29  
    30  var upgradeGitConflictsTests = []uniterTest{
    31  	// Upgrade scenarios - handling conflicts.
    32  	ut(
    33  		"upgrade: conflicting files",
    34  		startGitUpgradeError{},
    35  
    36  		// NOTE: this is just dumbly committing the conflicts, but AFAICT this
    37  		// is the only reasonable solution; if the user tells us it's resolved
    38  		// we have to take their word for it.
    39  		resolveError{state.ResolvedNoHooks},
    40  		waitHooks{"upgrade-charm", "config-changed"},
    41  		waitUnit{
    42  			status: params.StatusStarted,
    43  			charm:  1,
    44  		},
    45  		verifyGitCharm{revision: 1},
    46  	), ut(
    47  		`upgrade: conflicting directories`,
    48  		createCharm{
    49  			customize: func(c *gc.C, ctx *context, path string) {
    50  				err := os.Mkdir(filepath.Join(path, "data"), 0755)
    51  				c.Assert(err, gc.IsNil)
    52  				appendHook(c, path, "start", "echo DATA > data/newfile")
    53  			},
    54  		},
    55  		serveCharm{},
    56  		createUniter{},
    57  		waitUnit{
    58  			status: params.StatusStarted,
    59  		},
    60  		waitHooks{"install", "config-changed", "start"},
    61  		verifyGitCharm{dirty: true},
    62  
    63  		createCharm{
    64  			revision: 1,
    65  			customize: func(c *gc.C, ctx *context, path string) {
    66  				data := filepath.Join(path, "data")
    67  				err := ioutil.WriteFile(data, []byte("<nelson>ha ha</nelson>"), 0644)
    68  				c.Assert(err, gc.IsNil)
    69  			},
    70  		},
    71  		serveCharm{},
    72  		upgradeCharm{revision: 1},
    73  		waitUnit{
    74  			status: params.StatusError,
    75  			info:   "upgrade failed",
    76  			charm:  1,
    77  		},
    78  		verifyWaiting{},
    79  		verifyGitCharm{dirty: true},
    80  
    81  		resolveError{state.ResolvedNoHooks},
    82  		waitHooks{"upgrade-charm", "config-changed"},
    83  		waitUnit{
    84  			status: params.StatusStarted,
    85  			charm:  1,
    86  		},
    87  		verifyGitCharm{revision: 1},
    88  	), ut(
    89  		"upgrade conflict resolved with forced upgrade",
    90  		startGitUpgradeError{},
    91  		createCharm{
    92  			revision: 2,
    93  			customize: func(c *gc.C, ctx *context, path string) {
    94  				otherdata := filepath.Join(path, "otherdata")
    95  				err := ioutil.WriteFile(otherdata, []byte("blah"), 0644)
    96  				c.Assert(err, gc.IsNil)
    97  			},
    98  		},
    99  		serveCharm{},
   100  		upgradeCharm{revision: 2, forced: true},
   101  		waitUnit{
   102  			status: params.StatusStarted,
   103  			charm:  2,
   104  		},
   105  		waitHooks{"upgrade-charm", "config-changed"},
   106  		verifyGitCharm{revision: 2},
   107  		custom{func(c *gc.C, ctx *context) {
   108  			// otherdata should exist (in v2)
   109  			otherdata, err := ioutil.ReadFile(filepath.Join(ctx.path, "charm", "otherdata"))
   110  			c.Assert(err, gc.IsNil)
   111  			c.Assert(string(otherdata), gc.Equals, "blah")
   112  
   113  			// ignore should not (only in v1)
   114  			_, err = os.Stat(filepath.Join(ctx.path, "charm", "ignore"))
   115  			c.Assert(err, jc.Satisfies, os.IsNotExist)
   116  
   117  			// data should contain what was written in the start hook
   118  			data, err := ioutil.ReadFile(filepath.Join(ctx.path, "charm", "data"))
   119  			c.Assert(err, gc.IsNil)
   120  			c.Assert(string(data), gc.Equals, "STARTDATA\n")
   121  		}},
   122  	), ut(
   123  		"upgrade conflict service dying",
   124  		startGitUpgradeError{},
   125  		serviceDying,
   126  		verifyWaiting{},
   127  		resolveError{state.ResolvedNoHooks},
   128  		waitHooks{"upgrade-charm", "config-changed", "stop"},
   129  		waitUniterDead{},
   130  	), ut(
   131  		"upgrade conflict unit dying",
   132  		startGitUpgradeError{},
   133  		unitDying,
   134  		verifyWaiting{},
   135  		resolveError{state.ResolvedNoHooks},
   136  		waitHooks{"upgrade-charm", "config-changed", "stop"},
   137  		waitUniterDead{},
   138  	), ut(
   139  		"upgrade conflict unit dead",
   140  		startGitUpgradeError{},
   141  		unitDead,
   142  		waitUniterDead{},
   143  		waitHooks{},
   144  	),
   145  }
   146  
   147  func (s *UniterSuite) TestUniterUpgradeGitConflicts(c *gc.C) {
   148  	patchedTests := make([]uniterTest, len(upgradeGitConflictsTests))
   149  	for i, test := range upgradeGitConflictsTests {
   150  		patchedTests[i] = ut(test.summary, prepareGitUniter{test.steps})
   151  	}
   152  	s.runUniterTests(c, patchedTests)
   153  }
   154  
   155  type verifyGitCharm struct {
   156  	revision int
   157  	dirty    bool
   158  }
   159  
   160  func (s verifyGitCharm) step(c *gc.C, ctx *context) {
   161  	charmPath := filepath.Join(ctx.path, "charm")
   162  	if !s.dirty {
   163  		revisionPath := filepath.Join(charmPath, "revision")
   164  		content, err := ioutil.ReadFile(revisionPath)
   165  		c.Assert(err, gc.IsNil)
   166  		c.Assert(string(content), gc.Equals, strconv.Itoa(s.revision))
   167  		err = ctx.unit.Refresh()
   168  		c.Assert(err, gc.IsNil)
   169  		url, ok := ctx.unit.CharmURL()
   170  		c.Assert(ok, gc.Equals, true)
   171  		c.Assert(url, gc.DeepEquals, curl(s.revision))
   172  	}
   173  
   174  	// Before we try to check the git status, make sure expected hooks are all
   175  	// complete, to prevent the test and the uniter interfering with each other.
   176  	step(c, ctx, waitHooks{})
   177  	step(c, ctx, waitHooks{})
   178  	cmd := exec.Command("git", "status")
   179  	cmd.Dir = filepath.Join(ctx.path, "charm")
   180  	out, err := cmd.CombinedOutput()
   181  	c.Assert(err, gc.IsNil)
   182  	cmp := gc.Matches
   183  	if s.dirty {
   184  		cmp = gc.Not(gc.Matches)
   185  	}
   186  	c.Assert(string(out), cmp, "(# )?On branch master\nnothing to commit.*\n")
   187  }
   188  
   189  type startGitUpgradeError struct{}
   190  
   191  func (s startGitUpgradeError) step(c *gc.C, ctx *context) {
   192  	steps := []stepper{
   193  		createCharm{
   194  			customize: func(c *gc.C, ctx *context, path string) {
   195  				appendHook(c, path, "start", "echo STARTDATA > data")
   196  			},
   197  		},
   198  		serveCharm{},
   199  		createUniter{},
   200  		waitUnit{
   201  			status: params.StatusStarted,
   202  		},
   203  		waitHooks{"install", "config-changed", "start"},
   204  		verifyGitCharm{dirty: true},
   205  
   206  		createCharm{
   207  			revision: 1,
   208  			customize: func(c *gc.C, ctx *context, path string) {
   209  				ft.File{"data", "<nelson>ha ha</nelson>", 0644}.Create(c, path)
   210  				ft.File{"ignore", "anything", 0644}.Create(c, path)
   211  			},
   212  		},
   213  		serveCharm{},
   214  		upgradeCharm{revision: 1},
   215  		waitUnit{
   216  			status: params.StatusError,
   217  			info:   "upgrade failed",
   218  			charm:  1,
   219  		},
   220  		verifyWaiting{},
   221  		verifyGitCharm{dirty: true},
   222  	}
   223  	for _, s_ := range steps {
   224  		step(c, ctx, s_)
   225  	}
   226  }