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 {¶ms.Error{Message: "x2 error"}}, 138 {¶ms.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 }