github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/blockdevices_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/state"
    13  	"github.com/juju/juju/state/testing"
    14  )
    15  
    16  type BlockDevicesSuite struct {
    17  	ConnSuite
    18  	machine *state.Machine
    19  }
    20  
    21  var _ = gc.Suite(&BlockDevicesSuite{})
    22  
    23  func (s *BlockDevicesSuite) SetUpTest(c *gc.C) {
    24  	s.ConnSuite.SetUpTest(c)
    25  	var err error
    26  	s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits)
    27  	c.Assert(err, jc.ErrorIsNil)
    28  }
    29  
    30  func (s *BlockDevicesSuite) assertBlockDevices(c *gc.C, tag names.MachineTag, expected []state.BlockDeviceInfo) {
    31  	info, err := s.State.BlockDevices(tag)
    32  	c.Assert(err, jc.ErrorIsNil)
    33  	c.Assert(info, gc.DeepEquals, expected)
    34  }
    35  
    36  func (s *BlockDevicesSuite) TestSetMachineBlockDevices(c *gc.C) {
    37  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
    38  	err := s.machine.SetMachineBlockDevices(sda)
    39  	c.Assert(err, jc.ErrorIsNil)
    40  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda})
    41  }
    42  
    43  func (s *BlockDevicesSuite) TestSetMachineBlockDevicesReplaces(c *gc.C) {
    44  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
    45  	err := s.machine.SetMachineBlockDevices(sda)
    46  	c.Assert(err, jc.ErrorIsNil)
    47  
    48  	sdb := state.BlockDeviceInfo{DeviceName: "sdb"}
    49  	err = s.machine.SetMachineBlockDevices(sdb)
    50  	c.Assert(err, jc.ErrorIsNil)
    51  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sdb})
    52  }
    53  
    54  func (s *BlockDevicesSuite) TestSetMachineBlockDevicesUpdates(c *gc.C) {
    55  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
    56  	sdb := state.BlockDeviceInfo{DeviceName: "sdb"}
    57  	err := s.machine.SetMachineBlockDevices(sda, sdb)
    58  	c.Assert(err, jc.ErrorIsNil)
    59  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda, sdb})
    60  
    61  	sdb.Label = "root"
    62  	err = s.machine.SetMachineBlockDevices(sdb)
    63  	c.Assert(err, jc.ErrorIsNil)
    64  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sdb})
    65  
    66  	// If a device is attached, unattached, then attached again,
    67  	// then it gets a new name.
    68  	sdb.Label = "" // Label should be reset.
    69  	sdb.FilesystemType = "ext4"
    70  	err = s.machine.SetMachineBlockDevices(sda, sdb)
    71  	c.Assert(err, jc.ErrorIsNil)
    72  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{
    73  		sda,
    74  		sdb,
    75  	})
    76  }
    77  
    78  func (s *BlockDevicesSuite) TestSetMachineBlockDevicesUnchanged(c *gc.C) {
    79  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
    80  	err := s.machine.SetMachineBlockDevices(sda)
    81  	c.Assert(err, jc.ErrorIsNil)
    82  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda})
    83  
    84  	// Setting the same should not change txn-revno.
    85  	docID := state.DocID(s.State, s.machine.Id())
    86  	before, err := state.TxnRevno(s.State, state.BlockDevicesC, docID)
    87  	c.Assert(err, jc.ErrorIsNil)
    88  
    89  	err = s.machine.SetMachineBlockDevices(sda)
    90  	c.Assert(err, jc.ErrorIsNil)
    91  
    92  	after, err := state.TxnRevno(s.State, state.BlockDevicesC, docID)
    93  	c.Assert(err, jc.ErrorIsNil)
    94  	c.Assert(after, gc.Equals, before)
    95  }
    96  
    97  func (s *BlockDevicesSuite) TestSetMachineBlockDevicesConcurrently(c *gc.C) {
    98  	sdaInner := state.BlockDeviceInfo{DeviceName: "sda"}
    99  	defer state.SetBeforeHooks(c, s.State, func() {
   100  		err := s.machine.SetMachineBlockDevices(sdaInner)
   101  		c.Assert(err, jc.ErrorIsNil)
   102  	}).Check()
   103  
   104  	sdaOuter := state.BlockDeviceInfo{
   105  		DeviceName: "sda",
   106  		Label:      "root",
   107  	}
   108  	err := s.machine.SetMachineBlockDevices(sdaOuter)
   109  	c.Assert(err, jc.ErrorIsNil)
   110  
   111  	// the outer call should wipe out the inner one's update.
   112  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{
   113  		sdaOuter,
   114  	})
   115  }
   116  
   117  func (s *BlockDevicesSuite) TestSetMachineBlockDevicesEmpty(c *gc.C) {
   118  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
   119  	err := s.machine.SetMachineBlockDevices(sda)
   120  	c.Assert(err, jc.ErrorIsNil)
   121  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{sda})
   122  
   123  	err = s.machine.SetMachineBlockDevices()
   124  	c.Assert(err, jc.ErrorIsNil)
   125  	s.assertBlockDevices(c, s.machine.MachineTag(), []state.BlockDeviceInfo{})
   126  }
   127  
   128  func (s *BlockDevicesSuite) TestBlockDevicesMachineRemove(c *gc.C) {
   129  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
   130  	err := s.machine.SetMachineBlockDevices(sda)
   131  	c.Assert(err, jc.ErrorIsNil)
   132  
   133  	err = s.machine.EnsureDead()
   134  	c.Assert(err, jc.ErrorIsNil)
   135  	err = s.machine.Remove()
   136  	c.Assert(err, jc.ErrorIsNil)
   137  
   138  	_, err = s.State.BlockDevices(s.machine.MachineTag())
   139  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   140  }
   141  
   142  func (s *BlockDevicesSuite) TestWatchBlockDevices(c *gc.C) {
   143  	sda := state.BlockDeviceInfo{DeviceName: "sda"}
   144  	sdb := state.BlockDeviceInfo{DeviceName: "sdb"}
   145  	sdc := state.BlockDeviceInfo{DeviceName: "sdc"}
   146  	err := s.machine.SetMachineBlockDevices(sda, sdb, sdc)
   147  	c.Assert(err, jc.ErrorIsNil)
   148  
   149  	// Start block device watcher.
   150  	w := s.State.WatchBlockDevices(s.machine.MachineTag())
   151  	defer testing.AssertStop(c, w)
   152  	wc := testing.NewNotifyWatcherC(c, s.State, w)
   153  	wc.AssertOneChange()
   154  
   155  	// Setting the same should not trigger the watcher.
   156  	err = s.machine.SetMachineBlockDevices(sdc, sdb, sda)
   157  	c.Assert(err, jc.ErrorIsNil)
   158  	wc.AssertNoChange()
   159  
   160  	// change sdb's label.
   161  	sdb.Label = "fatty"
   162  	err = s.machine.SetMachineBlockDevices(sda, sdb, sdc)
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	wc.AssertOneChange()
   165  
   166  	// change sda's label and sdb's UUID at once.
   167  	sda.Label = "giggly"
   168  	sdb.UUID = "4c062658-6225-4f4b-96f3-debf00b964b4"
   169  	err = s.machine.SetMachineBlockDevices(sda, sdb, sdc)
   170  	c.Assert(err, jc.ErrorIsNil)
   171  	wc.AssertOneChange()
   172  
   173  	// drop sdc.
   174  	err = s.machine.SetMachineBlockDevices(sda, sdb)
   175  	c.Assert(err, jc.ErrorIsNil)
   176  	wc.AssertOneChange()
   177  
   178  	// add sdc again: should get a new name.
   179  	err = s.machine.SetMachineBlockDevices(sda, sdb, sdc)
   180  	c.Assert(err, jc.ErrorIsNil)
   181  	wc.AssertOneChange()
   182  }