Skip to content

Commit 8ecfaf3

Browse files
committed
add tests
Signed-off-by: Nick Van Wiggeren <[email protected]>
1 parent 29fb9e0 commit 8ecfaf3

File tree

4 files changed

+172
-4
lines changed

4 files changed

+172
-4
lines changed

go/test/endtoend/vtgate/misc_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,56 @@ func TestDDLTargeted(t *testing.T) {
835835
utils.AssertMatches(t, conn, `select id from ddl_targeted`, `[[INT64(1)]]`)
836836
}
837837

838+
// TestTabletTargeting tests tablet-specific routing with USE keyspace@tablet-alias syntax.
839+
func TestTabletTargeting(t *testing.T) {
840+
ctx := context.Background()
841+
conn, err := mysql.Connect(ctx, &vtParams)
842+
require.NoError(t, err)
843+
defer conn.Close()
844+
845+
// Get tablet aliases from show vitess_tablets
846+
qr := utils.Exec(t, conn, "show vitess_tablets")
847+
require.Greater(t, len(qr.Rows), 0, "no tablets found")
848+
849+
// Find a PRIMARY tablet
850+
var primaryAlias string
851+
for _, row := range qr.Rows {
852+
tabletType := row[3].ToString()
853+
if tabletType == "PRIMARY" {
854+
primaryAlias = row[0].ToString()
855+
break
856+
}
857+
}
858+
require.NotEmpty(t, primaryAlias, "no PRIMARY tablet found")
859+
860+
// Test: Basic tablet-specific SELECT
861+
utils.Exec(t, conn, fmt.Sprintf("USE ks@%s", primaryAlias))
862+
utils.Exec(t, conn, "insert into t1(id1, id2) values(9001, 1)")
863+
utils.AssertMatches(t, conn, "select id1 from t1 where id1=9001", "[[INT64(9001)]]")
864+
865+
// Test: Clear tablet targeting with plain USE
866+
utils.Exec(t, conn, "USE ks")
867+
utils.AssertMatches(t, conn, "select id1 from t1 where id1=9001", "[[INT64(9001)]]")
868+
869+
// Test: Transaction with tablet-specific routing
870+
utils.Exec(t, conn, fmt.Sprintf("USE ks@%s", primaryAlias))
871+
utils.Exec(t, conn, "begin")
872+
utils.Exec(t, conn, "insert into t1(id1, id2) values(9002, 1)")
873+
utils.Exec(t, conn, "commit")
874+
utils.AssertMatches(t, conn, "select id1 from t1 where id1 in (9001, 9002) order by id1", "[[INT64(9001)] [INT64(9002)]]")
875+
876+
// Test: Rollback with tablet-specific routing
877+
utils.Exec(t, conn, fmt.Sprintf("USE ks@%s", primaryAlias))
878+
utils.Exec(t, conn, "begin")
879+
utils.Exec(t, conn, "insert into t1(id1, id2) values(9003, 1)")
880+
utils.Exec(t, conn, "rollback")
881+
// 9003 should not exist
882+
utils.AssertIsEmpty(t, conn, "select id1 from t1 where id1=9003")
883+
884+
// Cleanup
885+
utils.Exec(t, conn, "delete from t1 where id1 >= 9001 and id1 <= 9003")
886+
}
887+
838888
// TestDynamicConfig tests the dynamic configurations.
839889
func TestDynamicConfig(t *testing.T) {
840890
t.Run("DiscoveryLowReplicationLag", func(t *testing.T) {

go/vt/topo/topoproto/destination_test.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func TestParseDestination(t *testing.T) {
3535
dest key.ShardDestination
3636
keyspace string
3737
tabletType topodatapb.TabletType
38+
tabletAlias *topodatapb.TabletAlias
3839
}{{
3940
targetString: "ks[10-20]@primary",
4041
keyspace: "ks",
@@ -87,18 +88,36 @@ func TestParseDestination(t *testing.T) {
8788
keyspace: "ks",
8889
dest: key.DestinationShard("-80"),
8990
tabletType: topodatapb.TabletType_PRIMARY,
91+
}, {
92+
targetString: "ks@zone1-0000000100",
93+
keyspace: "ks",
94+
tabletType: topodatapb.TabletType_PRIMARY,
95+
tabletAlias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100},
96+
}, {
97+
targetString: "ks:-80@zone1-0000000100",
98+
keyspace: "ks",
99+
dest: key.DestinationShard("-80"),
100+
tabletType: topodatapb.TabletType_PRIMARY,
101+
tabletAlias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 100},
102+
}, {
103+
targetString: "@zone1-0000000200",
104+
keyspace: "",
105+
tabletType: topodatapb.TabletType_PRIMARY,
106+
tabletAlias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 200},
90107
}}
91108

92109
for _, tcase := range testcases {
93-
if targetKeyspace, targetTabletType, targetDest, _, _ := ParseDestination(tcase.targetString, topodatapb.TabletType_PRIMARY); !reflect.DeepEqual(targetDest, tcase.dest) || targetKeyspace != tcase.keyspace || targetTabletType != tcase.tabletType {
94-
t.Errorf("ParseDestination(%s) - got: (%v, %v, %v), want (%v, %v, %v)",
110+
if targetKeyspace, targetTabletType, targetDest, targetAlias, _ := ParseDestination(tcase.targetString, topodatapb.TabletType_PRIMARY); !reflect.DeepEqual(targetDest, tcase.dest) || targetKeyspace != tcase.keyspace || targetTabletType != tcase.tabletType || !reflect.DeepEqual(targetAlias, tcase.tabletAlias) {
111+
t.Errorf("ParseDestination(%s) - got: (%v, %v, %v, %v), want (%v, %v, %v, %v)",
95112
tcase.targetString,
96-
targetDest,
97113
targetKeyspace,
98114
targetTabletType,
99-
tcase.dest,
115+
targetDest,
116+
targetAlias,
100117
tcase.keyspace,
101118
tcase.tabletType,
119+
tcase.dest,
120+
tcase.tabletAlias,
102121
)
103122
}
104123
}

go/vt/vtgate/executorcontext/safe_session_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,37 @@ func TestTimeZone(t *testing.T) {
205205
})
206206
}
207207
}
208+
209+
// TestTargetTabletAlias tests the SetTargetTabletAlias and GetTargetTabletAlias methods.
210+
func TestTargetTabletAlias(t *testing.T) {
211+
session := NewSafeSession(&vtgatepb.Session{})
212+
213+
// Test: initially nil
214+
assert.Nil(t, session.GetTargetTabletAlias())
215+
216+
// Test: Set and get
217+
alias := &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}
218+
session.SetTargetTabletAlias(alias)
219+
got := session.GetTargetTabletAlias()
220+
assert.Equal(t, alias, got)
221+
222+
// Test: Clear (set to nil)
223+
session.SetTargetTabletAlias(nil)
224+
assert.Nil(t, session.GetTargetTabletAlias())
225+
226+
// Test: Thread safety - concurrent access
227+
done := make(chan bool)
228+
for i := 0; i < 100; i++ {
229+
go func(uid uint32) {
230+
testAlias := &topodatapb.TabletAlias{Cell: "cell", Uid: uid}
231+
session.SetTargetTabletAlias(testAlias)
232+
_ = session.GetTargetTabletAlias()
233+
done <- true
234+
}(uint32(i))
235+
}
236+
for i := 0; i < 100; i++ {
237+
<-done
238+
}
239+
// Just verify we didn't panic - the final value is non-deterministic
240+
assert.NotNil(t, session.GetTargetTabletAlias())
241+
}

go/vt/vtgate/scatter_conn_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,3 +632,68 @@ func TestIsConnClosed(t *testing.T) {
632632
})
633633
}
634634
}
635+
636+
// TestActionInfoWithTabletAlias tests the actionInfo function with tablet-specific routing.
637+
func TestActionInfoWithTabletAlias(t *testing.T) {
638+
ctx := utils.LeakCheckContext(t)
639+
target := &querypb.Target{
640+
Keyspace: "ks",
641+
Shard: "-80",
642+
TabletType: topodatapb.TabletType_PRIMARY,
643+
}
644+
tabletAlias := &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}
645+
646+
t.Run("non-transactional with tablet alias", func(t *testing.T) {
647+
session := econtext.NewSafeSession(&vtgatepb.Session{})
648+
session.SetTargetTabletAlias(tabletAlias)
649+
650+
info, shardSession, err := actionInfo(ctx, target, session, false, vtgatepb.TransactionMode_MULTI)
651+
require.NoError(t, err)
652+
assert.Nil(t, shardSession)
653+
assert.Equal(t, nothing, info.actionNeeded)
654+
assert.Equal(t, tabletAlias, info.alias)
655+
})
656+
657+
t.Run("transaction begin with tablet alias", func(t *testing.T) {
658+
session := econtext.NewSafeSession(&vtgatepb.Session{
659+
InTransaction: true,
660+
})
661+
session.SetTargetTabletAlias(tabletAlias)
662+
663+
info, shardSession, err := actionInfo(ctx, target, session, false, vtgatepb.TransactionMode_MULTI)
664+
require.NoError(t, err)
665+
assert.Nil(t, shardSession)
666+
assert.Equal(t, begin, info.actionNeeded)
667+
assert.Equal(t, tabletAlias, info.alias)
668+
})
669+
670+
t.Run("existing transaction with tablet alias", func(t *testing.T) {
671+
session := econtext.NewSafeSession(&vtgatepb.Session{
672+
InTransaction: true,
673+
ShardSessions: []*vtgatepb.Session_ShardSession{{
674+
Target: target,
675+
TransactionId: 12345,
676+
TabletAlias: &topodatapb.TabletAlias{Cell: "zone1", Uid: 50},
677+
}},
678+
})
679+
session.SetTargetTabletAlias(tabletAlias)
680+
681+
info, shardSession, err := actionInfo(ctx, target, session, false, vtgatepb.TransactionMode_MULTI)
682+
require.NoError(t, err)
683+
assert.NotNil(t, shardSession)
684+
assert.Equal(t, int64(12345), info.transactionID)
685+
assert.Equal(t, nothing, info.actionNeeded)
686+
// Tablet alias should be overridden
687+
assert.Equal(t, tabletAlias, info.alias)
688+
})
689+
690+
t.Run("no tablet alias - existing behavior", func(t *testing.T) {
691+
session := econtext.NewSafeSession(&vtgatepb.Session{})
692+
693+
info, shardSession, err := actionInfo(ctx, target, session, false, vtgatepb.TransactionMode_MULTI)
694+
require.NoError(t, err)
695+
assert.Nil(t, shardSession)
696+
assert.Equal(t, nothing, info.actionNeeded)
697+
assert.Nil(t, info.alias)
698+
})
699+
}

0 commit comments

Comments
 (0)