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