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  }