github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/apicaller/util_test.go (about)

     1  // Copyright 2015-2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apicaller_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/testing"
    10  	jc "github.com/juju/testing/checkers"
    11  	"github.com/juju/utils"
    12  	gc "gopkg.in/check.v1"
    13  	"gopkg.in/juju/names.v2"
    14  	"gopkg.in/juju/worker.v1"
    15  
    16  	"github.com/juju/juju/agent"
    17  	"github.com/juju/juju/api"
    18  	apiagent "github.com/juju/juju/api/agent"
    19  	"github.com/juju/juju/api/base"
    20  	"github.com/juju/juju/apiserver/params"
    21  	coretesting "github.com/juju/juju/testing"
    22  	"github.com/juju/juju/worker/apicaller"
    23  )
    24  
    25  var errNotProvisioned = &params.Error{Code: params.CodeNotProvisioned}
    26  var errNotAuthorized = &params.Error{Code: params.CodeUnauthorized}
    27  
    28  type mockAgent struct {
    29  	agent.Agent
    30  	stub   *testing.Stub
    31  	entity names.Tag
    32  	model  names.ModelTag
    33  }
    34  
    35  func (mock *mockAgent) CurrentConfig() agent.Config {
    36  	return dummyConfig{
    37  		entity: mock.entity,
    38  		model:  mock.model,
    39  	}
    40  }
    41  
    42  func (mock *mockAgent) ChangeConfig(mutator agent.ConfigMutator) error {
    43  	mock.stub.AddCall("ChangeConfig")
    44  	if err := mock.stub.NextErr(); err != nil {
    45  		return err
    46  	}
    47  	return mutator(&mockSetter{stub: mock.stub})
    48  }
    49  
    50  type dummyConfig struct {
    51  	agent.Config
    52  	entity names.Tag
    53  	model  names.ModelTag
    54  }
    55  
    56  func (dummy dummyConfig) Tag() names.Tag {
    57  	return dummy.entity
    58  }
    59  
    60  func (dummy dummyConfig) Model() names.ModelTag {
    61  	return dummy.model
    62  }
    63  
    64  func (dummy dummyConfig) APIInfo() (*api.Info, bool) {
    65  	return &api.Info{
    66  		ModelTag: dummy.model,
    67  		Tag:      dummy.entity,
    68  		Password: "new",
    69  	}, true
    70  }
    71  
    72  func (dummy dummyConfig) OldPassword() string {
    73  	return "old"
    74  }
    75  
    76  type mockSetter struct {
    77  	stub *testing.Stub
    78  	agent.ConfigSetter
    79  }
    80  
    81  func (mock *mockSetter) SetOldPassword(pw string) {
    82  	mock.stub.AddCall("SetOldPassword", pw)
    83  	mock.stub.PopNoErr()
    84  }
    85  
    86  func (mock *mockSetter) SetPassword(pw string) {
    87  	mock.stub.AddCall("SetPassword", pw)
    88  	mock.stub.PopNoErr()
    89  }
    90  
    91  type mockConn struct {
    92  	stub *testing.Stub
    93  	api.Connection
    94  	controllerOnly bool
    95  	broken         chan struct{}
    96  }
    97  
    98  func (mock *mockConn) ModelTag() (names.ModelTag, bool) {
    99  	mock.stub.AddCall("ModelTag")
   100  	if mock.controllerOnly {
   101  		return names.ModelTag{}, false
   102  	}
   103  	return coretesting.ModelTag, true
   104  }
   105  
   106  func (mock *mockConn) Broken() <-chan struct{} {
   107  	return mock.broken
   108  }
   109  
   110  func (mock *mockConn) Addr() string {
   111  	return "testing.invalid"
   112  }
   113  
   114  func (mock *mockConn) Close() error {
   115  	mock.stub.AddCall("Close")
   116  	return mock.stub.NextErr()
   117  }
   118  
   119  func newMockConnFacade(stub *testing.Stub, life apiagent.Life) apiagent.ConnFacade {
   120  	return &mockConnFacade{
   121  		stub: stub,
   122  		life: life,
   123  	}
   124  }
   125  
   126  type mockConnFacade struct {
   127  	stub *testing.Stub
   128  	life apiagent.Life
   129  }
   130  
   131  func (mock *mockConnFacade) Life(entity names.Tag) (apiagent.Life, error) {
   132  	mock.stub.AddCall("Life", entity)
   133  	if err := mock.stub.NextErr(); err != nil {
   134  		return "", err
   135  	}
   136  	return mock.life, nil
   137  }
   138  
   139  func (mock *mockConnFacade) SetPassword(entity names.Tag, password string) error {
   140  	mock.stub.AddCall("SetPassword", entity, password)
   141  	return mock.stub.NextErr()
   142  }
   143  
   144  type dummyWorker struct {
   145  	worker.Worker
   146  }
   147  
   148  func assertStop(c *gc.C, w worker.Worker) {
   149  	c.Assert(worker.Stop(w), jc.ErrorIsNil)
   150  }
   151  
   152  func assertStopError(c *gc.C, w worker.Worker, match string) {
   153  	c.Assert(worker.Stop(w), gc.ErrorMatches, match)
   154  }
   155  
   156  func lifeTest(c *gc.C, stub *testing.Stub, life apiagent.Life, test func() (api.Connection, error)) (api.Connection, error) {
   157  	newFacade := func(apiCaller base.APICaller) (apiagent.ConnFacade, error) {
   158  		c.Check(apiCaller, gc.FitsTypeOf, (*mockConn)(nil))
   159  		return newMockConnFacade(stub, life), nil
   160  	}
   161  	unpatch := testing.PatchValue(apicaller.NewConnFacade, newFacade)
   162  	defer unpatch()
   163  	return test()
   164  }
   165  
   166  // TODO(katco): 2016-08-09: lp:1611427
   167  func strategyTest(stub *testing.Stub, strategy utils.AttemptStrategy, test func(api.OpenFunc) (api.Connection, error)) (api.Connection, error) {
   168  	unpatch := testing.PatchValue(apicaller.Strategy, strategy)
   169  	defer unpatch()
   170  	return test(func(info *api.Info, opts api.DialOpts) (api.Connection, error) {
   171  		// copy because I don't trust what might happen to info
   172  		stub.AddCall("apiOpen", *info, opts)
   173  		err := stub.NextErr()
   174  		if err != nil {
   175  			return nil, err
   176  		}
   177  		return &mockConn{stub: stub}, nil
   178  	})
   179  }
   180  
   181  func checkOpenCalls(c *gc.C, stub *testing.Stub, passwords ...string) {
   182  	calls := openCalls(names.ModelTag{}, testEntity, passwords...)
   183  	stub.CheckCalls(c, calls)
   184  }
   185  
   186  func openCalls(model names.ModelTag, entity names.Tag, passwords ...string) []testing.StubCall {
   187  	calls := make([]testing.StubCall, len(passwords))
   188  	for i, pw := range passwords {
   189  		info := api.Info{
   190  			ModelTag: model,
   191  			Tag:      entity,
   192  			Password: pw,
   193  		}
   194  		calls[i] = testing.StubCall{
   195  			FuncName: "apiOpen",
   196  			Args: []interface{}{info, api.DialOpts{
   197  				DialAddressInterval: 200 * time.Millisecond,
   198  				DialTimeout:         3 * time.Second,
   199  				Timeout:             time.Minute,
   200  			}},
   201  		}
   202  	}
   203  	return calls
   204  }