launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/apiserver/common/password_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"fmt"
     8  
     9  	errgo "launchpad.net/errgo/errors"
    10  	gc "launchpad.net/gocheck"
    11  
    12  	"launchpad.net/juju-core/errors"
    13  	"launchpad.net/juju-core/state"
    14  	"launchpad.net/juju-core/state/api/params"
    15  	"launchpad.net/juju-core/state/apiserver/common"
    16  	apiservertesting "launchpad.net/juju-core/state/apiserver/testing"
    17  	jc "launchpad.net/juju-core/testing/checkers"
    18  )
    19  
    20  type passwordSuite struct{}
    21  
    22  var _ = gc.Suite(&passwordSuite{})
    23  
    24  type entityWithError interface {
    25  	state.Entity
    26  	error() error
    27  }
    28  
    29  type fakeState struct {
    30  	entities map[string]entityWithError
    31  }
    32  
    33  func (st *fakeState) FindEntity(tag string) (state.Entity, error) {
    34  	entity, ok := st.entities[tag]
    35  	if !ok {
    36  		return nil, errors.NotFoundf("entity %q", tag)
    37  	}
    38  	if err := entity.error(); err != nil {
    39  		return nil, err
    40  	}
    41  	return entity, nil
    42  }
    43  
    44  type fetchError string
    45  
    46  func (f fetchError) error() error {
    47  	if f == "" {
    48  		return nil
    49  	}
    50  	return errgo.Newf("%s", string(f))
    51  }
    52  
    53  type fakeAuthenticator struct {
    54  	// Any Authenticator methods we don't implement on fakeAuthenticator
    55  	// will fall back to this and panic because it's always nil.
    56  	state.Authenticator
    57  	state.Entity
    58  	err  error
    59  	pass string
    60  	fetchError
    61  }
    62  
    63  func (a *fakeAuthenticator) SetPassword(pass string) error {
    64  	if a.err != nil {
    65  		return a.err
    66  	}
    67  	a.pass = pass
    68  	return nil
    69  }
    70  
    71  // fakeUnitAuthenticator simulates a unit entity.
    72  type fakeUnitAuthenticator struct {
    73  	fakeAuthenticator
    74  	mongoPass string
    75  }
    76  
    77  func (a *fakeUnitAuthenticator) Tag() string {
    78  	return "fake"
    79  }
    80  
    81  func (a *fakeUnitAuthenticator) SetMongoPassword(pass string) error {
    82  	if a.err != nil {
    83  		return a.err
    84  	}
    85  	a.mongoPass = pass
    86  	return nil
    87  }
    88  
    89  // fakeMachineAuthenticator simulates a machine entity.
    90  type fakeMachineAuthenticator struct {
    91  	fakeUnitAuthenticator
    92  	jobs []state.MachineJob
    93  }
    94  
    95  func (a *fakeMachineAuthenticator) Jobs() []state.MachineJob {
    96  	return a.jobs
    97  }
    98  
    99  func (*passwordSuite) TestSetPasswords(c *gc.C) {
   100  	st := &fakeState{
   101  		entities: map[string]entityWithError{
   102  			"x0": &fakeAuthenticator{},
   103  			"x1": &fakeAuthenticator{},
   104  			"x2": &fakeAuthenticator{
   105  				err: errgo.Newf("x2 error"),
   106  			},
   107  			"x3": &fakeAuthenticator{
   108  				fetchError: "x3 error",
   109  			},
   110  			"x4": &fakeUnitAuthenticator{},
   111  			"x5": &fakeMachineAuthenticator{jobs: []state.MachineJob{state.JobHostUnits}},
   112  			"x6": &fakeMachineAuthenticator{jobs: []state.MachineJob{state.JobManageEnviron}},
   113  		},
   114  	}
   115  	getCanChange := func() (common.AuthFunc, error) {
   116  		return func(tag string) bool {
   117  			return tag != "x0"
   118  		}, nil
   119  	}
   120  	pc := common.NewPasswordChanger(st, getCanChange)
   121  	var changes []params.PasswordChange
   122  	for i := 0; i < len(st.entities); i++ {
   123  		tag := fmt.Sprintf("x%d", i)
   124  		changes = append(changes, params.PasswordChange{
   125  			Tag:      tag,
   126  			Password: fmt.Sprintf("%spass", tag),
   127  		})
   128  	}
   129  	results, err := pc.SetPasswords(params.PasswordChanges{
   130  		Changes: changes,
   131  	})
   132  	c.Assert(err, gc.IsNil)
   133  	c.Assert(results, jc.DeepEquals, params.ErrorResults{
   134  		Results: []params.ErrorResult{
   135  			{apiservertesting.ErrUnauthorized},
   136  			{nil},
   137  			{&params.Error{Message: "x2 error"}},
   138  			{&params.Error{Message: "x3 error"}},
   139  			{nil},
   140  			{nil},
   141  			{nil},
   142  		},
   143  	})
   144  	c.Check(st.entities["x0"].(*fakeAuthenticator).pass, gc.Equals, "")
   145  	c.Check(st.entities["x1"].(*fakeAuthenticator).pass, gc.Equals, "x1pass")
   146  	c.Check(st.entities["x2"].(*fakeAuthenticator).pass, gc.Equals, "")
   147  	c.Check(st.entities["x4"].(*fakeUnitAuthenticator).pass, gc.Equals, "x4pass")
   148  	c.Check(st.entities["x4"].(*fakeUnitAuthenticator).mongoPass, gc.Equals, "")
   149  	c.Check(st.entities["x5"].(*fakeMachineAuthenticator).pass, gc.Equals, "x5pass")
   150  	c.Check(st.entities["x5"].(*fakeMachineAuthenticator).mongoPass, gc.Equals, "")
   151  	c.Check(st.entities["x6"].(*fakeMachineAuthenticator).pass, gc.Equals, "x6pass")
   152  	c.Check(st.entities["x6"].(*fakeMachineAuthenticator).mongoPass, gc.Equals, "x6pass")
   153  }
   154  
   155  func (*passwordSuite) TestSetPasswordsError(c *gc.C) {
   156  	getCanChange := func() (common.AuthFunc, error) {
   157  		return nil, errgo.Newf("splat")
   158  	}
   159  	pc := common.NewPasswordChanger(&fakeState{}, getCanChange)
   160  	var changes []params.PasswordChange
   161  	for i := 0; i < 4; i++ {
   162  		tag := fmt.Sprintf("x%d", i)
   163  		changes = append(changes, params.PasswordChange{
   164  			Tag:      tag,
   165  			Password: fmt.Sprintf("%spass", tag),
   166  		})
   167  	}
   168  	_, err := pc.SetPasswords(params.PasswordChanges{Changes: changes})
   169  	c.Assert(err, gc.ErrorMatches, "splat")
   170  }
   171  
   172  func (*passwordSuite) TestSetPasswordsNoArgsNoError(c *gc.C) {
   173  	getCanChange := func() (common.AuthFunc, error) {
   174  		return nil, errgo.Newf("splat")
   175  	}
   176  	pc := common.NewPasswordChanger(&fakeState{}, getCanChange)
   177  	result, err := pc.SetPasswords(params.PasswordChanges{})
   178  	c.Assert(err, gc.IsNil)
   179  	c.Assert(result.Results, gc.HasLen, 0)
   180  }