Skip to content

Commit 37b7e62

Browse files
committed
Add more e2e tests
Signed-off-by: Mohamed Hamza <mhamza15@github.com>
1 parent cd30d9d commit 37b7e62

3 files changed

Lines changed: 180 additions & 109 deletions

File tree

‎go/test/endtoend/vtgate/sessionbalancer/main_test.go‎

Lines changed: 0 additions & 79 deletions
This file was deleted.

‎go/test/endtoend/vtgate/sessionbalancer/session_test.go‎

Lines changed: 180 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,71 +18,226 @@ package sessionbalancer
1818

1919
import (
2020
"context"
21+
_ "embed"
22+
"fmt"
23+
"slices"
2124
"testing"
25+
"time"
2226

2327
"github.com/stretchr/testify/require"
2428

2529
"vitess.io/vitess/go/mysql"
30+
"vitess.io/vitess/go/test/endtoend/cluster"
2631
)
2732

33+
const (
34+
cell = "test_misc"
35+
keyspace = "uks"
36+
)
37+
38+
//go:embed uschema.sql
39+
var uschemaSQL string
40+
41+
func createCluster(t *testing.T, replicaCount int) (*cluster.LocalProcessCluster, *mysql.ConnParams) {
42+
t.Helper()
43+
44+
// Create a new clusterInstance
45+
clusterInstance := cluster.NewCluster(cell, "localhost")
46+
47+
// Start topo server
48+
err := clusterInstance.StartTopo()
49+
require.NoError(t, err, "Failed to start topo server")
50+
51+
// Enable session balancer in vtgate
52+
clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs,
53+
"--enable-balancer",
54+
"--balancer-vtgate-cells", clusterInstance.Cell,
55+
"--balancer-type", "session")
56+
57+
ks := cluster.Keyspace{
58+
Name: keyspace,
59+
SchemaSQL: uschemaSQL,
60+
}
61+
err = clusterInstance.StartUnshardedKeyspace(ks, replicaCount, false)
62+
require.NoError(t, err, "Failed to start keyspace")
63+
64+
err = clusterInstance.StartVtgate()
65+
require.NoError(t, err, "Failed to start vtgate")
66+
67+
vtParams := clusterInstance.GetVTParams(keyspace)
68+
69+
return clusterInstance, &vtParams
70+
}
71+
2872
// TestSessionBalancer validates that the session balancer consistently routes
2973
// queries for the same session to the same tablet.
3074
func TestSessionBalancer(t *testing.T) {
75+
cluster, vtParams := createCluster(t, 2)
76+
defer cluster.Teardown()
77+
78+
// Get connections that route to different tablets
79+
conns, ids := connections(t, vtParams, "replica", 2)
80+
81+
for _, conn := range conns {
82+
defer conn.Close()
83+
}
84+
85+
// Validate that each connection consistently returns the same server ID
86+
for range 20 {
87+
for i, conn := range conns {
88+
id := serverID(t, conn)
89+
require.Equal(t, ids[i], id)
90+
}
91+
}
92+
}
93+
94+
// TestSessionBalancerRemoveTablet validates that when a tablet is killed,
95+
// connections that were using that tablet get rerouted to remaining tablets.
96+
func TestSessionBalancerRemoveTablet(t *testing.T) {
97+
cluster, vtParams := createCluster(t, 2)
98+
defer cluster.Teardown()
99+
31100
// Get connections that route to different tablets
32-
conn1, conn2, id1, id2 := connections(t)
101+
conns, _ := connections(t, vtParams, "replica", 2)
102+
conn1, conn2 := conns[0], conns[1]
33103

34104
defer conn1.Close()
35105
defer conn2.Close()
36106

37-
// Validate that each connection consistently returns the same server ID
107+
tablets := tablets(t, cluster, "replica")
108+
require.NotNil(t, tablets)
109+
require.Len(t, tablets, 2)
110+
111+
err := tablets[0].VttabletProcess.TearDown()
112+
require.NoError(t, err)
113+
114+
time.Sleep(10 * time.Millisecond)
115+
38116
for range 20 {
39117
newID1 := serverID(t, conn1)
40-
require.Equal(t, id1, newID1)
41-
42118
newID2 := serverID(t, conn2)
43-
require.Equal(t, id2, newID2)
44119

45-
require.NotEqual(t, newID2, newID1)
120+
require.Equal(t, newID1, newID2)
121+
}
122+
}
123+
124+
// TestSessionBalancerAddTablet validates that when a new tablet is added,
125+
// new connections get routed to the new tablet.
126+
func TestSessionBalancerAddTablet(t *testing.T) {
127+
cluster, vtParams := createCluster(t, 3)
128+
defer cluster.Teardown()
129+
130+
// Get 3 connections that route to different tablets
131+
conns, ids := connections(t, vtParams, "replica", 3)
132+
for _, conn := range conns {
133+
defer conn.Close()
134+
}
135+
136+
tablets := tablets(t, cluster, "replica")
137+
require.NotNil(t, tablets)
138+
require.Len(t, tablets, 3)
139+
140+
// Start with only 2 tablets serving
141+
tablet := tablets[2]
142+
err := tablet.VttabletProcess.TearDown()
143+
require.NoError(t, err)
144+
145+
time.Sleep(10 * time.Millisecond)
146+
147+
// Find the connection that moved
148+
var conn *mysql.Conn
149+
for i, c := range conns {
150+
newID := serverID(t, c)
151+
if newID != ids[i] {
152+
conn = c
153+
break
154+
}
155+
}
156+
157+
require.NotNil(t, conn, "One connection should've moved tablets")
158+
159+
// Start up the tablet again
160+
err = tablet.RestartOnlyTablet()
161+
require.NoError(t, err)
162+
163+
time.Sleep(10 * time.Millisecond)
164+
165+
// All connections should route to the same IDs again
166+
for range 20 {
167+
for i, conn := range conns {
168+
id := ids[i]
169+
newID := serverID(t, conn)
170+
require.Equal(t, id, newID)
171+
}
46172
}
47173
}
48174

49-
// connections returns two connections that should route to different servers.
50-
func connections(t *testing.T) (conn1, conn2 *mysql.Conn, id1, id2 string) {
175+
// connections returns the specified number of connections that should route to different tablets.
176+
func connections(t *testing.T, vtParams *mysql.ConnParams, tabletType string, numConnections int) ([]*mysql.Conn, []string) {
51177
t.Helper()
52178

53-
// Keep creating connections until we find two that route to different server IDs
54-
vtParams.DbName = uks + "@replica"
55-
for {
56-
conn1, err := mysql.Connect(context.Background(), &vtParams)
57-
require.NoError(t, err)
179+
vtParams.DbName = fmt.Sprintf("%s@%s", keyspace, tabletType)
180+
181+
conns := make([]*mysql.Conn, 0, numConnections)
182+
ids := make([]string, 0, numConnections)
58183

59-
conn2, err = mysql.Connect(context.Background(), &vtParams)
184+
// Keep creating connections until we have the required number with different server IDs
185+
for range 20 {
186+
conn, err := mysql.Connect(context.Background(), vtParams)
60187
require.NoError(t, err)
61188

62-
id1 = serverID(t, conn1)
63-
id2 = serverID(t, conn2)
189+
id := serverID(t, conn)
190+
newID := !slices.Contains(ids, id)
191+
192+
// If we found a new tablet, add it to the list of connections
193+
if newID {
194+
conns = append(conns, conn)
195+
ids = append(ids, id)
196+
197+
if len(conns) == numConnections {
198+
return conns, ids
199+
}
64200

65-
// Break if we found connections with different server IDs
66-
if id1 != id2 {
67-
return conn1, conn2, id1, id2
201+
continue
68202
}
69203

70-
// If not, close the connections and try again
71-
conn1.Close()
72-
conn2.Close()
204+
conn.Close()
73205
}
206+
207+
t.Fatalf("could not create %d connections with different tablet connections", numConnections)
208+
return nil, nil
74209
}
75210

76-
// serverID runs a `SELECT @@server_id` on the given connection and returns the
77-
// server's ID.
211+
// serverID runs a `SELECT @@server_id` on the given connection and returns the server's ID.
78212
func serverID(t *testing.T, conn *mysql.Conn) string {
79213
t.Helper()
80214

81-
result1, err := conn.ExecuteFetch("SELECT @@server_uuid", 1, false)
215+
result1, err := conn.ExecuteFetch("SELECT @@server_id", 1, false)
82216
require.NoError(t, err)
83217

84218
tablet1Bytes, err := result1.Rows[0][0].ToBytes()
85219
require.NoError(t, err)
86220

87221
return string(tablet1Bytes)
88222
}
223+
224+
func tablets(t *testing.T, clusterInstance *cluster.LocalProcessCluster, tabletType string) []*cluster.Vttablet {
225+
t.Helper()
226+
227+
if len(clusterInstance.Keyspaces) == 0 {
228+
return nil
229+
}
230+
231+
if len(clusterInstance.Keyspaces[0].Shards) == 0 {
232+
return nil
233+
}
234+
235+
tablets := make([]*cluster.Vttablet, 0, 2)
236+
for _, tablet := range clusterInstance.Keyspaces[0].Shards[0].Vttablets {
237+
if tablet.Type == tabletType {
238+
tablets = append(tablets, tablet)
239+
}
240+
}
241+
242+
return tablets
243+
}

‎go/test/endtoend/vtgate/sessionbalancer/uschema.sql‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,3 @@ CREATE TABLE t1 (
22
id int PRIMARY KEY,
33
name varchar(255)
44
);
5-
6-
CREATE TABLE t2 (
7-
id int PRIMARY KEY,
8-
value varchar(255)
9-
);

0 commit comments

Comments
 (0)