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 }