github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/maas/volumes_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"github.com/juju/gomaasapi"
     8  	"github.com/juju/names"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/constraints"
    13  	"github.com/juju/juju/instance"
    14  	"github.com/juju/juju/storage"
    15  	"github.com/juju/juju/testing"
    16  )
    17  
    18  type volumeSuite struct {
    19  	providerSuite
    20  }
    21  
    22  var _ = gc.Suite(&volumeSuite{})
    23  
    24  func (s *volumeSuite) TestBuildMAASVolumeParametersNoVolumes(c *gc.C) {
    25  	vInfo, err := buildMAASVolumeParameters(nil, constraints.Value{})
    26  	c.Assert(err, jc.ErrorIsNil)
    27  	c.Assert(vInfo, gc.HasLen, 0)
    28  }
    29  
    30  func (s *volumeSuite) TestBuildMAASVolumeParametersJustRootDisk(c *gc.C) {
    31  	var cons constraints.Value
    32  	rootSize := uint64(20000)
    33  	cons.RootDisk = &rootSize
    34  	vInfo, err := buildMAASVolumeParameters(nil, cons)
    35  	c.Assert(err, jc.ErrorIsNil)
    36  	c.Assert(vInfo, jc.DeepEquals, []volumeInfo{
    37  		{"root", 20, nil},
    38  	})
    39  }
    40  
    41  func (s *volumeSuite) TestBuildMAASVolumeParametersNoTags(c *gc.C) {
    42  	vInfo, err := buildMAASVolumeParameters([]storage.VolumeParams{
    43  		{Tag: names.NewVolumeTag("1"), Size: 2000000},
    44  	}, constraints.Value{})
    45  	c.Assert(err, jc.ErrorIsNil)
    46  	c.Assert(vInfo, jc.DeepEquals, []volumeInfo{
    47  		{"root", 0, nil}, //root disk
    48  		{"1", 1954, nil},
    49  	})
    50  }
    51  
    52  func (s *volumeSuite) TestBuildMAASVolumeParametersWithRootDisk(c *gc.C) {
    53  	var cons constraints.Value
    54  	rootSize := uint64(20000)
    55  	cons.RootDisk = &rootSize
    56  	vInfo, err := buildMAASVolumeParameters([]storage.VolumeParams{
    57  		{Tag: names.NewVolumeTag("1"), Size: 2000000},
    58  	}, cons)
    59  	c.Assert(err, jc.ErrorIsNil)
    60  	c.Assert(vInfo, jc.DeepEquals, []volumeInfo{
    61  		{"root", 20, nil}, //root disk
    62  		{"1", 1954, nil},
    63  	})
    64  }
    65  
    66  func (s *volumeSuite) TestBuildMAASVolumeParametersWithTags(c *gc.C) {
    67  	vInfo, err := buildMAASVolumeParameters([]storage.VolumeParams{
    68  		{Tag: names.NewVolumeTag("1"), Size: 2000000, Attributes: map[string]interface{}{"tags": "tag1,tag2"}},
    69  	}, constraints.Value{})
    70  	c.Assert(err, jc.ErrorIsNil)
    71  	c.Assert(vInfo, jc.DeepEquals, []volumeInfo{
    72  		{"root", 0, nil}, //root disk
    73  		{"1", 1954, []string{"tag1", "tag2"}},
    74  	})
    75  }
    76  
    77  func (s *volumeSuite) TestInstanceVolumesMAAS2(c *gc.C) {
    78  	instance := maas2Instance{
    79  		machine: &fakeMachine{},
    80  		constraintMatches: gomaasapi.ConstraintMatches{
    81  			Storage: map[string]gomaasapi.BlockDevice{
    82  				"root": &fakeBlockDevice{name: "sda", path: "/dev/disk/by-dname/sda", size: 250059350016},
    83  				"1":    &fakeBlockDevice{name: "sdb", path: "/dev/disk/by-dname/sdb", size: 500059350016},
    84  				"2":    &fakeBlockDevice{name: "sdc", path: "/dev/disk/by-dname/sdc", size: 250362438230},
    85  				"3":    &fakeBlockDevice{name: "sdd", path: "/dev/disk/by-dname/sdd", size: 250362438230},
    86  				"4":    &fakeBlockDevice{name: "sde", path: "/dev/disk/by-dname/sde", size: 250362438230},
    87  			},
    88  		},
    89  	}
    90  	mTag := names.NewMachineTag("1")
    91  	volumes, attachments, err := instance.volumes(mTag, []names.VolumeTag{
    92  		names.NewVolumeTag("1"),
    93  		names.NewVolumeTag("2"),
    94  	})
    95  	c.Assert(err, jc.ErrorIsNil)
    96  	// Expect 2 volumes - root volume is ignored.
    97  	c.Assert(volumes, gc.HasLen, 2)
    98  	c.Assert(attachments, gc.HasLen, 2)
    99  	c.Check(volumes, jc.SameContents, []storage.Volume{{
   100  		names.NewVolumeTag("1"),
   101  		storage.VolumeInfo{
   102  			VolumeId:   "volume-1",
   103  			Size:       476893,
   104  			Persistent: false,
   105  		},
   106  	}, {
   107  		names.NewVolumeTag("2"),
   108  		storage.VolumeInfo{
   109  			VolumeId:   "volume-2",
   110  			Size:       238764,
   111  			Persistent: false,
   112  		},
   113  	}})
   114  	c.Assert(attachments, jc.SameContents, []storage.VolumeAttachment{
   115  		{
   116  			names.NewVolumeTag("1"),
   117  			mTag,
   118  			storage.VolumeAttachmentInfo{
   119  				DeviceLink: "/dev/disk/by-dname/sdb",
   120  				ReadOnly:   false,
   121  			},
   122  		},
   123  		{
   124  			names.NewVolumeTag("2"),
   125  			mTag,
   126  			storage.VolumeAttachmentInfo{
   127  				DeviceLink: "/dev/disk/by-dname/sdc",
   128  				ReadOnly:   false,
   129  			},
   130  		},
   131  	})
   132  }
   133  
   134  func (s *volumeSuite) TestInstanceVolumes(c *gc.C) {
   135  	obj := s.testMAASObject.TestServer.NewNode(validVolumeJson)
   136  	statusGetter := func(instance.Id) (string, string) {
   137  		return "unknown", "FAKE"
   138  	}
   139  
   140  	instance := maas1Instance{&obj, nil, statusGetter}
   141  	mTag := names.NewMachineTag("1")
   142  	volumes, attachments, err := instance.volumes(mTag, []names.VolumeTag{
   143  		names.NewVolumeTag("1"),
   144  		names.NewVolumeTag("2"),
   145  	})
   146  	c.Assert(err, jc.ErrorIsNil)
   147  	// Expect 2 volumes - root volume is ignored.
   148  	c.Assert(volumes, gc.HasLen, 2)
   149  	c.Assert(attachments, gc.HasLen, 2)
   150  	c.Check(volumes, jc.DeepEquals, []storage.Volume{
   151  		{
   152  			// This volume has no id_path.
   153  			names.NewVolumeTag("1"),
   154  			storage.VolumeInfo{
   155  				HardwareId: "",
   156  				VolumeId:   "volume-1",
   157  				Size:       476893,
   158  				Persistent: false,
   159  			},
   160  		},
   161  		{
   162  			names.NewVolumeTag("2"),
   163  			storage.VolumeInfo{
   164  				HardwareId: "id_for_sdc",
   165  				VolumeId:   "volume-2",
   166  				Size:       238764,
   167  				Persistent: false,
   168  			},
   169  		},
   170  	})
   171  	c.Assert(attachments, jc.DeepEquals, []storage.VolumeAttachment{
   172  		{
   173  			names.NewVolumeTag("1"),
   174  			mTag,
   175  			storage.VolumeAttachmentInfo{
   176  				DeviceName: "sdb",
   177  				ReadOnly:   false,
   178  			},
   179  		},
   180  		// Device name not set because there's a hardware id in the volume.
   181  		{
   182  			names.NewVolumeTag("2"),
   183  			mTag,
   184  			storage.VolumeAttachmentInfo{
   185  				DeviceName: "",
   186  				ReadOnly:   false,
   187  			},
   188  		},
   189  	})
   190  }
   191  
   192  func (s *volumeSuite) TestInstanceVolumesOldMass(c *gc.C) {
   193  	obj := s.testMAASObject.TestServer.NewNode(`{"system_id": "node0"}`)
   194  	statusGetter := func(instance.Id) (string, string) {
   195  		// status, substatus or status info.
   196  		return "provisioning", "substatus"
   197  	}
   198  
   199  	instance := maas1Instance{&obj, nil, statusGetter}
   200  	volumes, attachments, err := instance.volumes(names.NewMachineTag("1"), []names.VolumeTag{
   201  		names.NewVolumeTag("1"),
   202  		names.NewVolumeTag("2"),
   203  	})
   204  	c.Assert(err, jc.ErrorIsNil)
   205  	c.Assert(volumes, gc.HasLen, 0)
   206  	c.Assert(attachments, gc.HasLen, 0)
   207  }
   208  
   209  var validVolumeJson = `
   210  {
   211      "system_id": "node0",
   212      "physicalblockdevice_set": [
   213          {
   214              "name": "sda",
   215              "tags": [
   216                  "ssd",
   217                  "sata"
   218              ],
   219              "id": 1,
   220              "id_path": "/dev/disk/by-id/id_for_sda",
   221              "path": "/dev/sda",
   222              "model": "Samsung_SSD_850_EVO_250GB",
   223              "block_size": 4096,
   224              "serial": "S21NNSAFC38075L",
   225              "size": 250059350016
   226          },
   227          {
   228              "name": "sdb",
   229              "tags": [
   230                  "ssd",
   231                  "sata"
   232              ],
   233              "id": 2,
   234              "path": "/dev/sdb",
   235              "model": "Samsung_SSD_850_EVO_500GB",
   236              "block_size": 4096,
   237              "serial": "S21NNSAFC38076L",
   238              "size": 500059350016
   239          },
   240          {
   241              "name": "sdb",
   242              "tags": [
   243                  "ssd",
   244                  "sata"
   245              ],
   246              "id": 3,
   247              "id_path": "/dev/disk/by-id/id_for_sdc",
   248              "path": "/dev/sdc",
   249              "model": "Samsung_SSD_850_EVO_250GB",
   250              "block_size": 4096,
   251              "serial": "S21NNSAFC38999L",
   252              "size": 250362438230
   253          },
   254          {
   255              "name": "sdd",
   256              "tags": [
   257                  "ssd",
   258                  "sata"
   259              ],
   260              "id": 4,
   261              "id_path": "/dev/disk/by-id/id_for_sdd",
   262              "path": "/dev/sdd",
   263              "model": "Samsung_SSD_850_EVO_250GB",
   264              "block_size": 4096,
   265              "serial": "S21NNSAFC386666L",
   266              "size": 250362438230
   267          },
   268          {
   269              "name": "sde",
   270              "tags": [
   271                  "ssd",
   272                  "sata"
   273              ],
   274              "id": 666,
   275              "id_path": "/dev/disk/by-id/id_for_sde",
   276              "path": "/dev/sde",
   277              "model": "Samsung_SSD_850_EVO_250GB",
   278              "block_size": 4096,
   279              "serial": "S21NNSAFC388888L",
   280              "size": 250362438230
   281          }
   282      ],
   283      "constraint_map": {
   284          "1": "root",
   285          "2": "1",
   286          "3": "2",
   287          "4": "3"
   288      }
   289  }
   290  `[1:]
   291  
   292  type storageProviderSuite struct {
   293  	testing.BaseSuite
   294  }
   295  
   296  var _ = gc.Suite(&storageProviderSuite{})
   297  
   298  func (*storageProviderSuite) TestValidateConfigTags(c *gc.C) {
   299  	p := maasStorageProvider{}
   300  	validate := func(tags interface{}) {
   301  		cfg, err := storage.NewConfig("foo", maasStorageProviderType, map[string]interface{}{
   302  			"tags": tags,
   303  		})
   304  		c.Assert(err, jc.ErrorIsNil)
   305  		err = p.ValidateConfig(cfg)
   306  		c.Assert(err, jc.ErrorIsNil)
   307  	}
   308  	validate("singular")
   309  	validate("mul,ti,ple")
   310  	validate(" leading, spaces")
   311  	validate("trailing ,spaces ")
   312  	validate(" and,everything, in ,  between ")
   313  }
   314  
   315  func (*storageProviderSuite) TestValidateConfigInvalidConfig(c *gc.C) {
   316  	p := maasStorageProvider{}
   317  	cfg, err := storage.NewConfig("foo", maasStorageProviderType, map[string]interface{}{
   318  		"tags": "white space",
   319  	})
   320  	c.Assert(err, jc.ErrorIsNil)
   321  	err = p.ValidateConfig(cfg)
   322  	c.Assert(err, gc.ErrorMatches, `tags may not contain whitespace: "white space"`)
   323  }
   324  
   325  func (*storageProviderSuite) TestValidateConfigUnknownAttribute(c *gc.C) {
   326  	p := maasStorageProvider{}
   327  	cfg, err := storage.NewConfig("foo", maasStorageProviderType, map[string]interface{}{
   328  		"unknown": "config",
   329  	})
   330  	c.Assert(err, jc.ErrorIsNil)
   331  	err = p.ValidateConfig(cfg)
   332  	c.Assert(err, jc.ErrorIsNil) // unknown attributes are ignored
   333  }
   334  
   335  func (s *storageProviderSuite) TestSupports(c *gc.C) {
   336  	p := maasStorageProvider{}
   337  	c.Assert(p.Supports(storage.StorageKindBlock), jc.IsTrue)
   338  	c.Assert(p.Supports(storage.StorageKindFilesystem), jc.IsFalse)
   339  }
   340  
   341  func (s *storageProviderSuite) TestScope(c *gc.C) {
   342  	p := maasStorageProvider{}
   343  	c.Assert(p.Scope(), gc.Equals, storage.ScopeEnviron)
   344  }