github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/featureflag/flag_test.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package featureflag_test 5 6 import ( 7 "sync" 8 "time" 9 10 "github.com/juju/testing" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 "gopkg.in/juju/worker.v1" 14 "gopkg.in/juju/worker.v1/workertest" 15 16 "github.com/juju/juju/cmd/jujud/agent/engine" 17 "github.com/juju/juju/controller" 18 "github.com/juju/juju/state" 19 "github.com/juju/juju/state/watcher/watchertest" 20 coretesting "github.com/juju/juju/testing" 21 "github.com/juju/juju/worker/featureflag" 22 ) 23 24 type WorkerSuite struct { 25 testing.IsolationSuite 26 config featureflag.Config 27 source *configSource 28 changes chan struct{} 29 worker worker.Worker 30 flag engine.Flag 31 } 32 33 var _ = gc.Suite(&WorkerSuite{}) 34 35 func (s *WorkerSuite) SetUpTest(c *gc.C) { 36 s.IsolationSuite.SetUpTest(c) 37 s.changes = make(chan struct{}) 38 s.source = &configSource{ 39 cfg: controller.Config{ 40 "features": []interface{}{"new-hotness"}, 41 }, 42 watcher: watchertest.NewNotifyWatcher(s.changes), 43 } 44 s.config = featureflag.Config{ 45 Source: s.source, 46 FlagName: "new-hotness", 47 } 48 worker, err := featureflag.NewWorker(s.config) 49 c.Assert(err, jc.ErrorIsNil) 50 s.AddCleanup(func(c *gc.C) { 51 workertest.DirtyKill(c, worker) 52 }) 53 s.worker = worker 54 s.flag = worker.(engine.Flag) 55 } 56 57 func (s *WorkerSuite) TestCleanKill(c *gc.C) { 58 workertest.CleanKill(c, s.worker) 59 } 60 61 func (s *WorkerSuite) TestCheckFeatureFlag(c *gc.C) { 62 c.Assert(s.flag.Check(), jc.IsTrue) 63 } 64 65 func (s *WorkerSuite) TestCheckInverted(c *gc.C) { 66 s.config.Invert = true 67 w, err := featureflag.NewWorker(s.config) 68 c.Assert(err, jc.ErrorIsNil) 69 s.AddCleanup(func(c *gc.C) { 70 workertest.DirtyKill(c, w) 71 }) 72 73 c.Assert(w.(engine.Flag).Check(), jc.IsFalse) 74 } 75 76 func (s *WorkerSuite) TestFlagOff(c *gc.C) { 77 s.source.setConfig(controller.Config{"features": []interface{}{}}) 78 w, err := featureflag.NewWorker(s.config) 79 c.Assert(err, jc.ErrorIsNil) 80 s.AddCleanup(func(c *gc.C) { 81 workertest.DirtyKill(c, w) 82 }) 83 84 c.Assert(w.(engine.Flag).Check(), jc.IsFalse) 85 } 86 87 func (s *WorkerSuite) TestDiesWhenFlagChanges(c *gc.C) { 88 s.source.setConfig(controller.Config{"features": []interface{}{}}) 89 select { 90 case s.changes <- struct{}{}: 91 case <-time.After(coretesting.LongWait): 92 c.Fatalf("timed out sending config change") 93 } 94 95 c.Assert(workertest.CheckKilled(c, s.worker), gc.Equals, featureflag.ErrRefresh) 96 } 97 98 func (s *WorkerSuite) TestNoDieWhenNoChange(c *gc.C) { 99 select { 100 case s.changes <- struct{}{}: 101 case <-time.After(coretesting.LongWait): 102 c.Fatalf("timed out sending config change") 103 } 104 time.Sleep(coretesting.ShortWait) 105 workertest.CheckAlive(c, s.worker) 106 } 107 108 type configSource struct { 109 mu sync.Mutex 110 stub testing.Stub 111 watcher *watchertest.NotifyWatcher 112 cfg controller.Config 113 } 114 115 func (s *configSource) WatchControllerConfig() state.NotifyWatcher { 116 s.stub.AddCall("WatchControllerConfig") 117 return s.watcher 118 } 119 120 func (s *configSource) ControllerConfig() (controller.Config, error) { 121 s.mu.Lock() 122 defer s.mu.Unlock() 123 s.stub.AddCall("ControllerConfig") 124 if err := s.stub.NextErr(); err != nil { 125 return nil, err 126 } 127 return s.cfg, nil 128 } 129 130 func (s *configSource) setConfig(cfg controller.Config) { 131 s.mu.Lock() 132 defer s.mu.Unlock() 133 s.cfg = cfg 134 }