github.com/hashicorp/vault/sdk@v0.13.0/plugin/grpc_backend_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package plugin
     5  
     6  import (
     7  	"context"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	log "github.com/hashicorp/go-hclog"
    13  	gplugin "github.com/hashicorp/go-plugin"
    14  	"github.com/hashicorp/vault/sdk/helper/logging"
    15  	"github.com/hashicorp/vault/sdk/logical"
    16  	"github.com/hashicorp/vault/sdk/plugin/mock"
    17  )
    18  
    19  func TestGRPCBackendPlugin_impl(t *testing.T) {
    20  	var _ gplugin.Plugin = new(GRPCBackendPlugin)
    21  	var _ logical.Backend = new(backendGRPCPluginClient)
    22  }
    23  
    24  func TestGRPCBackendPlugin_HandleRequest(t *testing.T) {
    25  	b, cleanup := testGRPCBackend(t)
    26  	defer cleanup()
    27  
    28  	resp, err := b.HandleRequest(context.Background(), &logical.Request{
    29  		Operation: logical.CreateOperation,
    30  		Path:      "kv/foo",
    31  		Data: map[string]interface{}{
    32  			"value": "bar",
    33  		},
    34  	})
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	if resp.Data["value"] != "bar" {
    39  		t.Fatalf("bad: %#v", resp)
    40  	}
    41  }
    42  
    43  func TestGRPCBackendPlugin_SpecialPaths(t *testing.T) {
    44  	b, cleanup := testGRPCBackend(t)
    45  	defer cleanup()
    46  
    47  	paths := b.SpecialPaths()
    48  	if paths == nil {
    49  		t.Fatal("SpecialPaths() returned nil")
    50  	}
    51  }
    52  
    53  func TestGRPCBackendPlugin_System(t *testing.T) {
    54  	b, cleanup := testGRPCBackend(t)
    55  	defer cleanup()
    56  
    57  	sys := b.System()
    58  	if sys == nil {
    59  		t.Fatal("System() returned nil")
    60  	}
    61  
    62  	actual := sys.DefaultLeaseTTL()
    63  	expected := 300 * time.Second
    64  
    65  	if actual != expected {
    66  		t.Fatalf("bad: %v, expected %v", actual, expected)
    67  	}
    68  }
    69  
    70  func TestGRPCBackendPlugin_Logger(t *testing.T) {
    71  	b, cleanup := testGRPCBackend(t)
    72  	defer cleanup()
    73  
    74  	logger := b.Logger()
    75  	if logger == nil {
    76  		t.Fatal("Logger() returned nil")
    77  	}
    78  }
    79  
    80  func TestGRPCBackendPlugin_HandleExistenceCheck(t *testing.T) {
    81  	b, cleanup := testGRPCBackend(t)
    82  	defer cleanup()
    83  
    84  	checkFound, exists, err := b.HandleExistenceCheck(context.Background(), &logical.Request{
    85  		Operation: logical.CreateOperation,
    86  		Path:      "kv/foo",
    87  		Data:      map[string]interface{}{"value": "bar"},
    88  	})
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	if !checkFound {
    93  		t.Fatal("existence check not found for path 'kv/foo")
    94  	}
    95  	if exists {
    96  		t.Fatal("existence check should have returned 'false' for 'kv/foo'")
    97  	}
    98  }
    99  
   100  func TestGRPCBackendPlugin_Cleanup(t *testing.T) {
   101  	b, cleanup := testGRPCBackend(t)
   102  	defer cleanup()
   103  
   104  	b.Cleanup(context.Background())
   105  }
   106  
   107  func TestGRPCBackendPlugin_InvalidateKey(t *testing.T) {
   108  	b, cleanup := testGRPCBackend(t)
   109  	defer cleanup()
   110  
   111  	ctx := context.Background()
   112  
   113  	resp, err := b.HandleRequest(ctx, &logical.Request{
   114  		Operation: logical.ReadOperation,
   115  		Path:      "internal",
   116  	})
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	if resp.Data["value"] == "" {
   121  		t.Fatalf("bad: %#v, expected non-empty value", resp)
   122  	}
   123  
   124  	b.InvalidateKey(ctx, "internal")
   125  
   126  	resp, err = b.HandleRequest(ctx, &logical.Request{
   127  		Operation: logical.ReadOperation,
   128  		Path:      "internal",
   129  	})
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  	if resp.Data["value"] != "" {
   134  		t.Fatalf("bad: expected empty response data, got %#v", resp)
   135  	}
   136  }
   137  
   138  func TestGRPCBackendPlugin_Setup(t *testing.T) {
   139  	_, cleanup := testGRPCBackend(t)
   140  	defer cleanup()
   141  }
   142  
   143  func TestGRPCBackendPlugin_Initialize(t *testing.T) {
   144  	b, cleanup := testGRPCBackend(t)
   145  	defer cleanup()
   146  
   147  	err := b.Initialize(context.Background(), &logical.InitializationRequest{})
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  }
   152  
   153  func TestGRPCBackendPlugin_Version(t *testing.T) {
   154  	b, cleanup := testGRPCBackend(t)
   155  	defer cleanup()
   156  
   157  	versioner, ok := b.(logical.PluginVersioner)
   158  	if !ok {
   159  		t.Fatalf("Expected %T to implement logical.PluginVersioner interface", b)
   160  	}
   161  
   162  	version := versioner.PluginVersion().Version
   163  	if version != "v0.0.0+mock" {
   164  		t.Fatalf("Got version %s, expected 'mock'", version)
   165  	}
   166  }
   167  
   168  func testGRPCBackend(t *testing.T) (logical.Backend, func()) {
   169  	// Create a mock provider
   170  	pluginMap := map[string]gplugin.Plugin{
   171  		"backend": &GRPCBackendPlugin{
   172  			Factory: mock.Factory,
   173  			Logger: log.New(&log.LoggerOptions{
   174  				Level:      log.Debug,
   175  				Output:     os.Stderr,
   176  				JSONFormat: true,
   177  			}),
   178  		},
   179  	}
   180  	client, _ := gplugin.TestPluginGRPCConn(t, false, pluginMap)
   181  	cleanup := func() {
   182  		client.Close()
   183  	}
   184  
   185  	// Request the backend
   186  	raw, err := client.Dispense(BackendPluginName)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	b := raw.(logical.Backend)
   191  
   192  	err = b.Setup(context.Background(), &logical.BackendConfig{
   193  		Logger: logging.NewVaultLogger(log.Debug),
   194  		System: &logical.StaticSystemView{
   195  			DefaultLeaseTTLVal: 300 * time.Second,
   196  			MaxLeaseTTLVal:     1800 * time.Second,
   197  		},
   198  		StorageView: &logical.InmemStorage{},
   199  	})
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	return b, cleanup
   205  }