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  }