github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/common/lifeflag/facade_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package lifeflag_test 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 "github.com/juju/worker/v3/workertest" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/api/base" 15 apitesting "github.com/juju/juju/api/base/testing" 16 "github.com/juju/juju/api/common/lifeflag" 17 "github.com/juju/juju/core/life" 18 "github.com/juju/juju/rpc/params" 19 "github.com/juju/juju/worker" 20 ) 21 22 type FacadeSuite struct { 23 testing.IsolationSuite 24 } 25 26 var _ = gc.Suite(&FacadeSuite{}) 27 28 func (*FacadeSuite) TestLifeCall(c *gc.C) { 29 var called bool 30 caller := apiCaller(c, func(request string, args, _ interface{}) error { 31 called = true 32 c.Check(request, gc.Equals, "Life") 33 c.Check(args, jc.DeepEquals, params.Entities{ 34 Entities: []params.Entity{{Tag: "application-blah"}}, 35 }) 36 return nil 37 }) 38 facade := lifeflag.NewClient(caller, "LifeFlag") 39 40 facade.Life(names.NewApplicationTag("blah")) 41 c.Check(called, jc.IsTrue) 42 } 43 44 func (*FacadeSuite) TestLifeCallError(c *gc.C) { 45 caller := apiCaller(c, func(_ string, _, _ interface{}) error { 46 return errors.New("crunch belch") 47 }) 48 facade := lifeflag.NewClient(caller, "LifeFlag") 49 50 result, err := facade.Life(names.NewApplicationTag("blah")) 51 c.Check(err, gc.ErrorMatches, "crunch belch") 52 c.Check(result, gc.Equals, life.Value("")) 53 } 54 55 func (*FacadeSuite) TestLifeNoResultsError(c *gc.C) { 56 caller := apiCaller(c, func(_ string, _, _ interface{}) error { 57 return nil 58 }) 59 facade := lifeflag.NewClient(caller, "LifeFlag") 60 61 result, err := facade.Life(names.NewApplicationTag("blah")) 62 c.Check(err, gc.ErrorMatches, "expected 1 Life result, got 0") 63 c.Check(result, gc.Equals, life.Value("")) 64 } 65 66 func (*FacadeSuite) TestLifeExtraResultsError(c *gc.C) { 67 caller := apiCaller(c, func(_ string, _, results interface{}) error { 68 typed, ok := results.(*params.LifeResults) 69 c.Assert(ok, jc.IsTrue) 70 *typed = params.LifeResults{ 71 Results: make([]params.LifeResult, 2), 72 } 73 return nil 74 }) 75 facade := lifeflag.NewClient(caller, "LifeFlag") 76 77 result, err := facade.Life(names.NewApplicationTag("blah")) 78 c.Check(err, gc.ErrorMatches, "expected 1 Life result, got 2") 79 c.Check(result, gc.Equals, life.Value("")) 80 } 81 82 func (*FacadeSuite) TestLifeNotFoundError(c *gc.C) { 83 caller := apiCaller(c, func(_ string, _, results interface{}) error { 84 typed, ok := results.(*params.LifeResults) 85 c.Assert(ok, jc.IsTrue) 86 *typed = params.LifeResults{ 87 Results: []params.LifeResult{{ 88 Error: ¶ms.Error{Code: params.CodeNotFound}, 89 }}, 90 } 91 return nil 92 }) 93 facade := lifeflag.NewClient(caller, "LifeFlag") 94 95 result, err := facade.Life(names.NewApplicationTag("blah")) 96 c.Check(err, gc.Equals, lifeflag.ErrEntityNotFound) 97 c.Check(result, gc.Equals, life.Value("")) 98 } 99 100 func (*FacadeSuite) TestLifeInvalidResultError(c *gc.C) { 101 caller := apiCaller(c, func(_ string, _, results interface{}) error { 102 typed, ok := results.(*params.LifeResults) 103 c.Assert(ok, jc.IsTrue) 104 *typed = params.LifeResults{ 105 Results: []params.LifeResult{{Life: "decomposed"}}, 106 } 107 return nil 108 }) 109 facade := lifeflag.NewClient(caller, "LifeFlag") 110 111 result, err := facade.Life(names.NewApplicationTag("blah")) 112 c.Check(err, gc.ErrorMatches, `life value "decomposed" not valid`) 113 c.Check(result, gc.Equals, life.Value("")) 114 } 115 116 func (*FacadeSuite) TestLifeSuccess(c *gc.C) { 117 caller := apiCaller(c, func(_ string, _, results interface{}) error { 118 typed, ok := results.(*params.LifeResults) 119 c.Assert(ok, jc.IsTrue) 120 *typed = params.LifeResults{ 121 Results: []params.LifeResult{{Life: "dying"}}, 122 } 123 return nil 124 }) 125 facade := lifeflag.NewClient(caller, "LifeFlag") 126 127 result, err := facade.Life(names.NewApplicationTag("blah")) 128 c.Check(err, jc.ErrorIsNil) 129 c.Check(result, gc.Equals, life.Dying) 130 } 131 132 func (*FacadeSuite) TestWatchCall(c *gc.C) { 133 var called bool 134 caller := apiCaller(c, func(request string, args, _ interface{}) error { 135 called = true 136 c.Check(request, gc.Equals, "Watch") 137 c.Check(args, jc.DeepEquals, params.Entities{ 138 Entities: []params.Entity{{Tag: "application-blah"}}, 139 }) 140 return nil 141 }) 142 facade := lifeflag.NewClient(caller, "LifeFlag") 143 144 facade.Watch(names.NewApplicationTag("blah")) 145 c.Check(called, jc.IsTrue) 146 } 147 148 func (*FacadeSuite) TestWatchCallError(c *gc.C) { 149 caller := apiCaller(c, func(_ string, _, _ interface{}) error { 150 return errors.New("crunch belch") 151 }) 152 facade := lifeflag.NewClient(caller, "LifeFlag") 153 154 watcher, err := facade.Watch(names.NewApplicationTag("blah")) 155 c.Check(err, gc.ErrorMatches, "crunch belch") 156 c.Check(watcher, gc.IsNil) 157 } 158 159 func (*FacadeSuite) TestWatchNoResultsError(c *gc.C) { 160 caller := apiCaller(c, func(_ string, _, _ interface{}) error { 161 return nil 162 }) 163 facade := lifeflag.NewClient(caller, "LifeFlag") 164 165 watcher, err := facade.Watch(names.NewApplicationTag("blah")) 166 c.Check(err, gc.ErrorMatches, "expected 1 Watch result, got 0") 167 c.Check(watcher, gc.IsNil) 168 } 169 170 func (*FacadeSuite) TestWatchExtraResultsError(c *gc.C) { 171 caller := apiCaller(c, func(_ string, _, results interface{}) error { 172 typed, ok := results.(*params.NotifyWatchResults) 173 c.Assert(ok, jc.IsTrue) 174 *typed = params.NotifyWatchResults{ 175 Results: make([]params.NotifyWatchResult, 2), 176 } 177 return nil 178 }) 179 facade := lifeflag.NewClient(caller, "LifeFlag") 180 181 watcher, err := facade.Watch(names.NewApplicationTag("blah")) 182 c.Check(err, gc.ErrorMatches, "expected 1 Watch result, got 2") 183 c.Check(watcher, gc.IsNil) 184 } 185 186 func (*FacadeSuite) TestWatchNotFoundError(c *gc.C) { 187 caller := apiCaller(c, func(_ string, _, results interface{}) error { 188 typed, ok := results.(*params.NotifyWatchResults) 189 c.Assert(ok, jc.IsTrue) 190 *typed = params.NotifyWatchResults{ 191 Results: []params.NotifyWatchResult{{ 192 Error: ¶ms.Error{Code: params.CodeNotFound}, 193 }}, 194 } 195 return nil 196 }) 197 facade := lifeflag.NewClient(caller, "LifeFlag") 198 199 watcher, err := facade.Watch(names.NewApplicationTag("blah")) 200 c.Check(err, gc.Equals, lifeflag.ErrEntityNotFound) 201 c.Check(watcher, gc.IsNil) 202 } 203 204 func (*FacadeSuite) TestWatchSuccess(c *gc.C) { 205 caller := apitesting.APICallerFunc(func(facade string, version int, id, request string, arg, result interface{}) error { 206 switch facade { 207 case "LifeFlag": 208 c.Check(request, gc.Equals, "Watch") 209 c.Check(version, gc.Equals, 0) 210 c.Check(id, gc.Equals, "") 211 typed, ok := result.(*params.NotifyWatchResults) 212 c.Assert(ok, jc.IsTrue) 213 *typed = params.NotifyWatchResults{ 214 Results: []params.NotifyWatchResult{{ 215 NotifyWatcherId: "123", 216 }}, 217 } 218 return nil 219 case "NotifyWatcher": 220 return worker.ErrKilled 221 default: 222 c.Fatalf("unknown facade %q", facade) 223 return nil 224 } 225 }) 226 facade := lifeflag.NewClient(caller, "LifeFlag") 227 watcher, err := facade.Watch(names.NewApplicationTag("blah")) 228 c.Check(err, jc.ErrorIsNil) 229 workertest.CheckKilled(c, watcher) 230 } 231 232 func apiCaller(c *gc.C, check func(request string, arg, result interface{}) error) base.APICaller { 233 return apitesting.APICallerFunc(func(facade string, version int, id, request string, arg, result interface{}) error { 234 c.Check(facade, gc.Equals, "LifeFlag") 235 c.Check(version, gc.Equals, 0) 236 c.Check(id, gc.Equals, "") 237 return check(request, arg, result) 238 }) 239 }