github.com/drone/runner-go@v1.12.0/secret/external_test.go (about) 1 // Copyright 2019 Drone.IO Inc. All rights reserved. 2 // Use of this source code is governed by the Polyform License 3 // that can be found in the LICENSE file. 4 5 package secret 6 7 import ( 8 "context" 9 "errors" 10 "testing" 11 12 "github.com/drone/drone-go/drone" 13 "github.com/drone/drone-go/plugin/secret" 14 "github.com/drone/runner-go/manifest" 15 ) 16 17 func TestExternal(t *testing.T) { 18 args := &Request{ 19 Name: "docker_password", 20 Build: &drone.Build{Event: drone.EventPush}, 21 Repo: &drone.Repo{Private: false}, 22 Conf: &manifest.Manifest{ 23 Resources: []manifest.Resource{ 24 &manifest.Secret{ 25 Name: "docker_password", 26 Get: manifest.SecretGet{ 27 Path: "docker", 28 Name: "password", 29 }, 30 }, 31 }, 32 }, 33 } 34 extern := &drone.Secret{Name: "docker_password", Data: "correct-horse-battery-staple"} 35 provider := External("http://localhost", "secret", false) 36 provider.(*external).client = &mockPlugin{sec: extern} 37 result, err := provider.Find(noContext, args) 38 if err != nil { 39 t.Errorf("Expect nil error, secret found") 40 } 41 if extern == nil { 42 t.Errorf("Expect secret returned, got nil") 43 return 44 } 45 if got, want := result.Name, extern.Name; got != want { 46 t.Errorf("Want secret name %s, got %s", want, got) 47 } 48 if got, want := result.Data, extern.Data; got != want { 49 t.Errorf("Want secret value %s, got %s", want, got) 50 } 51 } 52 53 // This test verifies that if no endpoint is configured the 54 // provider exits immediately and returns a nil secret and nil 55 // error. 56 func TestExternal_NoEndpoint(t *testing.T) { 57 provider := External("", "", false) 58 sec, err := provider.Find(noContext, nil) 59 if err != nil { 60 t.Errorf("Expect nil error, provider disabled") 61 } 62 if sec != nil { 63 t.Errorf("Expect nil secret, provider disabled") 64 } 65 } 66 67 // This test verifies that a nil secret and nil error are 68 // returned if no corresponding secret resource entry is found 69 // in the manifest. No error is returned because Not Found is 70 // not considered an error. 71 func TestExternal_NotFound(t *testing.T) { 72 args := &Request{ 73 Name: "docker_username", 74 Build: &drone.Build{Event: drone.EventPush}, 75 Conf: &manifest.Manifest{ 76 Resources: []manifest.Resource{ 77 &manifest.Signature{ 78 Name: "signature", 79 Hmac: "<signature>", 80 }, 81 }, 82 }, 83 } 84 provider := External("http://localhost", "secret", false) 85 sec, err := provider.Find(noContext, args) 86 if err != nil { 87 t.Errorf("Expect nil error, secret not found") 88 } 89 if sec != nil { 90 t.Errorf("Expect nil secret, secret not found") 91 } 92 } 93 94 // This test verifies that a nil secret and nil error are 95 // returned if no matching secret resources is found in the 96 // manifest. 97 func TestExternal_NoMatch(t *testing.T) { 98 args := &Request{ 99 Name: "docker_username", 100 Build: &drone.Build{Event: drone.EventPush}, 101 Conf: &manifest.Manifest{ 102 Resources: []manifest.Resource{ 103 &manifest.Secret{ 104 Name: "docker_password", 105 }, 106 }, 107 }, 108 } 109 provider := External("http://localhost", "secret", false) 110 sec, err := provider.Find(noContext, args) 111 if err != nil { 112 t.Errorf("Expect nil error, no matching secret") 113 } 114 if sec != nil { 115 t.Errorf("Expect nil secret, no matching secret") 116 } 117 } 118 119 // This test verifies that if a secret is requested, and secret 120 // resource exists in the manifest but with no path or name, a 121 // nil secret and nil error are returned. 122 func TestExternal_NoPath(t *testing.T) { 123 args := &Request{ 124 Name: "docker_password", 125 Build: &drone.Build{Event: drone.EventPush}, 126 Conf: &manifest.Manifest{ 127 Resources: []manifest.Resource{ 128 &manifest.Secret{ 129 Name: "docker_password", 130 Get: manifest.SecretGet{ 131 Path: "", 132 Name: "", 133 }, 134 }, 135 }, 136 }, 137 } 138 provider := External("http://localhost", "secret", false) 139 sec, err := provider.Find(noContext, args) 140 if err != nil { 141 t.Errorf("Expect nil error, no path") 142 } 143 if sec != nil { 144 t.Errorf("Expect nil secret, no path") 145 } 146 } 147 148 // This test verifies that if the remote API call to the 149 // external plugin returns an error, the provider returns the 150 // error to the caller. 151 func TestExternal_ClientError(t *testing.T) { 152 args := &Request{ 153 Name: "docker_password", 154 Build: &drone.Build{Event: drone.EventPush}, 155 Repo: &drone.Repo{Private: false}, 156 Conf: &manifest.Manifest{ 157 Resources: []manifest.Resource{ 158 &manifest.Secret{ 159 Name: "docker_password", 160 Get: manifest.SecretGet{ 161 Path: "docker", 162 Name: "password", 163 }, 164 }, 165 }, 166 }, 167 } 168 want := errors.New("not found") 169 provider := External("http://localhost", "secret", false) 170 provider.(*external).client = &mockPlugin{err: want} 171 _, got := provider.Find(noContext, args) 172 if got != want { 173 t.Errorf("Expect error returned from client") 174 } 175 } 176 177 // This test verifies that if a secret with an emtpy value is 178 // returned from the external plugin, a nil secret and nil error 179 // are returned by the provider. 180 func TestExternal_EmptySecret(t *testing.T) { 181 args := &Request{ 182 Name: "docker_password", 183 Build: &drone.Build{Event: drone.EventPush}, 184 Repo: &drone.Repo{Private: false}, 185 Conf: &manifest.Manifest{ 186 Resources: []manifest.Resource{ 187 &manifest.Secret{ 188 Name: "docker_password", 189 Get: manifest.SecretGet{ 190 Path: "docker", 191 Name: "password", 192 }, 193 }, 194 }, 195 }, 196 } 197 res := &drone.Secret{Name: "docker_password", Data: ""} 198 provider := External("http://localhost", "secret", false) 199 provider.(*external).client = &mockPlugin{sec: res} 200 sec, err := provider.Find(noContext, args) 201 if err != nil { 202 t.Errorf("Expect nil error, secret not found") 203 } 204 if sec != nil { 205 t.Errorf("Expect nil secret, secret not found") 206 } 207 } 208 209 type mockPlugin struct { 210 sec *drone.Secret 211 err error 212 } 213 214 func (m *mockPlugin) Find(context.Context, *secret.Request) (*drone.Secret, error) { 215 return m.sec, m.err 216 }