github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/api/singular/api_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package singular_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/testing"
    11  	jc "github.com/juju/testing/checkers"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  
    15  	"github.com/juju/juju/api/base"
    16  	basetesting "github.com/juju/juju/api/base/testing"
    17  	"github.com/juju/juju/api/singular"
    18  	"github.com/juju/juju/apiserver/common"
    19  	"github.com/juju/juju/apiserver/params"
    20  	"github.com/juju/juju/core/lease"
    21  )
    22  
    23  type APISuite struct {
    24  	testing.IsolationSuite
    25  }
    26  
    27  var _ = gc.Suite(&APISuite{})
    28  
    29  var machine123 = names.NewMachineTag("123")
    30  
    31  func (s *APISuite) TestBadControllerTag(c *gc.C) {
    32  	apiCaller := apiCaller(c, nil, nil)
    33  	badTag := names.NewMachineTag("")
    34  	api, err := singular.NewAPI(apiCaller, badTag)
    35  	c.Check(api, gc.IsNil)
    36  	c.Check(err, jc.Satisfies, errors.IsNotValid)
    37  	c.Check(err, gc.ErrorMatches, "controller tag not valid")
    38  }
    39  
    40  func (s *APISuite) TestControllerOnlyAPI(c *gc.C) {
    41  	api, err := singular.NewAPI(mockAPICaller{}, machine123)
    42  	c.Check(api, gc.IsNil)
    43  	c.Check(err, gc.ErrorMatches, `cannot use singular API on controller-only connection`)
    44  }
    45  
    46  func (s *APISuite) TestNoCalls(c *gc.C) {
    47  	stub := &testing.Stub{}
    48  	apiCaller := apiCaller(c, nil, nil)
    49  	_, err := singular.NewAPI(apiCaller, machine123)
    50  	c.Check(err, jc.ErrorIsNil)
    51  	stub.CheckCallNames(c)
    52  }
    53  
    54  func (s *APISuite) TestClaimSuccess(c *gc.C) {
    55  	stub := &testing.Stub{}
    56  	apiCaller := apiCaller(c, stub, func(result *params.ErrorResults) error {
    57  		result.Results = []params.ErrorResult{{}}
    58  		return nil
    59  	})
    60  	api, err := singular.NewAPI(apiCaller, machine123)
    61  	c.Assert(err, jc.ErrorIsNil)
    62  
    63  	err = api.Claim(time.Minute)
    64  	c.Check(err, jc.ErrorIsNil)
    65  	checkCall(c, stub, "Claim", params.SingularClaims{
    66  		Claims: []params.SingularClaim{{
    67  			ModelTag:      "model-deadbeef-0bad-400d-8000-4b1d0d06f00d",
    68  			ControllerTag: "machine-123",
    69  			Duration:      time.Minute,
    70  		}},
    71  	})
    72  }
    73  
    74  func (s *APISuite) TestClaimDenied(c *gc.C) {
    75  	stub := &testing.Stub{}
    76  	apiCaller := apiCaller(c, stub, func(result *params.ErrorResults) error {
    77  		result.Results = []params.ErrorResult{{
    78  			Error: common.ServerError(lease.ErrClaimDenied),
    79  		}}
    80  		return nil
    81  	})
    82  	api, err := singular.NewAPI(apiCaller, machine123)
    83  	c.Assert(err, jc.ErrorIsNil)
    84  
    85  	err = api.Claim(time.Hour)
    86  	c.Check(err, gc.Equals, lease.ErrClaimDenied)
    87  	checkCall(c, stub, "Claim", params.SingularClaims{
    88  		Claims: []params.SingularClaim{{
    89  			ModelTag:      "model-deadbeef-0bad-400d-8000-4b1d0d06f00d",
    90  			ControllerTag: "machine-123",
    91  			Duration:      time.Hour,
    92  		}},
    93  	})
    94  }
    95  
    96  func (s *APISuite) TestClaimError(c *gc.C) {
    97  	stub := &testing.Stub{}
    98  	apiCaller := apiCaller(c, stub, func(result *params.ErrorResults) error {
    99  		result.Results = []params.ErrorResult{{
   100  			Error: common.ServerError(errors.New("zap pow splat oof")),
   101  		}}
   102  		return nil
   103  	})
   104  	api, err := singular.NewAPI(apiCaller, machine123)
   105  	c.Assert(err, jc.ErrorIsNil)
   106  
   107  	err = api.Claim(time.Second)
   108  	c.Check(err, gc.ErrorMatches, "zap pow splat oof")
   109  	checkCall(c, stub, "Claim", params.SingularClaims{
   110  		Claims: []params.SingularClaim{{
   111  			ModelTag:      "model-deadbeef-0bad-400d-8000-4b1d0d06f00d",
   112  			ControllerTag: "machine-123",
   113  			Duration:      time.Second,
   114  		}},
   115  	})
   116  }
   117  
   118  func (s *APISuite) TestWaitSuccess(c *gc.C) {
   119  	stub := &testing.Stub{}
   120  	apiCaller := apiCaller(c, stub, func(result *params.ErrorResults) error {
   121  		result.Results = []params.ErrorResult{{}}
   122  		return nil
   123  	})
   124  	api, err := singular.NewAPI(apiCaller, machine123)
   125  	c.Assert(err, jc.ErrorIsNil)
   126  
   127  	err = api.Wait()
   128  	c.Check(err, jc.ErrorIsNil)
   129  	checkCall(c, stub, "Wait", params.Entities{
   130  		Entities: []params.Entity{{
   131  			Tag: "model-deadbeef-0bad-400d-8000-4b1d0d06f00d",
   132  		}},
   133  	})
   134  }
   135  
   136  func (s *APISuite) TestWaitError(c *gc.C) {
   137  	stub := &testing.Stub{}
   138  	apiCaller := apiCaller(c, stub, func(result *params.ErrorResults) error {
   139  		result.Results = []params.ErrorResult{{
   140  			Error: common.ServerError(errors.New("crunch squelch")),
   141  		}}
   142  		return nil
   143  	})
   144  	api, err := singular.NewAPI(apiCaller, machine123)
   145  	c.Assert(err, jc.ErrorIsNil)
   146  
   147  	err = api.Wait()
   148  	c.Check(err, gc.ErrorMatches, "crunch squelch")
   149  	checkCall(c, stub, "Wait", params.Entities{
   150  		Entities: []params.Entity{{
   151  			Tag: "model-deadbeef-0bad-400d-8000-4b1d0d06f00d",
   152  		}},
   153  	})
   154  }
   155  
   156  type setResultFunc func(result *params.ErrorResults) error
   157  
   158  func apiCaller(c *gc.C, stub *testing.Stub, setResult setResultFunc) base.APICaller {
   159  	return basetesting.APICallerFunc(
   160  		func(objType string,
   161  			version int,
   162  			id, request string,
   163  			args, response interface{},
   164  		) error {
   165  			stub.AddCall(objType, version, id, request, args)
   166  			result, ok := response.(*params.ErrorResults)
   167  			c.Assert(ok, jc.IsTrue)
   168  			return setResult(result)
   169  		},
   170  	)
   171  }
   172  
   173  func checkCall(c *gc.C, stub *testing.Stub, method string, args interface{}) {
   174  	stub.CheckCalls(c, []testing.StubCall{{
   175  		FuncName: "Singular",
   176  		Args:     []interface{}{0, "", method, args},
   177  	}})
   178  }
   179  
   180  type mockAPICaller struct {
   181  	base.APICaller
   182  }
   183  
   184  func (mockAPICaller) ModelTag() (names.ModelTag, bool) {
   185  	return names.ModelTag{}, false
   186  }