Skip to content

Commit 31289c9

Browse files
committed
Add helper public method to validate that a replica with a given server_id is not registered.
And use it in the feature tests.
1 parent 8244b45 commit 31289c9

2 files changed

Lines changed: 37 additions & 33 deletions

File tree

flow/connectors/mysql/cdc_test.go

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/PeerDB-io/peerdb/flow/generated/protos"
2525
"github.com/PeerDB-io/peerdb/flow/model"
2626
"github.com/PeerDB-io/peerdb/flow/otel_metrics"
27+
mysql_validation "github.com/PeerDB-io/peerdb/flow/pkg/mysql"
2728
"github.com/PeerDB-io/peerdb/flow/shared"
2829
)
2930

@@ -137,38 +138,6 @@ func TestIntegrationANSIQuotesDDLParsedFromBinlog(t *testing.T) {
137138
}
138139
}
139140

140-
func sourceHasRegisteredReplica(ctx context.Context, c *MySqlConnector, serverID uint32) (bool, error) {
141-
rs, err := c.Execute(ctx, "SHOW REPLICAS")
142-
if err != nil {
143-
if rs, err = c.Execute(ctx, "SHOW SLAVE HOSTS"); err != nil {
144-
return false, fmt.Errorf("failed to query source for registered replicas")
145-
}
146-
}
147-
148-
serverIDCol := -1
149-
for i, field := range rs.Fields {
150-
// Case insensitive match because the column name differs between MySQL and MariaDB.
151-
if strings.EqualFold(string(field.Name), "Server_id") {
152-
serverIDCol = i
153-
break
154-
}
155-
}
156-
if serverIDCol < 0 {
157-
return false, fmt.Errorf("no Server_id column in replica list, got fields %v", rs.Fields)
158-
}
159-
160-
for row := range rs.RowNumber() {
161-
got, err := rs.GetInt(row, serverIDCol)
162-
if err != nil {
163-
return false, err
164-
}
165-
if uint32(got) == serverID {
166-
return true, nil
167-
}
168-
}
169-
return false, nil
170-
}
171-
172141
// TestIntegrationConfiguredServerID verifies that an explicitly configured server_id is used for
173142
// the binlog connection instead of the legacy random fallback: the source must list a replica
174143
// registered with exactly that id.
@@ -193,7 +162,7 @@ func TestIntegrationConfiguredServerID(t *testing.T) {
193162

194163
// The source's replica list can lag briefly after registration, so retry until it shows up.
195164
require.EventuallyWithT(t, func(c *assert.CollectT) {
196-
found, err := sourceHasRegisteredReplica(ctx, connector, wantServerID)
165+
found, err := mysql_validation.HasReplicaWithServerId(connector.conn.Load(), wantServerID)
197166
assert.NoError(c, err)
198167
assert.True(c, found, "source does not list a replica registered with server_id %d", wantServerID)
199168
}, 15*time.Second, time.Second)

flow/pkg/mysql/validation.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,38 @@ func IsVitess(conn *client.Conn) (bool, error) {
295295
}
296296
return true, nil // is a Vitess server
297297
}
298+
299+
func HasReplicaWithServerId(conn *client.Conn, serverID uint32) (bool, error) {
300+
// This check assumes that the number of replicas is not beyond the order of magnitude of thousands.
301+
// This is a reasonable assumption given that services like RDS limit them to 15 and that
302+
// this number is constrained by concurrent connections and main server resources.
303+
rs, err := conn.Execute("SHOW REPLICAS")
304+
if err != nil {
305+
if rs, err = conn.Execute("SHOW SLAVE HOSTS"); err != nil {
306+
return false, fmt.Errorf("failed to query source for registered replicas")
307+
}
308+
}
309+
310+
serverIDCol := -1
311+
for i, field := range rs.Fields {
312+
// Case insensitive match because the column name differs between MySQL and MariaDB.
313+
if strings.EqualFold(string(field.Name), "Server_id") {
314+
serverIDCol = i
315+
break
316+
}
317+
}
318+
if serverIDCol < 0 {
319+
return false, fmt.Errorf("no Server_id column in replica list, got fields %v", rs.Fields)
320+
}
321+
322+
for row := range rs.RowNumber() {
323+
got, err := rs.GetInt(row, serverIDCol)
324+
if err != nil {
325+
return false, err
326+
}
327+
if uint32(got) == serverID {
328+
return true, nil
329+
}
330+
}
331+
return false, nil
332+
}

0 commit comments

Comments
 (0)