github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/core/cache/controller_test.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 package cache_test 4 5 import ( 6 "time" 7 8 "github.com/juju/errors" 9 "github.com/juju/testing" 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/core/cache" 15 "github.com/juju/juju/core/life" 16 ) 17 18 type ControllerSuite struct { 19 baseSuite 20 21 changes chan interface{} 22 config cache.ControllerConfig 23 } 24 25 var _ = gc.Suite(&ControllerSuite{}) 26 27 func (s *ControllerSuite) SetUpTest(c *gc.C) { 28 s.baseSuite.SetUpTest(c) 29 s.changes = make(chan interface{}) 30 s.config = cache.ControllerConfig{ 31 Changes: s.changes, 32 } 33 } 34 35 func (s *ControllerSuite) TestConfigValid(c *gc.C) { 36 err := s.config.Validate() 37 c.Assert(err, jc.ErrorIsNil) 38 } 39 40 func (s *ControllerSuite) TestConfigMissingChanges(c *gc.C) { 41 s.config.Changes = nil 42 err := s.config.Validate() 43 c.Check(err, gc.ErrorMatches, "nil Changes not valid") 44 c.Check(err, jc.Satisfies, errors.IsNotValid) 45 } 46 47 func (s *ControllerSuite) TestController(c *gc.C) { 48 controller, err := cache.NewController(s.config) 49 c.Assert(err, jc.ErrorIsNil) 50 51 c.Check(controller.ModelUUIDs(), gc.HasLen, 0) 52 c.Check(controller.Report(), gc.HasLen, 0) 53 54 workertest.CleanKill(c, controller) 55 } 56 57 func (s *ControllerSuite) TestAddModel(c *gc.C) { 58 controller, events := s.new(c) 59 s.processChange(c, modelChange, events) 60 61 c.Check(controller.ModelUUIDs(), jc.SameContents, []string{"model-uuid"}) 62 c.Check(controller.Report(), gc.DeepEquals, map[string]interface{}{ 63 "model-uuid": map[string]interface{}{ 64 "name": "model-owner/test-model", 65 "life": life.Value("alive"), 66 "application-count": 0, 67 }}) 68 } 69 70 func (s *ControllerSuite) TestRemoveModel(c *gc.C) { 71 controller, events := s.new(c) 72 s.processChange(c, modelChange, events) 73 74 remove := cache.RemoveModel{ModelUUID: "model-uuid"} 75 s.processChange(c, remove, events) 76 77 c.Check(controller.ModelUUIDs(), gc.HasLen, 0) 78 c.Check(controller.Report(), gc.HasLen, 0) 79 } 80 81 func (s *ControllerSuite) TestAddApplication(c *gc.C) { 82 controller, events := s.new(c) 83 s.processChange(c, modelChange, events) 84 s.processChange(c, appChange, events) 85 86 mod, err := controller.Model("model-uuid") 87 c.Assert(err, jc.ErrorIsNil) 88 c.Check(mod.Report()["application-count"], gc.Equals, 1) 89 90 app, err := mod.Application("application-name") 91 c.Assert(err, jc.ErrorIsNil) 92 c.Check(app, gc.NotNil) 93 } 94 95 func (s *ControllerSuite) TestRemoveApplication(c *gc.C) { 96 controller, events := s.new(c) 97 s.processChange(c, modelChange, events) 98 s.processChange(c, appChange, events) 99 100 remove := cache.RemoveApplication{ 101 ModelUUID: "model-uuid", 102 Name: "application-name", 103 } 104 s.processChange(c, remove, events) 105 106 mod, err := controller.Model("model-uuid") 107 c.Assert(err, jc.ErrorIsNil) 108 c.Check(mod.Report()["application-count"], gc.Equals, 0) 109 } 110 111 func (s *ControllerSuite) new(c *gc.C) (*cache.Controller, <-chan interface{}) { 112 events := s.captureEvents(c) 113 controller, err := cache.NewController(s.config) 114 c.Assert(err, jc.ErrorIsNil) 115 s.AddCleanup(func(c *gc.C) { workertest.CleanKill(c, controller) }) 116 return controller, events 117 } 118 119 func (s *ControllerSuite) captureEvents(c *gc.C) <-chan interface{} { 120 events := make(chan interface{}) 121 s.config.Notify = func(change interface{}) { 122 send := false 123 switch change.(type) { 124 case cache.ModelChange: 125 send = true 126 case cache.RemoveModel: 127 send = true 128 case cache.ApplicationChange: 129 send = true 130 case cache.RemoveApplication: 131 send = true 132 default: 133 // no-op 134 } 135 if send { 136 c.Logf("sending %#v", change) 137 select { 138 case events <- change: 139 case <-time.After(testing.LongWait): 140 c.Fatalf("change not processed by test") 141 } 142 } 143 } 144 return events 145 } 146 147 func (s *ControllerSuite) processChange(c *gc.C, change interface{}, notify <-chan interface{}) { 148 select { 149 case s.changes <- change: 150 case <-time.After(testing.LongWait): 151 c.Fatalf("controller did not read change") 152 } 153 select { 154 case obtained := <-notify: 155 c.Check(obtained, jc.DeepEquals, change) 156 case <-time.After(testing.LongWait): 157 c.Fatalf("controller did not handle change") 158 } 159 } 160 161 func (s *ControllerSuite) nextChange(c *gc.C, changes <-chan interface{}) interface{} { 162 var obtained interface{} 163 select { 164 case obtained = <-changes: 165 case <-time.After(testing.LongWait): 166 c.Fatalf("no change") 167 } 168 return obtained 169 }