github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/environ/environ_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environ_test 5 6 import ( 7 "time" 8 9 "github.com/juju/errors" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/juju/worker.v1/workertest" 13 14 "github.com/juju/juju/environs" 15 coretesting "github.com/juju/juju/testing" 16 "github.com/juju/juju/worker/environ" 17 ) 18 19 type TrackerSuite struct { 20 coretesting.BaseSuite 21 } 22 23 var _ = gc.Suite(&TrackerSuite{}) 24 25 func (s *TrackerSuite) TestValidateObserver(c *gc.C) { 26 config := environ.Config{} 27 s.testValidate(c, config, func(err error) { 28 c.Check(err, jc.Satisfies, errors.IsNotValid) 29 c.Check(err, gc.ErrorMatches, "nil Observer not valid") 30 }) 31 } 32 33 func (s *TrackerSuite) TestValidateNewEnvironFunc(c *gc.C) { 34 config := environ.Config{ 35 Observer: &runContext{}, 36 } 37 s.testValidate(c, config, func(err error) { 38 c.Check(err, jc.Satisfies, errors.IsNotValid) 39 c.Check(err, gc.ErrorMatches, "nil NewEnvironFunc not valid") 40 }) 41 } 42 43 func (s *TrackerSuite) testValidate(c *gc.C, config environ.Config, check func(err error)) { 44 err := config.Validate() 45 check(err) 46 47 tracker, err := environ.NewTracker(config) 48 c.Check(tracker, gc.IsNil) 49 check(err) 50 } 51 52 func (s *TrackerSuite) TestModelConfigFails(c *gc.C) { 53 fix := &fixture{ 54 observerErrs: []error{ 55 errors.New("no you"), 56 }, 57 } 58 fix.Run(c, func(context *runContext) { 59 tracker, err := environ.NewTracker(environ.Config{ 60 Observer: context, 61 NewEnvironFunc: newMockEnviron, 62 }) 63 c.Check(err, gc.ErrorMatches, "cannot create environ: no you") 64 c.Check(tracker, gc.IsNil) 65 context.CheckCallNames(c, "ModelConfig") 66 }) 67 } 68 69 func (s *TrackerSuite) TestModelConfigInvalid(c *gc.C) { 70 fix := &fixture{} 71 fix.Run(c, func(context *runContext) { 72 tracker, err := environ.NewTracker(environ.Config{ 73 Observer: context, 74 NewEnvironFunc: func(environs.OpenParams) (environs.Environ, error) { 75 return nil, errors.NotValidf("config") 76 }, 77 }) 78 c.Check(err, gc.ErrorMatches, `cannot create environ: config not valid`) 79 c.Check(tracker, gc.IsNil) 80 context.CheckCallNames(c, "ModelConfig", "CloudSpec") 81 }) 82 } 83 84 func (s *TrackerSuite) TestModelConfigValid(c *gc.C) { 85 fix := &fixture{ 86 initialConfig: coretesting.Attrs{ 87 "name": "this-particular-name", 88 }, 89 } 90 fix.Run(c, func(context *runContext) { 91 tracker, err := environ.NewTracker(environ.Config{ 92 Observer: context, 93 NewEnvironFunc: newMockEnviron, 94 }) 95 c.Assert(err, jc.ErrorIsNil) 96 defer workertest.CleanKill(c, tracker) 97 98 gotEnviron := tracker.Environ() 99 c.Assert(gotEnviron, gc.NotNil) 100 c.Check(gotEnviron.Config().Name(), gc.Equals, "this-particular-name") 101 }) 102 } 103 104 func (s *TrackerSuite) TestCloudSpec(c *gc.C) { 105 cloudSpec := environs.CloudSpec{ 106 Name: "foo", 107 Type: "bar", 108 Region: "baz", 109 } 110 fix := &fixture{cloud: cloudSpec} 111 fix.Run(c, func(context *runContext) { 112 tracker, err := environ.NewTracker(environ.Config{ 113 Observer: context, 114 NewEnvironFunc: func(args environs.OpenParams) (environs.Environ, error) { 115 c.Assert(args.Cloud, jc.DeepEquals, cloudSpec) 116 return nil, errors.NotValidf("cloud spec") 117 }, 118 }) 119 c.Check(err, gc.ErrorMatches, `cannot create environ: cloud spec not valid`) 120 c.Check(tracker, gc.IsNil) 121 context.CheckCallNames(c, "ModelConfig", "CloudSpec") 122 }) 123 } 124 125 func (s *TrackerSuite) TestWatchFails(c *gc.C) { 126 fix := &fixture{ 127 observerErrs: []error{ 128 nil, nil, errors.New("grrk splat"), 129 }, 130 } 131 fix.Run(c, func(context *runContext) { 132 tracker, err := environ.NewTracker(environ.Config{ 133 Observer: context, 134 NewEnvironFunc: newMockEnviron, 135 }) 136 c.Assert(err, jc.ErrorIsNil) 137 defer workertest.DirtyKill(c, tracker) 138 139 err = workertest.CheckKilled(c, tracker) 140 c.Check(err, gc.ErrorMatches, "cannot watch environ config: grrk splat") 141 context.CheckCallNames(c, "ModelConfig", "CloudSpec", "WatchForModelConfigChanges") 142 }) 143 } 144 145 func (s *TrackerSuite) TestWatchCloses(c *gc.C) { 146 fix := &fixture{} 147 fix.Run(c, func(context *runContext) { 148 tracker, err := environ.NewTracker(environ.Config{ 149 Observer: context, 150 NewEnvironFunc: newMockEnviron, 151 }) 152 c.Assert(err, jc.ErrorIsNil) 153 defer workertest.DirtyKill(c, tracker) 154 155 context.CloseModelConfigNotify() 156 err = workertest.CheckKilled(c, tracker) 157 c.Check(err, gc.ErrorMatches, "environ config watch closed") 158 context.CheckCallNames(c, "ModelConfig", "CloudSpec", "WatchForModelConfigChanges") 159 }) 160 } 161 162 func (s *TrackerSuite) TestWatchedModelConfigFails(c *gc.C) { 163 fix := &fixture{ 164 observerErrs: []error{ 165 nil, nil, nil, errors.New("blam ouch"), 166 }, 167 } 168 fix.Run(c, func(context *runContext) { 169 tracker, err := environ.NewTracker(environ.Config{ 170 Observer: context, 171 NewEnvironFunc: newMockEnviron, 172 }) 173 c.Check(err, jc.ErrorIsNil) 174 defer workertest.DirtyKill(c, tracker) 175 176 context.SendModelConfigNotify() 177 err = workertest.CheckKilled(c, tracker) 178 c.Check(err, gc.ErrorMatches, "cannot read environ config: blam ouch") 179 context.CheckCallNames(c, "ModelConfig", "CloudSpec", "WatchForModelConfigChanges", "ModelConfig") 180 }) 181 } 182 183 func (s *TrackerSuite) TestWatchedModelConfigIncompatible(c *gc.C) { 184 fix := &fixture{} 185 fix.Run(c, func(context *runContext) { 186 tracker, err := environ.NewTracker(environ.Config{ 187 Observer: context, 188 NewEnvironFunc: func(environs.OpenParams) (environs.Environ, error) { 189 env := &mockEnviron{} 190 env.SetErrors(errors.New("SetConfig is broken")) 191 return env, nil 192 }, 193 }) 194 c.Check(err, jc.ErrorIsNil) 195 defer workertest.DirtyKill(c, tracker) 196 197 context.SendModelConfigNotify() 198 err = workertest.CheckKilled(c, tracker) 199 c.Check(err, gc.ErrorMatches, "cannot update environ config: SetConfig is broken") 200 context.CheckCallNames(c, "ModelConfig", "CloudSpec", "WatchForModelConfigChanges", "ModelConfig") 201 }) 202 } 203 204 func (s *TrackerSuite) TestWatchedModelConfigUpdates(c *gc.C) { 205 fix := &fixture{ 206 initialConfig: coretesting.Attrs{ 207 "name": "original-name", 208 }, 209 } 210 fix.Run(c, func(context *runContext) { 211 tracker, err := environ.NewTracker(environ.Config{ 212 Observer: context, 213 NewEnvironFunc: newMockEnviron, 214 }) 215 c.Check(err, jc.ErrorIsNil) 216 defer workertest.CleanKill(c, tracker) 217 218 context.SetConfig(c, coretesting.Attrs{ 219 "name": "updated-name", 220 }) 221 gotEnviron := tracker.Environ() 222 c.Assert(gotEnviron.Config().Name(), gc.Equals, "original-name") 223 224 timeout := time.After(coretesting.LongWait) 225 attempt := time.After(0) 226 context.SendModelConfigNotify() 227 for { 228 select { 229 case <-attempt: 230 name := gotEnviron.Config().Name() 231 if name == "original-name" { 232 attempt = time.After(coretesting.ShortWait) 233 continue 234 } 235 c.Check(name, gc.Equals, "updated-name") 236 case <-timeout: 237 c.Fatalf("timed out waiting for environ to be updated") 238 } 239 break 240 } 241 context.CheckCallNames(c, "ModelConfig", "CloudSpec", "WatchForModelConfigChanges", "ModelConfig") 242 }) 243 }