diff --git a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go index 8df060e4170..be93ff58cf5 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/framework_test.go @@ -26,6 +26,7 @@ import ( "sync" "testing" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -660,3 +661,16 @@ func (tvde *testVDiffEnv) addTablet(id int, keyspace, shard string, tabletType t tstenv.SchemaEngine.Reload(context.Background()) return tvde.tablets[id] } + +func (tvde *testVDiffEnv) createController(t *testing.T) *controller { + controllerQR := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + vdiffTestCols, + vdiffTestColTypes, + ), + fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", uuid.New(), tvde.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), + ) + tvde.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) + ct, err := newController(context.Background(), controllerQR.Named().Row(), tvde.dbClientFactory, tstenv.TopoServ, tvde.vde, tvde.opts) + require.NoError(t, err) + return ct +} diff --git a/go/vt/vttablet/tabletmanager/vdiff/report_test.go b/go/vt/vttablet/tabletmanager/vdiff/report_test.go new file mode 100644 index 00000000000..39b3158b9e3 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vdiff/report_test.go @@ -0,0 +1,189 @@ +/* +Copyright 2022 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vdiff + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/sqltypes" + + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" +) + +func TestGenRowDiff(t *testing.T) { + vdenv := newTestVDiffEnv(t) + defer vdenv.close() + + testCases := []struct { + name string + schema *tabletmanagerdatapb.SchemaDefinition + query string + tablePlan *tablePlan + row []sqltypes.Value + reportOptions *tabletmanagerdatapb.VDiffReportOptions + want *RowDiff + wantErr bool + }{ + { + name: "defaults", + schema: &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, + }, + }, + query: "select c1,c2 from t1", + tablePlan: &tablePlan{ + selectPks: []int{0}, + }, + row: []sqltypes.Value{ + sqltypes.NewInt64(1), + sqltypes.NewInt64(2), + }, + reportOptions: &tabletmanagerdatapb.VDiffReportOptions{}, + want: &RowDiff{ + Row: map[string]string{ + "c1": "1", "c2": "2", + }, + }, + }, + { + name: "only PKs", + schema: &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, + }, + }, + query: "select c1,c2 from t1", + tablePlan: &tablePlan{ + selectPks: []int{0}, + }, + row: []sqltypes.Value{ + sqltypes.NewInt64(1), + sqltypes.NewInt64(2), + }, + reportOptions: &tabletmanagerdatapb.VDiffReportOptions{ + OnlyPks: true, + }, + want: &RowDiff{ + Row: map[string]string{ + "c1": "1", + }, + }, + }, + { + name: "debug query", + schema: &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, + }, + }, + query: "select c1,c2 from t1", + tablePlan: &tablePlan{ + selectPks: []int{0}, + }, + row: []sqltypes.Value{ + sqltypes.NewInt64(1), + sqltypes.NewInt64(2), + }, + reportOptions: &tabletmanagerdatapb.VDiffReportOptions{ + DebugQuery: true, + }, + want: &RowDiff{ + Row: map[string]string{ + "c1": "1", + "c2": "2", + }, + Query: "select c1, c2 from t1 where c1=1;", + }, + }, + { + name: "column truncation", + schema: &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{ + { + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "varchar|varchar"), + }, + }, + }, + query: "select c1,c2 from t1", + tablePlan: &tablePlan{ + selectPks: []int{0}, + }, + row: []sqltypes.Value{ + sqltypes.NewVarChar(strings.Repeat("a", 100)), + sqltypes.NewVarChar(strings.Repeat("b", 100)), + }, + reportOptions: &tabletmanagerdatapb.VDiffReportOptions{ + RowDiffColumnTruncateAt: 5, + }, + want: &RowDiff{ + Row: map[string]string{ + "c1": strings.Repeat("a", 100), // PK fields are not truncated + "c2": strings.Repeat("b", 5) + truncatedNotation, + }, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + require.NotNil(t, tc.tablePlan) + require.NotNil(t, tc.row) + require.NotNil(t, tc.reportOptions) + + vdenv.tmc.schema = tc.schema + ct := vdenv.createController(t) + wd, err := newWorkflowDiffer(ct, vdenv.opts, collations.MySQL8()) + require.NoError(t, err) + + td := &tableDiffer{ + wd: wd, + sourceQuery: tc.query, + tablePlan: tc.tablePlan, + } + got, err := td.genRowDiff(tc.query, tc.row, tc.reportOptions) + if tc.wantErr { + require.Error(t, err, "tableDiffer.genRowDiff() error = %v, wantErr %v", + err, tc.wantErr) + return + } else { + require.EqualValues(t, tc.want, got) + } + }) + } +} diff --git a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go index d4f9ddb001d..928d595e0cf 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go +++ b/go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go @@ -588,15 +588,7 @@ func TestBuildPlanInclude(t *testing.T) { vdenv := newTestVDiffEnv(t) defer vdenv.close() - controllerQR := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - vdiffTestCols, - vdiffTestColTypes, - ), - fmt.Sprintf("1|%s|%s|%s|%s|%s|%s|%s|", uuid.New(), vdiffenv.workflow, tstenv.KeyspaceName, tstenv.ShardName, vdiffDBName, PendingState, optionsJS), - ) - vdiffenv.dbClient.ExpectRequest("select * from _vt.vdiff where id = 1", noResults, nil) - ct, err := newController(context.Background(), controllerQR.Named().Row(), vdiffenv.dbClientFactory, tstenv.TopoServ, vdiffenv.vde, vdiffenv.opts) - require.NoError(t, err) + ct := vdenv.createController(t) schm := &tabletmanagerdatapb.SchemaDefinition{ TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{