github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/status_unit_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  	"time"
     8  
     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/status"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  type UnitStatusSuite struct {
    18  	ConnSuite
    19  	unit *state.Unit
    20  }
    21  
    22  var _ = gc.Suite(&UnitStatusSuite{})
    23  
    24  func (s *UnitStatusSuite) SetUpTest(c *gc.C) {
    25  	s.ConnSuite.SetUpTest(c)
    26  	s.unit = s.Factory.MakeUnit(c, nil)
    27  }
    28  
    29  func (s *UnitStatusSuite) TestInitialStatus(c *gc.C) {
    30  	s.checkInitialStatus(c)
    31  }
    32  
    33  func (s *UnitStatusSuite) checkInitialStatus(c *gc.C) {
    34  	statusInfo, err := s.unit.Status()
    35  	c.Check(err, jc.ErrorIsNil)
    36  	checkInitialWorkloadStatus(c, statusInfo)
    37  }
    38  
    39  func (s *UnitStatusSuite) TestSetUnknownStatus(c *gc.C) {
    40  	now := testing.ZeroTime()
    41  	sInfo := status.StatusInfo{
    42  		Status:  status.Status("vliegkat"),
    43  		Message: "orville",
    44  		Since:   &now,
    45  	}
    46  	err := s.unit.SetStatus(sInfo)
    47  	c.Check(err, gc.ErrorMatches, `cannot set invalid status "vliegkat"`)
    48  
    49  	s.checkInitialStatus(c)
    50  }
    51  
    52  func (s *UnitStatusSuite) TestSetOverwritesData(c *gc.C) {
    53  	now := testing.ZeroTime()
    54  	sInfo := status.StatusInfo{
    55  		Status:  status.Active,
    56  		Message: "healthy",
    57  		Data: map[string]interface{}{
    58  			"pew.pew": "zap",
    59  		},
    60  		Since: &now,
    61  	}
    62  	err := s.unit.SetStatus(sInfo)
    63  	c.Check(err, jc.ErrorIsNil)
    64  
    65  	s.checkGetSetStatus(c)
    66  }
    67  
    68  func (s *UnitStatusSuite) TestGetSetStatusAlive(c *gc.C) {
    69  	s.checkGetSetStatus(c)
    70  }
    71  
    72  func (s *UnitStatusSuite) checkGetSetStatus(c *gc.C) {
    73  	now := testing.ZeroTime()
    74  	sInfo := status.StatusInfo{
    75  		Status:  status.Active,
    76  		Message: "healthy",
    77  		Data: map[string]interface{}{
    78  			"$ping": map[string]interface{}{
    79  				"foo.bar": 123,
    80  			}},
    81  		Since: &now,
    82  	}
    83  	err := s.unit.SetStatus(sInfo)
    84  	c.Check(err, jc.ErrorIsNil)
    85  
    86  	unit, err := s.State.Unit(s.unit.Name())
    87  	c.Assert(err, jc.ErrorIsNil)
    88  
    89  	statusInfo, err := unit.Status()
    90  	c.Check(err, jc.ErrorIsNil)
    91  	c.Check(statusInfo.Status, gc.Equals, status.Active)
    92  	c.Check(statusInfo.Message, gc.Equals, "healthy")
    93  	c.Check(statusInfo.Data, jc.DeepEquals, map[string]interface{}{
    94  		"$ping": map[string]interface{}{
    95  			"foo.bar": 123,
    96  		},
    97  	})
    98  	c.Check(statusInfo.Since, gc.NotNil)
    99  }
   100  
   101  func (s *UnitStatusSuite) TestGetSetStatusDying(c *gc.C) {
   102  	preventUnitDestroyRemove(c, s.unit)
   103  	err := s.unit.Destroy()
   104  	c.Assert(err, jc.ErrorIsNil)
   105  
   106  	s.checkGetSetStatus(c)
   107  }
   108  
   109  func (s *UnitStatusSuite) TestGetSetStatusDead(c *gc.C) {
   110  	preventUnitDestroyRemove(c, s.unit)
   111  	err := s.unit.Destroy()
   112  	c.Assert(err, jc.ErrorIsNil)
   113  	err = s.unit.EnsureDead()
   114  	c.Assert(err, jc.ErrorIsNil)
   115  
   116  	// NOTE: it would be more technically correct to reject status updates
   117  	// while Dead, but it's easier and clearer, not to mention more efficient,
   118  	// to just depend on status doc existence.
   119  	s.checkGetSetStatus(c)
   120  }
   121  
   122  func (s *UnitStatusSuite) TestGetSetStatusGone(c *gc.C) {
   123  	err := s.unit.Destroy()
   124  	c.Assert(err, jc.ErrorIsNil)
   125  
   126  	now := testing.ZeroTime()
   127  	sInfo := status.StatusInfo{
   128  		Status:  status.Active,
   129  		Message: "not really",
   130  		Since:   &now,
   131  	}
   132  	err = s.unit.SetStatus(sInfo)
   133  	c.Check(err, gc.ErrorMatches, `cannot set status: unit not found`)
   134  
   135  	statusInfo, err := s.unit.Status()
   136  	c.Check(err, gc.ErrorMatches, `cannot get status: unit not found`)
   137  	c.Check(statusInfo, gc.DeepEquals, status.StatusInfo{})
   138  }
   139  
   140  func (s *UnitStatusSuite) TestSetUnitStatusSince(c *gc.C) {
   141  	now := testing.ZeroTime()
   142  	sInfo := status.StatusInfo{
   143  		Status:  status.Maintenance,
   144  		Message: "",
   145  		Since:   &now,
   146  	}
   147  	err := s.unit.SetStatus(sInfo)
   148  	c.Assert(err, jc.ErrorIsNil)
   149  	statusInfo, err := s.unit.Status()
   150  	c.Assert(err, jc.ErrorIsNil)
   151  	firstTime := statusInfo.Since
   152  	c.Assert(firstTime, gc.NotNil)
   153  	c.Assert(timeBeforeOrEqual(now, *firstTime), jc.IsTrue)
   154  
   155  	// Setting the same status a second time also updates the timestamp.
   156  	now = now.Add(1 * time.Second)
   157  	sInfo = status.StatusInfo{
   158  		Status:  status.Maintenance,
   159  		Message: "",
   160  		Since:   &now,
   161  	}
   162  	err = s.unit.SetStatus(sInfo)
   163  	c.Assert(err, jc.ErrorIsNil)
   164  	statusInfo, err = s.unit.Status()
   165  	c.Assert(err, jc.ErrorIsNil)
   166  	c.Assert(timeBeforeOrEqual(*firstTime, *statusInfo.Since), jc.IsTrue)
   167  }
   168  
   169  func (s *UnitStatusSuite) TestStatusHistoryInitial(c *gc.C) {
   170  	history, err := s.unit.StatusHistory(status.StatusHistoryFilter{Size: 1})
   171  	c.Check(err, jc.ErrorIsNil)
   172  	c.Assert(history, gc.HasLen, 1)
   173  
   174  	checkInitialWorkloadStatus(c, history[0])
   175  }
   176  
   177  func (s *UnitStatusSuite) TestStatusHistoryShort(c *gc.C) {
   178  	primeUnitStatusHistory(c, s.unit, 5, 0)
   179  
   180  	history, err := s.unit.StatusHistory(status.StatusHistoryFilter{Size: 10})
   181  	c.Check(err, jc.ErrorIsNil)
   182  	c.Assert(history, gc.HasLen, 6)
   183  
   184  	checkInitialWorkloadStatus(c, history[5])
   185  	history = history[:5]
   186  	for i, statusInfo := range history {
   187  		checkPrimedUnitStatus(c, statusInfo, 4-i, 0)
   188  	}
   189  }
   190  
   191  func (s *UnitStatusSuite) TestStatusHistoryLong(c *gc.C) {
   192  	primeUnitStatusHistory(c, s.unit, 25, 0)
   193  
   194  	history, err := s.unit.StatusHistory(status.StatusHistoryFilter{Size: 15})
   195  	c.Check(err, jc.ErrorIsNil)
   196  	c.Check(history, gc.HasLen, 15)
   197  	for i, statusInfo := range history {
   198  		checkPrimedUnitStatus(c, statusInfo, 24-i, 0)
   199  	}
   200  }