github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/status_volume_test.go (about) 1 // Copyright 2012-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state_test 5 6 import ( 7 jc "github.com/juju/testing/checkers" 8 gc "gopkg.in/check.v1" 9 10 "github.com/juju/juju/state" 11 "github.com/juju/juju/status" 12 ) 13 14 type VolumeStatusSuite struct { 15 StorageStateSuiteBase 16 machine *state.Machine 17 volume state.Volume 18 } 19 20 var _ = gc.Suite(&VolumeStatusSuite{}) 21 22 func (s *VolumeStatusSuite) SetUpTest(c *gc.C) { 23 s.StorageStateSuiteBase.SetUpTest(c) 24 25 machine, err := s.State.AddOneMachine(state.MachineTemplate{ 26 Series: "quantal", 27 Jobs: []state.MachineJob{state.JobHostUnits}, 28 Volumes: []state.MachineVolumeParams{{ 29 Volume: state.VolumeParams{ 30 Pool: "environscoped", Size: 1024, 31 }, 32 }}, 33 }) 34 c.Assert(err, jc.ErrorIsNil) 35 36 volumeAttachments, err := machine.VolumeAttachments() 37 c.Assert(err, jc.ErrorIsNil) 38 c.Assert(volumeAttachments, gc.HasLen, 1) 39 40 volume, err := s.State.Volume(volumeAttachments[0].Volume()) 41 c.Assert(err, jc.ErrorIsNil) 42 43 s.machine = machine 44 s.volume = volume 45 } 46 47 func (s *VolumeStatusSuite) TestInitialStatus(c *gc.C) { 48 s.checkInitialStatus(c) 49 } 50 51 func (s *VolumeStatusSuite) checkInitialStatus(c *gc.C) { 52 statusInfo, err := s.volume.Status() 53 c.Check(err, jc.ErrorIsNil) 54 c.Check(statusInfo.Status, gc.Equals, status.StatusPending) 55 c.Check(statusInfo.Message, gc.Equals, "") 56 c.Check(statusInfo.Data, gc.HasLen, 0) 57 c.Check(statusInfo.Since, gc.NotNil) 58 } 59 60 func (s *VolumeStatusSuite) TestSetErrorStatusWithoutInfo(c *gc.C) { 61 err := s.volume.SetStatus(status.StatusError, "", nil) 62 c.Check(err, gc.ErrorMatches, `cannot set status "error" without info`) 63 64 s.checkInitialStatus(c) 65 } 66 67 func (s *VolumeStatusSuite) TestSetUnknownStatus(c *gc.C) { 68 err := s.volume.SetStatus(status.Status("vliegkat"), "orville", nil) 69 c.Assert(err, gc.ErrorMatches, `cannot set invalid status "vliegkat"`) 70 71 s.checkInitialStatus(c) 72 } 73 74 func (s *VolumeStatusSuite) TestSetOverwritesData(c *gc.C) { 75 err := s.volume.SetStatus(status.StatusAttaching, "blah", map[string]interface{}{ 76 "pew.pew": "zap", 77 }) 78 c.Check(err, jc.ErrorIsNil) 79 80 s.checkGetSetStatus(c, status.StatusAttaching) 81 } 82 83 func (s *VolumeStatusSuite) TestGetSetStatusAlive(c *gc.C) { 84 validStatuses := []status.Status{ 85 status.StatusAttaching, status.StatusAttached, status.StatusDetaching, 86 status.StatusDetached, status.StatusDestroying, 87 } 88 for _, status := range validStatuses { 89 s.checkGetSetStatus(c, status) 90 } 91 } 92 93 func (s *VolumeStatusSuite) checkGetSetStatus(c *gc.C, status status.Status) { 94 err := s.volume.SetStatus(status, "blah", map[string]interface{}{ 95 "$foo.bar.baz": map[string]interface{}{ 96 "pew.pew": "zap", 97 }, 98 }) 99 c.Check(err, jc.ErrorIsNil) 100 101 volume, err := s.State.Volume(s.volume.VolumeTag()) 102 c.Assert(err, jc.ErrorIsNil) 103 104 statusInfo, err := volume.Status() 105 c.Check(err, jc.ErrorIsNil) 106 c.Check(statusInfo.Status, gc.Equals, status) 107 c.Check(statusInfo.Message, gc.Equals, "blah") 108 c.Check(statusInfo.Data, jc.DeepEquals, map[string]interface{}{ 109 "$foo.bar.baz": map[string]interface{}{ 110 "pew.pew": "zap", 111 }, 112 }) 113 c.Check(statusInfo.Since, gc.NotNil) 114 } 115 116 func (s *VolumeStatusSuite) TestGetSetStatusDying(c *gc.C) { 117 err := s.State.DestroyVolume(s.volume.VolumeTag()) 118 c.Assert(err, jc.ErrorIsNil) 119 120 s.checkGetSetStatus(c, status.StatusAttaching) 121 } 122 123 func (s *VolumeStatusSuite) TestGetSetStatusDead(c *gc.C) { 124 err := s.State.DestroyVolume(s.volume.VolumeTag()) 125 c.Assert(err, jc.ErrorIsNil) 126 err = s.State.DetachVolume(s.machine.MachineTag(), s.volume.VolumeTag()) 127 c.Assert(err, jc.ErrorIsNil) 128 err = s.State.RemoveVolumeAttachment(s.machine.MachineTag(), s.volume.VolumeTag()) 129 c.Assert(err, jc.ErrorIsNil) 130 131 volume, err := s.State.Volume(s.volume.VolumeTag()) 132 c.Assert(err, jc.ErrorIsNil) 133 c.Assert(volume.Life(), gc.Equals, state.Dead) 134 135 // NOTE: it would be more technically correct to reject status updates 136 // while Dead, but it's easier and clearer, not to mention more efficient, 137 // to just depend on status doc existence. 138 s.checkGetSetStatus(c, status.StatusAttaching) 139 } 140 141 func (s *VolumeStatusSuite) TestGetSetStatusGone(c *gc.C) { 142 s.obliterateVolume(c, s.volume.VolumeTag()) 143 144 err := s.volume.SetStatus(status.StatusAttaching, "not really", nil) 145 c.Check(err, gc.ErrorMatches, `cannot set status: volume not found`) 146 147 statusInfo, err := s.volume.Status() 148 c.Check(err, gc.ErrorMatches, `cannot get status: volume not found`) 149 c.Check(statusInfo, gc.DeepEquals, status.StatusInfo{}) 150 } 151 152 func (s *VolumeStatusSuite) TestSetStatusPendingUnprovisioned(c *gc.C) { 153 err := s.volume.SetStatus(status.StatusPending, "still", nil) 154 c.Check(err, jc.ErrorIsNil) 155 } 156 157 func (s *VolumeStatusSuite) TestSetStatusPendingProvisioned(c *gc.C) { 158 err := s.State.SetVolumeInfo(s.volume.VolumeTag(), state.VolumeInfo{ 159 VolumeId: "vol-ume", 160 }) 161 c.Assert(err, jc.ErrorIsNil) 162 err = s.volume.SetStatus(status.StatusPending, "", nil) 163 c.Check(err, gc.ErrorMatches, `cannot set status "pending"`) 164 }