github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/core/description/volume_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package description 5 6 import ( 7 "github.com/juju/errors" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 "gopkg.in/juju/names.v2" 11 "gopkg.in/yaml.v2" 12 ) 13 14 type VolumeSerializationSuite struct { 15 SliceSerializationSuite 16 StatusHistoryMixinSuite 17 } 18 19 var _ = gc.Suite(&VolumeSerializationSuite{}) 20 21 func (s *VolumeSerializationSuite) SetUpTest(c *gc.C) { 22 s.SliceSerializationSuite.SetUpTest(c) 23 s.importName = "volumes" 24 s.sliceName = "volumes" 25 s.importFunc = func(m map[string]interface{}) (interface{}, error) { 26 return importVolumes(m) 27 } 28 s.testFields = func(m map[string]interface{}) { 29 m["volumes"] = []interface{}{} 30 } 31 s.StatusHistoryMixinSuite.creator = func() HasStatusHistory { 32 return testVolume() 33 } 34 s.StatusHistoryMixinSuite.serializer = func(c *gc.C, initial interface{}) HasStatusHistory { 35 return s.exportImport(c, initial.(*volume)) 36 } 37 } 38 39 func testVolumeMap() map[interface{}]interface{} { 40 return map[interface{}]interface{}{ 41 "id": "1234", 42 "storage-id": "test/1", 43 "binding": "machine-42", 44 "provisioned": true, 45 "size": int(20 * gig), 46 "pool": "swimming", 47 "hardware-id": "a hardware id", 48 "volume-id": "some volume id", 49 "persistent": true, 50 "status": minimalStatusMap(), 51 "status-history": emptyStatusHistoryMap(), 52 "attachments": map[interface{}]interface{}{ 53 "version": 1, 54 "attachments": []interface{}{}, 55 }, 56 } 57 } 58 59 func testVolume() *volume { 60 v := newVolume(testVolumeArgs()) 61 v.SetStatus(minimalStatusArgs()) 62 return v 63 } 64 65 func testVolumeArgs() VolumeArgs { 66 return VolumeArgs{ 67 Tag: names.NewVolumeTag("1234"), 68 Storage: names.NewStorageTag("test/1"), 69 Binding: names.NewMachineTag("42"), 70 Provisioned: true, 71 Size: 20 * gig, 72 Pool: "swimming", 73 HardwareID: "a hardware id", 74 VolumeID: "some volume id", 75 Persistent: true, 76 } 77 } 78 79 func (s *VolumeSerializationSuite) TestNewVolume(c *gc.C) { 80 volume := testVolume() 81 82 c.Check(volume.Tag(), gc.Equals, names.NewVolumeTag("1234")) 83 c.Check(volume.Storage(), gc.Equals, names.NewStorageTag("test/1")) 84 binding, err := volume.Binding() 85 c.Check(err, jc.ErrorIsNil) 86 c.Check(binding, gc.Equals, names.NewMachineTag("42")) 87 c.Check(volume.Provisioned(), jc.IsTrue) 88 c.Check(volume.Size(), gc.Equals, 20*gig) 89 c.Check(volume.Pool(), gc.Equals, "swimming") 90 c.Check(volume.HardwareID(), gc.Equals, "a hardware id") 91 c.Check(volume.VolumeID(), gc.Equals, "some volume id") 92 c.Check(volume.Persistent(), jc.IsTrue) 93 94 c.Check(volume.Attachments(), gc.HasLen, 0) 95 } 96 97 func (s *VolumeSerializationSuite) TestVolumeValid(c *gc.C) { 98 volume := testVolume() 99 c.Assert(volume.Validate(), jc.ErrorIsNil) 100 } 101 102 func (s *VolumeSerializationSuite) TestVolumeValidMissingID(c *gc.C) { 103 v := newVolume(VolumeArgs{}) 104 err := v.Validate() 105 c.Check(err, gc.ErrorMatches, `volume missing id not valid`) 106 c.Check(err, jc.Satisfies, errors.IsNotValid) 107 } 108 109 func (s *VolumeSerializationSuite) TestVolumeValidMissingSize(c *gc.C) { 110 v := newVolume(VolumeArgs{ 111 Tag: names.NewVolumeTag("123"), 112 }) 113 err := v.Validate() 114 c.Check(err, gc.ErrorMatches, `volume "123" missing size not valid`) 115 c.Check(err, jc.Satisfies, errors.IsNotValid) 116 } 117 118 func (s *VolumeSerializationSuite) TestVolumeValidMissingStatus(c *gc.C) { 119 v := newVolume(VolumeArgs{ 120 Tag: names.NewVolumeTag("123"), 121 Size: 5, 122 }) 123 err := v.Validate() 124 c.Check(err, gc.ErrorMatches, `volume "123" missing status not valid`) 125 c.Check(err, jc.Satisfies, errors.IsNotValid) 126 } 127 128 func (s *VolumeSerializationSuite) TestVolumeValidMinimal(c *gc.C) { 129 v := newVolume(VolumeArgs{ 130 Tag: names.NewVolumeTag("123"), 131 Size: 5, 132 }) 133 v.SetStatus(minimalStatusArgs()) 134 err := v.Validate() 135 c.Check(err, jc.ErrorIsNil) 136 } 137 138 func (s *VolumeSerializationSuite) TestVolumeMatches(c *gc.C) { 139 bytes, err := yaml.Marshal(testVolume()) 140 c.Assert(err, jc.ErrorIsNil) 141 142 var source map[interface{}]interface{} 143 err = yaml.Unmarshal(bytes, &source) 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(source, jc.DeepEquals, testVolumeMap()) 146 } 147 148 func (s *VolumeSerializationSuite) exportImport(c *gc.C, volume_ *volume) *volume { 149 initial := volumes{ 150 Version: 1, 151 Volumes_: []*volume{volume_}, 152 } 153 154 bytes, err := yaml.Marshal(initial) 155 c.Assert(err, jc.ErrorIsNil) 156 157 var source map[string]interface{} 158 err = yaml.Unmarshal(bytes, &source) 159 c.Assert(err, jc.ErrorIsNil) 160 161 volumes, err := importVolumes(source) 162 c.Assert(err, jc.ErrorIsNil) 163 c.Assert(volumes, gc.HasLen, 1) 164 return volumes[0] 165 } 166 167 func (s *VolumeSerializationSuite) TestAddingAttachments(c *gc.C) { 168 // The core code does not care about duplicates, so we'll just add 169 // the same attachment twice. 170 original := testVolume() 171 attachment1 := original.AddAttachment(testVolumeAttachmentArgs("1")) 172 attachment2 := original.AddAttachment(testVolumeAttachmentArgs("2")) 173 volume := s.exportImport(c, original) 174 c.Assert(volume, jc.DeepEquals, original) 175 attachments := volume.Attachments() 176 c.Assert(attachments, gc.HasLen, 2) 177 c.Check(attachments[0], jc.DeepEquals, attachment1) 178 c.Check(attachments[1], jc.DeepEquals, attachment2) 179 } 180 181 func (s *VolumeSerializationSuite) TestParsingSerializedData(c *gc.C) { 182 original := testVolume() 183 original.AddAttachment(testVolumeAttachmentArgs()) 184 volume := s.exportImport(c, original) 185 c.Assert(volume, jc.DeepEquals, original) 186 } 187 188 type VolumeAttachmentSerializationSuite struct { 189 SliceSerializationSuite 190 } 191 192 var _ = gc.Suite(&VolumeAttachmentSerializationSuite{}) 193 194 func (s *VolumeAttachmentSerializationSuite) SetUpTest(c *gc.C) { 195 s.SliceSerializationSuite.SetUpTest(c) 196 s.importName = "volume attachments" 197 s.sliceName = "attachments" 198 s.importFunc = func(m map[string]interface{}) (interface{}, error) { 199 return importVolumeAttachments(m) 200 } 201 s.testFields = func(m map[string]interface{}) { 202 m["attachments"] = []interface{}{} 203 } 204 } 205 206 func testVolumeAttachmentMap() map[interface{}]interface{} { 207 return map[interface{}]interface{}{ 208 "machine-id": "42", 209 "provisioned": true, 210 "read-only": true, 211 "device-name": "sdd", 212 "device-link": "link?", 213 "bus-address": "nfi", 214 } 215 } 216 217 func testVolumeAttachment() *volumeAttachment { 218 return newVolumeAttachment(testVolumeAttachmentArgs()) 219 } 220 221 func testVolumeAttachmentArgs(id ...string) VolumeAttachmentArgs { 222 machineID := "42" 223 if len(id) > 0 { 224 machineID = id[0] 225 } 226 return VolumeAttachmentArgs{ 227 Machine: names.NewMachineTag(machineID), 228 Provisioned: true, 229 ReadOnly: true, 230 DeviceName: "sdd", 231 DeviceLink: "link?", 232 BusAddress: "nfi", 233 } 234 } 235 236 func (s *VolumeAttachmentSerializationSuite) TestNewVolumeAttachment(c *gc.C) { 237 attachment := testVolumeAttachment() 238 239 c.Check(attachment.Machine(), gc.Equals, names.NewMachineTag("42")) 240 c.Check(attachment.Provisioned(), jc.IsTrue) 241 c.Check(attachment.ReadOnly(), jc.IsTrue) 242 c.Check(attachment.DeviceName(), gc.Equals, "sdd") 243 c.Check(attachment.DeviceLink(), gc.Equals, "link?") 244 c.Check(attachment.BusAddress(), gc.Equals, "nfi") 245 } 246 247 func (s *VolumeAttachmentSerializationSuite) TestVolumeAttachmentMatches(c *gc.C) { 248 bytes, err := yaml.Marshal(testVolumeAttachment()) 249 c.Assert(err, jc.ErrorIsNil) 250 251 var source map[interface{}]interface{} 252 err = yaml.Unmarshal(bytes, &source) 253 c.Assert(err, jc.ErrorIsNil) 254 c.Assert(source, jc.DeepEquals, testVolumeAttachmentMap()) 255 } 256 257 func (s *VolumeAttachmentSerializationSuite) exportImport(c *gc.C, attachment *volumeAttachment) *volumeAttachment { 258 initial := volumeAttachments{ 259 Version: 1, 260 Attachments_: []*volumeAttachment{attachment}, 261 } 262 263 bytes, err := yaml.Marshal(initial) 264 c.Assert(err, jc.ErrorIsNil) 265 266 var source map[string]interface{} 267 err = yaml.Unmarshal(bytes, &source) 268 c.Assert(err, jc.ErrorIsNil) 269 270 attachments, err := importVolumeAttachments(source) 271 c.Assert(err, jc.ErrorIsNil) 272 c.Assert(attachments, gc.HasLen, 1) 273 return attachments[0] 274 } 275 276 func (s *VolumeAttachmentSerializationSuite) TestParsingSerializedData(c *gc.C) { 277 original := testVolumeAttachment() 278 attachment := s.exportImport(c, original) 279 c.Assert(attachment, jc.DeepEquals, original) 280 }