github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/machine_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"sort"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/names"
    12  	jc "github.com/juju/testing/checkers"
    13  	jujutxn "github.com/juju/txn"
    14  	"github.com/juju/version"
    15  	gc "gopkg.in/check.v1"
    16  	"gopkg.in/mgo.v2"
    17  	"gopkg.in/mgo.v2/bson"
    18  
    19  	"github.com/juju/juju/constraints"
    20  	"github.com/juju/juju/environs/config"
    21  	"github.com/juju/juju/instance"
    22  	"github.com/juju/juju/network"
    23  	"github.com/juju/juju/state"
    24  	"github.com/juju/juju/state/testing"
    25  	"github.com/juju/juju/status"
    26  	"github.com/juju/juju/storage/poolmanager"
    27  	"github.com/juju/juju/storage/provider"
    28  	"github.com/juju/juju/storage/provider/registry"
    29  	coretesting "github.com/juju/juju/testing"
    30  )
    31  
    32  type MachineSuite struct {
    33  	ConnSuite
    34  	machine0 *state.Machine
    35  	machine  *state.Machine
    36  }
    37  
    38  var _ = gc.Suite(&MachineSuite{})
    39  
    40  func (s *MachineSuite) SetUpTest(c *gc.C) {
    41  	s.ConnSuite.SetUpTest(c)
    42  	s.policy.GetConstraintsValidator = func(*config.Config, state.SupportedArchitecturesQuerier) (constraints.Validator, error) {
    43  		validator := constraints.NewValidator()
    44  		validator.RegisterConflicts([]string{constraints.InstanceType}, []string{constraints.Mem})
    45  		validator.RegisterUnsupported([]string{constraints.CpuPower})
    46  		return validator, nil
    47  	}
    48  	var err error
    49  	s.machine0, err = s.State.AddMachine("quantal", state.JobManageModel)
    50  	c.Assert(err, jc.ErrorIsNil)
    51  	s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits)
    52  	c.Assert(err, jc.ErrorIsNil)
    53  }
    54  
    55  func (s *MachineSuite) TestSetRebootFlagDeadMachine(c *gc.C) {
    56  	err := s.machine.EnsureDead()
    57  	c.Assert(err, jc.ErrorIsNil)
    58  
    59  	err = s.machine.SetRebootFlag(true)
    60  	c.Assert(err, gc.Equals, mgo.ErrNotFound)
    61  
    62  	rFlag, err := s.machine.GetRebootFlag()
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	c.Assert(rFlag, jc.IsFalse)
    65  
    66  	err = s.machine.SetRebootFlag(false)
    67  	c.Assert(err, jc.ErrorIsNil)
    68  
    69  	action, err := s.machine.ShouldRebootOrShutdown()
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	c.Assert(action, gc.Equals, state.ShouldDoNothing)
    72  }
    73  
    74  func (s *MachineSuite) TestSetRebootFlagDeadMachineRace(c *gc.C) {
    75  	setFlag := jujutxn.TestHook{
    76  		Before: func() {
    77  			err := s.machine.EnsureDead()
    78  			c.Assert(err, jc.ErrorIsNil)
    79  		},
    80  	}
    81  	defer state.SetTestHooks(c, s.State, setFlag).Check()
    82  
    83  	err := s.machine.SetRebootFlag(true)
    84  	c.Assert(err, gc.Equals, mgo.ErrNotFound)
    85  }
    86  
    87  func (s *MachineSuite) TestSetRebootFlag(c *gc.C) {
    88  	err := s.machine.SetRebootFlag(true)
    89  	c.Assert(err, jc.ErrorIsNil)
    90  
    91  	rebootFlag, err := s.machine.GetRebootFlag()
    92  	c.Assert(err, jc.ErrorIsNil)
    93  	c.Assert(rebootFlag, jc.IsTrue)
    94  }
    95  
    96  func (s *MachineSuite) TestSetUnsetRebootFlag(c *gc.C) {
    97  	err := s.machine.SetRebootFlag(true)
    98  	c.Assert(err, jc.ErrorIsNil)
    99  
   100  	rebootFlag, err := s.machine.GetRebootFlag()
   101  	c.Assert(err, jc.ErrorIsNil)
   102  	c.Assert(rebootFlag, jc.IsTrue)
   103  
   104  	err = s.machine.SetRebootFlag(false)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  
   107  	rebootFlag, err = s.machine.GetRebootFlag()
   108  	c.Assert(err, jc.ErrorIsNil)
   109  	c.Assert(rebootFlag, jc.IsFalse)
   110  }
   111  
   112  func (s *MachineSuite) TestAddMachineInsideMachineModelDying(c *gc.C) {
   113  	model, err := s.State.Model()
   114  	c.Assert(err, jc.ErrorIsNil)
   115  	c.Assert(model.Destroy(), jc.ErrorIsNil)
   116  
   117  	_, err = s.State.AddMachineInsideMachine(state.MachineTemplate{
   118  		Series: "quantal",
   119  		Jobs:   []state.MachineJob{state.JobHostUnits},
   120  	}, s.machine.Id(), instance.LXC)
   121  	c.Assert(err, gc.ErrorMatches, `model "testenv" is no longer alive`)
   122  }
   123  
   124  func (s *MachineSuite) TestAddMachineInsideMachineModelMigrating(c *gc.C) {
   125  	model, err := s.State.Model()
   126  	c.Assert(err, jc.ErrorIsNil)
   127  	c.Assert(model.SetMigrationMode(state.MigrationModeExporting), jc.ErrorIsNil)
   128  
   129  	_, err = s.State.AddMachineInsideMachine(state.MachineTemplate{
   130  		Series: "quantal",
   131  		Jobs:   []state.MachineJob{state.JobHostUnits},
   132  	}, s.machine.Id(), instance.LXC)
   133  	c.Assert(err, gc.ErrorMatches, `model "testenv" is being migrated`)
   134  }
   135  
   136  func (s *MachineSuite) TestShouldShutdownOrReboot(c *gc.C) {
   137  	// Add first container.
   138  	c1, err := s.State.AddMachineInsideMachine(state.MachineTemplate{
   139  		Series: "quantal",
   140  		Jobs:   []state.MachineJob{state.JobHostUnits},
   141  	}, s.machine.Id(), instance.LXC)
   142  	c.Assert(err, jc.ErrorIsNil)
   143  
   144  	// Add second container.
   145  	c2, err := s.State.AddMachineInsideMachine(state.MachineTemplate{
   146  		Series: "quantal",
   147  		Jobs:   []state.MachineJob{state.JobHostUnits},
   148  	}, c1.Id(), instance.LXC)
   149  	c.Assert(err, jc.ErrorIsNil)
   150  
   151  	err = c2.SetRebootFlag(true)
   152  	c.Assert(err, jc.ErrorIsNil)
   153  
   154  	rAction, err := s.machine.ShouldRebootOrShutdown()
   155  	c.Assert(err, jc.ErrorIsNil)
   156  	c.Assert(rAction, gc.Equals, state.ShouldDoNothing)
   157  
   158  	rAction, err = c1.ShouldRebootOrShutdown()
   159  	c.Assert(err, jc.ErrorIsNil)
   160  	c.Assert(rAction, gc.Equals, state.ShouldDoNothing)
   161  
   162  	rAction, err = c2.ShouldRebootOrShutdown()
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	c.Assert(rAction, gc.Equals, state.ShouldReboot)
   165  
   166  	// // Reboot happens on the root node
   167  	err = c2.SetRebootFlag(false)
   168  	c.Assert(err, jc.ErrorIsNil)
   169  
   170  	err = s.machine.SetRebootFlag(true)
   171  	c.Assert(err, jc.ErrorIsNil)
   172  
   173  	rAction, err = s.machine.ShouldRebootOrShutdown()
   174  	c.Assert(err, jc.ErrorIsNil)
   175  	c.Assert(rAction, gc.Equals, state.ShouldReboot)
   176  
   177  	rAction, err = c1.ShouldRebootOrShutdown()
   178  	c.Assert(err, jc.ErrorIsNil)
   179  	c.Assert(rAction, gc.Equals, state.ShouldShutdown)
   180  
   181  	rAction, err = c2.ShouldRebootOrShutdown()
   182  	c.Assert(err, jc.ErrorIsNil)
   183  	c.Assert(rAction, gc.Equals, state.ShouldShutdown)
   184  }
   185  
   186  func (s *MachineSuite) TestContainerDefaults(c *gc.C) {
   187  	c.Assert(string(s.machine.ContainerType()), gc.Equals, "")
   188  	containers, err := s.machine.Containers()
   189  	c.Assert(err, jc.ErrorIsNil)
   190  	c.Assert(containers, gc.DeepEquals, []string(nil))
   191  }
   192  
   193  func (s *MachineSuite) TestParentId(c *gc.C) {
   194  	parentId, ok := s.machine.ParentId()
   195  	c.Assert(parentId, gc.Equals, "")
   196  	c.Assert(ok, jc.IsFalse)
   197  	container, err := s.State.AddMachineInsideMachine(state.MachineTemplate{
   198  		Series: "quantal",
   199  		Jobs:   []state.MachineJob{state.JobHostUnits},
   200  	}, s.machine.Id(), instance.LXC)
   201  	c.Assert(err, jc.ErrorIsNil)
   202  	parentId, ok = container.ParentId()
   203  	c.Assert(parentId, gc.Equals, s.machine.Id())
   204  	c.Assert(ok, jc.IsTrue)
   205  }
   206  
   207  func (s *MachineSuite) TestMachineIsManager(c *gc.C) {
   208  	c.Assert(s.machine0.IsManager(), jc.IsTrue)
   209  	c.Assert(s.machine.IsManager(), jc.IsFalse)
   210  }
   211  
   212  func (s *MachineSuite) TestMachineIsManualBootstrap(c *gc.C) {
   213  	cfg, err := s.State.ModelConfig()
   214  	c.Assert(err, jc.ErrorIsNil)
   215  	c.Assert(cfg.Type(), gc.Not(gc.Equals), "null")
   216  	c.Assert(s.machine.Id(), gc.Equals, "1")
   217  	manual, err := s.machine0.IsManual()
   218  	c.Assert(err, jc.ErrorIsNil)
   219  	c.Assert(manual, jc.IsFalse)
   220  	attrs := map[string]interface{}{"type": "null"}
   221  	err = s.State.UpdateModelConfig(attrs, nil, nil)
   222  	c.Assert(err, jc.ErrorIsNil)
   223  	manual, err = s.machine0.IsManual()
   224  	c.Assert(err, jc.ErrorIsNil)
   225  	c.Assert(manual, jc.IsTrue)
   226  }
   227  
   228  func (s *MachineSuite) TestMachineIsManual(c *gc.C) {
   229  	tests := []struct {
   230  		instanceId instance.Id
   231  		nonce      string
   232  		isManual   bool
   233  	}{
   234  		{instanceId: "x", nonce: "y", isManual: false},
   235  		{instanceId: "manual:", nonce: "y", isManual: false},
   236  		{instanceId: "x", nonce: "manual:", isManual: true},
   237  		{instanceId: "x", nonce: "manual:y", isManual: true},
   238  		{instanceId: "x", nonce: "manual", isManual: false},
   239  	}
   240  	for _, test := range tests {
   241  		m, err := s.State.AddOneMachine(state.MachineTemplate{
   242  			Series:     "quantal",
   243  			Jobs:       []state.MachineJob{state.JobHostUnits},
   244  			InstanceId: test.instanceId,
   245  			Nonce:      test.nonce,
   246  		})
   247  		c.Assert(err, jc.ErrorIsNil)
   248  		isManual, err := m.IsManual()
   249  		c.Assert(isManual, gc.Equals, test.isManual)
   250  	}
   251  }
   252  
   253  func (s *MachineSuite) TestMachineIsContainer(c *gc.C) {
   254  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   255  	c.Assert(err, jc.ErrorIsNil)
   256  
   257  	template := state.MachineTemplate{
   258  		Series: "quantal",
   259  		Jobs:   []state.MachineJob{state.JobHostUnits},
   260  	}
   261  	container, err := s.State.AddMachineInsideMachine(template, machine.Id(), instance.LXC)
   262  	c.Assert(err, jc.ErrorIsNil)
   263  
   264  	c.Assert(machine.IsContainer(), jc.IsFalse)
   265  	c.Assert(container.IsContainer(), jc.IsTrue)
   266  }
   267  
   268  func (s *MachineSuite) TestLifeJobManageModel(c *gc.C) {
   269  	// A JobManageModel machine must never advance lifecycle.
   270  	m := s.machine0
   271  	err := m.Destroy()
   272  	c.Assert(err, gc.ErrorMatches, "machine 0 is required by the model")
   273  	err = m.ForceDestroy()
   274  	c.Assert(err, gc.ErrorMatches, "machine is required by the model")
   275  	err = m.EnsureDead()
   276  	c.Assert(err, gc.ErrorMatches, "machine 0 is required by the model")
   277  }
   278  
   279  func (s *MachineSuite) TestLifeMachineWithContainer(c *gc.C) {
   280  	// A machine hosting a container must not advance lifecycle.
   281  	_, err := s.State.AddMachineInsideMachine(state.MachineTemplate{
   282  		Series: "quantal",
   283  		Jobs:   []state.MachineJob{state.JobHostUnits},
   284  	}, s.machine.Id(), instance.LXC)
   285  	c.Assert(err, jc.ErrorIsNil)
   286  	err = s.machine.Destroy()
   287  	c.Assert(err, gc.FitsTypeOf, &state.HasContainersError{})
   288  	c.Assert(err, gc.ErrorMatches, `machine 1 is hosting containers "1/lxc/0"`)
   289  	err1 := s.machine.EnsureDead()
   290  	c.Assert(err1, gc.DeepEquals, err)
   291  	c.Assert(s.machine.Life(), gc.Equals, state.Alive)
   292  }
   293  
   294  func (s *MachineSuite) TestLifeJobHostUnits(c *gc.C) {
   295  	// A machine with an assigned unit must not advance lifecycle.
   296  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   297  	unit, err := svc.AddUnit()
   298  	c.Assert(err, jc.ErrorIsNil)
   299  	err = unit.AssignToMachine(s.machine)
   300  	c.Assert(err, jc.ErrorIsNil)
   301  	err = s.machine.Destroy()
   302  	c.Assert(err, jc.Satisfies, state.IsHasAssignedUnitsError)
   303  	c.Assert(err, gc.ErrorMatches, `machine 1 has unit "wordpress/0" assigned`)
   304  	err1 := s.machine.EnsureDead()
   305  	c.Assert(err1, gc.DeepEquals, err)
   306  	c.Assert(s.machine.Life(), gc.Equals, state.Alive)
   307  
   308  	// Once no unit is assigned, lifecycle can advance.
   309  	err = unit.UnassignFromMachine()
   310  	c.Assert(err, jc.ErrorIsNil)
   311  	err = s.machine.Destroy()
   312  	c.Assert(s.machine.Life(), gc.Equals, state.Dying)
   313  	c.Assert(err, jc.ErrorIsNil)
   314  	err = s.machine.EnsureDead()
   315  	c.Assert(err, jc.ErrorIsNil)
   316  	c.Assert(s.machine.Life(), gc.Equals, state.Dead)
   317  
   318  	// A machine that has never had units assigned can advance lifecycle.
   319  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
   320  	c.Assert(err, jc.ErrorIsNil)
   321  	err = m.Destroy()
   322  	c.Assert(err, jc.ErrorIsNil)
   323  	c.Assert(m.Life(), gc.Equals, state.Dying)
   324  	err = m.EnsureDead()
   325  	c.Assert(err, jc.ErrorIsNil)
   326  	c.Assert(m.Life(), gc.Equals, state.Dead)
   327  }
   328  
   329  func (s *MachineSuite) TestDestroyRemovePorts(c *gc.C) {
   330  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   331  	unit, err := svc.AddUnit()
   332  	c.Assert(err, jc.ErrorIsNil)
   333  	err = unit.AssignToMachine(s.machine)
   334  	c.Assert(err, jc.ErrorIsNil)
   335  	err = unit.OpenPort("tcp", 8080)
   336  	c.Assert(err, jc.ErrorIsNil)
   337  	ports, err := state.GetPorts(s.State, s.machine.Id(), "")
   338  	c.Assert(ports, gc.NotNil)
   339  	c.Assert(err, jc.ErrorIsNil)
   340  	err = unit.UnassignFromMachine()
   341  	c.Assert(err, jc.ErrorIsNil)
   342  	err = s.machine.Destroy()
   343  	c.Assert(err, jc.ErrorIsNil)
   344  	err = s.machine.EnsureDead()
   345  	c.Assert(err, jc.ErrorIsNil)
   346  	err = s.machine.Remove()
   347  	c.Assert(err, jc.ErrorIsNil)
   348  	// once the machine is destroyed, there should be no ports documents present for it
   349  	ports, err = state.GetPorts(s.State, s.machine.Id(), "")
   350  	c.Assert(ports, gc.IsNil)
   351  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   352  }
   353  
   354  func (s *MachineSuite) TestDestroyOps(c *gc.C) {
   355  	m := s.Factory.MakeMachine(c, nil)
   356  	ops, err := state.ForceDestroyMachineOps(m)
   357  	c.Assert(err, jc.ErrorIsNil)
   358  	c.Assert(ops, gc.NotNil)
   359  }
   360  
   361  func (s *MachineSuite) TestDestroyOpsForManagerFails(c *gc.C) {
   362  	// s.Factory does not allow us to make a manager machine, so we grab one
   363  	// from State ...
   364  	machines, err := s.State.AllMachines()
   365  	c.Assert(err, jc.ErrorIsNil)
   366  	c.Assert(len(machines), jc.GreaterThan, 0)
   367  	m := machines[0]
   368  	c.Assert(m.IsManager(), jc.IsTrue)
   369  
   370  	// ... and assert that we cannot get the destroy ops for it.
   371  	ops, err := state.ForceDestroyMachineOps(m)
   372  	c.Assert(err, jc.Satisfies, state.IsManagerMachineError)
   373  	c.Assert(ops, gc.IsNil)
   374  }
   375  
   376  func (s *MachineSuite) TestDestroyAbort(c *gc.C) {
   377  	defer state.SetBeforeHooks(c, s.State, func() {
   378  		c.Assert(s.machine.Destroy(), gc.IsNil)
   379  	}).Check()
   380  	err := s.machine.Destroy()
   381  	c.Assert(err, jc.ErrorIsNil)
   382  }
   383  
   384  func (s *MachineSuite) TestDestroyCancel(c *gc.C) {
   385  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   386  	unit, err := svc.AddUnit()
   387  	c.Assert(err, jc.ErrorIsNil)
   388  
   389  	defer state.SetBeforeHooks(c, s.State, func() {
   390  		c.Assert(unit.AssignToMachine(s.machine), gc.IsNil)
   391  	}).Check()
   392  	err = s.machine.Destroy()
   393  	c.Assert(err, jc.Satisfies, state.IsHasAssignedUnitsError)
   394  }
   395  
   396  func (s *MachineSuite) TestDestroyContention(c *gc.C) {
   397  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   398  	unit, err := svc.AddUnit()
   399  	c.Assert(err, jc.ErrorIsNil)
   400  
   401  	perturb := jujutxn.TestHook{
   402  		Before: func() { c.Assert(unit.AssignToMachine(s.machine), gc.IsNil) },
   403  		After:  func() { c.Assert(unit.UnassignFromMachine(), gc.IsNil) },
   404  	}
   405  	defer state.SetTestHooks(c, s.State, perturb, perturb, perturb).Check()
   406  
   407  	err = s.machine.Destroy()
   408  	c.Assert(err, gc.ErrorMatches, "machine 1 cannot advance lifecycle: state changing too quickly; try again soon")
   409  }
   410  
   411  func (s *MachineSuite) TestDestroyWithServiceDestroyPending(c *gc.C) {
   412  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   413  	unit, err := svc.AddUnit()
   414  	c.Assert(err, jc.ErrorIsNil)
   415  	err = unit.AssignToMachine(s.machine)
   416  	c.Assert(err, jc.ErrorIsNil)
   417  
   418  	err = svc.Destroy()
   419  	c.Assert(err, jc.ErrorIsNil)
   420  	err = s.machine.Destroy()
   421  	c.Assert(err, jc.ErrorIsNil)
   422  	// Machine is still advanced to Dying.
   423  	life := s.machine.Life()
   424  	c.Assert(life, gc.Equals, state.Dying)
   425  }
   426  
   427  func (s *MachineSuite) TestDestroyFailsWhenNewUnitAdded(c *gc.C) {
   428  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   429  	unit, err := svc.AddUnit()
   430  	c.Assert(err, jc.ErrorIsNil)
   431  	err = unit.AssignToMachine(s.machine)
   432  	c.Assert(err, jc.ErrorIsNil)
   433  
   434  	err = svc.Destroy()
   435  	c.Assert(err, jc.ErrorIsNil)
   436  
   437  	defer state.SetBeforeHooks(c, s.State, func() {
   438  		anotherSvc := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql"))
   439  		anotherUnit, err := anotherSvc.AddUnit()
   440  		c.Assert(err, jc.ErrorIsNil)
   441  		err = anotherUnit.AssignToMachine(s.machine)
   442  		c.Assert(err, jc.ErrorIsNil)
   443  	}).Check()
   444  
   445  	err = s.machine.Destroy()
   446  	c.Assert(err, jc.Satisfies, state.IsHasAssignedUnitsError)
   447  	life := s.machine.Life()
   448  	c.Assert(life, gc.Equals, state.Alive)
   449  }
   450  
   451  func (s *MachineSuite) TestDestroyWithUnitDestroyPending(c *gc.C) {
   452  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   453  	unit, err := svc.AddUnit()
   454  	c.Assert(err, jc.ErrorIsNil)
   455  	err = unit.AssignToMachine(s.machine)
   456  	c.Assert(err, jc.ErrorIsNil)
   457  
   458  	err = unit.Destroy()
   459  	c.Assert(err, jc.ErrorIsNil)
   460  	err = s.machine.Destroy()
   461  	c.Assert(err, jc.ErrorIsNil)
   462  	// Machine is still advanced to Dying.
   463  	life := s.machine.Life()
   464  	c.Assert(life, gc.Equals, state.Dying)
   465  }
   466  
   467  func (s *MachineSuite) TestDestroyFailsWhenNewContainerAdded(c *gc.C) {
   468  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
   469  	unit, err := svc.AddUnit()
   470  	c.Assert(err, jc.ErrorIsNil)
   471  	err = unit.AssignToMachine(s.machine)
   472  	c.Assert(err, jc.ErrorIsNil)
   473  
   474  	err = svc.Destroy()
   475  	c.Assert(err, jc.ErrorIsNil)
   476  
   477  	defer state.SetBeforeHooks(c, s.State, func() {
   478  		_, err := s.State.AddMachineInsideMachine(state.MachineTemplate{
   479  			Series: "quantal",
   480  			Jobs:   []state.MachineJob{state.JobHostUnits},
   481  		}, s.machine.Id(), instance.LXC)
   482  		c.Assert(err, jc.ErrorIsNil)
   483  	}).Check()
   484  
   485  	err = s.machine.Destroy()
   486  	c.Assert(err, jc.Satisfies, state.IsHasAssignedUnitsError)
   487  	life := s.machine.Life()
   488  	c.Assert(life, gc.Equals, state.Alive)
   489  }
   490  
   491  func (s *MachineSuite) TestRemove(c *gc.C) {
   492  	err := s.State.SetSSHHostKeys(s.machine.MachineTag(), state.SSHHostKeys{"rsa", "dsa"})
   493  	c.Assert(err, jc.ErrorIsNil)
   494  
   495  	err = s.machine.Remove()
   496  	c.Assert(err, gc.ErrorMatches, "cannot remove machine 1: machine is not dead")
   497  
   498  	err = s.machine.EnsureDead()
   499  	c.Assert(err, jc.ErrorIsNil)
   500  
   501  	err = s.machine.Remove()
   502  	c.Assert(err, jc.ErrorIsNil)
   503  
   504  	err = s.machine.Refresh()
   505  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   506  
   507  	_, err = s.machine.HardwareCharacteristics()
   508  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   509  
   510  	_, err = s.machine.Containers()
   511  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   512  
   513  	_, err = s.State.GetSSHHostKeys(s.machine.MachineTag())
   514  	c.Assert(errors.IsNotFound(err), jc.IsTrue)
   515  
   516  	// Removing an already removed machine is OK.
   517  	err = s.machine.Remove()
   518  	c.Assert(err, jc.ErrorIsNil)
   519  }
   520  
   521  func (s *MachineSuite) TestRemoveMarksAddressesAsDead(c *gc.C) {
   522  	err := s.machine.SetProvisioned("fake", "totally-fake", nil)
   523  	c.Assert(err, jc.ErrorIsNil)
   524  
   525  	addr1, err := s.State.AddIPAddress(network.NewAddress("10.0.0.1"), "foo")
   526  	c.Assert(err, jc.ErrorIsNil)
   527  	err = addr1.AllocateTo(s.machine.Id(), "bar", "01:23:45:67:89:ab")
   528  	c.Assert(err, jc.ErrorIsNil)
   529  
   530  	addr2, err := s.State.AddIPAddress(network.NewAddress("10.0.0.2"), "foo")
   531  	c.Assert(err, jc.ErrorIsNil)
   532  	err = addr2.AllocateTo(s.machine.Id(), "bar", "01:23:45:67:89:ab")
   533  	c.Assert(err, jc.ErrorIsNil)
   534  
   535  	addr3, err := s.State.AddIPAddress(network.NewAddress("10.0.0.3"), "bar")
   536  	c.Assert(err, jc.ErrorIsNil)
   537  	err = addr3.AllocateTo(s.machine0.Id(), "bar", "01:23:45:67:89:ab")
   538  	c.Assert(err, jc.ErrorIsNil)
   539  
   540  	addr4, err := s.State.AddIPAddress(network.NewAddress("10.0.0.4"), "foo")
   541  	c.Assert(err, jc.ErrorIsNil)
   542  	err = addr4.AllocateTo(s.machine.Id(), "bar", "01:23:45:67:89:ab")
   543  	c.Assert(err, jc.ErrorIsNil)
   544  	err = addr4.EnsureDead()
   545  	c.Assert(err, jc.ErrorIsNil)
   546  
   547  	err = s.machine.EnsureDead()
   548  	c.Assert(err, jc.ErrorIsNil)
   549  	err = s.machine.Remove()
   550  	c.Assert(err, jc.ErrorIsNil)
   551  
   552  	err = addr1.Refresh()
   553  	c.Assert(err, jc.ErrorIsNil)
   554  	c.Assert(addr1.Life(), gc.Equals, state.Dead)
   555  	err = addr2.Refresh()
   556  	c.Assert(err, jc.ErrorIsNil)
   557  	c.Assert(addr2.Life(), gc.Equals, state.Dead)
   558  	err = addr3.Refresh()
   559  	c.Assert(err, jc.ErrorIsNil)
   560  	c.Assert(addr3.Life(), gc.Equals, state.Alive)
   561  	err = addr4.Refresh()
   562  	c.Assert(err, jc.ErrorIsNil)
   563  	c.Assert(addr4.Life(), gc.Equals, state.Dead)
   564  }
   565  
   566  func (s *MachineSuite) TestHasVote(c *gc.C) {
   567  	c.Assert(s.machine.HasVote(), jc.IsFalse)
   568  
   569  	// Make another machine value so that
   570  	// it won't have the cached HasVote value.
   571  	m, err := s.State.Machine(s.machine.Id())
   572  	c.Assert(err, jc.ErrorIsNil)
   573  
   574  	err = s.machine.SetHasVote(true)
   575  	c.Assert(err, jc.ErrorIsNil)
   576  	c.Assert(s.machine.HasVote(), jc.IsTrue)
   577  	c.Assert(m.HasVote(), jc.IsFalse)
   578  
   579  	err = m.Refresh()
   580  	c.Assert(err, jc.ErrorIsNil)
   581  	c.Assert(m.HasVote(), jc.IsTrue)
   582  
   583  	err = m.SetHasVote(false)
   584  	c.Assert(err, jc.ErrorIsNil)
   585  	c.Assert(m.HasVote(), jc.IsFalse)
   586  
   587  	c.Assert(s.machine.HasVote(), jc.IsTrue)
   588  	err = s.machine.Refresh()
   589  	c.Assert(err, jc.ErrorIsNil)
   590  	c.Assert(s.machine.HasVote(), jc.IsFalse)
   591  }
   592  
   593  func (s *MachineSuite) TestCannotDestroyMachineWithVote(c *gc.C) {
   594  	err := s.machine.SetHasVote(true)
   595  	c.Assert(err, jc.ErrorIsNil)
   596  
   597  	// Make another machine value so that
   598  	// it won't have the cached HasVote value.
   599  	m, err := s.State.Machine(s.machine.Id())
   600  	c.Assert(err, jc.ErrorIsNil)
   601  
   602  	err = s.machine.Destroy()
   603  	c.Assert(err, gc.ErrorMatches, "machine "+s.machine.Id()+" is a voting replica set member")
   604  
   605  	err = m.Destroy()
   606  	c.Assert(err, gc.ErrorMatches, "machine "+s.machine.Id()+" is a voting replica set member")
   607  }
   608  
   609  func (s *MachineSuite) TestRemoveAbort(c *gc.C) {
   610  	err := s.machine.EnsureDead()
   611  	c.Assert(err, jc.ErrorIsNil)
   612  
   613  	defer state.SetBeforeHooks(c, s.State, func() {
   614  		c.Assert(s.machine.Remove(), gc.IsNil)
   615  	}).Check()
   616  	err = s.machine.Remove()
   617  	c.Assert(err, jc.ErrorIsNil)
   618  }
   619  
   620  func (s *MachineSuite) TestMachineSetAgentPresence(c *gc.C) {
   621  	alive, err := s.machine.AgentPresence()
   622  	c.Assert(err, jc.ErrorIsNil)
   623  	c.Assert(alive, jc.IsFalse)
   624  
   625  	pinger, err := s.machine.SetAgentPresence()
   626  	c.Assert(err, jc.ErrorIsNil)
   627  	c.Assert(pinger, gc.NotNil)
   628  	defer pinger.Stop()
   629  
   630  	s.State.StartSync()
   631  	alive, err = s.machine.AgentPresence()
   632  	c.Assert(err, jc.ErrorIsNil)
   633  	c.Assert(alive, jc.IsTrue)
   634  }
   635  
   636  func (s *MachineSuite) TestTag(c *gc.C) {
   637  	tag := s.machine.MachineTag()
   638  	c.Assert(tag.Kind(), gc.Equals, names.MachineTagKind)
   639  	c.Assert(tag.Id(), gc.Equals, "1")
   640  
   641  	// To keep gccgo happy, don't compare an interface with a struct.
   642  	var asTag names.Tag = tag
   643  	c.Assert(s.machine.Tag(), gc.Equals, asTag)
   644  }
   645  
   646  func (s *MachineSuite) TestSetMongoPassword(c *gc.C) {
   647  	info := testing.NewMongoInfo()
   648  	st, err := state.Open(s.modelTag, info, testing.NewDialOpts(), state.Policy(nil))
   649  	c.Assert(err, jc.ErrorIsNil)
   650  	defer func() {
   651  		// Remove the admin password so that the test harness can reset the state.
   652  		err := st.SetAdminMongoPassword("")
   653  		c.Check(err, jc.ErrorIsNil)
   654  		err = st.Close()
   655  		c.Check(err, jc.ErrorIsNil)
   656  	}()
   657  
   658  	// Turn on fully-authenticated mode.
   659  	err = st.SetAdminMongoPassword("admin-secret")
   660  	c.Assert(err, jc.ErrorIsNil)
   661  	err = st.MongoSession().DB("admin").Login("admin", "admin-secret")
   662  	c.Assert(err, jc.ErrorIsNil)
   663  
   664  	// Set the password for the entity
   665  	ent, err := st.Machine("0")
   666  	c.Assert(err, jc.ErrorIsNil)
   667  	err = ent.SetMongoPassword("foo")
   668  	c.Assert(err, jc.ErrorIsNil)
   669  
   670  	// Check that we cannot log in with the wrong password.
   671  	info.Tag = ent.Tag()
   672  	info.Password = "bar"
   673  	err = tryOpenState(s.modelTag, info)
   674  	c.Check(errors.Cause(err), jc.Satisfies, errors.IsUnauthorized)
   675  	c.Check(err, gc.ErrorMatches, `cannot log in to admin database as "machine-0": unauthorized mongo access: .*`)
   676  
   677  	// Check that we can log in with the correct password.
   678  	info.Password = "foo"
   679  	st1, err := state.Open(s.modelTag, info, testing.NewDialOpts(), state.Policy(nil))
   680  	c.Assert(err, jc.ErrorIsNil)
   681  	defer st1.Close()
   682  
   683  	// Change the password with an entity derived from the newly
   684  	// opened and authenticated state.
   685  	ent, err = st.Machine("0")
   686  	c.Assert(err, jc.ErrorIsNil)
   687  	err = ent.SetMongoPassword("bar")
   688  	c.Assert(err, jc.ErrorIsNil)
   689  
   690  	// Check that we cannot log in with the old password.
   691  	info.Password = "foo"
   692  	err = tryOpenState(s.modelTag, info)
   693  	c.Check(errors.Cause(err), jc.Satisfies, errors.IsUnauthorized)
   694  	c.Check(err, gc.ErrorMatches, `cannot log in to admin database as "machine-0": unauthorized mongo access: .*`)
   695  
   696  	// Check that we can log in with the correct password.
   697  	info.Password = "bar"
   698  	err = tryOpenState(s.modelTag, info)
   699  	c.Assert(err, jc.ErrorIsNil)
   700  
   701  	// Check that the administrator can still log in.
   702  	info.Tag, info.Password = nil, "admin-secret"
   703  	err = tryOpenState(s.modelTag, info)
   704  	c.Assert(err, jc.ErrorIsNil)
   705  }
   706  
   707  func (s *MachineSuite) TestSetPassword(c *gc.C) {
   708  	testSetPassword(c, func() (state.Authenticator, error) {
   709  		return s.State.Machine(s.machine.Id())
   710  	})
   711  }
   712  
   713  func (s *MachineSuite) TestSetPasswordPreModelUUID(c *gc.C) {
   714  	// Ensure that SetPassword works for machines even when the env
   715  	// UUID upgrade migrations haven't run yet.
   716  	type oldMachineDoc struct {
   717  		Id     string `bson:"_id"`
   718  		Series string
   719  	}
   720  	s.machines.Insert(&oldMachineDoc{"99", "quantal"})
   721  
   722  	m, err := s.State.Machine("99")
   723  	c.Assert(err, jc.ErrorIsNil)
   724  
   725  	// Set the password and make sure it sticks.
   726  	c.Assert(m.PasswordValid(goodPassword), jc.IsFalse)
   727  	err = m.SetPassword(goodPassword)
   728  	c.Assert(err, jc.ErrorIsNil)
   729  	c.Assert(m.PasswordValid(goodPassword), jc.IsTrue)
   730  
   731  	// Check a newly-fetched entity has the same password.
   732  	err = m.Refresh()
   733  	c.Assert(err, jc.ErrorIsNil)
   734  	c.Assert(m.PasswordValid(goodPassword), jc.IsTrue)
   735  }
   736  
   737  func (s *MachineSuite) TestMachineWaitAgentPresence(c *gc.C) {
   738  	alive, err := s.machine.AgentPresence()
   739  	c.Assert(err, jc.ErrorIsNil)
   740  	c.Assert(alive, jc.IsFalse)
   741  
   742  	s.State.StartSync()
   743  	err = s.machine.WaitAgentPresence(coretesting.ShortWait)
   744  	c.Assert(err, gc.ErrorMatches, `waiting for agent of machine 1: still not alive after timeout`)
   745  
   746  	pinger, err := s.machine.SetAgentPresence()
   747  	c.Assert(err, jc.ErrorIsNil)
   748  
   749  	s.State.StartSync()
   750  	err = s.machine.WaitAgentPresence(coretesting.LongWait)
   751  	c.Assert(err, jc.ErrorIsNil)
   752  
   753  	alive, err = s.machine.AgentPresence()
   754  	c.Assert(err, jc.ErrorIsNil)
   755  	c.Assert(alive, jc.IsTrue)
   756  
   757  	err = pinger.KillForTesting()
   758  	c.Assert(err, jc.ErrorIsNil)
   759  
   760  	s.State.StartSync()
   761  	alive, err = s.machine.AgentPresence()
   762  	c.Assert(err, jc.ErrorIsNil)
   763  	c.Assert(alive, jc.IsFalse)
   764  }
   765  
   766  func (s *MachineSuite) TestMachineInstanceIdCorrupt(c *gc.C) {
   767  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   768  	c.Assert(err, jc.ErrorIsNil)
   769  	err = s.machines.Update(
   770  		bson.D{{"_id", state.DocID(s.State, machine.Id())}},
   771  		bson.D{{"$set", bson.D{{"instanceid", bson.D{{"foo", "bar"}}}}}},
   772  	)
   773  	c.Assert(err, jc.ErrorIsNil)
   774  
   775  	err = machine.Refresh()
   776  	c.Assert(err, jc.ErrorIsNil)
   777  	iid, err := machine.InstanceId()
   778  	c.Assert(err, jc.Satisfies, errors.IsNotProvisioned)
   779  	c.Assert(iid, gc.Equals, instance.Id(""))
   780  }
   781  
   782  func (s *MachineSuite) TestMachineInstanceIdMissing(c *gc.C) {
   783  	iid, err := s.machine.InstanceId()
   784  	c.Assert(err, jc.Satisfies, errors.IsNotProvisioned)
   785  	c.Assert(string(iid), gc.Equals, "")
   786  }
   787  
   788  func (s *MachineSuite) TestMachineInstanceIdBlank(c *gc.C) {
   789  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
   790  	c.Assert(err, jc.ErrorIsNil)
   791  	err = s.machines.Update(
   792  		bson.D{{"_id", state.DocID(s.State, machine.Id())}},
   793  		bson.D{{"$set", bson.D{{"instanceid", ""}}}},
   794  	)
   795  	c.Assert(err, jc.ErrorIsNil)
   796  
   797  	err = machine.Refresh()
   798  	c.Assert(err, jc.ErrorIsNil)
   799  	iid, err := machine.InstanceId()
   800  	c.Assert(err, jc.Satisfies, errors.IsNotProvisioned)
   801  	c.Assert(string(iid), gc.Equals, "")
   802  }
   803  
   804  func (s *MachineSuite) TestMachineSetProvisionedUpdatesCharacteristics(c *gc.C) {
   805  	// Before provisioning, there is no hardware characteristics.
   806  	_, err := s.machine.HardwareCharacteristics()
   807  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   808  	arch := "amd64"
   809  	mem := uint64(4096)
   810  	expected := &instance.HardwareCharacteristics{
   811  		Arch: &arch,
   812  		Mem:  &mem,
   813  	}
   814  	err = s.machine.SetProvisioned("umbrella/0", "fake_nonce", expected)
   815  	c.Assert(err, jc.ErrorIsNil)
   816  	md, err := s.machine.HardwareCharacteristics()
   817  	c.Assert(err, jc.ErrorIsNil)
   818  	c.Assert(*md, gc.DeepEquals, *expected)
   819  
   820  	// Reload machine and check again.
   821  	err = s.machine.Refresh()
   822  	c.Assert(err, jc.ErrorIsNil)
   823  	md, err = s.machine.HardwareCharacteristics()
   824  	c.Assert(err, jc.ErrorIsNil)
   825  	c.Assert(*md, gc.DeepEquals, *expected)
   826  }
   827  
   828  func (s *MachineSuite) TestMachineAvailabilityZone(c *gc.C) {
   829  	zone := "a_zone"
   830  	hwc := &instance.HardwareCharacteristics{
   831  		AvailabilityZone: &zone,
   832  	}
   833  	err := s.machine.SetProvisioned("umbrella/0", "fake_nonce", hwc)
   834  	c.Assert(err, jc.ErrorIsNil)
   835  
   836  	zone, err = s.machine.AvailabilityZone()
   837  	c.Assert(err, jc.ErrorIsNil)
   838  	c.Check(zone, gc.Equals, "a_zone")
   839  }
   840  
   841  func (s *MachineSuite) TestMachineAvailabilityZoneEmpty(c *gc.C) {
   842  	zone := ""
   843  	hwc := &instance.HardwareCharacteristics{
   844  		AvailabilityZone: &zone,
   845  	}
   846  	err := s.machine.SetProvisioned("umbrella/0", "fake_nonce", hwc)
   847  	c.Assert(err, jc.ErrorIsNil)
   848  
   849  	zone, err = s.machine.AvailabilityZone()
   850  	c.Assert(err, jc.ErrorIsNil)
   851  	c.Check(zone, gc.Equals, "")
   852  }
   853  
   854  func (s *MachineSuite) TestMachineAvailabilityZoneMissing(c *gc.C) {
   855  	zone := "a_zone"
   856  	hwc := &instance.HardwareCharacteristics{}
   857  	err := s.machine.SetProvisioned("umbrella/0", "fake_nonce", hwc)
   858  	c.Assert(err, jc.ErrorIsNil)
   859  
   860  	zone, err = s.machine.AvailabilityZone()
   861  	c.Assert(err, jc.ErrorIsNil)
   862  	c.Check(zone, gc.Equals, "")
   863  }
   864  
   865  func (s *MachineSuite) TestMachineSetCheckProvisioned(c *gc.C) {
   866  	// Check before provisioning.
   867  	c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsFalse)
   868  
   869  	// Either one should not be empty.
   870  	err := s.machine.SetProvisioned("umbrella/0", "", nil)
   871  	c.Assert(err, gc.ErrorMatches, `cannot set instance data for machine "1": instance id and nonce cannot be empty`)
   872  	err = s.machine.SetProvisioned("", "fake_nonce", nil)
   873  	c.Assert(err, gc.ErrorMatches, `cannot set instance data for machine "1": instance id and nonce cannot be empty`)
   874  	err = s.machine.SetProvisioned("", "", nil)
   875  	c.Assert(err, gc.ErrorMatches, `cannot set instance data for machine "1": instance id and nonce cannot be empty`)
   876  
   877  	err = s.machine.SetProvisioned("umbrella/0", "fake_nonce", nil)
   878  	c.Assert(err, jc.ErrorIsNil)
   879  
   880  	m, err := s.State.Machine(s.machine.Id())
   881  	c.Assert(err, jc.ErrorIsNil)
   882  	id, err := m.InstanceId()
   883  	c.Assert(err, jc.ErrorIsNil)
   884  	c.Assert(string(id), gc.Equals, "umbrella/0")
   885  	c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsTrue)
   886  	id, err = s.machine.InstanceId()
   887  	c.Assert(err, jc.ErrorIsNil)
   888  	c.Assert(string(id), gc.Equals, "umbrella/0")
   889  	c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsTrue)
   890  
   891  	// Try it twice, it should fail.
   892  	err = s.machine.SetProvisioned("doesn't-matter", "phony", nil)
   893  	c.Assert(err, gc.ErrorMatches, `cannot set instance data for machine "1": already set`)
   894  
   895  	// Check it with invalid nonce.
   896  	c.Assert(s.machine.CheckProvisioned("not-really"), jc.IsFalse)
   897  }
   898  
   899  func (s *MachineSuite) TestMachineSetInstanceInfoFailureDoesNotProvision(c *gc.C) {
   900  	assertNotProvisioned := func() {
   901  		c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsFalse)
   902  	}
   903  
   904  	assertNotProvisioned()
   905  
   906  	invalidVolumes := map[names.VolumeTag]state.VolumeInfo{
   907  		names.NewVolumeTag("1065"): state.VolumeInfo{VolumeId: "vol-ume"},
   908  	}
   909  	err := s.machine.SetInstanceInfo("umbrella/0", "fake_nonce", nil, nil, nil, invalidVolumes, nil)
   910  	c.Assert(err, gc.ErrorMatches, `cannot set info for volume \"1065\": volume \"1065\" not found`)
   911  	assertNotProvisioned()
   912  
   913  	invalidVolumes = map[names.VolumeTag]state.VolumeInfo{
   914  		names.NewVolumeTag("1065"): state.VolumeInfo{},
   915  	}
   916  	err = s.machine.SetInstanceInfo("umbrella/0", "fake_nonce", nil, nil, nil, invalidVolumes, nil)
   917  	c.Assert(err, gc.ErrorMatches, `cannot set info for volume \"1065\": volume ID not set`)
   918  	assertNotProvisioned()
   919  
   920  	// TODO(axw) test invalid volume attachment
   921  }
   922  
   923  func (s *MachineSuite) addVolume(c *gc.C, params state.VolumeParams, machineId string) names.VolumeTag {
   924  	ops, tag, err := state.AddVolumeOps(s.State, params, machineId)
   925  	c.Assert(err, jc.ErrorIsNil)
   926  	err = state.RunTransaction(s.State, ops)
   927  	c.Assert(err, jc.ErrorIsNil)
   928  	return tag
   929  }
   930  
   931  func (s *MachineSuite) TestMachineSetInstanceInfoSuccess(c *gc.C) {
   932  	pm := poolmanager.New(state.NewStateSettings(s.State))
   933  	_, err := pm.Create("loop-pool", provider.LoopProviderType, map[string]interface{}{})
   934  	c.Assert(err, jc.ErrorIsNil)
   935  	registry.RegisterEnvironStorageProviders("someprovider", provider.LoopProviderType)
   936  
   937  	// Must create the requested block device prior to SetInstanceInfo.
   938  	volumeTag := s.addVolume(c, state.VolumeParams{Size: 1000, Pool: "loop-pool"}, "123")
   939  	c.Assert(volumeTag, gc.Equals, names.NewVolumeTag("123/0"))
   940  
   941  	c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsFalse)
   942  	volumeInfo := state.VolumeInfo{
   943  		VolumeId: "storage-123",
   944  		Size:     1234,
   945  	}
   946  	volumes := map[names.VolumeTag]state.VolumeInfo{volumeTag: volumeInfo}
   947  	err = s.machine.SetInstanceInfo("umbrella/0", "fake_nonce", nil, nil, nil, volumes, nil)
   948  	c.Assert(err, jc.ErrorIsNil)
   949  	c.Assert(s.machine.CheckProvisioned("fake_nonce"), jc.IsTrue)
   950  
   951  	volume, err := s.State.Volume(volumeTag)
   952  	c.Assert(err, jc.ErrorIsNil)
   953  	info, err := volume.Info()
   954  	c.Assert(err, jc.ErrorIsNil)
   955  	volumeInfo.Pool = "loop-pool" // taken from params
   956  	c.Assert(info, gc.Equals, volumeInfo)
   957  }
   958  
   959  func (s *MachineSuite) TestMachineSetProvisionedWhenNotAlive(c *gc.C) {
   960  	testWhenDying(c, s.machine, notAliveErr, notAliveErr, func() error {
   961  		return s.machine.SetProvisioned("umbrella/0", "fake_nonce", nil)
   962  	})
   963  }
   964  
   965  func (s *MachineSuite) TestMachineSetInstanceStatus(c *gc.C) {
   966  	// Machine needs to be provisioned first.
   967  	err := s.machine.SetProvisioned("umbrella/0", "fake_nonce", nil)
   968  	c.Assert(err, jc.ErrorIsNil)
   969  
   970  	err = s.machine.SetInstanceStatus(status.StatusRunning, "alive", map[string]interface{}{})
   971  	c.Assert(err, jc.ErrorIsNil)
   972  
   973  	// Reload machine and check result.
   974  	err = s.machine.Refresh()
   975  	c.Assert(err, jc.ErrorIsNil)
   976  	machineStatus, err := s.machine.InstanceStatus()
   977  	c.Assert(err, jc.ErrorIsNil)
   978  	c.Assert(machineStatus.Status, gc.DeepEquals, status.StatusRunning)
   979  	c.Assert(machineStatus.Message, gc.DeepEquals, "alive")
   980  }
   981  
   982  func (s *MachineSuite) TestMachineRefresh(c *gc.C) {
   983  	m0, err := s.State.AddMachine("quantal", state.JobHostUnits)
   984  	c.Assert(err, jc.ErrorIsNil)
   985  	oldTools, _ := m0.AgentTools()
   986  	m1, err := s.State.Machine(m0.Id())
   987  	c.Assert(err, jc.ErrorIsNil)
   988  	err = m0.SetAgentVersion(version.MustParseBinary("0.0.3-quantal-amd64"))
   989  	c.Assert(err, jc.ErrorIsNil)
   990  	newTools, _ := m0.AgentTools()
   991  
   992  	m1Tools, _ := m1.AgentTools()
   993  	c.Assert(m1Tools, gc.DeepEquals, oldTools)
   994  	err = m1.Refresh()
   995  	c.Assert(err, jc.ErrorIsNil)
   996  	m1Tools, _ = m1.AgentTools()
   997  	c.Assert(*m1Tools, gc.Equals, *newTools)
   998  
   999  	err = m0.EnsureDead()
  1000  	c.Assert(err, jc.ErrorIsNil)
  1001  	err = m0.Remove()
  1002  	c.Assert(err, jc.ErrorIsNil)
  1003  	err = m0.Refresh()
  1004  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
  1005  }
  1006  
  1007  func (s *MachineSuite) TestRefreshWhenNotAlive(c *gc.C) {
  1008  	// Refresh should work regardless of liveness status.
  1009  	testWhenDying(c, s.machine, noErr, noErr, func() error {
  1010  		return s.machine.Refresh()
  1011  	})
  1012  }
  1013  
  1014  func (s *MachineSuite) TestMachinePrincipalUnits(c *gc.C) {
  1015  	// Check that Machine.Units and st.UnitsFor work correctly.
  1016  
  1017  	// Make three machines, three services and three units for each service;
  1018  	// variously assign units to machines and check that Machine.Units
  1019  	// tells us the right thing.
  1020  
  1021  	m1 := s.machine
  1022  	m2, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1023  	c.Assert(err, jc.ErrorIsNil)
  1024  	m3, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1025  	c.Assert(err, jc.ErrorIsNil)
  1026  
  1027  	dummy := s.AddTestingCharm(c, "dummy")
  1028  	logging := s.AddTestingCharm(c, "logging")
  1029  	s0 := s.AddTestingService(c, "s0", dummy)
  1030  	s1 := s.AddTestingService(c, "s1", dummy)
  1031  	s2 := s.AddTestingService(c, "s2", dummy)
  1032  	s3 := s.AddTestingService(c, "s3", logging)
  1033  
  1034  	units := make([][]*state.Unit, 4)
  1035  	for i, svc := range []*state.Service{s0, s1, s2} {
  1036  		units[i] = make([]*state.Unit, 3)
  1037  		for j := range units[i] {
  1038  			units[i][j], err = svc.AddUnit()
  1039  			c.Assert(err, jc.ErrorIsNil)
  1040  		}
  1041  	}
  1042  	// Add the logging units subordinate to the s2 units.
  1043  	eps, err := s.State.InferEndpoints("s2", "s3")
  1044  	c.Assert(err, jc.ErrorIsNil)
  1045  	rel, err := s.State.AddRelation(eps...)
  1046  	c.Assert(err, jc.ErrorIsNil)
  1047  	for _, u := range units[2] {
  1048  		ru, err := rel.Unit(u)
  1049  		c.Assert(err, jc.ErrorIsNil)
  1050  		err = ru.EnterScope(nil)
  1051  		c.Assert(err, jc.ErrorIsNil)
  1052  	}
  1053  	units[3], err = s3.AllUnits()
  1054  	c.Assert(err, jc.ErrorIsNil)
  1055  	c.Assert(sortedUnitNames(units[3]), jc.DeepEquals, []string{"s3/0", "s3/1", "s3/2"})
  1056  
  1057  	assignments := []struct {
  1058  		machine      *state.Machine
  1059  		units        []*state.Unit
  1060  		subordinates []*state.Unit
  1061  	}{
  1062  		{m1, []*state.Unit{units[0][0]}, nil},
  1063  		{m2, []*state.Unit{units[0][1], units[1][0], units[1][1], units[2][0]}, []*state.Unit{units[3][0]}},
  1064  		{m3, []*state.Unit{units[2][2]}, []*state.Unit{units[3][2]}},
  1065  	}
  1066  
  1067  	for _, a := range assignments {
  1068  		for _, u := range a.units {
  1069  			err := u.AssignToMachine(a.machine)
  1070  			c.Assert(err, jc.ErrorIsNil)
  1071  		}
  1072  	}
  1073  
  1074  	for i, a := range assignments {
  1075  		c.Logf("test %d", i)
  1076  		expect := sortedUnitNames(append(a.units, a.subordinates...))
  1077  
  1078  		// The units can be retrieved from the machine model.
  1079  		got, err := a.machine.Units()
  1080  		c.Assert(err, jc.ErrorIsNil)
  1081  		c.Assert(sortedUnitNames(got), jc.DeepEquals, expect)
  1082  
  1083  		// The units can be retrieved from the machine id.
  1084  		got, err = s.State.UnitsFor(a.machine.Id())
  1085  		c.Assert(err, jc.ErrorIsNil)
  1086  		c.Assert(sortedUnitNames(got), jc.DeepEquals, expect)
  1087  	}
  1088  }
  1089  
  1090  func sortedUnitNames(units []*state.Unit) []string {
  1091  	names := make([]string, len(units))
  1092  	for i, u := range units {
  1093  		names[i] = u.Name()
  1094  	}
  1095  	sort.Strings(names)
  1096  	return names
  1097  }
  1098  
  1099  func (s *MachineSuite) assertMachineDirtyAfterAddingUnit(c *gc.C) (*state.Machine, *state.Service, *state.Unit) {
  1100  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1101  	c.Assert(err, jc.ErrorIsNil)
  1102  	c.Assert(m.Clean(), jc.IsTrue)
  1103  
  1104  	svc := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress"))
  1105  	unit, err := svc.AddUnit()
  1106  	c.Assert(err, jc.ErrorIsNil)
  1107  	err = unit.AssignToMachine(m)
  1108  	c.Assert(err, jc.ErrorIsNil)
  1109  	c.Assert(m.Clean(), jc.IsFalse)
  1110  	return m, svc, unit
  1111  }
  1112  
  1113  func (s *MachineSuite) TestMachineDirtyAfterAddingUnit(c *gc.C) {
  1114  	s.assertMachineDirtyAfterAddingUnit(c)
  1115  }
  1116  
  1117  func (s *MachineSuite) TestMachineDirtyAfterUnassigningUnit(c *gc.C) {
  1118  	m, _, unit := s.assertMachineDirtyAfterAddingUnit(c)
  1119  	err := unit.UnassignFromMachine()
  1120  	c.Assert(err, jc.ErrorIsNil)
  1121  	c.Assert(m.Clean(), jc.IsFalse)
  1122  }
  1123  
  1124  func (s *MachineSuite) TestMachineDirtyAfterRemovingUnit(c *gc.C) {
  1125  	m, svc, unit := s.assertMachineDirtyAfterAddingUnit(c)
  1126  	err := unit.EnsureDead()
  1127  	c.Assert(err, jc.ErrorIsNil)
  1128  	err = unit.Remove()
  1129  	c.Assert(err, jc.ErrorIsNil)
  1130  	err = svc.Destroy()
  1131  	c.Assert(err, jc.ErrorIsNil)
  1132  	c.Assert(m.Clean(), jc.IsFalse)
  1133  }
  1134  
  1135  func (s *MachineSuite) TestWatchMachine(c *gc.C) {
  1136  	w := s.machine.Watch()
  1137  	defer testing.AssertStop(c, w)
  1138  
  1139  	// Initial event.
  1140  	wc := testing.NewNotifyWatcherC(c, s.State, w)
  1141  	wc.AssertOneChange()
  1142  
  1143  	// Make one change (to a separate instance), check one event.
  1144  	machine, err := s.State.Machine(s.machine.Id())
  1145  	c.Assert(err, jc.ErrorIsNil)
  1146  	err = machine.SetProvisioned("m-foo", "fake_nonce", nil)
  1147  	c.Assert(err, jc.ErrorIsNil)
  1148  	wc.AssertOneChange()
  1149  
  1150  	// Make two changes, check one event.
  1151  	err = machine.SetAgentVersion(version.MustParseBinary("0.0.3-quantal-amd64"))
  1152  	c.Assert(err, jc.ErrorIsNil)
  1153  	err = machine.Destroy()
  1154  	c.Assert(err, jc.ErrorIsNil)
  1155  	wc.AssertOneChange()
  1156  
  1157  	// Stop, check closed.
  1158  	testing.AssertStop(c, w)
  1159  	wc.AssertClosed()
  1160  
  1161  	// Remove machine, start new watch, check single event.
  1162  	err = machine.EnsureDead()
  1163  	c.Assert(err, jc.ErrorIsNil)
  1164  	err = machine.Remove()
  1165  	c.Assert(err, jc.ErrorIsNil)
  1166  	w = s.machine.Watch()
  1167  	defer testing.AssertStop(c, w)
  1168  	testing.NewNotifyWatcherC(c, s.State, w).AssertOneChange()
  1169  }
  1170  
  1171  func (s *MachineSuite) TestWatchDiesOnStateClose(c *gc.C) {
  1172  	// This test is testing logic in watcher.entityWatcher, which
  1173  	// is also used by:
  1174  	//  Machine.WatchHardwareCharacteristics
  1175  	//  Service.Watch
  1176  	//  Unit.Watch
  1177  	//  State.WatchForModelConfigChanges
  1178  	//  Unit.WatchConfigSettings
  1179  	testWatcherDiesWhenStateCloses(c, s.modelTag, func(c *gc.C, st *state.State) waiter {
  1180  		m, err := st.Machine(s.machine.Id())
  1181  		c.Assert(err, jc.ErrorIsNil)
  1182  		w := m.Watch()
  1183  		<-w.Changes()
  1184  		return w
  1185  	})
  1186  }
  1187  
  1188  func (s *MachineSuite) TestWatchPrincipalUnits(c *gc.C) {
  1189  	// TODO(mjs) - MODELUUID - test with multiple models with
  1190  	// identically named units and ensure there's no leakage.
  1191  
  1192  	// Start a watch on an empty machine; check no units reported.
  1193  	w := s.machine.WatchPrincipalUnits()
  1194  	defer testing.AssertStop(c, w)
  1195  	wc := testing.NewStringsWatcherC(c, s.State, w)
  1196  	wc.AssertChange()
  1197  	wc.AssertNoChange()
  1198  
  1199  	// Change machine, and create a unit independently; no change.
  1200  	err := s.machine.SetProvisioned("cheese", "fake_nonce", nil)
  1201  	c.Assert(err, jc.ErrorIsNil)
  1202  	wc.AssertNoChange()
  1203  	mysql := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql"))
  1204  	mysql0, err := mysql.AddUnit()
  1205  	c.Assert(err, jc.ErrorIsNil)
  1206  	wc.AssertNoChange()
  1207  
  1208  	// Assign that unit (to a separate machine instance); change detected.
  1209  	machine, err := s.State.Machine(s.machine.Id())
  1210  	c.Assert(err, jc.ErrorIsNil)
  1211  	err = mysql0.AssignToMachine(machine)
  1212  	c.Assert(err, jc.ErrorIsNil)
  1213  	wc.AssertChange("mysql/0")
  1214  	wc.AssertNoChange()
  1215  
  1216  	// Change the unit; no change.
  1217  	err = mysql0.SetAgentStatus(status.StatusIdle, "", nil)
  1218  	c.Assert(err, jc.ErrorIsNil)
  1219  	wc.AssertNoChange()
  1220  
  1221  	// Assign another unit and make the first Dying; check both changes detected.
  1222  	mysql1, err := mysql.AddUnit()
  1223  	c.Assert(err, jc.ErrorIsNil)
  1224  	err = mysql1.AssignToMachine(machine)
  1225  	c.Assert(err, jc.ErrorIsNil)
  1226  	err = mysql0.Destroy()
  1227  	c.Assert(err, jc.ErrorIsNil)
  1228  	wc.AssertChange("mysql/0", "mysql/1")
  1229  	wc.AssertNoChange()
  1230  
  1231  	// Add a subordinate to the Alive unit; no change.
  1232  	s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging"))
  1233  	eps, err := s.State.InferEndpoints("mysql", "logging")
  1234  	c.Assert(err, jc.ErrorIsNil)
  1235  	rel, err := s.State.AddRelation(eps...)
  1236  	c.Assert(err, jc.ErrorIsNil)
  1237  	mysqlru1, err := rel.Unit(mysql1)
  1238  	c.Assert(err, jc.ErrorIsNil)
  1239  	err = mysqlru1.EnterScope(nil)
  1240  	c.Assert(err, jc.ErrorIsNil)
  1241  	logging0, err := s.State.Unit("logging/0")
  1242  	c.Assert(err, jc.ErrorIsNil)
  1243  	wc.AssertNoChange()
  1244  
  1245  	// Change the subordinate; no change.
  1246  	err = logging0.SetAgentStatus(status.StatusIdle, "", nil)
  1247  	c.Assert(err, jc.ErrorIsNil)
  1248  	wc.AssertNoChange()
  1249  
  1250  	// Make the Dying unit Dead; change detected.
  1251  	err = mysql0.EnsureDead()
  1252  	c.Assert(err, jc.ErrorIsNil)
  1253  	wc.AssertChange("mysql/0")
  1254  	wc.AssertNoChange()
  1255  
  1256  	// Stop watcher; check Changes chan closed.
  1257  	testing.AssertStop(c, w)
  1258  	wc.AssertClosed()
  1259  
  1260  	// Start a fresh watcher; check both principals reported.
  1261  	w = s.machine.WatchPrincipalUnits()
  1262  	defer testing.AssertStop(c, w)
  1263  	wc = testing.NewStringsWatcherC(c, s.State, w)
  1264  	wc.AssertChange("mysql/0", "mysql/1")
  1265  	wc.AssertNoChange()
  1266  
  1267  	// Remove the Dead unit; no change.
  1268  	err = mysql0.Remove()
  1269  	c.Assert(err, jc.ErrorIsNil)
  1270  	wc.AssertNoChange()
  1271  
  1272  	// Destroy the subordinate; no change.
  1273  	err = logging0.Destroy()
  1274  	c.Assert(err, jc.ErrorIsNil)
  1275  	wc.AssertNoChange()
  1276  
  1277  	// Unassign the unit; check change.
  1278  	err = mysql1.UnassignFromMachine()
  1279  	c.Assert(err, jc.ErrorIsNil)
  1280  	wc.AssertChange("mysql/1")
  1281  	wc.AssertNoChange()
  1282  }
  1283  
  1284  func (s *MachineSuite) TestWatchPrincipalUnitsDiesOnStateClose(c *gc.C) {
  1285  	// This test is testing logic in watcher.unitsWatcher, which
  1286  	// is also used by Unit.WatchSubordinateUnits.
  1287  	testWatcherDiesWhenStateCloses(c, s.modelTag, func(c *gc.C, st *state.State) waiter {
  1288  		m, err := st.Machine(s.machine.Id())
  1289  		c.Assert(err, jc.ErrorIsNil)
  1290  		w := m.WatchPrincipalUnits()
  1291  		<-w.Changes()
  1292  		return w
  1293  	})
  1294  }
  1295  
  1296  func (s *MachineSuite) TestWatchUnits(c *gc.C) {
  1297  	// Start a watch on an empty machine; check no units reported.
  1298  	w := s.machine.WatchUnits()
  1299  	defer testing.AssertStop(c, w)
  1300  	wc := testing.NewStringsWatcherC(c, s.State, w)
  1301  	wc.AssertChange()
  1302  	wc.AssertNoChange()
  1303  
  1304  	// Change machine; no change.
  1305  	err := s.machine.SetProvisioned("cheese", "fake_nonce", nil)
  1306  	c.Assert(err, jc.ErrorIsNil)
  1307  	wc.AssertNoChange()
  1308  
  1309  	// Assign a unit (to a separate instance); change detected.
  1310  	mysql := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql"))
  1311  	mysql0, err := mysql.AddUnit()
  1312  	c.Assert(err, jc.ErrorIsNil)
  1313  	machine, err := s.State.Machine(s.machine.Id())
  1314  	c.Assert(err, jc.ErrorIsNil)
  1315  	err = mysql0.AssignToMachine(machine)
  1316  	c.Assert(err, jc.ErrorIsNil)
  1317  	wc.AssertChange("mysql/0")
  1318  	wc.AssertNoChange()
  1319  
  1320  	// Change the unit; no change.
  1321  	err = mysql0.SetAgentStatus(status.StatusIdle, "", nil)
  1322  	c.Assert(err, jc.ErrorIsNil)
  1323  	wc.AssertNoChange()
  1324  
  1325  	// Assign another unit and make the first Dying; check both changes detected.
  1326  	mysql1, err := mysql.AddUnit()
  1327  	c.Assert(err, jc.ErrorIsNil)
  1328  	err = mysql1.AssignToMachine(machine)
  1329  	c.Assert(err, jc.ErrorIsNil)
  1330  	err = mysql0.Destroy()
  1331  	c.Assert(err, jc.ErrorIsNil)
  1332  	wc.AssertChange("mysql/0", "mysql/1")
  1333  	wc.AssertNoChange()
  1334  
  1335  	// Add a subordinate to the Alive unit; change detected.
  1336  	s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging"))
  1337  	eps, err := s.State.InferEndpoints("mysql", "logging")
  1338  	c.Assert(err, jc.ErrorIsNil)
  1339  	rel, err := s.State.AddRelation(eps...)
  1340  	c.Assert(err, jc.ErrorIsNil)
  1341  	mysqlru1, err := rel.Unit(mysql1)
  1342  	c.Assert(err, jc.ErrorIsNil)
  1343  	err = mysqlru1.EnterScope(nil)
  1344  	c.Assert(err, jc.ErrorIsNil)
  1345  	logging0, err := s.State.Unit("logging/0")
  1346  	c.Assert(err, jc.ErrorIsNil)
  1347  	wc.AssertChange("logging/0")
  1348  	wc.AssertNoChange()
  1349  
  1350  	// Change the subordinate; no change.
  1351  	err = logging0.SetAgentStatus(status.StatusIdle, "", nil)
  1352  	c.Assert(err, jc.ErrorIsNil)
  1353  	wc.AssertNoChange()
  1354  
  1355  	// Make the Dying unit Dead; change detected.
  1356  	err = mysql0.EnsureDead()
  1357  	c.Assert(err, jc.ErrorIsNil)
  1358  	wc.AssertChange("mysql/0")
  1359  	wc.AssertNoChange()
  1360  
  1361  	// Stop watcher; check Changes chan closed.
  1362  	testing.AssertStop(c, w)
  1363  	wc.AssertClosed()
  1364  
  1365  	// Start a fresh watcher; check all units reported.
  1366  	w = s.machine.WatchUnits()
  1367  	defer testing.AssertStop(c, w)
  1368  	wc = testing.NewStringsWatcherC(c, s.State, w)
  1369  	wc.AssertChange("mysql/0", "mysql/1", "logging/0")
  1370  	wc.AssertNoChange()
  1371  
  1372  	// Remove the Dead unit; no change.
  1373  	err = mysql0.Remove()
  1374  	c.Assert(err, jc.ErrorIsNil)
  1375  	wc.AssertNoChange()
  1376  
  1377  	// Destroy the subordinate; change detected.
  1378  	err = logging0.Destroy()
  1379  	c.Assert(err, jc.ErrorIsNil)
  1380  	wc.AssertChange("logging/0")
  1381  	wc.AssertNoChange()
  1382  
  1383  	// Unassign the principal; check subordinate departure also reported.
  1384  	err = mysql1.UnassignFromMachine()
  1385  	c.Assert(err, jc.ErrorIsNil)
  1386  	wc.AssertChange("mysql/1", "logging/0")
  1387  	wc.AssertNoChange()
  1388  }
  1389  
  1390  func (s *MachineSuite) TestWatchUnitsDiesOnStateClose(c *gc.C) {
  1391  	testWatcherDiesWhenStateCloses(c, s.modelTag, func(c *gc.C, st *state.State) waiter {
  1392  		m, err := st.Machine(s.machine.Id())
  1393  		c.Assert(err, jc.ErrorIsNil)
  1394  		w := m.WatchUnits()
  1395  		<-w.Changes()
  1396  		return w
  1397  	})
  1398  }
  1399  
  1400  func (s *MachineSuite) TestConstraintsFromModel(c *gc.C) {
  1401  	econs1 := constraints.MustParse("mem=1G")
  1402  	econs2 := constraints.MustParse("mem=2G")
  1403  
  1404  	// A newly-created machine gets a copy of the model constraints.
  1405  	err := s.State.SetModelConstraints(econs1)
  1406  	c.Assert(err, jc.ErrorIsNil)
  1407  	machine1, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1408  	c.Assert(err, jc.ErrorIsNil)
  1409  	mcons1, err := machine1.Constraints()
  1410  	c.Assert(err, jc.ErrorIsNil)
  1411  	c.Assert(mcons1, gc.DeepEquals, econs1)
  1412  
  1413  	// Change model constraints and add a new machine.
  1414  	err = s.State.SetModelConstraints(econs2)
  1415  	c.Assert(err, jc.ErrorIsNil)
  1416  	machine2, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1417  	c.Assert(err, jc.ErrorIsNil)
  1418  	mcons2, err := machine2.Constraints()
  1419  	c.Assert(err, jc.ErrorIsNil)
  1420  	c.Assert(mcons2, gc.DeepEquals, econs2)
  1421  
  1422  	// Check the original machine has its original constraints.
  1423  	mcons1, err = machine1.Constraints()
  1424  	c.Assert(err, jc.ErrorIsNil)
  1425  	c.Assert(mcons1, gc.DeepEquals, econs1)
  1426  }
  1427  
  1428  func (s *MachineSuite) TestSetConstraints(c *gc.C) {
  1429  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1430  	c.Assert(err, jc.ErrorIsNil)
  1431  
  1432  	// Constraints can be set...
  1433  	cons1 := constraints.MustParse("mem=1G")
  1434  	err = machine.SetConstraints(cons1)
  1435  	c.Assert(err, jc.ErrorIsNil)
  1436  	mcons, err := machine.Constraints()
  1437  	c.Assert(err, jc.ErrorIsNil)
  1438  	c.Assert(mcons, gc.DeepEquals, cons1)
  1439  
  1440  	// ...until the machine is provisioned, at which point they stick.
  1441  	err = machine.SetProvisioned("i-mstuck", "fake_nonce", nil)
  1442  	c.Assert(err, jc.ErrorIsNil)
  1443  	cons2 := constraints.MustParse("mem=2G")
  1444  	err = machine.SetConstraints(cons2)
  1445  	c.Assert(err, gc.ErrorMatches, "cannot set constraints: machine is already provisioned")
  1446  
  1447  	// Check the failed set had no effect.
  1448  	mcons, err = machine.Constraints()
  1449  	c.Assert(err, jc.ErrorIsNil)
  1450  	c.Assert(mcons, gc.DeepEquals, cons1)
  1451  }
  1452  
  1453  func (s *MachineSuite) TestSetAmbiguousConstraints(c *gc.C) {
  1454  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1455  	c.Assert(err, jc.ErrorIsNil)
  1456  	cons := constraints.MustParse("mem=4G instance-type=foo")
  1457  	err = machine.SetConstraints(cons)
  1458  	c.Assert(err, gc.ErrorMatches, `cannot set constraints: ambiguous constraints: "instance-type" overlaps with "mem"`)
  1459  }
  1460  
  1461  func (s *MachineSuite) TestSetUnsupportedConstraintsWarning(c *gc.C) {
  1462  	defer loggo.ResetWriters()
  1463  	logger := loggo.GetLogger("test")
  1464  	logger.SetLogLevel(loggo.DEBUG)
  1465  	var tw loggo.TestWriter
  1466  	c.Assert(loggo.RegisterWriter("constraints-tester", &tw, loggo.DEBUG), gc.IsNil)
  1467  
  1468  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1469  	c.Assert(err, jc.ErrorIsNil)
  1470  	cons := constraints.MustParse("mem=4G cpu-power=10")
  1471  	err = machine.SetConstraints(cons)
  1472  	c.Assert(err, jc.ErrorIsNil)
  1473  	c.Assert(tw.Log(), jc.LogMatches, jc.SimpleMessages{{
  1474  		loggo.WARNING,
  1475  		`setting constraints on machine "2": unsupported constraints: cpu-power`},
  1476  	})
  1477  	mcons, err := machine.Constraints()
  1478  	c.Assert(err, jc.ErrorIsNil)
  1479  	c.Assert(mcons, gc.DeepEquals, cons)
  1480  }
  1481  
  1482  func (s *MachineSuite) TestConstraintsLifecycle(c *gc.C) {
  1483  	cons := constraints.MustParse("mem=1G")
  1484  	cannotSet := `cannot set constraints: not found or not alive`
  1485  	testWhenDying(c, s.machine, cannotSet, cannotSet, func() error {
  1486  		err := s.machine.SetConstraints(cons)
  1487  		mcons, err1 := s.machine.Constraints()
  1488  		c.Assert(err1, gc.IsNil)
  1489  		c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty)
  1490  		return err
  1491  	})
  1492  
  1493  	err := s.machine.Remove()
  1494  	c.Assert(err, jc.ErrorIsNil)
  1495  	err = s.machine.SetConstraints(cons)
  1496  	c.Assert(err, gc.ErrorMatches, cannotSet)
  1497  	_, err = s.machine.Constraints()
  1498  	c.Assert(err, gc.ErrorMatches, `constraints not found`)
  1499  }
  1500  
  1501  func (s *MachineSuite) TestSetProviderAddresses(c *gc.C) {
  1502  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1503  	c.Assert(err, jc.ErrorIsNil)
  1504  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1505  
  1506  	addresses := network.NewAddresses("127.0.0.1", "8.8.8.8")
  1507  	err = machine.SetProviderAddresses(addresses...)
  1508  	c.Assert(err, jc.ErrorIsNil)
  1509  	err = machine.Refresh()
  1510  	c.Assert(err, jc.ErrorIsNil)
  1511  
  1512  	expectedAddresses := network.NewAddresses("8.8.8.8", "127.0.0.1")
  1513  	c.Assert(machine.Addresses(), jc.DeepEquals, expectedAddresses)
  1514  }
  1515  
  1516  func (s *MachineSuite) TestSetProviderAddressesWithContainers(c *gc.C) {
  1517  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1518  	c.Assert(err, jc.ErrorIsNil)
  1519  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1520  
  1521  	// Create subnet and pick two addresses.
  1522  	subnetInfo := state.SubnetInfo{
  1523  		CIDR:              "192.168.1.0/24",
  1524  		AllocatableIPLow:  "192.168.1.0",
  1525  		AllocatableIPHigh: "192.168.1.10",
  1526  	}
  1527  	subnet, err := s.State.AddSubnet(subnetInfo)
  1528  	c.Assert(err, jc.ErrorIsNil)
  1529  
  1530  	ipAddr1, err := subnet.PickNewAddress()
  1531  	c.Assert(err, jc.ErrorIsNil)
  1532  	err = ipAddr1.SetState(state.AddressStateAllocated)
  1533  	c.Assert(err, jc.ErrorIsNil)
  1534  	ipAddr2, err := subnet.PickNewAddress()
  1535  	c.Assert(err, jc.ErrorIsNil)
  1536  	err = ipAddr2.SetState(state.AddressStateAllocated)
  1537  	c.Assert(err, jc.ErrorIsNil)
  1538  
  1539  	// When setting all addresses the subnet addresses have to be
  1540  	// filtered out.
  1541  	addresses := network.NewAddresses(
  1542  		"127.0.0.1",
  1543  		"8.8.8.8",
  1544  		ipAddr1.Value(),
  1545  		ipAddr2.Value(),
  1546  	)
  1547  	err = machine.SetProviderAddresses(addresses...)
  1548  	c.Assert(err, jc.ErrorIsNil)
  1549  	err = machine.Refresh()
  1550  	c.Assert(err, jc.ErrorIsNil)
  1551  
  1552  	expectedAddresses := network.NewAddresses("8.8.8.8", "127.0.0.1")
  1553  	c.Assert(machine.Addresses(), jc.DeepEquals, expectedAddresses)
  1554  }
  1555  
  1556  func (s *MachineSuite) TestSetProviderAddressesOnContainer(c *gc.C) {
  1557  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1558  	c.Assert(err, jc.ErrorIsNil)
  1559  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1560  
  1561  	// Create subnet and pick two addresses.
  1562  	subnetInfo := state.SubnetInfo{
  1563  		CIDR:              "192.168.1.0/24",
  1564  		AllocatableIPLow:  "192.168.1.0",
  1565  		AllocatableIPHigh: "192.168.1.10",
  1566  	}
  1567  	subnet, err := s.State.AddSubnet(subnetInfo)
  1568  	c.Assert(err, jc.ErrorIsNil)
  1569  
  1570  	ipAddr, err := subnet.PickNewAddress()
  1571  	c.Assert(err, jc.ErrorIsNil)
  1572  	err = ipAddr.SetState(state.AddressStateAllocated)
  1573  	c.Assert(err, jc.ErrorIsNil)
  1574  
  1575  	// Create an LXC container inside the machine.
  1576  	template := state.MachineTemplate{
  1577  		Series: "quantal",
  1578  		Jobs:   []state.MachineJob{state.JobHostUnits},
  1579  	}
  1580  	container, err := s.State.AddMachineInsideMachine(template, machine.Id(), instance.LXC)
  1581  	c.Assert(err, jc.ErrorIsNil)
  1582  
  1583  	// When setting all addresses the subnet address has to accepted.
  1584  	addresses := network.NewAddresses("127.0.0.1", ipAddr.Value())
  1585  	err = container.SetProviderAddresses(addresses...)
  1586  	c.Assert(err, jc.ErrorIsNil)
  1587  	err = container.Refresh()
  1588  	c.Assert(err, jc.ErrorIsNil)
  1589  
  1590  	expectedAddresses := network.NewAddresses(ipAddr.Value(), "127.0.0.1")
  1591  	c.Assert(container.Addresses(), jc.DeepEquals, expectedAddresses)
  1592  }
  1593  
  1594  func (s *MachineSuite) TestSetMachineAddresses(c *gc.C) {
  1595  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1596  	c.Assert(err, jc.ErrorIsNil)
  1597  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1598  
  1599  	addresses := network.NewAddresses("127.0.0.1", "8.8.8.8")
  1600  	err = machine.SetMachineAddresses(addresses...)
  1601  	c.Assert(err, jc.ErrorIsNil)
  1602  	err = machine.Refresh()
  1603  	c.Assert(err, jc.ErrorIsNil)
  1604  
  1605  	expectedAddresses := network.NewAddresses("8.8.8.8", "127.0.0.1")
  1606  	c.Assert(machine.MachineAddresses(), jc.DeepEquals, expectedAddresses)
  1607  }
  1608  
  1609  func (s *MachineSuite) TestSetEmptyMachineAddresses(c *gc.C) {
  1610  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1611  	c.Assert(err, jc.ErrorIsNil)
  1612  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1613  
  1614  	// Add some machine addresses initially to make sure they're removed.
  1615  	addresses := network.NewAddresses("127.0.0.1", "8.8.8.8")
  1616  	err = machine.SetMachineAddresses(addresses...)
  1617  	c.Assert(err, jc.ErrorIsNil)
  1618  	err = machine.Refresh()
  1619  	c.Assert(err, jc.ErrorIsNil)
  1620  	c.Assert(machine.MachineAddresses(), gc.HasLen, 2)
  1621  
  1622  	// Make call with empty address list.
  1623  	err = machine.SetMachineAddresses()
  1624  	c.Assert(err, jc.ErrorIsNil)
  1625  	err = machine.Refresh()
  1626  	c.Assert(err, jc.ErrorIsNil)
  1627  
  1628  	c.Assert(machine.MachineAddresses(), gc.HasLen, 0)
  1629  }
  1630  
  1631  func (s *MachineSuite) TestMergedAddresses(c *gc.C) {
  1632  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1633  	c.Assert(err, jc.ErrorIsNil)
  1634  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1635  
  1636  	providerAddresses := network.NewAddresses(
  1637  		"127.0.0.2",
  1638  		"8.8.8.8",
  1639  		"fc00::1",
  1640  		"::1",
  1641  		"",
  1642  		"2001:db8::1",
  1643  		"127.0.0.2",
  1644  		"example.org",
  1645  	)
  1646  	err = machine.SetProviderAddresses(providerAddresses...)
  1647  	c.Assert(err, jc.ErrorIsNil)
  1648  
  1649  	machineAddresses := network.NewAddresses(
  1650  		"127.0.0.1",
  1651  		"localhost",
  1652  		"2001:db8::1",
  1653  		"192.168.0.1",
  1654  		"fe80::1",
  1655  		"::1",
  1656  		"fd00::1",
  1657  	)
  1658  	err = machine.SetMachineAddresses(machineAddresses...)
  1659  	c.Assert(err, jc.ErrorIsNil)
  1660  	err = machine.Refresh()
  1661  	c.Assert(err, jc.ErrorIsNil)
  1662  
  1663  	// Before setting the addresses coming from either the provider or
  1664  	// the machine itself, they are sorted to prefer public IPs on
  1665  	// top, then hostnames, cloud-local, machine-local, link-local.
  1666  	// Duplicates are removed, then when calling Addresses() both
  1667  	// sources are merged while preservig the provider addresses
  1668  	// order.
  1669  	c.Assert(machine.Addresses(), jc.DeepEquals, network.NewAddresses(
  1670  		"8.8.8.8",
  1671  		"2001:db8::1",
  1672  		"example.org",
  1673  		"fc00::1",
  1674  		"127.0.0.2",
  1675  		"::1",
  1676  		"localhost",
  1677  		"192.168.0.1",
  1678  		"fd00::1",
  1679  		"127.0.0.1",
  1680  		"fe80::1",
  1681  	))
  1682  
  1683  	// Now simulate prefer-ipv6: true
  1684  	c.Assert(
  1685  		s.State.UpdateModelConfig(
  1686  			map[string]interface{}{"prefer-ipv6": true},
  1687  			nil, nil,
  1688  		),
  1689  		gc.IsNil,
  1690  	)
  1691  
  1692  	err = machine.SetProviderAddresses(providerAddresses...)
  1693  	c.Assert(err, jc.ErrorIsNil)
  1694  	err = machine.SetMachineAddresses(machineAddresses...)
  1695  	c.Assert(err, jc.ErrorIsNil)
  1696  	err = machine.Refresh()
  1697  	c.Assert(err, jc.ErrorIsNil)
  1698  	c.Assert(machine.Addresses(), jc.DeepEquals, network.NewAddresses(
  1699  		"2001:db8::1",
  1700  		"8.8.8.8",
  1701  		"example.org",
  1702  		"fc00::1",
  1703  		"::1",
  1704  		"127.0.0.2",
  1705  		"localhost",
  1706  		"fd00::1",
  1707  		"192.168.0.1",
  1708  		"127.0.0.1",
  1709  		"fe80::1",
  1710  	))
  1711  }
  1712  
  1713  func (s *MachineSuite) TestSetProviderAddressesConcurrentChangeDifferent(c *gc.C) {
  1714  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1715  	c.Assert(err, jc.ErrorIsNil)
  1716  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1717  
  1718  	addr0 := network.NewAddress("127.0.0.1")
  1719  	addr1 := network.NewAddress("8.8.8.8")
  1720  
  1721  	defer state.SetBeforeHooks(c, s.State, func() {
  1722  		machine, err := s.State.Machine(machine.Id())
  1723  		c.Assert(err, jc.ErrorIsNil)
  1724  		err = machine.SetProviderAddresses(addr1, addr0)
  1725  		c.Assert(err, jc.ErrorIsNil)
  1726  	}).Check()
  1727  
  1728  	err = machine.SetProviderAddresses(addr0, addr1)
  1729  	c.Assert(err, jc.ErrorIsNil)
  1730  	c.Assert(machine.Addresses(), jc.SameContents, []network.Address{addr0, addr1})
  1731  }
  1732  
  1733  func (s *MachineSuite) TestSetProviderAddressesConcurrentChangeEqual(c *gc.C) {
  1734  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1735  	c.Assert(err, jc.ErrorIsNil)
  1736  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1737  	machineDocID := state.DocID(s.State, machine.Id())
  1738  	revno0, err := state.TxnRevno(s.State, "machines", machineDocID)
  1739  	c.Assert(err, jc.ErrorIsNil)
  1740  
  1741  	addr0 := network.NewAddress("127.0.0.1")
  1742  	addr1 := network.NewAddress("8.8.8.8")
  1743  
  1744  	var revno1 int64
  1745  	defer state.SetBeforeHooks(c, s.State, func() {
  1746  		machine, err := s.State.Machine(machine.Id())
  1747  		c.Assert(err, jc.ErrorIsNil)
  1748  		err = machine.SetProviderAddresses(addr0, addr1)
  1749  		c.Assert(err, jc.ErrorIsNil)
  1750  		revno1, err = state.TxnRevno(s.State, "machines", machineDocID)
  1751  		c.Assert(err, jc.ErrorIsNil)
  1752  		c.Assert(revno1, jc.GreaterThan, revno0)
  1753  	}).Check()
  1754  
  1755  	err = machine.SetProviderAddresses(addr0, addr1)
  1756  	c.Assert(err, jc.ErrorIsNil)
  1757  
  1758  	// Doc will be updated; concurrent changes are explicitly ignored.
  1759  	revno2, err := state.TxnRevno(s.State, "machines", machineDocID)
  1760  	c.Assert(err, jc.ErrorIsNil)
  1761  	c.Assert(revno2, jc.GreaterThan, revno1)
  1762  	c.Assert(machine.Addresses(), jc.SameContents, []network.Address{addr0, addr1})
  1763  }
  1764  
  1765  func (s *MachineSuite) TestSetProviderAddressesInvalidateMemory(c *gc.C) {
  1766  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1767  	c.Assert(err, jc.ErrorIsNil)
  1768  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1769  	machineDocID := state.DocID(s.State, machine.Id())
  1770  
  1771  	addr0 := network.NewAddress("127.0.0.1")
  1772  	addr1 := network.NewAddress("8.8.8.8")
  1773  
  1774  	// Set addresses to [addr0] initially. We'll get a separate Machine
  1775  	// object to update addresses, to ensure that the in-memory cache of
  1776  	// addresses does not prevent the initial Machine from updating
  1777  	// addresses back to the original value.
  1778  	err = machine.SetProviderAddresses(addr0)
  1779  	c.Assert(err, jc.ErrorIsNil)
  1780  	revno0, err := state.TxnRevno(s.State, "machines", machineDocID)
  1781  	c.Assert(err, jc.ErrorIsNil)
  1782  
  1783  	machine2, err := s.State.Machine(machine.Id())
  1784  	c.Assert(err, jc.ErrorIsNil)
  1785  	err = machine2.SetProviderAddresses(addr1)
  1786  	c.Assert(err, jc.ErrorIsNil)
  1787  	revno1, err := state.TxnRevno(s.State, "machines", machineDocID)
  1788  	c.Assert(err, jc.ErrorIsNil)
  1789  	c.Assert(revno1, jc.GreaterThan, revno0)
  1790  	c.Assert(machine.Addresses(), jc.SameContents, []network.Address{addr0})
  1791  	c.Assert(machine2.Addresses(), jc.SameContents, []network.Address{addr1})
  1792  
  1793  	err = machine.SetProviderAddresses(addr0)
  1794  	c.Assert(err, jc.ErrorIsNil)
  1795  	revno2, err := state.TxnRevno(s.State, "machines", machineDocID)
  1796  	c.Assert(err, jc.ErrorIsNil)
  1797  	c.Assert(revno2, jc.GreaterThan, revno1)
  1798  	c.Assert(machine.Addresses(), jc.SameContents, []network.Address{addr0})
  1799  }
  1800  
  1801  func (s *MachineSuite) TestPublicAddressSetOnNewMachine(c *gc.C) {
  1802  	m, err := s.State.AddOneMachine(state.MachineTemplate{
  1803  		Series:    "quantal",
  1804  		Jobs:      []state.MachineJob{state.JobHostUnits},
  1805  		Addresses: network.NewAddresses("10.0.0.1", "8.8.8.8"),
  1806  	})
  1807  	c.Assert(err, jc.ErrorIsNil)
  1808  	addr, err := m.PublicAddress()
  1809  	c.Assert(err, jc.ErrorIsNil)
  1810  	c.Assert(addr, jc.DeepEquals, network.NewAddress("8.8.8.8"))
  1811  }
  1812  
  1813  func (s *MachineSuite) TestPrivateAddressSetOnNewMachine(c *gc.C) {
  1814  	m, err := s.State.AddOneMachine(state.MachineTemplate{
  1815  		Series:    "quantal",
  1816  		Jobs:      []state.MachineJob{state.JobHostUnits},
  1817  		Addresses: network.NewAddresses("10.0.0.1", "8.8.8.8"),
  1818  	})
  1819  	c.Assert(err, jc.ErrorIsNil)
  1820  	addr, err := m.PrivateAddress()
  1821  	c.Assert(err, jc.ErrorIsNil)
  1822  	c.Assert(addr, jc.DeepEquals, network.NewAddress("10.0.0.1"))
  1823  }
  1824  
  1825  func (s *MachineSuite) TestPublicAddressEmptyAddresses(c *gc.C) {
  1826  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1827  	c.Assert(err, jc.ErrorIsNil)
  1828  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1829  
  1830  	addr, err := machine.PublicAddress()
  1831  	c.Assert(err, jc.Satisfies, network.IsNoAddress)
  1832  	c.Assert(addr.Value, gc.Equals, "")
  1833  }
  1834  
  1835  func (s *MachineSuite) TestPrivateAddressEmptyAddresses(c *gc.C) {
  1836  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1837  	c.Assert(err, jc.ErrorIsNil)
  1838  	c.Assert(machine.Addresses(), gc.HasLen, 0)
  1839  
  1840  	addr, err := machine.PrivateAddress()
  1841  	c.Assert(err, jc.Satisfies, network.IsNoAddress)
  1842  	c.Assert(addr.Value, gc.Equals, "")
  1843  }
  1844  
  1845  func (s *MachineSuite) TestPublicAddress(c *gc.C) {
  1846  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1847  	c.Assert(err, jc.ErrorIsNil)
  1848  
  1849  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  1850  	c.Assert(err, jc.ErrorIsNil)
  1851  
  1852  	addr, err := machine.PublicAddress()
  1853  	c.Assert(err, jc.ErrorIsNil)
  1854  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  1855  }
  1856  
  1857  func (s *MachineSuite) TestPrivateAddress(c *gc.C) {
  1858  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1859  	c.Assert(err, jc.ErrorIsNil)
  1860  
  1861  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.1"))
  1862  	c.Assert(err, jc.ErrorIsNil)
  1863  
  1864  	addr, err := machine.PrivateAddress()
  1865  	c.Assert(err, jc.ErrorIsNil)
  1866  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  1867  }
  1868  
  1869  func (s *MachineSuite) TestPublicAddressBetterMatch(c *gc.C) {
  1870  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1871  	c.Assert(err, jc.ErrorIsNil)
  1872  
  1873  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.1"))
  1874  	c.Assert(err, jc.ErrorIsNil)
  1875  
  1876  	addr, err := machine.PublicAddress()
  1877  	c.Assert(err, jc.ErrorIsNil)
  1878  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  1879  
  1880  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  1881  	c.Assert(err, jc.ErrorIsNil)
  1882  
  1883  	addr, err = machine.PublicAddress()
  1884  	c.Assert(err, jc.ErrorIsNil)
  1885  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  1886  }
  1887  
  1888  func (s *MachineSuite) TestPrivateAddressBetterMatch(c *gc.C) {
  1889  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1890  	c.Assert(err, jc.ErrorIsNil)
  1891  
  1892  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  1893  	c.Assert(err, jc.ErrorIsNil)
  1894  
  1895  	addr, err := machine.PrivateAddress()
  1896  	c.Assert(err, jc.ErrorIsNil)
  1897  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  1898  
  1899  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"), network.NewAddress("10.0.0.1"))
  1900  	c.Assert(err, jc.ErrorIsNil)
  1901  
  1902  	addr, err = machine.PrivateAddress()
  1903  	c.Assert(err, jc.ErrorIsNil)
  1904  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  1905  }
  1906  
  1907  func (s *MachineSuite) TestPublicAddressChanges(c *gc.C) {
  1908  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1909  	c.Assert(err, jc.ErrorIsNil)
  1910  
  1911  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  1912  	c.Assert(err, jc.ErrorIsNil)
  1913  
  1914  	addr, err := machine.PublicAddress()
  1915  	c.Assert(err, jc.ErrorIsNil)
  1916  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  1917  
  1918  	err = machine.SetProviderAddresses(network.NewAddress("8.8.4.4"))
  1919  	c.Assert(err, jc.ErrorIsNil)
  1920  
  1921  	addr, err = machine.PublicAddress()
  1922  	c.Assert(err, jc.ErrorIsNil)
  1923  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  1924  }
  1925  
  1926  func (s *MachineSuite) TestPrivateAddressChanges(c *gc.C) {
  1927  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1928  	c.Assert(err, jc.ErrorIsNil)
  1929  
  1930  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.2"))
  1931  	c.Assert(err, jc.ErrorIsNil)
  1932  
  1933  	addr, err := machine.PrivateAddress()
  1934  	c.Assert(err, jc.ErrorIsNil)
  1935  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  1936  
  1937  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.1"))
  1938  	c.Assert(err, jc.ErrorIsNil)
  1939  
  1940  	addr, err = machine.PrivateAddress()
  1941  	c.Assert(err, jc.ErrorIsNil)
  1942  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  1943  }
  1944  
  1945  func (s *MachineSuite) TestAddressesDeadMachine(c *gc.C) {
  1946  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1947  	c.Assert(err, jc.ErrorIsNil)
  1948  
  1949  	err = machine.SetProviderAddresses(network.NewAddress("10.0.0.2"), network.NewAddress("8.8.4.4"))
  1950  	c.Assert(err, jc.ErrorIsNil)
  1951  
  1952  	addr, err := machine.PrivateAddress()
  1953  	c.Assert(err, jc.ErrorIsNil)
  1954  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  1955  
  1956  	addr, err = machine.PublicAddress()
  1957  	c.Assert(err, jc.ErrorIsNil)
  1958  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  1959  
  1960  	err = machine.EnsureDead()
  1961  	c.Assert(err, jc.ErrorIsNil)
  1962  
  1963  	// A dead machine should still report the last known addresses.
  1964  	addr, err = machine.PrivateAddress()
  1965  	c.Assert(err, jc.ErrorIsNil)
  1966  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  1967  
  1968  	addr, err = machine.PublicAddress()
  1969  	c.Assert(err, jc.ErrorIsNil)
  1970  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  1971  }
  1972  
  1973  func (s *MachineSuite) TestStablePrivateAddress(c *gc.C) {
  1974  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1975  	c.Assert(err, jc.ErrorIsNil)
  1976  
  1977  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.2"))
  1978  	c.Assert(err, jc.ErrorIsNil)
  1979  
  1980  	addr, err := machine.PrivateAddress()
  1981  	c.Assert(err, jc.ErrorIsNil)
  1982  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  1983  
  1984  	// Now add an address that would previously have sorted before the
  1985  	// default.
  1986  	err = machine.SetMachineAddresses(network.NewAddress("10.0.0.1"), network.NewAddress("10.0.0.2"))
  1987  	c.Assert(err, jc.ErrorIsNil)
  1988  
  1989  	// Assert the address is unchanged.
  1990  	addr, err = machine.PrivateAddress()
  1991  	c.Assert(err, jc.ErrorIsNil)
  1992  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  1993  }
  1994  
  1995  func (s *MachineSuite) TestStablePublicAddress(c *gc.C) {
  1996  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  1997  	c.Assert(err, jc.ErrorIsNil)
  1998  
  1999  	err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  2000  	c.Assert(err, jc.ErrorIsNil)
  2001  
  2002  	addr, err := machine.PublicAddress()
  2003  	c.Assert(err, jc.ErrorIsNil)
  2004  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  2005  
  2006  	// Now add an address that would previously have sorted before the
  2007  	// default.
  2008  	err = machine.SetProviderAddresses(network.NewAddress("8.8.4.4"), network.NewAddress("8.8.8.8"))
  2009  	c.Assert(err, jc.ErrorIsNil)
  2010  
  2011  	// Assert the address is unchanged.
  2012  	addr, err = machine.PublicAddress()
  2013  	c.Assert(err, jc.ErrorIsNil)
  2014  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  2015  }
  2016  
  2017  func (s *MachineSuite) TestAddressesRaceMachineFirst(c *gc.C) {
  2018  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2019  	c.Assert(err, jc.ErrorIsNil)
  2020  
  2021  	changeAddresses := jujutxn.TestHook{
  2022  		Before: func() {
  2023  			err = machine.SetProviderAddresses(network.NewAddress("8.8.8.8"))
  2024  			c.Assert(err, jc.ErrorIsNil)
  2025  			address, err := machine.PublicAddress()
  2026  			c.Assert(err, jc.ErrorIsNil)
  2027  			c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.8.8"))
  2028  			address, err = machine.PrivateAddress()
  2029  			c.Assert(err, jc.ErrorIsNil)
  2030  			c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.8.8"))
  2031  		},
  2032  	}
  2033  	defer state.SetTestHooks(c, s.State, changeAddresses).Check()
  2034  
  2035  	err = machine.SetMachineAddresses(network.NewAddress("8.8.4.4"))
  2036  	c.Assert(err, jc.ErrorIsNil)
  2037  
  2038  	machine, err = s.State.Machine(machine.Id())
  2039  	c.Assert(err, jc.ErrorIsNil)
  2040  	address, err := machine.PublicAddress()
  2041  	c.Assert(err, jc.ErrorIsNil)
  2042  	c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.8.8"))
  2043  	address, err = machine.PrivateAddress()
  2044  	c.Assert(err, jc.ErrorIsNil)
  2045  	c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.8.8"))
  2046  }
  2047  
  2048  func (s *MachineSuite) TestAddressesRaceProviderFirst(c *gc.C) {
  2049  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2050  	c.Assert(err, jc.ErrorIsNil)
  2051  
  2052  	changeAddresses := jujutxn.TestHook{
  2053  		Before: func() {
  2054  			err = machine.SetMachineAddresses(network.NewAddress("10.0.0.1"))
  2055  			c.Assert(err, jc.ErrorIsNil)
  2056  			address, err := machine.PublicAddress()
  2057  			c.Assert(err, jc.ErrorIsNil)
  2058  			c.Assert(address, jc.DeepEquals, network.NewAddress("10.0.0.1"))
  2059  			address, err = machine.PrivateAddress()
  2060  			c.Assert(err, jc.ErrorIsNil)
  2061  			c.Assert(address, jc.DeepEquals, network.NewAddress("10.0.0.1"))
  2062  		},
  2063  	}
  2064  	defer state.SetTestHooks(c, s.State, changeAddresses).Check()
  2065  
  2066  	err = machine.SetProviderAddresses(network.NewAddress("8.8.4.4"))
  2067  	c.Assert(err, jc.ErrorIsNil)
  2068  
  2069  	machine, err = s.State.Machine(machine.Id())
  2070  	c.Assert(err, jc.ErrorIsNil)
  2071  	address, err := machine.PublicAddress()
  2072  	c.Assert(err, jc.ErrorIsNil)
  2073  	c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.4.4"))
  2074  	address, err = machine.PrivateAddress()
  2075  	c.Assert(err, jc.ErrorIsNil)
  2076  	c.Assert(address, jc.DeepEquals, network.NewAddress("8.8.4.4"))
  2077  }
  2078  
  2079  func (s *MachineSuite) TestPrivateAddressPrefersProvider(c *gc.C) {
  2080  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2081  	c.Assert(err, jc.ErrorIsNil)
  2082  
  2083  	err = machine.SetMachineAddresses(network.NewAddress("8.8.8.8"), network.NewAddress("10.0.0.2"))
  2084  	c.Assert(err, jc.ErrorIsNil)
  2085  
  2086  	addr, err := machine.PublicAddress()
  2087  	c.Assert(err, jc.ErrorIsNil)
  2088  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  2089  	addr, err = machine.PrivateAddress()
  2090  	c.Assert(err, jc.ErrorIsNil)
  2091  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  2092  
  2093  	err = machine.SetProviderAddresses(network.NewAddress("10.0.0.1"))
  2094  	c.Assert(err, jc.ErrorIsNil)
  2095  
  2096  	addr, err = machine.PublicAddress()
  2097  	c.Assert(err, jc.ErrorIsNil)
  2098  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  2099  	addr, err = machine.PrivateAddress()
  2100  	c.Assert(err, jc.ErrorIsNil)
  2101  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  2102  }
  2103  
  2104  func (s *MachineSuite) TestPublicAddressPrefersProvider(c *gc.C) {
  2105  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2106  	c.Assert(err, jc.ErrorIsNil)
  2107  
  2108  	err = machine.SetMachineAddresses(network.NewAddress("8.8.8.8"), network.NewAddress("10.0.0.2"))
  2109  	c.Assert(err, jc.ErrorIsNil)
  2110  
  2111  	addr, err := machine.PublicAddress()
  2112  	c.Assert(err, jc.ErrorIsNil)
  2113  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  2114  	addr, err = machine.PrivateAddress()
  2115  	c.Assert(err, jc.ErrorIsNil)
  2116  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  2117  
  2118  	err = machine.SetProviderAddresses(network.NewAddress("8.8.4.4"))
  2119  	c.Assert(err, jc.ErrorIsNil)
  2120  
  2121  	addr, err = machine.PublicAddress()
  2122  	c.Assert(err, jc.ErrorIsNil)
  2123  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  2124  	addr, err = machine.PrivateAddress()
  2125  	c.Assert(err, jc.ErrorIsNil)
  2126  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  2127  }
  2128  
  2129  func (s *MachineSuite) TestAddressesPrefersProviderBoth(c *gc.C) {
  2130  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2131  	c.Assert(err, jc.ErrorIsNil)
  2132  
  2133  	err = machine.SetMachineAddresses(network.NewAddress("8.8.8.8"), network.NewAddress("10.0.0.1"))
  2134  	c.Assert(err, jc.ErrorIsNil)
  2135  
  2136  	addr, err := machine.PublicAddress()
  2137  	c.Assert(err, jc.ErrorIsNil)
  2138  	c.Assert(addr.Value, gc.Equals, "8.8.8.8")
  2139  	addr, err = machine.PrivateAddress()
  2140  	c.Assert(err, jc.ErrorIsNil)
  2141  	c.Assert(addr.Value, gc.Equals, "10.0.0.1")
  2142  
  2143  	err = machine.SetProviderAddresses(network.NewAddress("8.8.4.4"), network.NewAddress("10.0.0.2"))
  2144  	c.Assert(err, jc.ErrorIsNil)
  2145  
  2146  	addr, err = machine.PublicAddress()
  2147  	c.Assert(err, jc.ErrorIsNil)
  2148  	c.Assert(addr.Value, gc.Equals, "8.8.4.4")
  2149  	addr, err = machine.PrivateAddress()
  2150  	c.Assert(err, jc.ErrorIsNil)
  2151  	c.Assert(addr.Value, gc.Equals, "10.0.0.2")
  2152  }
  2153  
  2154  func (s *MachineSuite) addMachineWithSupportedContainer(c *gc.C, container instance.ContainerType) *state.Machine {
  2155  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2156  	c.Assert(err, jc.ErrorIsNil)
  2157  	containers := []instance.ContainerType{container}
  2158  	err = machine.SetSupportedContainers(containers)
  2159  	c.Assert(err, jc.ErrorIsNil)
  2160  	assertSupportedContainers(c, machine, containers)
  2161  	return machine
  2162  }
  2163  
  2164  // assertSupportedContainers checks the document in memory has the specified
  2165  // containers and then reloads the document from the database to assert saved
  2166  // values match also.
  2167  func assertSupportedContainers(c *gc.C, machine *state.Machine, containers []instance.ContainerType) {
  2168  	supportedContainers, known := machine.SupportedContainers()
  2169  	c.Assert(known, jc.IsTrue)
  2170  	c.Assert(supportedContainers, gc.DeepEquals, containers)
  2171  	// Reload so we can check the saved values.
  2172  	err := machine.Refresh()
  2173  	c.Assert(err, jc.ErrorIsNil)
  2174  	supportedContainers, known = machine.SupportedContainers()
  2175  	c.Assert(known, jc.IsTrue)
  2176  	c.Assert(supportedContainers, gc.DeepEquals, containers)
  2177  }
  2178  
  2179  func assertSupportedContainersUnknown(c *gc.C, machine *state.Machine) {
  2180  	containers, known := machine.SupportedContainers()
  2181  	c.Assert(known, jc.IsFalse)
  2182  	c.Assert(containers, gc.HasLen, 0)
  2183  }
  2184  
  2185  func (s *MachineSuite) TestSupportedContainersInitiallyUnknown(c *gc.C) {
  2186  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2187  	c.Assert(err, jc.ErrorIsNil)
  2188  	assertSupportedContainersUnknown(c, machine)
  2189  }
  2190  
  2191  func (s *MachineSuite) TestSupportsNoContainers(c *gc.C) {
  2192  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2193  	c.Assert(err, jc.ErrorIsNil)
  2194  
  2195  	err = machine.SupportsNoContainers()
  2196  	c.Assert(err, jc.ErrorIsNil)
  2197  	assertSupportedContainers(c, machine, []instance.ContainerType{})
  2198  }
  2199  
  2200  func (s *MachineSuite) TestSetSupportedContainerTypeNoneIsError(c *gc.C) {
  2201  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2202  	c.Assert(err, jc.ErrorIsNil)
  2203  
  2204  	err = machine.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.NONE})
  2205  	c.Assert(err, gc.ErrorMatches, `"none" is not a valid container type`)
  2206  	assertSupportedContainersUnknown(c, machine)
  2207  	err = machine.Refresh()
  2208  	c.Assert(err, jc.ErrorIsNil)
  2209  	assertSupportedContainersUnknown(c, machine)
  2210  }
  2211  
  2212  func (s *MachineSuite) TestSupportsNoContainersOverwritesExisting(c *gc.C) {
  2213  	machine := s.addMachineWithSupportedContainer(c, instance.LXC)
  2214  
  2215  	err := machine.SupportsNoContainers()
  2216  	c.Assert(err, jc.ErrorIsNil)
  2217  	assertSupportedContainers(c, machine, []instance.ContainerType{})
  2218  }
  2219  
  2220  func (s *MachineSuite) TestSetSupportedContainersSingle(c *gc.C) {
  2221  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2222  	c.Assert(err, jc.ErrorIsNil)
  2223  
  2224  	err = machine.SetSupportedContainers([]instance.ContainerType{instance.LXC})
  2225  	c.Assert(err, jc.ErrorIsNil)
  2226  	assertSupportedContainers(c, machine, []instance.ContainerType{instance.LXC})
  2227  }
  2228  
  2229  func (s *MachineSuite) TestSetSupportedContainersSame(c *gc.C) {
  2230  	machine := s.addMachineWithSupportedContainer(c, instance.LXC)
  2231  
  2232  	err := machine.SetSupportedContainers([]instance.ContainerType{instance.LXC})
  2233  	c.Assert(err, jc.ErrorIsNil)
  2234  	assertSupportedContainers(c, machine, []instance.ContainerType{instance.LXC})
  2235  }
  2236  
  2237  func (s *MachineSuite) TestSetSupportedContainersNew(c *gc.C) {
  2238  	machine := s.addMachineWithSupportedContainer(c, instance.LXC)
  2239  
  2240  	err := machine.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.KVM})
  2241  	c.Assert(err, jc.ErrorIsNil)
  2242  	assertSupportedContainers(c, machine, []instance.ContainerType{instance.LXC, instance.KVM})
  2243  }
  2244  
  2245  func (s *MachineSuite) TestSetSupportedContainersMultipeNew(c *gc.C) {
  2246  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2247  	c.Assert(err, jc.ErrorIsNil)
  2248  
  2249  	err = machine.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.KVM})
  2250  	c.Assert(err, jc.ErrorIsNil)
  2251  	assertSupportedContainers(c, machine, []instance.ContainerType{instance.LXC, instance.KVM})
  2252  }
  2253  
  2254  func (s *MachineSuite) TestSetSupportedContainersMultipleExisting(c *gc.C) {
  2255  	machine := s.addMachineWithSupportedContainer(c, instance.LXC)
  2256  
  2257  	err := machine.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.KVM})
  2258  	c.Assert(err, jc.ErrorIsNil)
  2259  	assertSupportedContainers(c, machine, []instance.ContainerType{instance.LXC, instance.KVM})
  2260  }
  2261  
  2262  func (s *MachineSuite) TestSetSupportedContainersSetsUnknownToError(c *gc.C) {
  2263  	// Create a machine and add lxc and kvm containers prior to calling SetSupportedContainers
  2264  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2265  	template := state.MachineTemplate{
  2266  		Series: "quantal",
  2267  		Jobs:   []state.MachineJob{state.JobHostUnits},
  2268  	}
  2269  	container, err := s.State.AddMachineInsideMachine(template, machine.Id(), instance.LXC)
  2270  	c.Assert(err, jc.ErrorIsNil)
  2271  	supportedContainer, err := s.State.AddMachineInsideMachine(template, machine.Id(), instance.KVM)
  2272  	c.Assert(err, jc.ErrorIsNil)
  2273  	err = machine.SetSupportedContainers([]instance.ContainerType{instance.KVM})
  2274  	c.Assert(err, jc.ErrorIsNil)
  2275  
  2276  	// A supported (kvm) container will have a pending status.
  2277  	err = supportedContainer.Refresh()
  2278  	c.Assert(err, jc.ErrorIsNil)
  2279  	statusInfo, err := supportedContainer.Status()
  2280  	c.Assert(err, jc.ErrorIsNil)
  2281  	c.Assert(statusInfo.Status, gc.Equals, status.StatusPending)
  2282  
  2283  	// An unsupported (lxc) container will have an error status.
  2284  	err = container.Refresh()
  2285  	c.Assert(err, jc.ErrorIsNil)
  2286  	statusInfo, err = container.Status()
  2287  	c.Assert(err, jc.ErrorIsNil)
  2288  	c.Assert(statusInfo.Status, gc.Equals, status.StatusError)
  2289  	c.Assert(statusInfo.Message, gc.Equals, "unsupported container")
  2290  	c.Assert(statusInfo.Data, gc.DeepEquals, map[string]interface{}{"type": "lxc"})
  2291  }
  2292  
  2293  func (s *MachineSuite) TestSupportsNoContainersSetsAllToError(c *gc.C) {
  2294  	// Create a machine and add all container types prior to calling SupportsNoContainers
  2295  	machine, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2296  	var containers []*state.Machine
  2297  	template := state.MachineTemplate{
  2298  		Series: "quantal",
  2299  		Jobs:   []state.MachineJob{state.JobHostUnits},
  2300  	}
  2301  	for _, containerType := range instance.ContainerTypes {
  2302  		container, err := s.State.AddMachineInsideMachine(template, machine.Id(), containerType)
  2303  		c.Assert(err, jc.ErrorIsNil)
  2304  		containers = append(containers, container)
  2305  	}
  2306  
  2307  	err = machine.SupportsNoContainers()
  2308  	c.Assert(err, jc.ErrorIsNil)
  2309  
  2310  	// All containers should be in error state.
  2311  	for _, container := range containers {
  2312  		err = container.Refresh()
  2313  		c.Assert(err, jc.ErrorIsNil)
  2314  		statusInfo, err := container.Status()
  2315  		c.Assert(err, jc.ErrorIsNil)
  2316  		c.Assert(statusInfo.Status, gc.Equals, status.StatusError)
  2317  		c.Assert(statusInfo.Message, gc.Equals, "unsupported container")
  2318  		containerType := state.ContainerTypeFromId(container.Id())
  2319  		c.Assert(statusInfo.Data, gc.DeepEquals, map[string]interface{}{"type": string(containerType)})
  2320  	}
  2321  }
  2322  
  2323  func (s *MachineSuite) TestMachineAgentTools(c *gc.C) {
  2324  	m, err := s.State.AddMachine("quantal", state.JobHostUnits)
  2325  	c.Assert(err, jc.ErrorIsNil)
  2326  	testAgentTools(c, m, "machine "+m.Id())
  2327  }
  2328  
  2329  func (s *MachineSuite) TestMachineValidActions(c *gc.C) {
  2330  	m, err := s.State.AddMachine("trusty", state.JobHostUnits)
  2331  	c.Assert(err, jc.ErrorIsNil)
  2332  
  2333  	var tests = []struct {
  2334  		actionName      string
  2335  		errString       string
  2336  		givenPayload    map[string]interface{}
  2337  		expectedPayload map[string]interface{}
  2338  	}{
  2339  		{
  2340  			actionName: "juju-run",
  2341  			errString:  `validation failed: (root) : "command" property is missing and required, given {}; (root) : "timeout" property is missing and required, given {}`,
  2342  		},
  2343  		{
  2344  			actionName:      "juju-run",
  2345  			givenPayload:    map[string]interface{}{"command": "allyourbasearebelongtous", "timeout": 5.0},
  2346  			expectedPayload: map[string]interface{}{"command": "allyourbasearebelongtous", "timeout": 5.0},
  2347  		},
  2348  		{
  2349  			actionName: "baiku",
  2350  			errString:  `cannot add action "baiku" to a machine; only predefined actions allowed`,
  2351  		},
  2352  	}
  2353  
  2354  	for i, t := range tests {
  2355  		c.Logf("running test %d", i)
  2356  		action, err := m.AddAction(t.actionName, t.givenPayload)
  2357  		if t.errString != "" {
  2358  			c.Assert(err.Error(), gc.Equals, t.errString)
  2359  			continue
  2360  		} else {
  2361  			c.Assert(err, jc.ErrorIsNil)
  2362  			c.Assert(action.Parameters(), jc.DeepEquals, t.expectedPayload)
  2363  		}
  2364  	}
  2365  }
  2366  
  2367  func (s *MachineSuite) TestMachineAddDifferentAction(c *gc.C) {
  2368  	m, err := s.State.AddMachine("trusty", state.JobHostUnits)
  2369  	c.Assert(err, jc.ErrorIsNil)
  2370  
  2371  	_, err = m.AddAction("benchmark", nil)
  2372  	c.Assert(err, gc.ErrorMatches, `cannot add action "benchmark" to a machine; only predefined actions allowed`)
  2373  }