github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/cmd/juju/ensureavailability_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "fmt" 8 9 jc "github.com/juju/testing/checkers" 10 gc "launchpad.net/gocheck" 11 12 "github.com/juju/juju/cmd/envcmd" 13 "github.com/juju/juju/constraints" 14 jujutesting "github.com/juju/juju/juju/testing" 15 "github.com/juju/juju/state" 16 "github.com/juju/juju/state/presence" 17 coretesting "github.com/juju/juju/testing" 18 ) 19 20 type EnsureAvailabilitySuite struct { 21 jujutesting.RepoSuite 22 machine0Pinger *presence.Pinger 23 } 24 25 var _ = gc.Suite(&EnsureAvailabilitySuite{}) 26 27 func (s *EnsureAvailabilitySuite) SetUpTest(c *gc.C) { 28 s.RepoSuite.SetUpTest(c) 29 // Add a state server to the environment, and ensure that it is 30 // considered 'alive' so that calls don't spawn new instances 31 _, err := s.State.AddMachine("precise", state.JobManageEnviron) 32 c.Assert(err, gc.IsNil) 33 m, err := s.BackingState.Machine("0") 34 c.Assert(err, gc.IsNil) 35 s.machine0Pinger, err = m.SetAgentAlive() 36 c.Assert(err, gc.IsNil) 37 s.BackingState.StartSync() 38 err = m.WaitAgentAlive(coretesting.LongWait) 39 c.Assert(err, gc.IsNil) 40 } 41 42 func (s *EnsureAvailabilitySuite) TearDownTest(c *gc.C) { 43 // We have to Kill the Pinger before TearDownTest, otherwise the State 44 // connection is already closed. 45 if s.machine0Pinger != nil { 46 s.machine0Pinger.Kill() 47 s.machine0Pinger = nil 48 } 49 s.RepoSuite.TearDownTest(c) 50 } 51 52 func runEnsureAvailability(c *gc.C, args ...string) error { 53 _, err := coretesting.RunCommand(c, envcmd.Wrap(&EnsureAvailabilityCommand{}), args...) 54 return err 55 } 56 57 func (s *EnsureAvailabilitySuite) TestEnsureAvailability(c *gc.C) { 58 err := runEnsureAvailability(c, "-n", "1") 59 c.Assert(err, gc.IsNil) 60 m, err := s.State.Machine("0") 61 c.Assert(err, gc.IsNil) 62 c.Assert(m.Life(), gc.Equals, state.Alive) 63 c.Assert(m.Series(), gc.DeepEquals, "precise") 64 mcons, err := m.Constraints() 65 c.Assert(err, gc.IsNil) 66 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) 67 } 68 69 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithSeries(c *gc.C) { 70 err := runEnsureAvailability(c, "--series", "series", "-n", "3") 71 c.Assert(err, gc.IsNil) 72 m, err := s.State.Machine("1") 73 c.Assert(err, gc.IsNil) 74 c.Assert(m.Series(), gc.DeepEquals, "series") 75 } 76 77 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityWithConstraints(c *gc.C) { 78 err := runEnsureAvailability(c, "--constraints", "mem=4G", "-n", "3") 79 c.Assert(err, gc.IsNil) 80 m, err := s.State.Machine("1") 81 c.Assert(err, gc.IsNil) 82 mcons, err := m.Constraints() 83 c.Assert(err, gc.IsNil) 84 expectedCons := constraints.MustParse("mem=4G") 85 c.Assert(mcons, gc.DeepEquals, expectedCons) 86 } 87 88 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityIdempotent(c *gc.C) { 89 for i := 0; i < 2; i++ { 90 err := runEnsureAvailability(c, "-n", "1") 91 c.Assert(err, gc.IsNil) 92 } 93 machines, err := s.State.AllMachines() 94 c.Assert(err, gc.IsNil) 95 c.Assert(machines, gc.HasLen, 1) 96 m, err := s.State.Machine("0") 97 c.Assert(err, gc.IsNil) 98 mcons, err := m.Constraints() 99 c.Assert(err, gc.IsNil) 100 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) 101 102 // Running ensure-availability with constraints or series 103 // will have no effect unless new machines are 104 // created. 105 err = runEnsureAvailability(c, "-n", "1", "--constraints", "mem=4G") 106 c.Assert(err, gc.IsNil) 107 m, err = s.State.Machine("0") 108 c.Assert(err, gc.IsNil) 109 mcons, err = m.Constraints() 110 c.Assert(err, gc.IsNil) 111 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) 112 } 113 114 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityMultiple(c *gc.C) { 115 err := runEnsureAvailability(c, "-n", "3", "--constraints", "mem=4G") 116 c.Assert(err, gc.IsNil) 117 118 machines, err := s.State.AllMachines() 119 c.Assert(err, gc.IsNil) 120 c.Assert(machines, gc.HasLen, 3) 121 mcons, err := machines[0].Constraints() 122 c.Assert(err, gc.IsNil) 123 c.Assert(&mcons, jc.Satisfies, constraints.IsEmpty) 124 for i := 1; i < 3; i++ { 125 mcons, err := machines[i].Constraints() 126 c.Assert(err, gc.IsNil) 127 expectedCons := constraints.MustParse("mem=4G") 128 c.Assert(mcons, gc.DeepEquals, expectedCons) 129 } 130 } 131 132 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityErrors(c *gc.C) { 133 for _, n := range []int{-1, 2} { 134 err := runEnsureAvailability(c, "-n", fmt.Sprint(n)) 135 c.Assert(err, gc.ErrorMatches, "must specify a number of state servers odd and non-negative") 136 } 137 err := runEnsureAvailability(c, "-n", "3") 138 c.Assert(err, gc.IsNil) 139 err = runEnsureAvailability(c, "-n", "1") 140 c.Assert(err, gc.ErrorMatches, "cannot reduce state server count") 141 } 142 143 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityAllows0(c *gc.C) { 144 err := runEnsureAvailability(c, "-n", "0") 145 c.Assert(err, gc.IsNil) 146 machines, err := s.State.AllMachines() 147 c.Assert(err, gc.IsNil) 148 c.Assert(machines, gc.HasLen, 3) 149 } 150 151 func (s *EnsureAvailabilitySuite) TestEnsureAvailabilityDefaultsTo3(c *gc.C) { 152 err := runEnsureAvailability(c) 153 c.Assert(err, gc.IsNil) 154 machines, err := s.State.AllMachines() 155 c.Assert(err, gc.IsNil) 156 c.Assert(machines, gc.HasLen, 3) 157 }