github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/api/uniter/leadership_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package uniter_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/testing"
     9  	jc "github.com/juju/testing/checkers"
    10  	gc "gopkg.in/check.v1"
    11  
    12  	"github.com/juju/juju/api/uniter"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/watcher"
    15  )
    16  
    17  type leadershipSuite struct {
    18  	testing.IsolationSuite
    19  	stub       *testing.Stub
    20  	responders []responder
    21  	lsa        *uniter.LeadershipSettingsAccessor
    22  }
    23  
    24  var _ = gc.Suite(&leadershipSuite{})
    25  
    26  type responder func(interface{})
    27  
    28  var mockWatcher = struct{ watcher.NotifyWatcher }{}
    29  
    30  func (s *leadershipSuite) SetUpTest(c *gc.C) {
    31  	s.IsolationSuite.SetUpTest(c)
    32  	s.lsa = uniter.NewLeadershipSettingsAccessor(
    33  		func(request string, params, response interface{}) error {
    34  			s.stub.AddCall("FacadeCall", request, params)
    35  			s.nextResponse(response)
    36  			return s.stub.NextErr()
    37  		},
    38  		func(result params.NotifyWatchResult) watcher.NotifyWatcher {
    39  			s.stub.AddCall("NewNotifyWatcher", result)
    40  			return mockWatcher
    41  		},
    42  		func(name string) error {
    43  			s.stub.AddCall("CheckApiVersion", name)
    44  			return s.stub.NextErr()
    45  		},
    46  	)
    47  }
    48  
    49  func (s *leadershipSuite) nextResponse(response interface{}) {
    50  	var responder responder
    51  	responder, s.responders = s.responders[0], s.responders[1:]
    52  	if responder != nil {
    53  		responder(response)
    54  	}
    55  }
    56  
    57  func (s *leadershipSuite) addResponder(responder responder) {
    58  	s.responders = append(s.responders, responder)
    59  }
    60  
    61  func (s *leadershipSuite) CheckCalls(c *gc.C, calls []testing.StubCall, f func()) {
    62  	s.stub = &testing.Stub{}
    63  	s.responders = nil
    64  	f()
    65  	s.stub.CheckCalls(c, calls)
    66  }
    67  
    68  func (s *leadershipSuite) TestReadBadVersion(c *gc.C) {
    69  	s.CheckCalls(c, []testing.StubCall{{
    70  		FuncName: "CheckApiVersion",
    71  		Args:     []interface{}{"Read"},
    72  	}}, func() {
    73  		s.stub.SetErrors(errors.New("splat"))
    74  		settings, err := s.lsa.Read("foobar")
    75  		c.Check(err, gc.ErrorMatches, "cannot access leadership api: splat")
    76  		c.Check(settings, gc.IsNil)
    77  	})
    78  }
    79  
    80  func (s *leadershipSuite) expectReadCalls() []testing.StubCall {
    81  	return []testing.StubCall{{
    82  		FuncName: "CheckApiVersion",
    83  		Args:     []interface{}{"Read"},
    84  	}, {
    85  		FuncName: "FacadeCall",
    86  		Args: []interface{}{
    87  			"Read",
    88  			params.Entities{Entities: []params.Entity{{
    89  				Tag: "application-foobar",
    90  			}}},
    91  		},
    92  	}}
    93  }
    94  
    95  func (s *leadershipSuite) TestReadSuccess(c *gc.C) {
    96  	s.CheckCalls(c, s.expectReadCalls(), func() {
    97  		s.addResponder(func(response interface{}) {
    98  			typed, ok := response.(*params.GetLeadershipSettingsBulkResults)
    99  			c.Assert(ok, jc.IsTrue)
   100  			typed.Results = []params.GetLeadershipSettingsResult{{
   101  				Settings: params.Settings{
   102  					"foo": "bar",
   103  					"baz": "qux",
   104  				},
   105  			}}
   106  		})
   107  		settings, err := s.lsa.Read("foobar")
   108  		c.Check(err, jc.ErrorIsNil)
   109  		c.Check(settings, jc.DeepEquals, map[string]string{
   110  			"foo": "bar",
   111  			"baz": "qux",
   112  		})
   113  	})
   114  }
   115  
   116  func (s *leadershipSuite) TestReadFailure(c *gc.C) {
   117  	s.CheckCalls(c, s.expectReadCalls(), func() {
   118  		s.addResponder(func(response interface{}) {
   119  			typed, ok := response.(*params.GetLeadershipSettingsBulkResults)
   120  			c.Assert(ok, jc.IsTrue)
   121  			typed.Results = []params.GetLeadershipSettingsResult{{
   122  				Error: &params.Error{Message: "pow"},
   123  			}}
   124  		})
   125  		settings, err := s.lsa.Read("foobar")
   126  		c.Check(err, gc.ErrorMatches, "failed to read leadership settings: pow")
   127  		c.Check(settings, gc.IsNil)
   128  	})
   129  }
   130  
   131  func (s *leadershipSuite) TestReadError(c *gc.C) {
   132  	s.CheckCalls(c, s.expectReadCalls(), func() {
   133  		s.addResponder(nil)
   134  		s.stub.SetErrors(nil, errors.New("blart"))
   135  		settings, err := s.lsa.Read("foobar")
   136  		c.Check(err, gc.ErrorMatches, "failed to call leadership api: blart")
   137  		c.Check(settings, gc.IsNil)
   138  	})
   139  }
   140  
   141  func (s *leadershipSuite) TestReadNoResults(c *gc.C) {
   142  	s.CheckCalls(c, s.expectReadCalls(), func() {
   143  		s.addResponder(nil)
   144  		settings, err := s.lsa.Read("foobar")
   145  		c.Check(err, gc.ErrorMatches, "expected 1 result from leadership api, got 0")
   146  		c.Check(settings, gc.IsNil)
   147  	})
   148  }
   149  
   150  func (s *leadershipSuite) TestMergeBadVersion(c *gc.C) {
   151  	s.CheckCalls(c, []testing.StubCall{{
   152  		FuncName: "CheckApiVersion",
   153  		Args:     []interface{}{"Merge"},
   154  	}}, func() {
   155  		s.stub.SetErrors(errors.New("splat"))
   156  		err := s.lsa.Merge("foobar", map[string]string{"foo": "bar"})
   157  		c.Check(err, gc.ErrorMatches, "cannot access leadership api: splat")
   158  	})
   159  }
   160  
   161  func (s *leadershipSuite) expectMergeCalls() []testing.StubCall {
   162  	return []testing.StubCall{{
   163  		FuncName: "CheckApiVersion",
   164  		Args:     []interface{}{"Merge"},
   165  	}, {
   166  		FuncName: "FacadeCall",
   167  		Args: []interface{}{
   168  			"Merge",
   169  			params.MergeLeadershipSettingsBulkParams{
   170  				Params: []params.MergeLeadershipSettingsParam{{
   171  					ApplicationTag: "application-foobar",
   172  					Settings: map[string]string{
   173  						"foo": "bar",
   174  						"baz": "qux",
   175  					},
   176  				}},
   177  			},
   178  		},
   179  	}}
   180  }
   181  
   182  func (s *leadershipSuite) TestMergeSuccess(c *gc.C) {
   183  	s.CheckCalls(c, s.expectMergeCalls(), func() {
   184  		s.addResponder(func(response interface{}) {
   185  			typed, ok := response.(*params.ErrorResults)
   186  			c.Assert(ok, jc.IsTrue)
   187  			typed.Results = []params.ErrorResult{{
   188  				Error: nil,
   189  			}}
   190  		})
   191  		err := s.lsa.Merge("foobar", map[string]string{
   192  			"foo": "bar",
   193  			"baz": "qux",
   194  		})
   195  		c.Check(err, jc.ErrorIsNil)
   196  	})
   197  }
   198  
   199  func (s *leadershipSuite) TestMergeFailure(c *gc.C) {
   200  	s.CheckCalls(c, s.expectMergeCalls(), func() {
   201  		s.addResponder(func(response interface{}) {
   202  			typed, ok := response.(*params.ErrorResults)
   203  			c.Assert(ok, jc.IsTrue)
   204  			typed.Results = []params.ErrorResult{{
   205  				Error: &params.Error{Message: "zap"},
   206  			}}
   207  		})
   208  		err := s.lsa.Merge("foobar", map[string]string{
   209  			"foo": "bar",
   210  			"baz": "qux",
   211  		})
   212  		c.Check(err, gc.ErrorMatches, "failed to merge leadership settings: zap")
   213  	})
   214  }
   215  
   216  func (s *leadershipSuite) TestMergeError(c *gc.C) {
   217  	s.CheckCalls(c, s.expectMergeCalls(), func() {
   218  		s.addResponder(nil)
   219  		s.stub.SetErrors(nil, errors.New("dink"))
   220  		err := s.lsa.Merge("foobar", map[string]string{
   221  			"foo": "bar",
   222  			"baz": "qux",
   223  		})
   224  		c.Check(err, gc.ErrorMatches, "failed to call leadership api: dink")
   225  	})
   226  }
   227  
   228  func (s *leadershipSuite) TestMergeNoResults(c *gc.C) {
   229  	s.CheckCalls(c, s.expectMergeCalls(), func() {
   230  		s.addResponder(nil)
   231  		err := s.lsa.Merge("foobar", map[string]string{
   232  			"foo": "bar",
   233  			"baz": "qux",
   234  		})
   235  		c.Check(err, gc.ErrorMatches, "expected 1 result from leadership api, got 0")
   236  	})
   237  }
   238  
   239  func (s *leadershipSuite) TestWatchBadVersion(c *gc.C) {
   240  	s.CheckCalls(c, []testing.StubCall{{
   241  		FuncName: "CheckApiVersion",
   242  		Args:     []interface{}{"WatchLeadershipSettings"},
   243  	}}, func() {
   244  		s.stub.SetErrors(errors.New("splat"))
   245  		watcher, err := s.lsa.WatchLeadershipSettings("foobar")
   246  		c.Check(err, gc.ErrorMatches, "cannot access leadership api: splat")
   247  		c.Check(watcher, gc.IsNil)
   248  	})
   249  }
   250  
   251  func (s *leadershipSuite) expectWatchCalls() []testing.StubCall {
   252  	return []testing.StubCall{{
   253  		FuncName: "CheckApiVersion",
   254  		Args:     []interface{}{"WatchLeadershipSettings"},
   255  	}, {
   256  		FuncName: "FacadeCall",
   257  		Args: []interface{}{
   258  			"WatchLeadershipSettings",
   259  			params.Entities{Entities: []params.Entity{{
   260  				Tag: "application-foobar",
   261  			}}},
   262  		},
   263  	}}
   264  }
   265  
   266  func (s *leadershipSuite) TestWatchSuccess(c *gc.C) {
   267  	expectCalls := append(s.expectWatchCalls(), testing.StubCall{
   268  		FuncName: "NewNotifyWatcher",
   269  		Args: []interface{}{
   270  			params.NotifyWatchResult{
   271  				NotifyWatcherId: "123",
   272  			},
   273  		},
   274  	})
   275  	s.CheckCalls(c, expectCalls, func() {
   276  		s.addResponder(func(response interface{}) {
   277  			typed, ok := response.(*params.NotifyWatchResults)
   278  			c.Assert(ok, jc.IsTrue)
   279  			typed.Results = []params.NotifyWatchResult{{
   280  				NotifyWatcherId: "123",
   281  			}}
   282  		})
   283  		watcher, err := s.lsa.WatchLeadershipSettings("foobar")
   284  		c.Check(err, jc.ErrorIsNil)
   285  		c.Check(watcher, gc.Equals, mockWatcher)
   286  	})
   287  }
   288  
   289  func (s *leadershipSuite) TestWatchFailure(c *gc.C) {
   290  	s.CheckCalls(c, s.expectWatchCalls(), func() {
   291  		s.addResponder(func(response interface{}) {
   292  			typed, ok := response.(*params.NotifyWatchResults)
   293  			c.Assert(ok, jc.IsTrue)
   294  			typed.Results = []params.NotifyWatchResult{{
   295  				Error: &params.Error{Message: "blah"},
   296  			}}
   297  		})
   298  		watcher, err := s.lsa.WatchLeadershipSettings("foobar")
   299  		c.Check(err, gc.ErrorMatches, "failed to watch leadership settings: blah")
   300  		c.Check(watcher, gc.IsNil)
   301  	})
   302  }
   303  
   304  func (s *leadershipSuite) TestWatchError(c *gc.C) {
   305  	s.CheckCalls(c, s.expectWatchCalls(), func() {
   306  		s.addResponder(nil)
   307  		s.stub.SetErrors(nil, errors.New("snerk"))
   308  		watcher, err := s.lsa.WatchLeadershipSettings("foobar")
   309  		c.Check(err, gc.ErrorMatches, "failed to call leadership api: snerk")
   310  		c.Check(watcher, gc.IsNil)
   311  	})
   312  }
   313  
   314  func (s *leadershipSuite) TestWatchNoResults(c *gc.C) {
   315  	s.CheckCalls(c, s.expectWatchCalls(), func() {
   316  		s.addResponder(nil)
   317  		watcher, err := s.lsa.WatchLeadershipSettings("foobar")
   318  		c.Check(err, gc.ErrorMatches, "expected 1 result from leadership api, got 0")
   319  		c.Check(watcher, gc.IsNil)
   320  	})
   321  }