github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/api/controller/instancepoller/instancepoller_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package instancepoller_test 5 6 import ( 7 "errors" 8 9 "github.com/juju/names/v5" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/api/base" 14 apitesting "github.com/juju/juju/api/base/testing" 15 "github.com/juju/juju/api/controller/instancepoller" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/core/life" 18 "github.com/juju/juju/core/watcher" 19 "github.com/juju/juju/rpc/params" 20 coretesting "github.com/juju/juju/testing" 21 ) 22 23 type InstancePollerSuite struct { 24 coretesting.BaseSuite 25 } 26 27 var _ = gc.Suite(&InstancePollerSuite{}) 28 29 func (s *InstancePollerSuite) TestNewAPI(c *gc.C) { 30 apiCaller := clientErrorAPICaller(c, "Life", nil) 31 api := instancepoller.NewAPI(apiCaller) 32 c.Check(api, gc.NotNil) 33 c.Check(apiCaller.CallCount, gc.Equals, 0) 34 35 // Nothing happens until we actually call something else. 36 m, err := api.Machine(names.MachineTag{}) 37 c.Assert(err, gc.ErrorMatches, "client error!") 38 c.Assert(m, gc.IsNil) 39 c.Check(apiCaller.CallCount, gc.Equals, 1) 40 } 41 42 func (s *InstancePollerSuite) TestNewAPIWithNilCaller(c *gc.C) { 43 panicFunc := func() { instancepoller.NewAPI(nil) } 44 c.Assert(panicFunc, gc.PanicMatches, "caller is nil") 45 } 46 47 func (s *InstancePollerSuite) TestMachineCallsLife(c *gc.C) { 48 // We have tested separately the Life method, here we just check 49 // it's called internally. 50 expectedResults := params.LifeResults{ 51 Results: []params.LifeResult{{Life: "working"}}, 52 } 53 apiCaller := successAPICaller(c, "Life", entitiesArgs, expectedResults) 54 api := instancepoller.NewAPI(apiCaller) 55 m, err := api.Machine(names.NewMachineTag("42")) 56 c.Assert(err, jc.ErrorIsNil) 57 c.Assert(apiCaller.CallCount, gc.Equals, 1) 58 c.Assert(m.Life(), gc.Equals, life.Value("working")) 59 c.Assert(m.Id(), gc.Equals, "42") 60 } 61 62 func (s *InstancePollerSuite) TestWatchModelMachineStartTimesSuccess(c *gc.C) { 63 // We're not testing the watcher logic here as it's already tested elsewhere. 64 var numWatcherCalls int 65 expectResult := params.StringsWatchResult{ 66 StringsWatcherId: "42", 67 Changes: []string{"foo", "bar"}, 68 } 69 watcherFunc := func(caller base.APICaller, result params.StringsWatchResult) watcher.StringsWatcher { 70 numWatcherCalls++ 71 c.Check(caller, gc.NotNil) 72 c.Check(result, jc.DeepEquals, expectResult) 73 return nil 74 } 75 s.PatchValue(instancepoller.NewStringsWatcher, watcherFunc) 76 77 apiCaller := successAPICaller(c, "WatchModelMachineStartTimes", nil, expectResult) 78 79 api := instancepoller.NewAPI(apiCaller) 80 w, err := api.WatchModelMachines() 81 c.Assert(err, jc.ErrorIsNil) 82 c.Assert(apiCaller.CallCount, gc.Equals, 1) 83 c.Assert(numWatcherCalls, gc.Equals, 1) 84 c.Assert(w, gc.IsNil) 85 } 86 87 func (s *InstancePollerSuite) TestWatchModelMachineStartTimesClientError(c *gc.C) { 88 apiCaller := clientErrorAPICaller(c, "WatchModelMachineStartTimes", nil) 89 api := instancepoller.NewAPI(apiCaller) 90 w, err := api.WatchModelMachines() 91 c.Assert(err, gc.ErrorMatches, "client error!") 92 c.Assert(w, gc.IsNil) 93 c.Assert(apiCaller.CallCount, gc.Equals, 1) 94 } 95 96 func (s *InstancePollerSuite) TestWatchModelMachineStartTimesServerError(c *gc.C) { 97 expectedResults := params.StringsWatchResult{ 98 Error: apiservertesting.ServerError("server boom!"), 99 } 100 apiCaller := successAPICaller(c, "WatchModelMachineStartTimes", nil, expectedResults) 101 102 api := instancepoller.NewAPI(apiCaller) 103 w, err := api.WatchModelMachines() 104 c.Assert(err, gc.ErrorMatches, "server boom!") 105 c.Assert(apiCaller.CallCount, gc.Equals, 1) 106 c.Assert(w, gc.IsNil) 107 } 108 109 func (s *InstancePollerSuite) TestWatchForModelConfigChangesClientError(c *gc.C) { 110 // We're not testing the success case as we're not patching the 111 // NewNotifyWatcher call the embedded ModelWatcher is calling. 112 apiCaller := clientErrorAPICaller(c, "WatchForModelConfigChanges", nil) 113 114 api := instancepoller.NewAPI(apiCaller) 115 w, err := api.WatchForModelConfigChanges() 116 c.Assert(err, gc.ErrorMatches, "client error!") 117 c.Assert(apiCaller.CallCount, gc.Equals, 1) 118 c.Assert(w, gc.IsNil) 119 } 120 121 func (s *InstancePollerSuite) TestModelConfigSuccess(c *gc.C) { 122 expectedConfig := coretesting.ModelConfig(c) 123 expectedResults := params.ModelConfigResult{ 124 Config: params.ModelConfig(expectedConfig.AllAttrs()), 125 } 126 apiCaller := successAPICaller(c, "ModelConfig", nil, expectedResults) 127 128 api := instancepoller.NewAPI(apiCaller) 129 cfg, err := api.ModelConfig() 130 c.Assert(err, jc.ErrorIsNil) 131 c.Assert(apiCaller.CallCount, gc.Equals, 1) 132 c.Assert(cfg, jc.DeepEquals, expectedConfig) 133 } 134 135 func (s *InstancePollerSuite) TestModelConfigClientError(c *gc.C) { 136 apiCaller := clientErrorAPICaller(c, "ModelConfig", nil) 137 api := instancepoller.NewAPI(apiCaller) 138 cfg, err := api.ModelConfig() 139 c.Assert(err, gc.ErrorMatches, "client error!") 140 c.Assert(cfg, gc.IsNil) 141 c.Assert(apiCaller.CallCount, gc.Equals, 1) 142 } 143 144 func (s *InstancePollerSuite) TestModelConfigServerError(c *gc.C) { 145 expectResults := params.ModelConfigResult{ 146 Config: params.ModelConfig{"type": "foo"}, 147 } 148 apiCaller := successAPICaller(c, "ModelConfig", nil, expectResults) 149 150 api := instancepoller.NewAPI(apiCaller) 151 cfg, err := api.ModelConfig() 152 c.Assert(err, gc.NotNil) // the actual error doesn't matter 153 c.Assert(apiCaller.CallCount, gc.Equals, 1) 154 c.Assert(cfg, gc.IsNil) 155 } 156 157 func clientErrorAPICaller(c *gc.C, method string, expectArgs interface{}) *apitesting.CallChecker { 158 return apitesting.APICallChecker(c, apitesting.APICall{ 159 Facade: "InstancePoller", 160 VersionIsZero: true, 161 IdIsEmpty: true, 162 Method: method, 163 Args: expectArgs, 164 Error: errors.New("client error!"), 165 }) 166 } 167 168 func successAPICaller(c *gc.C, method string, expectArgs, useResults interface{}) *apitesting.CallChecker { 169 return apitesting.APICallChecker(c, apitesting.APICall{ 170 Facade: "InstancePoller", 171 VersionIsZero: true, 172 IdIsEmpty: true, 173 Method: method, 174 Args: expectArgs, 175 Results: useResults, 176 }) 177 }