github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/payload/api/private/client/unitfacade_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package client_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  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/common"
    14  	"github.com/juju/juju/apiserver/params"
    15  	"github.com/juju/juju/payload"
    16  	"github.com/juju/juju/payload/api"
    17  	"github.com/juju/juju/payload/api/private/client"
    18  )
    19  
    20  type clientSuite struct {
    21  	testing.IsolationSuite
    22  
    23  	stub    *testing.Stub
    24  	facade  *stubFacade
    25  	payload params.Payload
    26  }
    27  
    28  var _ = gc.Suite(&clientSuite{})
    29  
    30  func (s *clientSuite) SetUpTest(c *gc.C) {
    31  	s.IsolationSuite.SetUpTest(c)
    32  
    33  	s.stub = &testing.Stub{}
    34  	s.facade = &stubFacade{stub: s.stub}
    35  	s.facade.methods = &unitMethods{}
    36  	s.payload = params.Payload{
    37  		Class:  "foobar",
    38  		Type:   "type",
    39  		ID:     "idfoo",
    40  		Status: payload.StateRunning,
    41  	}
    42  
    43  }
    44  
    45  func (s *clientSuite) TestTrack(c *gc.C) {
    46  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
    47  	numStubCalls := 0
    48  	s.facade.FacadeCallFn = func(name string, args, response interface{}) error {
    49  		numStubCalls++
    50  		c.Check(name, gc.Equals, "Track")
    51  
    52  		typedResponse, ok := response.(*params.PayloadResults)
    53  		c.Assert(ok, gc.Equals, true)
    54  		typedResponse.Results = []params.PayloadResult{{
    55  			Entity: params.Entity{
    56  				Tag: names.NewPayloadTag(id).String(),
    57  			},
    58  			Payload:  nil,
    59  			NotFound: false,
    60  			Error:    nil,
    61  		}}
    62  		return nil
    63  	}
    64  
    65  	pclient := client.NewUnitFacadeClient(s.facade)
    66  
    67  	pl, err := api.API2Payload(s.payload)
    68  	c.Assert(err, jc.ErrorIsNil)
    69  	results, err := pclient.Track(pl.Payload)
    70  	c.Assert(err, jc.ErrorIsNil)
    71  
    72  	c.Check(numStubCalls, gc.Equals, 1)
    73  	c.Check(results, jc.DeepEquals, []payload.Result{{
    74  		ID:       id,
    75  		Payload:  nil,
    76  		NotFound: false,
    77  		Error:    nil,
    78  	}})
    79  }
    80  
    81  func (s *clientSuite) TestList(c *gc.C) {
    82  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
    83  	responses := []interface{}{
    84  		&params.PayloadResults{
    85  			Results: []params.PayloadResult{{
    86  				Entity: params.Entity{
    87  					Tag: names.NewPayloadTag(id).String(),
    88  				},
    89  				Payload:  nil,
    90  				NotFound: false,
    91  				Error:    nil,
    92  			}},
    93  		},
    94  		&params.PayloadResults{
    95  			Results: []params.PayloadResult{{
    96  				Entity: params.Entity{
    97  					Tag: names.NewPayloadTag(id).String(),
    98  				},
    99  				Payload:  &s.payload,
   100  				NotFound: false,
   101  				Error:    nil,
   102  			}},
   103  		},
   104  	}
   105  	s.facade.responses = append(s.facade.responses, responses...)
   106  
   107  	pclient := client.NewUnitFacadeClient(s.facade)
   108  
   109  	results, err := pclient.List("idfoo/bar")
   110  	c.Assert(err, jc.ErrorIsNil)
   111  
   112  	expected, err := api.API2Payload(s.payload)
   113  	c.Assert(err, jc.ErrorIsNil)
   114  	c.Check(results, jc.DeepEquals, []payload.Result{{
   115  		ID:       id,
   116  		Payload:  &expected,
   117  		NotFound: false,
   118  		Error:    nil,
   119  	}})
   120  	s.stub.CheckCalls(c, []testing.StubCall{{
   121  		FuncName: "FacadeCall",
   122  		Args: []interface{}{
   123  			"LookUp",
   124  			&params.LookUpPayloadArgs{
   125  				Args: []params.LookUpPayloadArg{{
   126  					Name: "idfoo",
   127  					ID:   "bar",
   128  				}},
   129  			},
   130  			responses[0],
   131  		},
   132  	}, {
   133  		FuncName: "FacadeCall",
   134  		Args: []interface{}{
   135  			"List",
   136  			&params.Entities{
   137  				Entities: []params.Entity{{
   138  					Tag: names.NewPayloadTag(id).String(),
   139  				}},
   140  			},
   141  			responses[1],
   142  		},
   143  	}})
   144  }
   145  
   146  func (s *clientSuite) TestLookUpOkay(c *gc.C) {
   147  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   148  	response := &params.PayloadResults{
   149  		Results: []params.PayloadResult{{
   150  			Entity: params.Entity{
   151  				Tag: names.NewPayloadTag(id).String(),
   152  			},
   153  			Payload:  nil,
   154  			NotFound: false,
   155  			Error:    nil,
   156  		}},
   157  	}
   158  	s.facade.responses = append(s.facade.responses, response)
   159  
   160  	pclient := client.NewUnitFacadeClient(s.facade)
   161  	results, err := pclient.LookUp("idfoo/bar")
   162  	c.Assert(err, jc.ErrorIsNil)
   163  
   164  	c.Check(results, jc.DeepEquals, []payload.Result{{
   165  		ID:       id,
   166  		Payload:  nil,
   167  		NotFound: false,
   168  		Error:    nil,
   169  	}})
   170  	s.stub.CheckCalls(c, []testing.StubCall{{
   171  		FuncName: "FacadeCall",
   172  		Args: []interface{}{
   173  			"LookUp",
   174  			&params.LookUpPayloadArgs{
   175  				Args: []params.LookUpPayloadArg{{
   176  					Name: "idfoo",
   177  					ID:   "bar",
   178  				}},
   179  			},
   180  			response,
   181  		},
   182  	}})
   183  }
   184  
   185  func (s *clientSuite) TestLookUpMulti(c *gc.C) {
   186  	id1 := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   187  	id2 := "ce5bc2a7-65d8-4800-8199-a7c3356ab311"
   188  	response := &params.PayloadResults{
   189  		Results: []params.PayloadResult{{
   190  			Entity: params.Entity{
   191  				Tag: names.NewPayloadTag(id1).String(),
   192  			},
   193  			Payload:  nil,
   194  			NotFound: false,
   195  			Error:    nil,
   196  		}, {
   197  			Entity: params.Entity{
   198  				Tag: "",
   199  			},
   200  			Payload:  nil,
   201  			NotFound: true,
   202  			Error:    common.ServerError(errors.NotFoundf("payload")),
   203  		}, {
   204  			Entity: params.Entity{
   205  				Tag: names.NewPayloadTag(id2).String(),
   206  			},
   207  			Payload:  nil,
   208  			NotFound: false,
   209  			Error:    nil,
   210  		}},
   211  	}
   212  	s.facade.responses = append(s.facade.responses, response)
   213  
   214  	pclient := client.NewUnitFacadeClient(s.facade)
   215  	results, err := pclient.LookUp("idfoo/bar", "idbaz/bam", "spam/eggs")
   216  	c.Assert(err, jc.ErrorIsNil)
   217  
   218  	c.Assert(results, gc.HasLen, 3)
   219  	c.Assert(results[1].Error, gc.NotNil)
   220  	results[1].Error = nil
   221  	c.Check(results, jc.DeepEquals, []payload.Result{{
   222  		ID:       id1,
   223  		Payload:  nil,
   224  		NotFound: false,
   225  		Error:    nil,
   226  	}, {
   227  		ID:       "",
   228  		Payload:  nil,
   229  		NotFound: true,
   230  		Error:    nil,
   231  	}, {
   232  		ID:       id2,
   233  		Payload:  nil,
   234  		NotFound: false,
   235  		Error:    nil,
   236  	}})
   237  	s.stub.CheckCalls(c, []testing.StubCall{{
   238  		FuncName: "FacadeCall",
   239  		Args: []interface{}{
   240  			"LookUp",
   241  			&params.LookUpPayloadArgs{
   242  				Args: []params.LookUpPayloadArg{{
   243  					Name: "idfoo",
   244  					ID:   "bar",
   245  				}, {
   246  					Name: "idbaz",
   247  					ID:   "bam",
   248  				}, {
   249  					Name: "spam",
   250  					ID:   "eggs",
   251  				}},
   252  			},
   253  			response,
   254  		},
   255  	}})
   256  }
   257  
   258  func (s *clientSuite) TestSetStatus(c *gc.C) {
   259  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   260  	responses := []interface{}{
   261  		&params.PayloadResults{
   262  			Results: []params.PayloadResult{{
   263  				Entity: params.Entity{
   264  					Tag: names.NewPayloadTag(id).String(),
   265  				},
   266  				Payload:  nil,
   267  				NotFound: false,
   268  				Error:    nil,
   269  			}},
   270  		},
   271  		&params.PayloadResults{
   272  			Results: []params.PayloadResult{{
   273  				Entity: params.Entity{
   274  					Tag: names.NewPayloadTag(id).String(),
   275  				},
   276  				Payload:  nil,
   277  				NotFound: false,
   278  				Error:    nil,
   279  			}},
   280  		},
   281  	}
   282  	s.facade.responses = append(s.facade.responses, responses...)
   283  
   284  	pclient := client.NewUnitFacadeClient(s.facade)
   285  	results, err := pclient.SetStatus(payload.StateRunning, "idfoo/bar")
   286  	c.Assert(err, jc.ErrorIsNil)
   287  
   288  	c.Check(results, jc.DeepEquals, []payload.Result{{
   289  		ID:       id,
   290  		Payload:  nil,
   291  		NotFound: false,
   292  		Error:    nil,
   293  	}})
   294  	s.stub.CheckCalls(c, []testing.StubCall{{
   295  		FuncName: "FacadeCall",
   296  		Args: []interface{}{
   297  			"LookUp",
   298  			&params.LookUpPayloadArgs{
   299  				Args: []params.LookUpPayloadArg{{
   300  					Name: "idfoo",
   301  					ID:   "bar",
   302  				}},
   303  			},
   304  			responses[0],
   305  		},
   306  	}, {
   307  		FuncName: "FacadeCall",
   308  		Args: []interface{}{
   309  			"SetStatus",
   310  			&params.SetPayloadStatusArgs{
   311  				Args: []params.SetPayloadStatusArg{{
   312  					Entity: params.Entity{
   313  						Tag: names.NewPayloadTag(id).String(),
   314  					},
   315  					Status: "running",
   316  				}},
   317  			},
   318  			responses[1],
   319  		},
   320  	}})
   321  }
   322  
   323  func (s *clientSuite) TestUntrack(c *gc.C) {
   324  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   325  	responses := []interface{}{
   326  		&params.PayloadResults{
   327  			Results: []params.PayloadResult{{
   328  				Entity: params.Entity{
   329  					Tag: names.NewPayloadTag(id).String(),
   330  				},
   331  				Payload:  nil,
   332  				NotFound: false,
   333  				Error:    nil,
   334  			}},
   335  		},
   336  		&params.PayloadResults{
   337  			Results: []params.PayloadResult{{
   338  				Entity: params.Entity{
   339  					Tag: names.NewPayloadTag(id).String(),
   340  				},
   341  				Payload:  nil,
   342  				NotFound: false,
   343  				Error:    nil,
   344  			}},
   345  		},
   346  	}
   347  	s.facade.responses = append(s.facade.responses, responses...)
   348  
   349  	pclient := client.NewUnitFacadeClient(s.facade)
   350  	results, err := pclient.Untrack("idfoo/bar")
   351  	c.Assert(err, jc.ErrorIsNil)
   352  
   353  	c.Check(results, jc.DeepEquals, []payload.Result{{
   354  		ID:       id,
   355  		Payload:  nil,
   356  		NotFound: false,
   357  		Error:    nil,
   358  	}})
   359  	s.stub.CheckCalls(c, []testing.StubCall{{
   360  		FuncName: "FacadeCall",
   361  		Args: []interface{}{
   362  			"LookUp",
   363  			&params.LookUpPayloadArgs{
   364  				Args: []params.LookUpPayloadArg{{
   365  					Name: "idfoo",
   366  					ID:   "bar",
   367  				}},
   368  			},
   369  			responses[0],
   370  		},
   371  	}, {
   372  		FuncName: "FacadeCall",
   373  		Args: []interface{}{
   374  			"Untrack",
   375  			&params.Entities{
   376  				Entities: []params.Entity{{
   377  					Tag: names.NewPayloadTag(id).String(),
   378  				}},
   379  			},
   380  			responses[1],
   381  		},
   382  	}})
   383  }
   384  
   385  type apiMethods interface {
   386  	Handler(name string) (func(target, response interface{}), bool)
   387  }
   388  
   389  type stubFacade struct {
   390  	stub      *testing.Stub
   391  	responses []interface{}
   392  	methods   apiMethods
   393  
   394  	// TODO(ericsnow) Eliminate this.
   395  	FacadeCallFn func(name string, params, response interface{}) error
   396  }
   397  
   398  func (s *stubFacade) nextResponse() interface{} {
   399  	if len(s.responses) == 0 {
   400  		return nil
   401  	}
   402  	resp := s.responses[0]
   403  	s.responses = s.responses[1:]
   404  	return resp
   405  }
   406  
   407  func (s *stubFacade) FacadeCall(request string, params, response interface{}) error {
   408  	s.stub.AddCall("FacadeCall", request, params, response)
   409  	resp := s.nextResponse()
   410  	if err := s.stub.NextErr(); err != nil {
   411  		return errors.Trace(err)
   412  	}
   413  
   414  	if s.FacadeCallFn != nil {
   415  		return s.FacadeCallFn(request, params, response)
   416  	}
   417  
   418  	if resp == nil {
   419  		// TODO(ericsnow) Fail?
   420  		return nil
   421  	}
   422  	handler, ok := s.methods.Handler(request)
   423  	if !ok {
   424  		return errors.Errorf("unknown request %q", request)
   425  	}
   426  	handler(response, resp)
   427  	return nil
   428  }
   429  
   430  func (s *stubFacade) Close() error {
   431  	s.stub.AddCall("Close")
   432  	if err := s.stub.NextErr(); err != nil {
   433  		return errors.Trace(err)
   434  	}
   435  
   436  	return nil
   437  }
   438  
   439  type unitMethods struct{}
   440  
   441  func (m unitMethods) Handler(name string) (func(target, response interface{}), bool) {
   442  	switch name {
   443  	case "List", "LookUp", "SetStatus", "Untrack":
   444  		return m.generic, true
   445  	default:
   446  		return nil, false
   447  	}
   448  }
   449  
   450  func (unitMethods) generic(target, response interface{}) {
   451  	typedTarget := target.(*params.PayloadResults)
   452  	typedResponse := response.(*params.PayloadResults)
   453  	*typedTarget = *typedResponse
   454  }