github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/common/crossmodel/crossmodel_test.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package crossmodel_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 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/common/crossmodel" 14 corecrossmodel "github.com/juju/juju/core/crossmodel" 15 "github.com/juju/juju/core/status" 16 "github.com/juju/juju/rpc/params" 17 coretesting "github.com/juju/juju/testing" 18 ) 19 20 type crossmodelSuite struct { 21 coretesting.BaseSuite 22 } 23 24 var _ = gc.Suite(&crossmodelSuite{}) 25 26 func (s *crossmodelSuite) TestExpandChangeWhenRelationHasGone(c *gc.C) { 27 // Other aspects of ExpandChange are tested in the 28 // crossmodelrelations and remoterelations facade tests. 29 change := params.RelationUnitsChange{ 30 Changed: map[string]params.UnitSettings{ 31 "app/0": {Version: 1234}, 32 }, 33 AppChanged: map[string]int64{ 34 "app": 3456, 35 }, 36 Departed: []string{"app/2", "app/3"}, 37 } 38 result, err := crossmodel.ExpandChange( 39 &mockBackend{}, "some-relation", "some-app", change) 40 c.Assert(err, jc.ErrorIsNil) 41 c.Assert(result, gc.DeepEquals, params.RemoteRelationChangeEvent{ 42 RelationToken: "some-relation", 43 ApplicationToken: "some-app", 44 DepartedUnits: []int{2, 3}, 45 }) 46 } 47 48 func (s *crossmodelSuite) TestGetOfferStatusChangeOfferGoneNotMigrating(c *gc.C) { 49 st := &mockBackend{} 50 ch, err := crossmodel.GetOfferStatusChange(st, "uuid", "mysql") 51 c.Assert(err, jc.ErrorIsNil) 52 c.Assert(ch, gc.DeepEquals, ¶ms.OfferStatusChange{ 53 OfferName: "mysql", 54 Status: params.EntityStatus{Status: status.Terminated, Info: "offer has been removed"}, 55 }) 56 } 57 58 func (s *crossmodelSuite) TestGetOfferStatusChangeOfferGoneMigrating(c *gc.C) { 59 st := &mockBackend{ 60 migrating: true, 61 } 62 63 _, err := crossmodel.GetOfferStatusChange(st, "uuid", "mysql") 64 c.Assert(err, gc.ErrorMatches, "model is being migrated") 65 } 66 67 func (s *crossmodelSuite) TestGetOfferStatusChangeApplicationGoneNotMigrating(c *gc.C) { 68 st := &mockBackend{} 69 ch, err := crossmodel.GetOfferStatusChange(st, "deadbeef", "mysql") 70 c.Assert(err, jc.ErrorIsNil) 71 c.Assert(ch, gc.DeepEquals, ¶ms.OfferStatusChange{ 72 OfferName: "mysql", 73 Status: params.EntityStatus{Status: status.Terminated, Info: "application has been removed"}, 74 }) 75 } 76 77 func (s *crossmodelSuite) TestGetOfferStatusChangeApplicationGoneMigrating(c *gc.C) { 78 st := &mockBackend{ 79 migrating: true, 80 } 81 82 _, err := crossmodel.GetOfferStatusChange(st, "deadbeef", "mysql") 83 c.Assert(err, gc.ErrorMatches, "model is being migrated") 84 } 85 86 func (s *crossmodelSuite) TestGetOfferStatusChange(c *gc.C) { 87 st := &mockBackend{appName: "mysql", appStatus: status.StatusInfo{Status: status.Active}} 88 ch, err := crossmodel.GetOfferStatusChange(st, "deadbeef", "mysql") 89 c.Assert(err, jc.ErrorIsNil) 90 c.Assert(ch, gc.DeepEquals, ¶ms.OfferStatusChange{ 91 OfferName: "mysql", 92 Status: params.EntityStatus{Status: status.Active}, 93 }) 94 } 95 96 type mockBackend struct { 97 testing.Stub 98 crossmodel.Backend 99 100 appName string 101 appStatus status.StatusInfo 102 remoteEntities map[names.Tag]string 103 migrating bool 104 } 105 106 func (st *mockBackend) GetRemoteEntity(token string) (names.Tag, error) { 107 st.MethodCall(st, "GetRemoteEntity", token) 108 if err := st.NextErr(); err != nil { 109 return nil, err 110 } 111 for e, t := range st.remoteEntities { 112 if t == token { 113 return e, nil 114 } 115 } 116 return nil, errors.NotFoundf("token %v", token) 117 } 118 119 func (st *mockBackend) ApplicationOfferForUUID(uuid string) (*corecrossmodel.ApplicationOffer, error) { 120 if uuid != "deadbeef" { 121 return nil, errors.NotFoundf(uuid) 122 } 123 return &corecrossmodel.ApplicationOffer{ 124 ApplicationName: st.appName, 125 }, nil 126 } 127 128 func (st *mockBackend) Application(name string) (crossmodel.Application, error) { 129 if name != "mysql" { 130 return nil, errors.NotFoundf(name) 131 } 132 return &mockApplication{ 133 name: "mysql", 134 status: st.appStatus, 135 }, nil 136 } 137 138 func (st *mockBackend) IsMigrationActive() (bool, error) { 139 return st.migrating, nil 140 } 141 142 type mockApplication struct { 143 crossmodel.Application 144 name string 145 status status.StatusInfo 146 } 147 148 func (a *mockApplication) Name() string { 149 return a.name 150 } 151 152 func (a *mockApplication) Status() (status.StatusInfo, error) { 153 return a.status, nil 154 }