Skip to content

Commit f8a3d76

Browse files
committed
added api_test for vexplain end point
Signed-off-by: c-r-dev <crangavajha1@bloomberg.net>
1 parent b4d5425 commit f8a3d76

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed

go/vt/vtadmin/api_test.go

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5136,6 +5136,187 @@ func TestVTExplain(t *testing.T) {
51365136
}
51375137
}
51385138

5139+
func TestVExplain(t *testing.T) {
5140+
tests := []struct {
5141+
name string
5142+
keyspaces []*vtctldatapb.Keyspace
5143+
shards []*vtctldatapb.Shard
5144+
srvVSchema *vschemapb.SrvVSchema
5145+
tabletSchemas map[string]*tabletmanagerdatapb.SchemaDefinition
5146+
tablets []*vtadminpb.Tablet
5147+
req *vtadminpb.VExplainRequest
5148+
expectedError error
5149+
}{
5150+
{
5151+
name: "returns an error if cluster unspecified in request",
5152+
req: &vtadminpb.VExplainRequest{
5153+
Keyspace: "commerce",
5154+
Sql: "vexplain all select * from customers",
5155+
},
5156+
expectedError: vtadminerrors.ErrInvalidRequest,
5157+
},
5158+
{
5159+
name: "returns an error if keyspace unspecified in request",
5160+
req: &vtadminpb.VExplainRequest{
5161+
ClusterId: "c0",
5162+
Sql: "vexplain all select * from customers",
5163+
},
5164+
expectedError: vtadminerrors.ErrInvalidRequest,
5165+
},
5166+
{
5167+
name: "returns an error if SQL unspecified in request",
5168+
req: &vtadminpb.VExplainRequest{
5169+
ClusterId: "c0",
5170+
Keyspace: "commerce",
5171+
},
5172+
expectedError: vtadminerrors.ErrInvalidRequest,
5173+
},
5174+
{
5175+
name: "runs VExplain given a valid request in a valid topology",
5176+
keyspaces: []*vtctldatapb.Keyspace{
5177+
{
5178+
Name: "commerce",
5179+
Keyspace: &topodatapb.Keyspace{},
5180+
},
5181+
},
5182+
shards: []*vtctldatapb.Shard{
5183+
{
5184+
Name: "-",
5185+
Keyspace: "commerce",
5186+
},
5187+
},
5188+
srvVSchema: &vschemapb.SrvVSchema{
5189+
Keyspaces: map[string]*vschemapb.Keyspace{
5190+
"commerce": {
5191+
Sharded: false,
5192+
Tables: map[string]*vschemapb.Table{
5193+
"customers": {},
5194+
},
5195+
},
5196+
},
5197+
RoutingRules: &vschemapb.RoutingRules{
5198+
Rules: []*vschemapb.RoutingRule{},
5199+
},
5200+
},
5201+
tabletSchemas: map[string]*tabletmanagerdatapb.SchemaDefinition{
5202+
"c0_cell1-0000000100": {
5203+
DatabaseSchema: "CREATE DATABASE commerce",
5204+
TableDefinitions: []*tabletmanagerdatapb.TableDefinition{
5205+
{
5206+
Name: "t1",
5207+
Schema: `CREATE TABLE customers (id int(11) not null,PRIMARY KEY (id));`,
5208+
Type: "BASE",
5209+
Columns: []string{"id"},
5210+
DataLength: 100,
5211+
RowCount: 50,
5212+
Fields: []*querypb.Field{
5213+
{
5214+
Name: "id",
5215+
Type: querypb.Type_INT32,
5216+
},
5217+
},
5218+
},
5219+
},
5220+
},
5221+
},
5222+
tablets: []*vtadminpb.Tablet{
5223+
{
5224+
Cluster: &vtadminpb.Cluster{
5225+
Id: "c0",
5226+
Name: "cluster0",
5227+
},
5228+
State: vtadminpb.Tablet_SERVING,
5229+
Tablet: &topodatapb.Tablet{
5230+
Alias: &topodatapb.TabletAlias{
5231+
Uid: 100,
5232+
Cell: "c0_cell1",
5233+
},
5234+
Hostname: "tablet-cell1-a",
5235+
Keyspace: "commerce",
5236+
Shard: "-",
5237+
Type: topodatapb.TabletType_REPLICA,
5238+
},
5239+
},
5240+
},
5241+
req: &vtadminpb.VExplainRequest{
5242+
ClusterId: "c0",
5243+
Keyspace: "commerce",
5244+
Sql: "vexplain all select * from customers",
5245+
},
5246+
},
5247+
}
5248+
5249+
for _, tt := range tests {
5250+
t.Run(tt.name, func(t *testing.T) {
5251+
ctx, cancel := context.WithCancel(context.Background())
5252+
defer cancel()
5253+
toposerver := memorytopo.NewServer(ctx, "c0_cell1")
5254+
5255+
tmc := testutil.TabletManagerClient{
5256+
GetSchemaResults: map[string]struct {
5257+
Schema *tabletmanagerdatapb.SchemaDefinition
5258+
Error error
5259+
}{},
5260+
}
5261+
5262+
vtctldserver := testutil.NewVtctldServerWithTabletManagerClient(t, toposerver, &tmc, func(ts *topo.Server) vtctlservicepb.VtctldServer {
5263+
return grpcvtctldserver.NewVtctldServer(vtenv.NewTestEnv(), ts)
5264+
})
5265+
5266+
testutil.WithTestServer(ctx, t, vtctldserver, func(t *testing.T, vtctldClient vtctldclient.VtctldClient) {
5267+
if tt.srvVSchema != nil {
5268+
err := toposerver.UpdateSrvVSchema(ctx, "c0_cell1", tt.srvVSchema)
5269+
require.NoError(t, err)
5270+
}
5271+
testutil.AddKeyspaces(ctx, t, toposerver, tt.keyspaces...)
5272+
testutil.AddShards(ctx, t, toposerver, tt.shards...)
5273+
5274+
for _, tablet := range tt.tablets {
5275+
testutil.AddTablet(ctx, t, toposerver, tablet.Tablet, nil)
5276+
5277+
// Adds each SchemaDefinition to the fake TabletManagerClient, or nil
5278+
// if there are no schemas for that tablet. (All tablet aliases must
5279+
// exist in the map. Otherwise, TabletManagerClient will return an error when
5280+
// looking up the schema with tablet alias that doesn't exist.)
5281+
alias := topoproto.TabletAliasString(tablet.Tablet.Alias)
5282+
tmc.GetSchemaResults[alias] = struct {
5283+
Schema *tabletmanagerdatapb.SchemaDefinition
5284+
Error error
5285+
}{
5286+
Schema: tt.tabletSchemas[alias],
5287+
Error: nil,
5288+
}
5289+
}
5290+
5291+
clusters := []*cluster.Cluster{
5292+
vtadmintestutil.BuildCluster(t, vtadmintestutil.TestClusterConfig{
5293+
Cluster: &vtadminpb.Cluster{
5294+
Id: "c0",
5295+
Name: "cluster0",
5296+
},
5297+
VtctldClient: vtctldClient,
5298+
Tablets: tt.tablets,
5299+
}),
5300+
}
5301+
5302+
api := NewAPI(vtenv.NewTestEnv(), clusters, Options{})
5303+
resp, err := api.VExplain(ctx, tt.req)
5304+
5305+
if tt.expectedError != nil {
5306+
assert.True(t, errors.Is(err, tt.expectedError), "expected error type %w does not match actual error type %w", err, tt.expectedError)
5307+
} else {
5308+
require.NoError(t, err)
5309+
5310+
// We don't particularly care to test the contents of the VExplain response,
5311+
// just that it exists.
5312+
print(resp.Response)
5313+
assert.NotEmpty(t, resp.Response)
5314+
}
5315+
})
5316+
})
5317+
}
5318+
}
5319+
51395320
type ServeHTTPVtctldResponse struct {
51405321
Result ServeHTTPVtctldResult `json:"result"`
51415322
Ok bool `json:"ok"`

go/vt/vtadmin/vtsql/fakevtsql/conn.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
9090
})
9191
}
9292

93+
return &rows{
94+
cols: columns,
95+
vals: vals,
96+
pos: 0,
97+
closed: false,
98+
}, nil
99+
case "vexplain all select * from customers":
100+
columns := []string{"VExplain"}
101+
vals := [][]any{}
102+
vals = append(vals, []any{"{'Table' : 'customer, 'TestPlan' : 'TestPlan'}"})
103+
93104
return &rows{
94105
cols: columns,
95106
vals: vals,

0 commit comments

Comments
 (0)