github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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 "path/filepath" 9 "time" 10 11 "github.com/juju/errors" 12 "github.com/juju/names" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/agent" 17 "github.com/juju/juju/constraints" 18 "github.com/juju/juju/container" 19 "github.com/juju/juju/container/kvm/mock" 20 kvmtesting "github.com/juju/juju/container/kvm/testing" 21 "github.com/juju/juju/environs" 22 "github.com/juju/juju/instance" 23 instancetest "github.com/juju/juju/instance/testing" 24 jujutesting "github.com/juju/juju/juju/testing" 25 "github.com/juju/juju/state" 26 coretesting "github.com/juju/juju/testing" 27 coretools "github.com/juju/juju/tools" 28 "github.com/juju/juju/version" 29 "github.com/juju/juju/worker/provisioner" 30 ) 31 32 type kvmSuite struct { 33 kvmtesting.TestSuite 34 events chan mock.Event 35 eventsDone chan struct{} 36 } 37 38 type kvmBrokerSuite struct { 39 kvmSuite 40 broker environs.InstanceBroker 41 agentConfig agent.Config 42 } 43 44 var _ = gc.Suite(&kvmBrokerSuite{}) 45 46 func (s *kvmSuite) SetUpTest(c *gc.C) { 47 s.TestSuite.SetUpTest(c) 48 s.events = make(chan mock.Event) 49 s.eventsDone = make(chan struct{}) 50 go func() { 51 defer close(s.eventsDone) 52 for event := range s.events { 53 c.Output(3, fmt.Sprintf("kvm event: <%s, %s>", event.Action, event.InstanceId)) 54 } 55 }() 56 s.TestSuite.ContainerFactory.AddListener(s.events) 57 } 58 59 func (s *kvmSuite) TearDownTest(c *gc.C) { 60 close(s.events) 61 <-s.eventsDone 62 s.TestSuite.TearDownTest(c) 63 } 64 65 func (s *kvmBrokerSuite) SetUpTest(c *gc.C) { 66 s.kvmSuite.SetUpTest(c) 67 var err error 68 s.agentConfig, err = agent.NewAgentConfig( 69 agent.AgentConfigParams{ 70 DataDir: "/not/used/here", 71 Tag: names.NewUnitTag("ubuntu/1"), 72 UpgradedToVersion: version.Current.Number, 73 Password: "dummy-secret", 74 Nonce: "nonce", 75 APIAddresses: []string{"10.0.0.1:1234"}, 76 CACert: coretesting.CACert, 77 Environment: coretesting.EnvironmentTag, 78 }) 79 c.Assert(err, jc.ErrorIsNil) 80 managerConfig := container.ManagerConfig{container.ConfigName: "juju"} 81 s.broker, err = provisioner.NewKvmBroker(&fakeAPI{}, s.agentConfig, managerConfig) 82 c.Assert(err, jc.ErrorIsNil) 83 } 84 85 func (s *kvmBrokerSuite) startInstance(c *gc.C, machineId string) instance.Instance { 86 machineNonce := "fake-nonce" 87 stateInfo := jujutesting.FakeStateInfo(machineId) 88 apiInfo := jujutesting.FakeAPIInfo(machineId) 89 machineConfig, err := environs.NewMachineConfig(machineId, machineNonce, "released", "quantal", true, nil, stateInfo, apiInfo) 90 c.Assert(err, jc.ErrorIsNil) 91 cons := constraints.Value{} 92 possibleTools := coretools.List{&coretools.Tools{ 93 Version: version.MustParseBinary("2.3.4-quantal-amd64"), 94 URL: "http://tools.testing.invalid/2.3.4-quantal-amd64.tgz", 95 }} 96 result, err := s.broker.StartInstance(environs.StartInstanceParams{ 97 Constraints: cons, 98 Tools: possibleTools, 99 MachineConfig: machineConfig, 100 }) 101 c.Assert(err, jc.ErrorIsNil) 102 return result.Instance 103 } 104 105 func (s *kvmBrokerSuite) TestStopInstance(c *gc.C) { 106 kvm0 := s.startInstance(c, "1/kvm/0") 107 kvm1 := s.startInstance(c, "1/kvm/1") 108 kvm2 := s.startInstance(c, "1/kvm/2") 109 110 err := s.broker.StopInstances(kvm0.Id()) 111 c.Assert(err, jc.ErrorIsNil) 112 s.assertInstances(c, kvm1, kvm2) 113 c.Assert(s.kvmContainerDir(kvm0), jc.DoesNotExist) 114 c.Assert(s.kvmRemovedContainerDir(kvm0), jc.IsDirectory) 115 116 err = s.broker.StopInstances(kvm1.Id(), kvm2.Id()) 117 c.Assert(err, jc.ErrorIsNil) 118 s.assertInstances(c) 119 } 120 121 func (s *kvmBrokerSuite) TestAllInstances(c *gc.C) { 122 kvm0 := s.startInstance(c, "1/kvm/0") 123 kvm1 := s.startInstance(c, "1/kvm/1") 124 s.assertInstances(c, kvm0, kvm1) 125 126 err := s.broker.StopInstances(kvm1.Id()) 127 c.Assert(err, jc.ErrorIsNil) 128 kvm2 := s.startInstance(c, "1/kvm/2") 129 s.assertInstances(c, kvm0, kvm2) 130 } 131 132 func (s *kvmBrokerSuite) assertInstances(c *gc.C, inst ...instance.Instance) { 133 results, err := s.broker.AllInstances() 134 c.Assert(err, jc.ErrorIsNil) 135 instancetest.MatchInstances(c, results, inst...) 136 } 137 138 func (s *kvmBrokerSuite) kvmContainerDir(inst instance.Instance) string { 139 return filepath.Join(s.ContainerDir, string(inst.Id())) 140 } 141 142 func (s *kvmBrokerSuite) kvmRemovedContainerDir(inst instance.Instance) string { 143 return filepath.Join(s.RemovedDir, string(inst.Id())) 144 } 145 146 type kvmProvisionerSuite struct { 147 CommonProvisionerSuite 148 kvmSuite 149 events chan mock.Event 150 } 151 152 var _ = gc.Suite(&kvmProvisionerSuite{}) 153 154 func (s *kvmProvisionerSuite) SetUpSuite(c *gc.C) { 155 s.CommonProvisionerSuite.SetUpSuite(c) 156 s.kvmSuite.SetUpSuite(c) 157 } 158 159 func (s *kvmProvisionerSuite) TearDownSuite(c *gc.C) { 160 s.kvmSuite.TearDownSuite(c) 161 s.CommonProvisionerSuite.TearDownSuite(c) 162 } 163 164 func (s *kvmProvisionerSuite) SetUpTest(c *gc.C) { 165 s.CommonProvisionerSuite.SetUpTest(c) 166 s.kvmSuite.SetUpTest(c) 167 168 s.events = make(chan mock.Event, 25) 169 s.ContainerFactory.AddListener(s.events) 170 } 171 172 func (s *kvmProvisionerSuite) nextEvent(c *gc.C) mock.Event { 173 select { 174 case event := <-s.events: 175 return event 176 case <-time.After(coretesting.LongWait): 177 c.Fatalf("no event arrived") 178 } 179 panic("not reachable") 180 } 181 182 func (s *kvmProvisionerSuite) expectStarted(c *gc.C, machine *state.Machine) string { 183 s.State.StartSync() 184 event := s.nextEvent(c) 185 c.Assert(event.Action, gc.Equals, mock.Started) 186 err := machine.Refresh() 187 c.Assert(err, jc.ErrorIsNil) 188 s.waitInstanceId(c, machine, instance.Id(event.InstanceId)) 189 return event.InstanceId 190 } 191 192 func (s *kvmProvisionerSuite) expectStopped(c *gc.C, instId string) { 193 s.State.StartSync() 194 event := s.nextEvent(c) 195 c.Assert(event.Action, gc.Equals, mock.Stopped) 196 c.Assert(event.InstanceId, gc.Equals, instId) 197 } 198 199 func (s *kvmProvisionerSuite) expectNoEvents(c *gc.C) { 200 select { 201 case event := <-s.events: 202 c.Fatalf("unexpected event %#v", event) 203 case <-time.After(coretesting.ShortWait): 204 return 205 } 206 } 207 208 func (s *kvmProvisionerSuite) TearDownTest(c *gc.C) { 209 close(s.events) 210 s.kvmSuite.TearDownTest(c) 211 s.CommonProvisionerSuite.TearDownTest(c) 212 } 213 214 func (s *kvmProvisionerSuite) newKvmProvisioner(c *gc.C) provisioner.Provisioner { 215 machineTag := names.NewMachineTag("0") 216 agentConfig := s.AgentConfigForTag(c, machineTag) 217 managerConfig := container.ManagerConfig{container.ConfigName: "juju"} 218 broker, err := provisioner.NewKvmBroker(s.provisioner, agentConfig, managerConfig) 219 c.Assert(err, jc.ErrorIsNil) 220 return provisioner.NewContainerProvisioner(instance.KVM, s.provisioner, agentConfig, broker) 221 } 222 223 func (s *kvmProvisionerSuite) TestProvisionerStartStop(c *gc.C) { 224 p := s.newKvmProvisioner(c) 225 c.Assert(p.Stop(), gc.IsNil) 226 } 227 228 func (s *kvmProvisionerSuite) TestDoesNotStartEnvironMachines(c *gc.C) { 229 p := s.newKvmProvisioner(c) 230 defer stop(c, p) 231 232 // Check that an instance is not provisioned when the machine is created. 233 _, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) 234 c.Assert(err, jc.ErrorIsNil) 235 236 s.expectNoEvents(c) 237 } 238 239 func (s *kvmProvisionerSuite) TestDoesNotHaveRetryWatcher(c *gc.C) { 240 p := s.newKvmProvisioner(c) 241 defer stop(c, p) 242 243 w, err := provisioner.GetRetryWatcher(p) 244 c.Assert(w, gc.IsNil) 245 c.Assert(err, jc.Satisfies, errors.IsNotImplemented) 246 } 247 248 func (s *kvmProvisionerSuite) addContainer(c *gc.C) *state.Machine { 249 template := state.MachineTemplate{ 250 Series: coretesting.FakeDefaultSeries, 251 Jobs: []state.MachineJob{state.JobHostUnits}, 252 } 253 container, err := s.State.AddMachineInsideMachine(template, "0", instance.KVM) 254 c.Assert(err, jc.ErrorIsNil) 255 return container 256 } 257 258 func (s *kvmProvisionerSuite) TestContainerStartedAndStopped(c *gc.C) { 259 p := s.newKvmProvisioner(c) 260 defer stop(c, p) 261 262 container := s.addContainer(c) 263 264 instId := s.expectStarted(c, container) 265 266 // ...and removed, along with the machine, when the machine is Dead. 267 c.Assert(container.EnsureDead(), gc.IsNil) 268 s.expectStopped(c, instId) 269 s.waitRemoved(c, container) 270 }