-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
plugin multiplexing: add catalog test coverage (#14398)
* plugin client and plugin catalog tests * add v5 plugin cases and more checks * improve err msg * refactor tests; fix test err msg
- Loading branch information
1 parent
1e51162
commit 4d217be
Showing
2 changed files
with
244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package dbplugin | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"reflect" | ||
"testing" | ||
"time" | ||
|
||
log "github.com/hashicorp/go-hclog" | ||
"github.com/hashicorp/vault/sdk/database/dbplugin/v5/proto" | ||
"github.com/hashicorp/vault/sdk/helper/consts" | ||
"github.com/hashicorp/vault/sdk/helper/pluginutil" | ||
"github.com/hashicorp/vault/sdk/helper/wrapping" | ||
"github.com/stretchr/testify/mock" | ||
"google.golang.org/grpc" | ||
) | ||
|
||
func TestNewPluginClient(t *testing.T) { | ||
type testCase struct { | ||
config pluginutil.PluginClientConfig | ||
pluginClient pluginutil.PluginClient | ||
expectedResp *DatabasePluginClient | ||
expectedErr error | ||
} | ||
|
||
tests := map[string]testCase{ | ||
"happy path": { | ||
config: testPluginClientConfig(), | ||
pluginClient: &fakePluginClient{ | ||
connResp: nil, | ||
dispenseResp: gRPCClient{client: fakeClient{}}, | ||
dispenseErr: nil, | ||
}, | ||
expectedResp: &DatabasePluginClient{ | ||
client: &fakePluginClient{ | ||
connResp: nil, | ||
dispenseResp: gRPCClient{client: fakeClient{}}, | ||
dispenseErr: nil, | ||
}, | ||
Database: gRPCClient{proto.NewDatabaseClient(nil), context.Context(nil)}, | ||
}, | ||
expectedErr: nil, | ||
}, | ||
"dispense error": { | ||
config: testPluginClientConfig(), | ||
pluginClient: &fakePluginClient{ | ||
connResp: nil, | ||
dispenseResp: gRPCClient{}, | ||
dispenseErr: errors.New("dispense error"), | ||
}, | ||
expectedResp: nil, | ||
expectedErr: errors.New("dispense error"), | ||
}, | ||
"error unsupported client type": { | ||
config: testPluginClientConfig(), | ||
pluginClient: &fakePluginClient{ | ||
connResp: nil, | ||
dispenseResp: nil, | ||
dispenseErr: nil, | ||
}, | ||
expectedResp: nil, | ||
expectedErr: errors.New("unsupported client type"), | ||
}, | ||
} | ||
|
||
for name, test := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
ctx := context.Background() | ||
|
||
mockWrapper := new(mockRunnerUtil) | ||
mockWrapper.On("NewPluginClient", ctx, mock.Anything). | ||
Return(test.pluginClient, nil) | ||
defer mockWrapper.AssertNumberOfCalls(t, "NewPluginClient", 1) | ||
|
||
resp, err := NewPluginClient(ctx, mockWrapper, test.config) | ||
if test.expectedErr != nil && err == nil { | ||
t.Fatalf("err expected, got nil") | ||
} | ||
if test.expectedErr == nil && err != nil { | ||
t.Fatalf("no error expected, got: %s", err) | ||
} | ||
if test.expectedErr == nil && !reflect.DeepEqual(resp, test.expectedResp) { | ||
t.Fatalf("Actual response: %#v\nExpected response: %#v", resp, test.expectedResp) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func testPluginClientConfig() pluginutil.PluginClientConfig { | ||
return pluginutil.PluginClientConfig{ | ||
Name: "test-plugin", | ||
PluginSets: PluginSets, | ||
PluginType: consts.PluginTypeDatabase, | ||
HandshakeConfig: HandshakeConfig, | ||
Logger: log.NewNullLogger(), | ||
IsMetadataMode: true, | ||
AutoMTLS: true, | ||
} | ||
} | ||
|
||
var _ pluginutil.PluginClient = &fakePluginClient{} | ||
|
||
type fakePluginClient struct { | ||
connResp grpc.ClientConnInterface | ||
|
||
dispenseResp interface{} | ||
dispenseErr error | ||
} | ||
|
||
func (f *fakePluginClient) Conn() grpc.ClientConnInterface { | ||
return nil | ||
} | ||
|
||
func (f *fakePluginClient) Dispense(name string) (interface{}, error) { | ||
return f.dispenseResp, f.dispenseErr | ||
} | ||
|
||
func (f *fakePluginClient) Ping() error { | ||
return nil | ||
} | ||
|
||
func (f *fakePluginClient) Close() error { | ||
return nil | ||
} | ||
|
||
var _ pluginutil.RunnerUtil = &mockRunnerUtil{} | ||
|
||
type mockRunnerUtil struct { | ||
mock.Mock | ||
} | ||
|
||
func (m *mockRunnerUtil) NewPluginClient(ctx context.Context, config pluginutil.PluginClientConfig) (pluginutil.PluginClient, error) { | ||
args := m.Called(ctx, config) | ||
return args.Get(0).(pluginutil.PluginClient), args.Error(1) | ||
} | ||
|
||
func (m *mockRunnerUtil) ResponseWrapData(ctx context.Context, data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) { | ||
args := m.Called(ctx, data, ttl, jwt) | ||
return args.Get(0).(*wrapping.ResponseWrapInfo), args.Error(1) | ||
} | ||
|
||
func (m *mockRunnerUtil) MlockEnabled() bool { | ||
args := m.Called() | ||
return args.Bool(0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters