github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/storageprovisioner/caasworker_test.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package storageprovisioner_test 5 6 import ( 7 "time" 8 9 "github.com/juju/clock/testclock" 10 "github.com/juju/errors" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "github.com/juju/utils" 14 gc "gopkg.in/check.v1" 15 "gopkg.in/juju/names.v2" 16 "gopkg.in/juju/worker.v1" 17 "gopkg.in/juju/worker.v1/workertest" 18 19 "github.com/juju/juju/apiserver/params" 20 "github.com/juju/juju/environs/context" 21 "github.com/juju/juju/storage" 22 coretesting "github.com/juju/juju/testing" 23 "github.com/juju/juju/worker/storageprovisioner" 24 ) 25 26 type WorkerSuite struct { 27 testing.IsolationSuite 28 29 config storageprovisioner.Config 30 applicationsWatcher *mockApplicationsWatcher 31 lifeGetter *mockLifecycleManager 32 33 applicationChanges chan []string 34 35 clock *testclock.Clock 36 } 37 38 var _ = gc.Suite(&WorkerSuite{}) 39 40 func (s *WorkerSuite) SetUpTest(c *gc.C) { 41 s.IsolationSuite.SetUpTest(c) 42 43 s.applicationChanges = make(chan []string) 44 s.applicationsWatcher = newMockApplicationsWatcher(s.applicationChanges) 45 s.lifeGetter = &mockLifecycleManager{} 46 47 s.config = storageprovisioner.Config{ 48 Model: coretesting.ModelTag, 49 Scope: coretesting.ModelTag, 50 Applications: s.applicationsWatcher, 51 Volumes: newMockVolumeAccessor(), 52 Filesystems: newMockFilesystemAccessor(), 53 Life: s.lifeGetter, 54 Status: &mockStatusSetter{}, 55 Clock: &mockClock{}, 56 Registry: storage.StaticProviderRegistry{}, 57 CloudCallContext: context.NewCloudCallContext(), 58 } 59 } 60 61 func (s *WorkerSuite) TestValidateConfig(c *gc.C) { 62 s.testValidateConfig(c, func(config *storageprovisioner.Config) { 63 config.Scope = names.NewApplicationTag("mariadb") 64 config.Applications = nil 65 }, `nil Applications not valid`) 66 } 67 68 func (s *WorkerSuite) testValidateConfig(c *gc.C, f func(*storageprovisioner.Config), expect string) { 69 config := s.config 70 f(&config) 71 w, err := storageprovisioner.NewCaasWorker(config) 72 if err == nil { 73 workertest.DirtyKill(c, w) 74 } 75 c.Check(err, gc.ErrorMatches, expect) 76 } 77 78 func (s *WorkerSuite) TestStartStop(c *gc.C) { 79 w, err := storageprovisioner.NewCaasWorker(s.config) 80 c.Assert(err, jc.ErrorIsNil) 81 workertest.CheckAlive(c, w) 82 workertest.CleanKill(c, w) 83 } 84 85 func (s *WorkerSuite) setupNewUnitScenario(c *gc.C) worker.Worker { 86 w, err := storageprovisioner.NewCaasWorker(s.config) 87 c.Assert(err, jc.ErrorIsNil) 88 89 select { 90 case s.applicationChanges <- []string{"mariadb"}: 91 case <-time.After(coretesting.LongWait): 92 c.Fatal("timed out sending applications change") 93 } 94 return w 95 } 96 97 func (s *WorkerSuite) TestWatchApplicationDead(c *gc.C) { 98 w, err := storageprovisioner.NewCaasWorker(s.config) 99 c.Assert(err, jc.ErrorIsNil) 100 defer workertest.CleanKill(c, w) 101 102 select { 103 case s.applicationChanges <- []string{"postgresql"}: 104 case <-time.After(coretesting.LongWait): 105 c.Fatal("timed out sending applications change") 106 } 107 108 // Given the worker time to startup. 109 shortAttempt := &utils.AttemptStrategy{ 110 Total: coretesting.LongWait, 111 Delay: 10 * time.Millisecond, 112 } 113 for a := shortAttempt.Start(); a.Next(); { 114 if len(s.config.Filesystems.(*mockFilesystemAccessor).Calls()) > 0 { 115 break 116 } 117 } 118 119 workertest.CleanKill(c, w) 120 // Only call is to watch model. 121 s.config.Filesystems.(*mockFilesystemAccessor).CheckCallNames(c, "WatchFilesystems") 122 s.config.Filesystems.(*mockFilesystemAccessor).CheckCall(c, 0, "WatchFilesystems", coretesting.ModelTag) 123 } 124 125 func (s *WorkerSuite) TestRemoveApplicationStopsWatchingApplication(c *gc.C) { 126 w, err := storageprovisioner.NewCaasWorker(s.config) 127 c.Assert(err, jc.ErrorIsNil) 128 defer workertest.CleanKill(c, w) 129 130 select { 131 case s.applicationChanges <- []string{"mariadb"}: 132 case <-time.After(coretesting.LongWait): 133 c.Fatal("timed out sending applications change") 134 } 135 136 // Check that the worker is running or not; 137 // given it time to startup. 138 shortAttempt := &utils.AttemptStrategy{ 139 Total: coretesting.LongWait, 140 Delay: 10 * time.Millisecond, 141 } 142 running := false 143 for a := shortAttempt.Start(); a.Next(); { 144 _, running = storageprovisioner.StorageWorker(w, "mariadb") 145 if running { 146 break 147 } 148 } 149 c.Assert(running, jc.IsTrue) 150 151 // Add an additional app worker so we can check that the correct one is accessed. 152 storageprovisioner.NewStorageWorker(w, "postgresql") 153 154 s.lifeGetter.err = ¶ms.Error{Code: params.CodeNotFound} 155 select { 156 case s.applicationChanges <- []string{"postgresql"}: 157 case <-time.After(coretesting.LongWait): 158 c.Fatal("timed out sending applications change") 159 } 160 161 // The mariadb worker should still be running. 162 _, ok := storageprovisioner.StorageWorker(w, "mariadb") 163 c.Assert(ok, jc.IsTrue) 164 165 // Check that the postgresql worker is running or not; 166 // given it time to shutdown. 167 running = true 168 for a := shortAttempt.Start(); a.Next(); { 169 _, running = storageprovisioner.StorageWorker(w, "postgresql") 170 if !running { 171 break 172 } 173 } 174 c.Assert(running, jc.IsFalse) 175 workertest.CleanKill(c, w) 176 workertest.CheckKilled(c, s.applicationsWatcher.watcher) 177 } 178 179 func (s *WorkerSuite) TestWatcherErrorStopsWorker(c *gc.C) { 180 w, err := storageprovisioner.NewCaasWorker(s.config) 181 c.Assert(err, jc.ErrorIsNil) 182 defer workertest.DirtyKill(c, w) 183 184 select { 185 case s.applicationChanges <- []string{"mariadb"}: 186 case <-time.After(coretesting.LongWait): 187 c.Fatal("timed out sending applications change") 188 } 189 190 s.applicationsWatcher.watcher.KillErr(errors.New("splat")) 191 workertest.CheckKilled(c, s.applicationsWatcher.watcher) 192 err = workertest.CheckKilled(c, w) 193 c.Assert(err, gc.ErrorMatches, "splat") 194 }