github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/environ/fixture_test.go (about) 1 // Copyright 2012-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package environ_test 5 6 import ( 7 "sync" 8 9 "github.com/juju/testing" 10 gc "gopkg.in/check.v1" 11 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/environs/config" 14 coretesting "github.com/juju/juju/testing" 15 "github.com/juju/juju/watcher" 16 "github.com/juju/juju/worker" 17 "github.com/juju/juju/worker/workertest" 18 ) 19 20 type fixture struct { 21 watcherErr error 22 observerErrs []error 23 initialConfig map[string]interface{} 24 } 25 26 func (fix *fixture) Run(c *gc.C, test func(*runContext)) { 27 watcher := newNotifyWatcher(fix.watcherErr) 28 defer workertest.DirtyKill(c, watcher) 29 context := &runContext{ 30 config: newModelConfig(c, fix.initialConfig), 31 watcher: watcher, 32 } 33 context.stub.SetErrors(fix.observerErrs...) 34 test(context) 35 } 36 37 type runContext struct { 38 mu sync.Mutex 39 stub testing.Stub 40 config map[string]interface{} 41 watcher *notifyWatcher 42 } 43 44 // SetConfig updates the configuration returned by ModelConfig. 45 func (context *runContext) SetConfig(c *gc.C, extraAttrs coretesting.Attrs) { 46 context.mu.Lock() 47 defer context.mu.Unlock() 48 context.config = newModelConfig(c, extraAttrs) 49 } 50 51 // ModelConfig is part of the environ.ConfigObserver interface. 52 func (context *runContext) ModelConfig() (*config.Config, error) { 53 context.mu.Lock() 54 defer context.mu.Unlock() 55 context.stub.AddCall("ModelConfig") 56 if err := context.stub.NextErr(); err != nil { 57 return nil, err 58 } 59 return config.New(config.NoDefaults, context.config) 60 } 61 62 // KillNotify kills the watcher returned from WatchForModelConfigChanges with 63 // the error configured in the enclosing fixture. 64 func (context *runContext) KillNotify() { 65 context.watcher.Kill() 66 } 67 68 // SendNotify sends a value on the channel used by WatchForModelConfigChanges 69 // results. 70 func (context *runContext) SendNotify() { 71 context.watcher.changes <- struct{}{} 72 } 73 74 // CloseNotify closes the channel used by WatchForModelConfigChanges results. 75 func (context *runContext) CloseNotify() { 76 close(context.watcher.changes) 77 } 78 79 // WatchForModelConfigChanges is part of the environ.ConfigObserver interface. 80 func (context *runContext) WatchForModelConfigChanges() (watcher.NotifyWatcher, error) { 81 context.mu.Lock() 82 defer context.mu.Unlock() 83 context.stub.AddCall("WatchForModelConfigChanges") 84 if err := context.stub.NextErr(); err != nil { 85 return nil, err 86 } 87 return context.watcher, nil 88 } 89 90 func (context *runContext) CheckCallNames(c *gc.C, names ...string) { 91 context.mu.Lock() 92 defer context.mu.Unlock() 93 context.stub.CheckCallNames(c, names...) 94 } 95 96 // newNotifyWatcher returns a watcher.NotifyWatcher that will fail with the 97 // supplied error when Kill()ed. 98 func newNotifyWatcher(err error) *notifyWatcher { 99 return ¬ifyWatcher{ 100 Worker: workertest.NewErrorWorker(err), 101 changes: make(chan struct{}, 1000), 102 } 103 } 104 105 type notifyWatcher struct { 106 worker.Worker 107 changes chan struct{} 108 } 109 110 // Changes is part of the watcher.NotifyWatcher interface. 111 func (w *notifyWatcher) Changes() watcher.NotifyChannel { 112 return w.changes 113 } 114 115 // newModelConfig returns an environment config map with the supplied attrs 116 // (on top of some default set), or fails the test. 117 func newModelConfig(c *gc.C, extraAttrs coretesting.Attrs) map[string]interface{} { 118 return coretesting.CustomModelConfig(c, extraAttrs).AllAttrs() 119 } 120 121 type mockEnviron struct { 122 environs.Environ 123 testing.Stub 124 cfg *config.Config 125 mu sync.Mutex 126 } 127 128 func (e *mockEnviron) Config() *config.Config { 129 e.mu.Lock() 130 defer e.mu.Unlock() 131 e.MethodCall(e, "Config") 132 e.PopNoErr() 133 return e.cfg 134 } 135 136 func (e *mockEnviron) SetConfig(cfg *config.Config) error { 137 e.mu.Lock() 138 defer e.mu.Unlock() 139 e.MethodCall(e, "SetConfig", cfg) 140 if err := e.NextErr(); err != nil { 141 return err 142 } 143 e.cfg = cfg 144 return nil 145 } 146 147 func newMockEnviron(cfg *config.Config) (environs.Environ, error) { 148 return &mockEnviron{cfg: cfg}, nil 149 }