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