11package keychain
22
33import (
4- "maps "
4+ "errors "
55 "testing"
66
77 "github.com/docker/secrets-engine/store"
88 "github.com/docker/secrets-engine/store/mocks"
99 "github.com/stretchr/testify/require"
1010)
1111
12- func TestKeychain (t * testing.T ) {
13- ks , err := New ("com.test.test" , "test" ,
14- func () * mocks.MockCredential {
12+ type mustMarshalError struct {}
13+
14+ var _ store.Secret = & mustMarshalError {}
15+
16+ func (m * mustMarshalError ) Marshal () ([]byte , error ) {
17+ return nil , errors .New ("i am failing on purpose" )
18+ }
19+
20+ func (m * mustMarshalError ) Unmarshal (data []byte ) error {
21+ return nil
22+ }
23+
24+ type mustUnmarshalError struct {}
25+
26+ var _ store.Secret = & mustUnmarshalError {}
27+
28+ func (m * mustUnmarshalError ) Marshal () ([]byte , error ) {
29+ return []byte ("eeyyy" ), nil
30+ }
31+
32+ func (m * mustUnmarshalError ) Unmarshal (data []byte ) error {
33+ return errors .New ("i am failing on purpose" )
34+ }
35+
36+ func setupKeychain (t * testing.T , secretFactory func () store.Secret ) store.Store {
37+ t .Helper ()
38+ if secretFactory == nil {
39+ secretFactory = func () store.Secret {
1540 return & mocks.MockCredential {}
16- },
17- )
41+ }
42+ }
43+
44+ ks , err := New ("com.test.test" , "test" , secretFactory )
1845 require .NoError (t , err )
46+ return ks
47+ }
1948
49+ func TestKeychain (t * testing.T ) {
2050 t .Run ("save credentials" , func (t * testing.T ) {
51+ ks := setupKeychain (t , nil )
2152 id := store .ID ("com.test.test/test/bob" )
2253 require .NoError (t , id .Valid ())
2354 creds := & mocks.MockCredential {
2455 Username : "bob" ,
2556 Password : "bob-password" ,
2657 }
58+ t .Cleanup (func () {
59+ require .NoError (t , ks .Delete (t .Context (), id ))
60+ })
2761 require .NoError (t , ks .Save (t .Context (), id , creds ))
2862 })
2963
3064 t .Run ("get credential" , func (t * testing.T ) {
65+ ks := setupKeychain (t , nil )
3166 id := store .ID ("com.test.test/test/bob" )
67+ creds := & mocks.MockCredential {
68+ Username : "bob" ,
69+ Password : "bob-password" ,
70+ }
71+ t .Cleanup (func () {
72+ require .NoError (t , ks .Delete (t .Context (), id ))
73+ })
74+ require .NoError (t , ks .Save (t .Context (), id , creds ))
3275 require .NoError (t , id .Valid ())
3376 secret , err := ks .Get (t .Context (), id )
3477 require .NoError (t , err )
3578
3679 actual , ok := secret .(* mocks.MockCredential )
3780 require .True (t , ok )
3881
39- expected := & mocks.MockCredential {
40- Username : "bob" ,
41- Password : "bob-password" ,
42- }
82+ expected := creds
4383 require .EqualValues (t , expected , actual )
4484 })
4585
4686 t .Run ("list all credentials" , func (t * testing.T ) {
87+ ks := setupKeychain (t , nil )
88+
4789 moreCreds := map [store.ID ]* mocks.MockCredential {
90+ "com.test.test/test/bob" : {
91+ Username : "bob" ,
92+ Password : "bob-password" ,
93+ },
4894 "com.test.test/test/jeff" : {
4995 Username : "jeff" ,
5096 Password : "jeff-password" ,
@@ -54,6 +100,11 @@ func TestKeychain(t *testing.T) {
54100 Password : "pete-password" ,
55101 },
56102 }
103+ t .Cleanup (func () {
104+ for id := range moreCreds {
105+ require .NoError (t , ks .Delete (t .Context (), id ))
106+ }
107+ })
57108
58109 for id , anotherCred := range moreCreds {
59110 require .NoError (t , ks .Save (t .Context (), id , anotherCred ))
@@ -67,22 +118,85 @@ func TestKeychain(t *testing.T) {
67118 }
68119 require .Len (t , actual , 3 )
69120
70- expected := map [store.ID ]* mocks.MockCredential {
71- "com.test.test/test/bob" : {
72- Username : "bob" ,
73- Password : "bob-password" ,
74- },
75- }
76- maps .Copy (expected , moreCreds )
77- require .Len (t , expected , 3 )
121+ expected := moreCreds
78122 require .Equal (t , expected , actual )
79123 })
80124
81125 t .Run ("delete credential" , func (t * testing.T ) {
126+ ks := setupKeychain (t , nil )
82127 id := store .ID ("com.test.test/test/bob" )
83128 require .NoError (t , id .Valid ())
129+ creds := & mocks.MockCredential {
130+ Username : "bob" ,
131+ Password : "bob-password" ,
132+ }
133+ require .NoError (t , ks .Save (t .Context (), id , creds ))
84134 require .NoError (t , ks .Delete (t .Context (), id ))
85135 _ , err := ks .Get (t .Context (), id )
86136 require .ErrorIs (t , err , store .ErrCredentialNotFound )
87137 })
138+
139+ t .Run ("delete non-existent credential" , func (t * testing.T ) {
140+ ks := setupKeychain (t , nil )
141+ id := store .ID ("com.test.test/test/does-not-exist" )
142+ require .NoError (t , id .Valid ())
143+ require .NoError (t , ks .Delete (t .Context (), id ))
144+ })
145+
146+ t .Run ("invalid ID" , func (t * testing.T ) {
147+ id := store .ID ("completely*&@#$@invalid" )
148+ kc := setupKeychain (t , nil )
149+
150+ operations := []string {"save" , "get" , "delete" }
151+
152+ for _ , op := range operations {
153+ t .Run (op , func (t * testing.T ) {
154+ var err error
155+ switch op {
156+ case "save" :
157+ err = kc .Save (t .Context (), id , nil )
158+ case "delete" :
159+ err = kc .Delete (t .Context (), id )
160+ case "get" :
161+ _ , err = kc .Get (t .Context (), id )
162+ }
163+ require .ErrorContains (t , err , "invalid identifier" )
164+ })
165+ }
166+ })
167+
168+ t .Run ("marshal error on save" , func (t * testing.T ) {
169+ kc := setupKeychain (t , nil )
170+ id , err := store .ParseID ("something/will/fail" )
171+ require .NoError (t , err )
172+ require .ErrorContains (t , kc .Save (t .Context (), id , & mustMarshalError {}), "i am failing on purpose" )
173+ })
174+
175+ t .Run ("unmarshal error on get" , func (t * testing.T ) {
176+ kc := setupKeychain (t , func () store.Secret {
177+ return & mustUnmarshalError {}
178+ })
179+ id , err := store .ParseID ("something/will/fail" )
180+ require .NoError (t , err )
181+ t .Cleanup (func () {
182+ require .NoError (t , kc .Delete (t .Context (), id ))
183+ })
184+ require .NoError (t , kc .Save (t .Context (), id , & mustUnmarshalError {}))
185+ _ , err = kc .Get (t .Context (), id )
186+ require .ErrorContains (t , err , "i am failing on purpose" )
187+ })
188+
189+ t .Run ("unmarshal error on getAll" , func (t * testing.T ) {
190+ kc := setupKeychain (t , func () store.Secret {
191+ return & mustUnmarshalError {}
192+ })
193+ id , err := store .ParseID ("something/will/fail" )
194+ require .NoError (t , err )
195+ t .Cleanup (func () {
196+ require .NoError (t , kc .Delete (t .Context (), id ))
197+ })
198+ require .NoError (t , kc .Save (t .Context (), id , & mustUnmarshalError {}))
199+ _ , err = kc .GetAll (t .Context ())
200+ require .ErrorContains (t , err , "i am failing on purpose" )
201+ })
88202}
0 commit comments