github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/common/machine_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	"github.com/juju/utils"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/instance"
    15  	"github.com/juju/juju/state"
    16  	"github.com/juju/juju/state/multiwatcher"
    17  	"github.com/juju/juju/status"
    18  )
    19  
    20  type machineSuite struct{}
    21  
    22  var _ = gc.Suite(&machineSuite{})
    23  
    24  func (s *machineSuite) TestMachineJobFromParams(c *gc.C) {
    25  	var tests = []struct {
    26  		name multiwatcher.MachineJob
    27  		want state.MachineJob
    28  		err  string
    29  	}{{
    30  		name: multiwatcher.JobHostUnits,
    31  		want: state.JobHostUnits,
    32  	}, {
    33  		name: multiwatcher.JobManageModel,
    34  		want: state.JobManageModel,
    35  	}, {
    36  		name: "invalid",
    37  		want: -1,
    38  		err:  `invalid machine job "invalid"`,
    39  	}}
    40  	for _, test := range tests {
    41  		got, err := common.MachineJobFromParams(test.name)
    42  		if err != nil {
    43  			c.Check(err, gc.ErrorMatches, test.err)
    44  		}
    45  		c.Check(got, gc.Equals, test.want)
    46  	}
    47  }
    48  
    49  func (s *machineSuite) TestDestroyMachines(c *gc.C) {
    50  	st := mockState{
    51  		machines: map[string]*mockMachine{
    52  			"1": {},
    53  			"2": {destroyErr: errors.New("unit exists error")},
    54  			"3": {life: state.Dying},
    55  		},
    56  	}
    57  	err := common.MockableDestroyMachines(&st, false, "1", "2", "3", "4")
    58  
    59  	c.Assert(st.machines["1"].Life(), gc.Equals, state.Dying)
    60  	c.Assert(st.machines["1"].forceDestroyCalled, jc.IsFalse)
    61  
    62  	c.Assert(st.machines["2"].Life(), gc.Equals, state.Alive)
    63  	c.Assert(st.machines["2"].forceDestroyCalled, jc.IsFalse)
    64  
    65  	c.Assert(st.machines["3"].forceDestroyCalled, jc.IsFalse)
    66  	c.Assert(st.machines["3"].destroyCalled, jc.IsFalse)
    67  
    68  	c.Assert(err, gc.ErrorMatches, "some machines were not destroyed: unit exists error; machine 4 does not exist")
    69  }
    70  
    71  func (s *machineSuite) TestForceDestroyMachines(c *gc.C) {
    72  	st := mockState{
    73  		machines: map[string]*mockMachine{
    74  			"1": {},
    75  			"2": {life: state.Dying},
    76  		},
    77  	}
    78  	err := common.MockableDestroyMachines(&st, true, "1", "2")
    79  
    80  	c.Assert(st.machines["1"].Life(), gc.Equals, state.Dying)
    81  	c.Assert(st.machines["1"].forceDestroyCalled, jc.IsTrue)
    82  	c.Assert(st.machines["2"].forceDestroyCalled, jc.IsTrue)
    83  
    84  	c.Assert(err, jc.ErrorIsNil)
    85  }
    86  
    87  func (s *machineSuite) TestMachineHardwareInfo(c *gc.C) {
    88  	one := uint64(1)
    89  	amd64 := "amd64"
    90  	gig := uint64(1024)
    91  	st := mockState{
    92  		machines: map[string]*mockMachine{
    93  			"1": {id: "1", life: state.Alive, containerType: instance.NONE,
    94  				hw: &instance.HardwareCharacteristics{
    95  					Arch:     &amd64,
    96  					Mem:      &gig,
    97  					CpuCores: &one,
    98  					CpuPower: &one,
    99  				}},
   100  			"2": {id: "2", life: state.Alive, containerType: instance.LXD},
   101  			"3": {life: state.Dying},
   102  		},
   103  	}
   104  	info, err := common.ModelMachineInfo(&st)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  	c.Assert(info, jc.DeepEquals, []params.ModelMachineInfo{
   107  		{
   108  			Id: "1",
   109  			Hardware: &params.MachineHardware{
   110  				Arch:     &amd64,
   111  				Mem:      &gig,
   112  				Cores:    &one,
   113  				CpuPower: &one,
   114  			},
   115  		}, {
   116  			Id: "2",
   117  		},
   118  	})
   119  }
   120  
   121  func (s *machineSuite) TestMachineInstanceInfo(c *gc.C) {
   122  	st := mockState{
   123  		machines: map[string]*mockMachine{
   124  			"1": {id: "1", instId: instance.Id("123"), status: status.Down, hasVote: true, wantsVote: true},
   125  		},
   126  	}
   127  	info, err := common.ModelMachineInfo(&st)
   128  	c.Assert(err, jc.ErrorIsNil)
   129  	c.Assert(info, jc.DeepEquals, []params.ModelMachineInfo{
   130  		{
   131  			Id:         "1",
   132  			InstanceId: "123",
   133  			Status:     "down",
   134  			HasVote:    true,
   135  			WantsVote:  true,
   136  		},
   137  	})
   138  }
   139  
   140  type mockState struct {
   141  	common.ModelManagerBackend
   142  	machines map[string]*mockMachine
   143  }
   144  
   145  func (st *mockState) Machine(id string) (common.Machine, error) {
   146  	if m, ok := st.machines[id]; ok {
   147  		return m, nil
   148  	}
   149  	return nil, errors.Errorf("machine %s does not exist", id)
   150  }
   151  
   152  func (st *mockState) AllMachines() (machines []common.Machine, _ error) {
   153  	// Ensure we get machines in id order.
   154  	var ids []string
   155  	for id := range st.machines {
   156  		ids = append(ids, id)
   157  	}
   158  	utils.SortStringsNaturally(ids)
   159  	for _, id := range ids {
   160  		machines = append(machines, st.machines[id])
   161  	}
   162  	return machines, nil
   163  }
   164  
   165  type mockMachine struct {
   166  	state.Machine
   167  	id                 string
   168  	life               state.Life
   169  	containerType      instance.ContainerType
   170  	hw                 *instance.HardwareCharacteristics
   171  	instId             instance.Id
   172  	hasVote, wantsVote bool
   173  	status             status.Status
   174  	statusErr          error
   175  	destroyErr         error
   176  	forceDestroyErr    error
   177  	forceDestroyCalled bool
   178  	destroyCalled      bool
   179  	agentDead          bool
   180  	presenceErr        error
   181  }
   182  
   183  func (m *mockMachine) Id() string {
   184  	return m.id
   185  }
   186  
   187  func (m *mockMachine) Life() state.Life {
   188  	return m.life
   189  }
   190  
   191  func (m *mockMachine) InstanceId() (instance.Id, error) {
   192  	return m.instId, nil
   193  }
   194  
   195  func (m *mockMachine) WantsVote() bool {
   196  	return m.wantsVote
   197  }
   198  
   199  func (m *mockMachine) HasVote() bool {
   200  	return m.hasVote
   201  }
   202  
   203  func (m *mockMachine) Status() (status.StatusInfo, error) {
   204  	return status.StatusInfo{
   205  		Status: m.status,
   206  	}, m.statusErr
   207  }
   208  
   209  func (m *mockMachine) HardwareCharacteristics() (*instance.HardwareCharacteristics, error) {
   210  	return m.hw, nil
   211  }
   212  
   213  func (m *mockMachine) AgentPresence() (bool, error) {
   214  	return !m.agentDead, m.presenceErr
   215  }
   216  
   217  func (m *mockMachine) ForceDestroy() error {
   218  	m.forceDestroyCalled = true
   219  	if m.forceDestroyErr != nil {
   220  		return m.forceDestroyErr
   221  	}
   222  	m.life = state.Dying
   223  	return nil
   224  }
   225  
   226  func (m *mockMachine) Destroy() error {
   227  	m.destroyCalled = true
   228  	if m.destroyErr != nil {
   229  		return m.destroyErr
   230  	}
   231  	m.life = state.Dying
   232  	return nil
   233  }