github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/provisioner/containerprovisioner_test.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner_test 5 6 import ( 7 "fmt" 8 "runtime" 9 "time" 10 11 "github.com/juju/errors" 12 "github.com/juju/loggo" 13 "github.com/juju/names/v5" 14 jc "github.com/juju/testing/checkers" 15 "github.com/juju/worker/v3/workertest" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/container/kvm/mock" 19 kvmtesting "github.com/juju/juju/container/kvm/testing" 20 "github.com/juju/juju/core/arch" 21 "github.com/juju/juju/core/instance" 22 "github.com/juju/juju/state" 23 coretesting "github.com/juju/juju/testing" 24 "github.com/juju/juju/worker/provisioner" 25 ) 26 27 type kvmProvisionerSuite struct { 28 CommonProvisionerSuite 29 kvmtesting.TestSuite 30 31 events chan mock.Event 32 } 33 34 var _ = gc.Suite(&kvmProvisionerSuite{}) 35 36 func (s *kvmProvisionerSuite) SetUpSuite(c *gc.C) { 37 s.CommonProvisionerSuite.SetUpSuite(c) 38 s.TestSuite.SetUpSuite(c) 39 } 40 41 func (s *kvmProvisionerSuite) TearDownSuite(c *gc.C) { 42 s.TestSuite.TearDownSuite(c) 43 s.CommonProvisionerSuite.TearDownSuite(c) 44 } 45 46 func (s *kvmProvisionerSuite) SetUpTest(c *gc.C) { 47 s.CommonProvisionerSuite.SetUpTest(c) 48 s.TestSuite.SetUpTest(c) 49 50 s.events = make(chan mock.Event, 25) 51 s.ContainerFactory.AddListener(s.events) 52 } 53 54 func (s *kvmProvisionerSuite) nextEvent(c *gc.C) mock.Event { 55 select { 56 case event := <-s.events: 57 return event 58 case <-time.After(coretesting.LongWait): 59 c.Fatalf("no event arrived") 60 } 61 panic("not reachable") 62 } 63 64 func (s *kvmProvisionerSuite) expectStarted(c *gc.C, machine *state.Machine) string { 65 event := s.nextEvent(c) 66 c.Assert(event.Action, gc.Equals, mock.Started) 67 err := machine.Refresh() 68 c.Assert(err, jc.ErrorIsNil) 69 s.waitInstanceId(c, machine, instance.Id(event.InstanceId)) 70 return event.InstanceId 71 } 72 73 func (s *kvmProvisionerSuite) expectStopped(c *gc.C, instId string) { 74 event := s.nextEvent(c) 75 c.Assert(event.Action, gc.Equals, mock.Stopped) 76 c.Assert(event.InstanceId, gc.Equals, instId) 77 } 78 79 func (s *kvmProvisionerSuite) expectNoEvents(c *gc.C) { 80 select { 81 case event := <-s.events: 82 c.Fatalf("unexpected event %#v", event) 83 case <-time.After(coretesting.ShortWait): 84 return 85 } 86 } 87 88 func (s *kvmProvisionerSuite) TearDownTest(c *gc.C) { 89 close(s.events) 90 s.TestSuite.TearDownTest(c) 91 s.CommonProvisionerSuite.TearDownTest(c) 92 } 93 94 func (s *kvmProvisionerSuite) newKvmProvisioner(c *gc.C) provisioner.Provisioner { 95 broker := &mockBroker{Environ: s.Environ, retryCount: make(map[string]int), 96 startInstanceFailureInfo: map[string]mockBrokerFailures{ 97 "3": {whenSucceed: 2, err: fmt.Errorf("error: some error")}, 98 "4": {whenSucceed: 2, err: fmt.Errorf("error: some error")}, 99 }, 100 } 101 machineTag := names.NewMachineTag("0") 102 agentConfig := s.AgentConfigForTag(c, machineTag) 103 toolsFinder := (*provisioner.GetToolsFinder)(s.provisioner) 104 w, err := provisioner.NewContainerProvisioner( 105 instance.KVM, s.provisioner, loggo.GetLogger("test"), 106 agentConfig, broker, 107 toolsFinder, &mockDistributionGroupFinder{}, &credentialAPIForTest{}) 108 c.Assert(err, jc.ErrorIsNil) 109 return w 110 } 111 112 func (s *kvmProvisionerSuite) TestProvisionerStartStop(c *gc.C) { 113 p := s.newKvmProvisioner(c) 114 workertest.CleanKill(c, p) 115 } 116 117 func (s *kvmProvisionerSuite) TestDoesNotStartEnvironMachines(c *gc.C) { 118 p := s.newKvmProvisioner(c) 119 defer workertest.CleanKill(c, p) 120 121 // Check that an instance is not provisioned when the machine is created. 122 _, err := s.State.AddMachine(state.UbuntuBase("22.04"), state.JobHostUnits) 123 c.Assert(err, jc.ErrorIsNil) 124 125 s.expectNoEvents(c) 126 } 127 128 func (s *kvmProvisionerSuite) TestDoesNotHaveRetryWatcher(c *gc.C) { 129 p := s.newKvmProvisioner(c) 130 defer workertest.CleanKill(c, p) 131 132 w, err := provisioner.GetRetryWatcher(p) 133 c.Assert(w, gc.IsNil) 134 c.Assert(err, jc.Satisfies, errors.IsNotImplemented) 135 } 136 137 func (s *kvmProvisionerSuite) addContainer(c *gc.C) *state.Machine { 138 template := state.MachineTemplate{ 139 Base: state.DefaultLTSBase(), 140 Jobs: []state.MachineJob{state.JobHostUnits}, 141 } 142 container, err := s.State.AddMachineInsideMachine(template, "0", instance.KVM) 143 c.Assert(err, jc.ErrorIsNil) 144 return container 145 } 146 147 func (s *kvmProvisionerSuite) TestContainerStartedAndStopped(c *gc.C) { 148 if arch.NormaliseArch(runtime.GOARCH) != arch.AMD64 { 149 c.Skip("Test only enabled on amd64, see bug lp:1572145") 150 } 151 p := s.newKvmProvisioner(c) 152 defer workertest.CleanKill(c, p) 153 154 container := s.addContainer(c) 155 156 // TODO(jam): 2016-12-22 recent changes to check for networking changes 157 // when starting a container cause this test to start failing, because 158 // the Dummy provider does not support Networking configuration. 159 _, _, err := s.provisioner.HostChangesForContainer(container.MachineTag()) 160 c.Assert(err, gc.ErrorMatches, "dummy provider network config not supported.*") 161 c.Skip("dummy provider doesn't support network config. https://pad.lv/1651974") 162 instId := s.expectStarted(c, container) 163 164 // ...and removed, along with the machine, when the machine is Dead. 165 c.Assert(container.EnsureDead(), gc.IsNil) 166 s.expectStopped(c, instId) 167 s.waitForRemovalMark(c, container) 168 } 169 170 func (s *kvmProvisionerSuite) TestKVMProvisionerObservesConfigChanges(c *gc.C) { 171 p := s.newKvmProvisioner(c) 172 defer workertest.CleanKill(c, p) 173 s.assertProvisionerObservesConfigChanges(c, p) 174 } 175 176 func (s *kvmProvisionerSuite) TestKVMProvisionerObservesConfigChangesWorkerCount(c *gc.C) { 177 p := s.newKvmProvisioner(c) 178 defer workertest.CleanKill(c, p) 179 s.assertProvisionerObservesConfigChangesWorkerCount(c, p, true) 180 } 181 182 type credentialAPIForTest struct{} 183 184 func (*credentialAPIForTest) InvalidateModelCredential(reason string) error { 185 return nil 186 }