launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/worker/provisioner/kvm-broker_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner_test 5 6 import ( 7 "fmt" 8 gc "launchpad.net/gocheck" 9 "path/filepath" 10 "time" 11 12 "launchpad.net/juju-core/agent" 13 "launchpad.net/juju-core/constraints" 14 "launchpad.net/juju-core/container/kvm/mock" 15 kvmtesting "launchpad.net/juju-core/container/kvm/testing" 16 "launchpad.net/juju-core/environs" 17 "launchpad.net/juju-core/environs/config" 18 "launchpad.net/juju-core/instance" 19 instancetest "launchpad.net/juju-core/instance/testing" 20 jujutesting "launchpad.net/juju-core/juju/testing" 21 "launchpad.net/juju-core/names" 22 "launchpad.net/juju-core/state" 23 coretesting "launchpad.net/juju-core/testing" 24 jc "launchpad.net/juju-core/testing/checkers" 25 coretools "launchpad.net/juju-core/tools" 26 "launchpad.net/juju-core/version" 27 "launchpad.net/juju-core/worker/provisioner" 28 ) 29 30 type kvmSuite struct { 31 kvmtesting.TestSuite 32 events chan mock.Event 33 } 34 35 type kvmBrokerSuite struct { 36 kvmSuite 37 broker environs.InstanceBroker 38 agentConfig agent.Config 39 } 40 41 var _ = gc.Suite(&kvmBrokerSuite{}) 42 43 func (s *kvmSuite) SetUpTest(c *gc.C) { 44 s.TestSuite.SetUpTest(c) 45 s.events = make(chan mock.Event) 46 go func() { 47 for event := range s.events { 48 c.Output(3, fmt.Sprintf("kvm event: <%s, %s>", event.Action, event.InstanceId)) 49 } 50 }() 51 s.TestSuite.Factory.AddListener(s.events) 52 } 53 54 func (s *kvmSuite) TearDownTest(c *gc.C) { 55 close(s.events) 56 s.TestSuite.TearDownTest(c) 57 } 58 59 func (s *kvmBrokerSuite) SetUpTest(c *gc.C) { 60 s.kvmSuite.SetUpTest(c) 61 tools := &coretools.Tools{ 62 Version: version.MustParseBinary("2.3.4-foo-bar"), 63 URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", 64 } 65 var err error 66 s.agentConfig, err = agent.NewAgentConfig( 67 agent.AgentConfigParams{ 68 DataDir: "/not/used/here", 69 Tag: "tag", 70 Password: "dummy-secret", 71 Nonce: "nonce", 72 APIAddresses: []string{"10.0.0.1:1234"}, 73 CACert: []byte(coretesting.CACert), 74 }) 75 c.Assert(err, gc.IsNil) 76 s.broker, err = provisioner.NewKvmBroker(&fakeAPI{}, tools, s.agentConfig) 77 c.Assert(err, gc.IsNil) 78 } 79 80 func (s *kvmBrokerSuite) startInstance(c *gc.C, machineId string) instance.Instance { 81 machineNonce := "fake-nonce" 82 stateInfo := jujutesting.FakeStateInfo(machineId) 83 apiInfo := jujutesting.FakeAPIInfo(machineId) 84 machineConfig := environs.NewMachineConfig(machineId, machineNonce, stateInfo, apiInfo) 85 cons := constraints.Value{} 86 possibleTools := s.broker.(coretools.HasTools).Tools() 87 kvm, _, err := s.broker.StartInstance(cons, possibleTools, machineConfig) 88 c.Assert(err, gc.IsNil) 89 return kvm 90 } 91 92 func (s *kvmBrokerSuite) TestStopInstance(c *gc.C) { 93 kvm0 := s.startInstance(c, "1/kvm/0") 94 kvm1 := s.startInstance(c, "1/kvm/1") 95 kvm2 := s.startInstance(c, "1/kvm/2") 96 97 err := s.broker.StopInstances([]instance.Instance{kvm0}) 98 c.Assert(err, gc.IsNil) 99 s.assertInstances(c, kvm1, kvm2) 100 c.Assert(s.kvmContainerDir(kvm0), jc.DoesNotExist) 101 c.Assert(s.kvmRemovedContainerDir(kvm0), jc.IsDirectory) 102 103 err = s.broker.StopInstances([]instance.Instance{kvm1, kvm2}) 104 c.Assert(err, gc.IsNil) 105 s.assertInstances(c) 106 } 107 108 func (s *kvmBrokerSuite) TestAllInstances(c *gc.C) { 109 kvm0 := s.startInstance(c, "1/kvm/0") 110 kvm1 := s.startInstance(c, "1/kvm/1") 111 s.assertInstances(c, kvm0, kvm1) 112 113 err := s.broker.StopInstances([]instance.Instance{kvm1}) 114 c.Assert(err, gc.IsNil) 115 kvm2 := s.startInstance(c, "1/kvm/2") 116 s.assertInstances(c, kvm0, kvm2) 117 } 118 119 func (s *kvmBrokerSuite) assertInstances(c *gc.C, inst ...instance.Instance) { 120 results, err := s.broker.AllInstances() 121 c.Assert(err, gc.IsNil) 122 instancetest.MatchInstances(c, results, inst...) 123 } 124 125 func (s *kvmBrokerSuite) kvmContainerDir(inst instance.Instance) string { 126 return filepath.Join(s.ContainerDir, string(inst.Id())) 127 } 128 129 func (s *kvmBrokerSuite) kvmRemovedContainerDir(inst instance.Instance) string { 130 return filepath.Join(s.RemovedDir, string(inst.Id())) 131 } 132 133 type kvmProvisionerSuite struct { 134 CommonProvisionerSuite 135 kvmSuite 136 machineId string 137 events chan mock.Event 138 } 139 140 var _ = gc.Suite(&kvmProvisionerSuite{}) 141 142 func (s *kvmProvisionerSuite) SetUpSuite(c *gc.C) { 143 s.CommonProvisionerSuite.SetUpSuite(c) 144 s.kvmSuite.SetUpSuite(c) 145 } 146 147 func (s *kvmProvisionerSuite) TearDownSuite(c *gc.C) { 148 s.kvmSuite.TearDownSuite(c) 149 s.CommonProvisionerSuite.TearDownSuite(c) 150 } 151 152 func (s *kvmProvisionerSuite) SetUpTest(c *gc.C) { 153 s.CommonProvisionerSuite.SetUpTest(c) 154 s.kvmSuite.SetUpTest(c) 155 156 // The kvm provisioner actually needs the machine it is being created on 157 // to be in state, in order to get the watcher. 158 m, err := s.State.AddMachine(config.DefaultSeries, state.JobHostUnits, state.JobManageEnviron) 159 c.Assert(err, gc.IsNil) 160 err = m.SetAddresses([]instance.Address{ 161 instance.NewAddress("0.1.2.3"), 162 }) 163 c.Assert(err, gc.IsNil) 164 s.machineId = m.Id() 165 s.APILogin(c, m) 166 err = m.SetAgentVersion(version.Current) 167 c.Assert(err, gc.IsNil) 168 169 s.events = make(chan mock.Event, 25) 170 s.Factory.AddListener(s.events) 171 } 172 173 func (s *kvmProvisionerSuite) expectStarted(c *gc.C, machine *state.Machine) string { 174 s.State.StartSync() 175 event := <-s.events 176 c.Assert(event.Action, gc.Equals, mock.Started) 177 err := machine.Refresh() 178 c.Assert(err, gc.IsNil) 179 s.waitInstanceId(c, machine, instance.Id(event.InstanceId)) 180 return event.InstanceId 181 } 182 183 func (s *kvmProvisionerSuite) expectStopped(c *gc.C, instId string) { 184 s.State.StartSync() 185 event := <-s.events 186 c.Assert(event.Action, gc.Equals, mock.Stopped) 187 c.Assert(event.InstanceId, gc.Equals, instId) 188 } 189 190 func (s *kvmProvisionerSuite) expectNoEvents(c *gc.C) { 191 select { 192 case event := <-s.events: 193 c.Fatalf("unexpected event %#v", event) 194 case <-time.After(coretesting.ShortWait): 195 return 196 } 197 } 198 199 func (s *kvmProvisionerSuite) TearDownTest(c *gc.C) { 200 close(s.events) 201 s.kvmSuite.TearDownTest(c) 202 s.CommonProvisionerSuite.TearDownTest(c) 203 } 204 205 func (s *kvmProvisionerSuite) newKvmProvisioner(c *gc.C) provisioner.Provisioner { 206 machineTag := names.MachineTag(s.machineId) 207 agentConfig := s.AgentConfigForTag(c, machineTag) 208 tools, err := s.provisioner.Tools(agentConfig.Tag()) 209 c.Assert(err, gc.IsNil) 210 broker, err := provisioner.NewKvmBroker(s.provisioner, tools, agentConfig) 211 c.Assert(err, gc.IsNil) 212 return provisioner.NewContainerProvisioner(instance.KVM, s.provisioner, agentConfig, broker) 213 } 214 215 func (s *kvmProvisionerSuite) TestProvisionerStartStop(c *gc.C) { 216 p := s.newKvmProvisioner(c) 217 c.Assert(p.Stop(), gc.IsNil) 218 } 219 220 func (s *kvmProvisionerSuite) TestDoesNotStartEnvironMachines(c *gc.C) { 221 p := s.newKvmProvisioner(c) 222 defer stop(c, p) 223 224 // Check that an instance is not provisioned when the machine is created. 225 _, err := s.State.AddMachine(config.DefaultSeries, state.JobHostUnits) 226 c.Assert(err, gc.IsNil) 227 228 s.expectNoEvents(c) 229 } 230 231 func (s *kvmProvisionerSuite) addContainer(c *gc.C) *state.Machine { 232 template := state.MachineTemplate{ 233 Series: config.DefaultSeries, 234 Jobs: []state.MachineJob{state.JobHostUnits}, 235 } 236 container, err := s.State.AddMachineInsideMachine(template, s.machineId, instance.KVM) 237 c.Assert(err, gc.IsNil) 238 return container 239 } 240 241 func (s *kvmProvisionerSuite) TestContainerStartedAndStopped(c *gc.C) { 242 p := s.newKvmProvisioner(c) 243 defer stop(c, p) 244 245 container := s.addContainer(c) 246 247 instId := s.expectStarted(c, container) 248 249 // ...and removed, along with the machine, when the machine is Dead. 250 c.Assert(container.EnsureDead(), gc.IsNil) 251 s.expectStopped(c, instId) 252 s.waitRemoved(c, container) 253 }