github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/binarystorage_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 "fmt" 8 "io" 9 "strings" 10 11 "github.com/juju/blobstore/v3" 12 "github.com/juju/collections/set" 13 "github.com/juju/errors" 14 "github.com/juju/names/v5" 15 jc "github.com/juju/testing/checkers" 16 jujutxn "github.com/juju/txn/v3" 17 "github.com/juju/utils/v3" 18 "github.com/juju/version/v2" 19 gc "gopkg.in/check.v1" 20 21 "github.com/juju/juju/mongo" 22 "github.com/juju/juju/state" 23 "github.com/juju/juju/state/binarystorage" 24 "github.com/juju/juju/storage" 25 "github.com/juju/juju/testing" 26 "github.com/juju/juju/tools" 27 ) 28 29 type tooler interface { 30 AgentTools() (*tools.Tools, error) 31 SetAgentVersion(v version.Binary) error 32 Refresh() error 33 } 34 35 func testAgentTools(c *gc.C, obj tooler, agent string) { 36 // object starts with zero'd tools. 37 t, err := obj.AgentTools() 38 c.Assert(t, gc.IsNil) 39 c.Assert(err, jc.Satisfies, errors.IsNotFound) 40 41 err = obj.SetAgentVersion(version.Binary{}) 42 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("cannot set agent version for %s: empty series or arch", agent)) 43 44 v2 := version.MustParseBinary("7.8.9-ubuntu-amd64") 45 err = obj.SetAgentVersion(v2) 46 c.Assert(err, jc.ErrorIsNil) 47 t3, err := obj.AgentTools() 48 c.Assert(err, jc.ErrorIsNil) 49 c.Assert(t3.Version, gc.DeepEquals, v2) 50 err = obj.Refresh() 51 c.Assert(err, jc.ErrorIsNil) 52 t3, err = obj.AgentTools() 53 c.Assert(err, jc.ErrorIsNil) 54 c.Assert(t3.Version, gc.DeepEquals, v2) 55 56 if le, ok := obj.(lifer); ok { 57 testWhenDying(c, le, noErr, deadErr, func() error { 58 return obj.SetAgentVersion(v2) 59 }) 60 } 61 } 62 63 type binaryStorageSuite struct { 64 ConnSuite 65 66 controllerModelUUID string 67 modelUUID string 68 st *state.State 69 } 70 71 var _ = gc.Suite(&binaryStorageSuite{}) 72 73 func (s *binaryStorageSuite) SetUpTest(c *gc.C) { 74 s.ConnSuite.SetUpTest(c) 75 76 s.controllerModelUUID = s.State.ControllerModelUUID() 77 78 // Create a new model and store its UUID. 79 s.modelUUID = utils.MustNewUUID().String() 80 cfg := testing.CustomModelConfig(c, testing.Attrs{ 81 "name": "new-model", 82 "uuid": s.modelUUID, 83 }) 84 var err error 85 _, s.st, err = s.Controller.NewModel(state.ModelArgs{ 86 Type: state.ModelTypeIAAS, 87 CloudName: "dummy", 88 CloudRegion: "dummy-region", 89 Config: cfg, 90 Owner: names.NewLocalUserTag("test-admin"), 91 StorageProviderRegistry: storage.StaticProviderRegistry{}, 92 }) 93 c.Assert(err, jc.ErrorIsNil) 94 s.AddCleanup(func(*gc.C) { 95 s.st.Close() 96 }) 97 } 98 99 type storageOpener func() (binarystorage.StorageCloser, error) 100 101 func (s *binaryStorageSuite) TestToolsStorage(c *gc.C) { 102 s.testStorage(c, "toolsmetadata", s.State.ToolsStorage) 103 } 104 105 func (s *binaryStorageSuite) TestToolsStorageParamsControllerModel(c *gc.C) { 106 s.testStorageParams(c, "toolsmetadata", []string{s.State.ModelUUID()}, s.State.ToolsStorage) 107 } 108 109 func (s *binaryStorageSuite) TestToolsStorageParamsHostedModel(c *gc.C) { 110 s.testStorageParams(c, "toolsmetadata", []string{s.modelUUID, s.State.ModelUUID()}, s.st.ToolsStorage) 111 } 112 113 func (s *binaryStorageSuite) testStorage(c *gc.C, collName string, openStorage storageOpener) { 114 session := s.State.MongoSession() 115 // if the collection didn't exist, we will create it on demand. 116 err := session.DB("juju").C(collName).DropCollection() 117 c.Assert(err, jc.ErrorIsNil) 118 collectionNames, err := session.DB("juju").CollectionNames() 119 c.Assert(err, jc.ErrorIsNil) 120 nameSet := set.NewStrings(collectionNames...) 121 c.Assert(nameSet.Contains(collName), jc.IsFalse) 122 123 storage, err := openStorage() 124 c.Assert(err, jc.ErrorIsNil) 125 defer func() { 126 err := storage.Close() 127 c.Assert(err, jc.ErrorIsNil) 128 }() 129 130 err = storage.Add(strings.NewReader(""), binarystorage.Metadata{}) 131 c.Assert(err, jc.ErrorIsNil) 132 133 collectionNames, err = session.DB("juju").CollectionNames() 134 c.Assert(err, jc.ErrorIsNil) 135 nameSet = set.NewStrings(collectionNames...) 136 c.Assert(nameSet.Contains(collName), jc.IsTrue) 137 } 138 139 func (s *binaryStorageSuite) testStorageParams(c *gc.C, collName string, uuids []string, openStorage storageOpener) { 140 var uuidArgs []string 141 s.PatchValue(state.BinarystorageNew, func( 142 modelUUID string, 143 managedStorage blobstore.ManagedStorage, 144 metadataCollection mongo.Collection, 145 runner jujutxn.Runner, 146 ) binarystorage.Storage { 147 uuidArgs = append(uuidArgs, modelUUID) 148 c.Assert(managedStorage, gc.NotNil) 149 c.Assert(metadataCollection.Name(), gc.Equals, collName) 150 c.Assert(runner, gc.NotNil) 151 return nil 152 }) 153 154 storage, err := openStorage() 155 c.Assert(err, jc.ErrorIsNil) 156 storage.Close() 157 c.Assert(uuidArgs, jc.DeepEquals, uuids) 158 } 159 160 func (s *binaryStorageSuite) TestToolsStorageLayered(c *gc.C) { 161 modelTools, err := s.st.ToolsStorage() 162 c.Assert(err, jc.ErrorIsNil) 163 defer modelTools.Close() 164 165 controllerTools, err := s.State.ToolsStorage() 166 c.Assert(err, jc.ErrorIsNil) 167 defer controllerTools.Close() 168 169 err = modelTools.Add(strings.NewReader("abc"), binarystorage.Metadata{Version: "1.0", Size: 3}) 170 c.Assert(err, jc.ErrorIsNil) 171 err = controllerTools.Add(strings.NewReader("defg"), binarystorage.Metadata{Version: "1.0", Size: 4}) 172 c.Assert(err, jc.ErrorIsNil) 173 err = controllerTools.Add(strings.NewReader("def"), binarystorage.Metadata{Version: "2.0", Size: 3}) 174 c.Assert(err, jc.ErrorIsNil) 175 176 all, err := modelTools.AllMetadata() 177 c.Assert(err, jc.ErrorIsNil) 178 c.Assert(all, jc.DeepEquals, []binarystorage.Metadata{ 179 {Version: "1.0", Size: 3}, 180 {Version: "2.0", Size: 3}, 181 }) 182 183 assertContents := func(v, contents string) { 184 _, rc, err := modelTools.Open(v) 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(rc, gc.NotNil) 187 defer rc.Close() 188 data, err := io.ReadAll(rc) 189 c.Assert(err, jc.ErrorIsNil) 190 c.Assert(string(data), gc.Equals, contents) 191 } 192 assertContents("1.0", "abc") 193 assertContents("2.0", "def") 194 }