github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/payload/api/private/server/unitfacade_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package server
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  	"gopkg.in/juju/charm.v6-unstable"
    13  
    14  	"github.com/juju/juju/apiserver/common"
    15  	"github.com/juju/juju/apiserver/params"
    16  	"github.com/juju/juju/payload"
    17  	"github.com/juju/juju/payload/api"
    18  	internal "github.com/juju/juju/payload/api/private"
    19  )
    20  
    21  var _ = gc.Suite(&suite{})
    22  
    23  type suite struct {
    24  	testing.IsolationSuite
    25  
    26  	stub  *testing.Stub
    27  	state *FakeState
    28  }
    29  
    30  func (s *suite) SetUpTest(c *gc.C) {
    31  	s.IsolationSuite.SetUpTest(c)
    32  
    33  	s.stub = &testing.Stub{}
    34  	s.state = &FakeState{stub: s.stub}
    35  }
    36  
    37  func (s *suite) TestTrack(c *gc.C) {
    38  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
    39  	s.state.stateIDs = []string{id}
    40  
    41  	a := UnitFacade{s.state}
    42  
    43  	args := internal.TrackArgs{
    44  		Payloads: []api.Payload{{
    45  			Class:  "idfoo",
    46  			Type:   "type",
    47  			ID:     "bar",
    48  			Status: payload.StateRunning,
    49  		}},
    50  	}
    51  
    52  	res, err := a.Track(args)
    53  	c.Assert(err, jc.ErrorIsNil)
    54  
    55  	c.Check(res, jc.DeepEquals, internal.PayloadResults{
    56  		Results: []internal.PayloadResult{{
    57  			Entity: params.Entity{
    58  				Tag: names.NewPayloadTag(id).String(),
    59  			},
    60  			Payload:  nil,
    61  			NotFound: false,
    62  			Error:    nil,
    63  		}},
    64  	})
    65  
    66  	c.Check(s.state.payload, jc.DeepEquals, payload.Payload{
    67  		PayloadClass: charm.PayloadClass{
    68  			Name: "idfoo",
    69  			Type: "type",
    70  		},
    71  		Status: payload.StateRunning,
    72  		Labels: []string{},
    73  		ID:     "bar",
    74  	})
    75  }
    76  
    77  func (s *suite) TestListOne(c *gc.C) {
    78  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
    79  	pl := payload.Payload{
    80  		PayloadClass: charm.PayloadClass{
    81  			Name: "foobar",
    82  			Type: "type",
    83  		},
    84  		ID:     "idfoo",
    85  		Status: payload.StateRunning,
    86  		Unit:   "a-service/0",
    87  	}
    88  	s.state.payloads = []payload.Result{{
    89  		ID: id,
    90  		Payload: &payload.FullPayloadInfo{
    91  			Payload: pl,
    92  			Machine: "1",
    93  		},
    94  	}}
    95  
    96  	a := UnitFacade{s.state}
    97  	args := params.Entities{
    98  		Entities: []params.Entity{{
    99  			Tag: names.NewPayloadTag(id).String(),
   100  		}},
   101  	}
   102  	results, err := a.List(args)
   103  	c.Assert(err, jc.ErrorIsNil)
   104  
   105  	expected := api.Payload{
   106  		Class:   "foobar",
   107  		Type:    "type",
   108  		ID:      "idfoo",
   109  		Status:  payload.StateRunning,
   110  		Labels:  []string{},
   111  		Unit:    "unit-a-service-0",
   112  		Machine: "machine-1",
   113  	}
   114  
   115  	c.Check(results, jc.DeepEquals, internal.PayloadResults{
   116  		Results: []internal.PayloadResult{{
   117  			Entity: params.Entity{
   118  				Tag: names.NewPayloadTag(id).String(),
   119  			},
   120  			Payload:  &expected,
   121  			NotFound: false,
   122  			Error:    nil,
   123  		}},
   124  	})
   125  }
   126  
   127  func (s *suite) TestListAll(c *gc.C) {
   128  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   129  	s.state.stateIDs = []string{id}
   130  	pl := payload.Payload{
   131  		PayloadClass: charm.PayloadClass{
   132  			Name: "foobar",
   133  			Type: "type",
   134  		},
   135  		ID:     "idfoo",
   136  		Status: payload.StateRunning,
   137  		Unit:   "a-service/0",
   138  	}
   139  	s.state.payloads = []payload.Result{{
   140  		ID: id,
   141  		Payload: &payload.FullPayloadInfo{
   142  			Payload: pl,
   143  			Machine: "1",
   144  		},
   145  	}}
   146  
   147  	a := UnitFacade{s.state}
   148  	args := params.Entities{}
   149  	results, err := a.List(args)
   150  	c.Assert(err, jc.ErrorIsNil)
   151  
   152  	expected := api.Payload{
   153  		Class:   "foobar",
   154  		Type:    "type",
   155  		ID:      "idfoo",
   156  		Status:  payload.StateRunning,
   157  		Labels:  []string{},
   158  		Unit:    "unit-a-service-0",
   159  		Machine: "machine-1",
   160  	}
   161  	c.Check(results, jc.DeepEquals, internal.PayloadResults{
   162  		Results: []internal.PayloadResult{{
   163  			Entity: params.Entity{
   164  				Tag: names.NewPayloadTag(id).String(),
   165  			},
   166  			Payload:  &expected,
   167  			NotFound: false,
   168  			Error:    nil,
   169  		}},
   170  	})
   171  }
   172  
   173  func (s *suite) TestLookUpOkay(c *gc.C) {
   174  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   175  	s.state.stateIDs = []string{id}
   176  
   177  	a := UnitFacade{s.state}
   178  	args := internal.LookUpArgs{
   179  		Args: []internal.LookUpArg{{
   180  			Name: "fooID",
   181  			ID:   "bar",
   182  		}},
   183  	}
   184  	res, err := a.LookUp(args)
   185  	c.Assert(err, jc.ErrorIsNil)
   186  
   187  	s.stub.CheckCalls(c, []testing.StubCall{{
   188  		FuncName: "LookUp",
   189  		Args:     []interface{}{"fooID", "bar"},
   190  	}})
   191  
   192  	c.Check(res, jc.DeepEquals, internal.PayloadResults{
   193  		Results: []internal.PayloadResult{{
   194  			Entity: params.Entity{
   195  				Tag: names.NewPayloadTag(id).String(),
   196  			},
   197  			NotFound: false,
   198  			Error:    nil,
   199  		}},
   200  	})
   201  }
   202  
   203  func (s *suite) TestLookUpMixed(c *gc.C) {
   204  	s.state.stateIDs = []string{
   205  		"ce5bc2a7-65d8-4800-8199-a7c3356ab309",
   206  		"",
   207  		"ce5bc2a7-65d8-4800-8199-a7c3356ab311",
   208  	}
   209  	notFound := errors.NotFoundf("payload")
   210  	s.stub.SetErrors(nil, notFound, nil)
   211  
   212  	a := UnitFacade{s.state}
   213  	args := internal.LookUpArgs{
   214  		Args: []internal.LookUpArg{{
   215  			Name: "fooID",
   216  			ID:   "bar",
   217  		}, {
   218  			Name: "bazID",
   219  			ID:   "bam",
   220  		}, {
   221  			Name: "spam",
   222  			ID:   "eggs",
   223  		}},
   224  	}
   225  	res, err := a.LookUp(args)
   226  	c.Assert(err, jc.ErrorIsNil)
   227  
   228  	s.stub.CheckCallNames(c, "LookUp", "LookUp", "LookUp")
   229  	c.Check(res, jc.DeepEquals, internal.PayloadResults{
   230  		Results: []internal.PayloadResult{{
   231  			Entity: params.Entity{
   232  				Tag: names.NewPayloadTag("ce5bc2a7-65d8-4800-8199-a7c3356ab309").String(),
   233  			},
   234  			NotFound: false,
   235  			Error:    nil,
   236  		}, {
   237  			Entity: params.Entity{
   238  				Tag: "",
   239  			},
   240  			NotFound: true,
   241  			Error:    common.ServerError(notFound),
   242  		}, {
   243  			Entity: params.Entity{
   244  				Tag: names.NewPayloadTag("ce5bc2a7-65d8-4800-8199-a7c3356ab311").String(),
   245  			},
   246  			NotFound: false,
   247  			Error:    nil,
   248  		}},
   249  	})
   250  }
   251  
   252  func (s *suite) TestSetStatus(c *gc.C) {
   253  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   254  	s.state.stateIDs = []string{id}
   255  	s.state.stateIDs = []string{"ce5bc2a7-65d8-4800-8199-a7c3356ab309"}
   256  
   257  	a := UnitFacade{s.state}
   258  	args := internal.SetStatusArgs{
   259  		Args: []internal.SetStatusArg{{
   260  			Entity: params.Entity{
   261  				Tag: names.NewPayloadTag(id).String(),
   262  			},
   263  			Status: payload.StateRunning,
   264  		}},
   265  	}
   266  	res, err := a.SetStatus(args)
   267  	c.Assert(err, jc.ErrorIsNil)
   268  
   269  	c.Check(s.state.id, gc.Equals, id)
   270  	c.Assert(s.state.status, gc.Equals, payload.StateRunning)
   271  
   272  	expected := internal.PayloadResults{
   273  		Results: []internal.PayloadResult{{
   274  			Entity: params.Entity{
   275  				Tag: names.NewPayloadTag(id).String(),
   276  			},
   277  			Error: nil,
   278  		}},
   279  	}
   280  	c.Assert(res, gc.DeepEquals, expected)
   281  }
   282  
   283  func (s *suite) TestUntrack(c *gc.C) {
   284  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   285  	s.state.stateIDs = []string{id}
   286  
   287  	a := UnitFacade{s.state}
   288  	args := params.Entities{
   289  		Entities: []params.Entity{{
   290  			Tag: names.NewPayloadTag(id).String(),
   291  		}},
   292  	}
   293  	res, err := a.Untrack(args)
   294  	c.Assert(err, jc.ErrorIsNil)
   295  
   296  	c.Assert(s.state.id, gc.Equals, id)
   297  
   298  	expected := internal.PayloadResults{
   299  		Results: []internal.PayloadResult{{
   300  			Entity: params.Entity{
   301  				Tag: names.NewPayloadTag(id).String(),
   302  			},
   303  			Error: nil,
   304  		}},
   305  	}
   306  	c.Assert(res, gc.DeepEquals, expected)
   307  }
   308  
   309  func (s *suite) TestUntrackEmptyID(c *gc.C) {
   310  	a := UnitFacade{s.state}
   311  	args := params.Entities{
   312  		Entities: []params.Entity{{
   313  			Tag: "",
   314  		}},
   315  	}
   316  	res, err := a.Untrack(args)
   317  	c.Assert(err, jc.ErrorIsNil)
   318  
   319  	c.Assert(s.state.id, gc.Equals, "")
   320  
   321  	expected := internal.PayloadResults{
   322  		Results: []internal.PayloadResult{{
   323  			Entity: params.Entity{
   324  				Tag: "",
   325  			},
   326  			Error: nil,
   327  		}},
   328  	}
   329  	c.Assert(res, gc.DeepEquals, expected)
   330  }
   331  
   332  func (s *suite) TestUntrackNoIDs(c *gc.C) {
   333  	id := "ce5bc2a7-65d8-4800-8199-a7c3356ab309"
   334  	s.state.id = id
   335  
   336  	a := UnitFacade{s.state}
   337  	args := params.Entities{
   338  		Entities: []params.Entity{},
   339  	}
   340  	res, err := a.Untrack(args)
   341  	c.Assert(err, jc.ErrorIsNil)
   342  
   343  	c.Assert(s.state.id, gc.Equals, id)
   344  
   345  	expected := internal.PayloadResults{}
   346  	c.Assert(res, gc.DeepEquals, expected)
   347  }
   348  
   349  type FakeState struct {
   350  	stub *testing.Stub
   351  
   352  	// inputs
   353  	id      string
   354  	ids     []string
   355  	status  string
   356  	payload payload.Payload
   357  
   358  	//outputs
   359  	stateIDs []string
   360  	payloads []payload.Result
   361  }
   362  
   363  func (f *FakeState) nextID() string {
   364  	if len(f.stateIDs) == 0 {
   365  		return ""
   366  	}
   367  	id := f.stateIDs[0]
   368  	f.stateIDs = f.stateIDs[1:]
   369  	return id
   370  }
   371  
   372  func (f *FakeState) Track(pl payload.Payload) error {
   373  	f.payload = pl
   374  	if err := f.stub.NextErr(); err != nil {
   375  		return errors.Trace(err)
   376  	}
   377  
   378  	return nil
   379  }
   380  
   381  func (f *FakeState) List(ids ...string) ([]payload.Result, error) {
   382  	f.ids = ids
   383  	if err := f.stub.NextErr(); err != nil {
   384  		return nil, errors.Trace(err)
   385  	}
   386  
   387  	return f.payloads, nil
   388  }
   389  
   390  func (f *FakeState) SetStatus(id, status string) error {
   391  	f.id = id
   392  	f.status = status
   393  	if err := f.stub.NextErr(); err != nil {
   394  		return errors.Trace(err)
   395  	}
   396  
   397  	return nil
   398  }
   399  
   400  func (f *FakeState) LookUp(name, rawID string) (string, error) {
   401  	f.stub.AddCall("LookUp", name, rawID)
   402  	id := f.nextID()
   403  	if err := f.stub.NextErr(); err != nil {
   404  		return "", errors.Trace(err)
   405  	}
   406  
   407  	return id, nil
   408  }
   409  
   410  func (f *FakeState) Untrack(id string) error {
   411  	f.id = id
   412  	if err := f.stub.NextErr(); err != nil {
   413  		return errors.Trace(err)
   414  	}
   415  
   416  	return nil
   417  }