Skip to content

Commit 56ff578

Browse files
committed
test: speed up compose lifecycle
1 parent b8a31fd commit 56ff578

17 files changed

Lines changed: 215 additions & 69 deletions

File tree

service/runway/server/docker-compose.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,23 @@ services:
1919
environment:
2020
MYSQL_ROOT_PASSWORD: root
2121
MYSQL_DATABASE: submitqueue
22+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
2223
ports:
2324
- "3306" # Random ephemeral port to avoid conflicts
25+
volumes:
26+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
27+
target: /var/lib/mysql
2428
healthcheck:
2529
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
2630
# "localhost" as a socket connection, which can be ready before the TCP
2731
# listener — causing dependent services that connect over TCP to fail.
2832
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
29-
interval: 5s
30-
timeout: 5s
31-
retries: 10
33+
interval: 1s
34+
timeout: 2s
35+
retries: 60
3236

3337
runway-service:
38+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-runway-service:latest
3439
build:
3540
context: ${REPO_ROOT}
3641
dockerfile: service/runway/server/Dockerfile

service/stovepipe/docker-compose.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,41 @@ services:
2323
environment:
2424
MYSQL_ROOT_PASSWORD: root
2525
MYSQL_DATABASE: submitqueue
26+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
2627
ports:
2728
- "3306" # Random ephemeral port to avoid conflicts
29+
volumes:
30+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
31+
target: /var/lib/mysql
2832
healthcheck:
2933
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
3034
# "localhost" as a socket connection, which can be ready before the TCP
3135
# listener — causing dependent services that connect over TCP to fail.
3236
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
33-
interval: 5s
34-
timeout: 5s
35-
retries: 10
37+
interval: 1s
38+
timeout: 2s
39+
retries: 60
3640

3741
# Queue database - messaging infrastructure (messages, offsets, partition leases).
3842
mysql-queue:
3943
image: mysql:8.0
4044
environment:
4145
MYSQL_ROOT_PASSWORD: root
4246
MYSQL_DATABASE: submitqueue
47+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
4348
ports:
4449
- "3306" # Random ephemeral port to avoid conflicts
50+
volumes:
51+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
52+
target: /var/lib/mysql
4553
healthcheck:
4654
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
47-
interval: 5s
48-
timeout: 5s
49-
retries: 10
55+
interval: 1s
56+
timeout: 2s
57+
retries: 60
5058

5159
stovepipe-service:
60+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-stovepipe-service:latest
5261
build:
5362
context: ${REPO_ROOT}
5463
dockerfile: service/stovepipe/server/Dockerfile

service/submitqueue/docker-compose.yml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ services:
1515
environment:
1616
MYSQL_ROOT_PASSWORD: root
1717
MYSQL_DATABASE: submitqueue
18+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
1819
ports:
1920
- "3306" # Random ephemeral port to avoid conflicts
21+
volumes:
22+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
23+
target: /var/lib/mysql
2024
healthcheck:
2125
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
2226
# "localhost" as a socket connection, which can be ready before the TCP
2327
# listener — causing dependent services that connect over TCP to fail.
2428
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
25-
interval: 5s
26-
timeout: 5s
27-
retries: 10
29+
interval: 1s
30+
timeout: 2s
31+
retries: 60
2832

2933
# Queue Database - Messaging infrastructure (messages, offsets, partition leases)
3034
# Separate from app DB to demonstrate queue is pluggable infrastructure
@@ -33,15 +37,20 @@ services:
3337
environment:
3438
MYSQL_ROOT_PASSWORD: root
3539
MYSQL_DATABASE: submitqueue
40+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
3641
ports:
3742
- "3306" # Random ephemeral port to avoid conflicts
43+
volumes:
44+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
45+
target: /var/lib/mysql
3846
healthcheck:
3947
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
40-
interval: 5s
41-
timeout: 5s
42-
retries: 10
48+
interval: 1s
49+
timeout: 2s
50+
retries: 60
4351

4452
gateway-service:
53+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-gateway-service:latest
4554
build:
4655
context: ${REPO_ROOT}
4756
dockerfile: service/submitqueue/gateway/server/Dockerfile
@@ -64,6 +73,7 @@ services:
6473
condition: service_healthy
6574

6675
orchestrator-service:
76+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-orchestrator-service:latest
6777
build:
6878
context: ${REPO_ROOT}
6979
dockerfile: service/submitqueue/orchestrator/server/Dockerfile
@@ -88,6 +98,7 @@ services:
8898
# needs the queue DB (shared with the orchestrator over mysql-queue); it has
8999
# no application database of its own.
90100
runway-service:
101+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-runway-service:latest
91102
build:
92103
context: ${REPO_ROOT}
93104
dockerfile: service/runway/server/Dockerfile

service/submitqueue/gateway/server/docker-compose.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ services:
1515
environment:
1616
MYSQL_ROOT_PASSWORD: root
1717
MYSQL_DATABASE: submitqueue
18+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
1819
ports:
1920
- "3306" # Random ephemeral port to avoid conflicts
21+
volumes:
22+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
23+
target: /var/lib/mysql
2024
healthcheck:
2125
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
2226
# "localhost" as a socket connection, which can be ready before the TCP
2327
# listener — causing dependent services that connect over TCP to fail.
2428
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
25-
interval: 5s
26-
timeout: 5s
27-
retries: 10
29+
interval: 1s
30+
timeout: 2s
31+
retries: 60
2832

2933
# Queue Database - Messaging infrastructure (messages, offsets, partition leases)
3034
# Separate from app DB to demonstrate queue is pluggable infrastructure
@@ -33,15 +37,20 @@ services:
3337
environment:
3438
MYSQL_ROOT_PASSWORD: root
3539
MYSQL_DATABASE: submitqueue
40+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
3641
ports:
3742
- "3306" # Random ephemeral port to avoid conflicts
43+
volumes:
44+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
45+
target: /var/lib/mysql
3846
healthcheck:
3947
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
40-
interval: 5s
41-
timeout: 5s
42-
retries: 10
48+
interval: 1s
49+
timeout: 2s
50+
retries: 60
4351

4452
gateway-service:
53+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-gateway-service:latest
4554
build:
4655
context: ${REPO_ROOT}
4756
dockerfile: service/submitqueue/gateway/server/Dockerfile

service/submitqueue/orchestrator/server/docker-compose.yml

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ services:
1515
environment:
1616
MYSQL_ROOT_PASSWORD: root
1717
MYSQL_DATABASE: submitqueue
18+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
1819
ports:
1920
- "3306" # Random ephemeral port to avoid conflicts
21+
volumes:
22+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
23+
target: /var/lib/mysql
2024
healthcheck:
2125
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
2226
# "localhost" as a socket connection, which can be ready before the TCP
2327
# listener — causing dependent services that connect over TCP to fail.
2428
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
25-
interval: 5s
26-
timeout: 5s
27-
retries: 10
29+
interval: 1s
30+
timeout: 2s
31+
retries: 60
2832

2933
# Queue Database - Messaging infrastructure (messages, offsets, partition leases)
3034
# Separate from app DB to demonstrate queue is pluggable infrastructure
@@ -33,15 +37,20 @@ services:
3337
environment:
3438
MYSQL_ROOT_PASSWORD: root
3539
MYSQL_DATABASE: submitqueue
40+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
3641
ports:
3742
- "3306" # Random ephemeral port to avoid conflicts
43+
volumes:
44+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
45+
target: /var/lib/mysql
3846
healthcheck:
3947
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
40-
interval: 5s
41-
timeout: 5s
42-
retries: 10
48+
interval: 1s
49+
timeout: 2s
50+
retries: 60
4351

4452
orchestrator-service:
53+
image: ${SQ_DOCKER_IMAGE_PREFIX:-submitqueue}-orchestrator-service:latest
4554
build:
4655
context: ${REPO_ROOT}
4756
dockerfile: service/submitqueue/orchestrator/server/Dockerfile

test/integration/extension/counter/mysql/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ go_test(
55
srcs = ["counter_test.go"],
66
data = [
77
"docker-compose.yml",
8+
"//:MODULE.bazel",
9+
"//:go.mod",
810
"//platform/extension/counter/mysql/schema",
911
],
1012
tags = [

test/integration/extension/counter/mysql/docker-compose.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ services:
88
environment:
99
MYSQL_ROOT_PASSWORD: root
1010
MYSQL_DATABASE: submitqueue
11+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
1112
ports:
1213
- "3306" # Random ephemeral port to avoid conflicts
14+
volumes:
15+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
16+
target: /var/lib/mysql
1317
healthcheck:
1418
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
1519
# "localhost" as a socket connection, which can be ready before the TCP
1620
# listener — causing dependent services that connect over TCP to fail.
1721
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
18-
interval: 5s
19-
timeout: 5s
20-
retries: 10
22+
interval: 1s
23+
timeout: 2s
24+
retries: 60

test/integration/extension/messagequeue/mysql/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ go_test(
55
srcs = ["queue_test.go"],
66
data = [
77
"docker-compose.yml",
8+
"//:MODULE.bazel",
9+
"//:go.mod",
810
"//platform/extension/messagequeue/mysql/schema",
911
],
1012
tags = [

test/integration/extension/messagequeue/mysql/docker-compose.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ services:
88
environment:
99
MYSQL_ROOT_PASSWORD: root
1010
MYSQL_DATABASE: submitqueue
11+
MYSQL_INITDB_SKIP_TZINFO: ${SQ_MYSQL_INITDB_SKIP_TZINFO:-}
1112
ports:
1213
- "3306" # Random ephemeral port to avoid conflicts
14+
volumes:
15+
- type: ${SQ_MYSQL_DATA_MOUNT_TYPE:-volume}
16+
target: /var/lib/mysql
1317
healthcheck:
1418
# Use 127.0.0.1 (TCP) instead of localhost (Unix socket). MySQL treats
1519
# "localhost" as a socket connection, which can be ready before the TCP
1620
# listener — causing dependent services that connect over TCP to fail.
1721
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
18-
interval: 5s
19-
timeout: 5s
20-
retries: 10
22+
interval: 1s
23+
timeout: 2s
24+
retries: 60

test/integration/extension/messagequeue/mysql/queue_test.go

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,40 @@ func waitForCondition(t *testing.T, signalCh <-chan queueMySQL.HookSignal, condi
291291
}
292292
}
293293

294+
// waitForLag waits for subscriber polls until the selected consumer lag
295+
// converges to expected. Lag must not advance past the expected value.
296+
func waitForLag(
297+
t *testing.T,
298+
ctx context.Context,
299+
admin *queueAdmin.AdminStore,
300+
signalCh <-chan queueMySQL.HookSignal,
301+
topic string,
302+
consumerGroup string,
303+
partitionKey string,
304+
expected int64,
305+
) int64 {
306+
t.Helper()
307+
308+
for {
309+
lags, err := admin.ConsumerLag(ctx, topic)
310+
require.NoError(t, err)
311+
312+
var actual int64 = -1
313+
for _, lag := range lags {
314+
if lag.ConsumerGroup == consumerGroup && lag.PartitionKey == partitionKey {
315+
actual = lag.Lag
316+
break
317+
}
318+
}
319+
320+
require.GreaterOrEqual(t, actual, expected, "watermark advanced past expected lag")
321+
if actual == expected {
322+
return actual
323+
}
324+
waitForSignal(t, signalCh, queueMySQL.SignalDeliveryCheck)
325+
}
326+
}
327+
294328
func (s *SQLQueueIntegrationSuite) TestPublishAndSubscribe() {
295329
t := s.T()
296330

@@ -2396,18 +2430,9 @@ func (s *SQLQueueIntegrationSuite) TestWatermarkAdvancesContiguously() {
23962430

23972431
admin := queueAdmin.NewAdminStore(s.db)
23982432

2399-
// Helper to get consumer lag
2400-
getLag := func() int64 {
2401-
lags, err := admin.ConsumerLag(s.ctx, topic)
2402-
require.NoError(t, err)
2403-
for _, lag := range lags {
2404-
if lag.ConsumerGroup == "watermark-cg" && lag.PartitionKey == "wm-part" {
2405-
return lag.Lag
2406-
}
2407-
}
2408-
return -1
2409-
}
2410-
2433+
// Watermark advancement is incremental and runs in the subscriber poll loop.
2434+
// A delivery-check signal proves one poll completed, but the watermark may
2435+
// need another poll to converge after several acknowledgements.
24112436
// Ack message 3 first (out of order)
24122437
require.NoError(t, deliveries["wm-msg-3"].Ack(s.ctx))
24132438
t.Logf("Acked msg-3")
@@ -2417,31 +2442,24 @@ func (s *SQLQueueIntegrationSuite) TestWatermarkAdvancesContiguously() {
24172442
require.NoError(t, deliveries["wm-msg-2"].Ack(s.ctx))
24182443
t.Logf("Acked msg-1 and msg-2")
24192444

2420-
// Wait for poll loop to advance watermark
2421-
waitForSignal(t, signalCh, queueMySQL.SignalDeliveryCheck)
2422-
24232445
// After acking 1,2,3: watermark should advance to 3, lag should be 2 (msg-4, msg-5)
2424-
lag := getLag()
2446+
lag := waitForLag(t, s.ctx, admin, signalCh, topic, "watermark-cg", "wm-part", 2)
24252447
assert.Equal(t, int64(2), lag, "lag should be 2 after acking 1,2,3 (4 and 5 remain)")
24262448
t.Logf("After acking 1,2,3: lag=%d", lag)
24272449

24282450
// Ack message 5 (skip 4) — watermark should NOT advance past 3
24292451
require.NoError(t, deliveries["wm-msg-5"].Ack(s.ctx))
24302452
t.Logf("Acked msg-5 (skipping msg-4)")
24312453

2432-
waitForSignal(t, signalCh, queueMySQL.SignalDeliveryCheck)
2433-
2434-
lag = getLag()
2454+
lag = waitForLag(t, s.ctx, admin, signalCh, topic, "watermark-cg", "wm-part", 2)
24352455
assert.Equal(t, int64(2), lag, "lag should still be 2 after acking 5 but not 4")
24362456
t.Logf("After acking 5 (not 4): lag=%d", lag)
24372457

24382458
// Ack message 4 — now all 5 are contiguous, watermark should advance to 5
24392459
require.NoError(t, deliveries["wm-msg-4"].Ack(s.ctx))
24402460
t.Logf("Acked msg-4")
24412461

2442-
waitForSignal(t, signalCh, queueMySQL.SignalDeliveryCheck)
2443-
2444-
lag = getLag()
2462+
lag = waitForLag(t, s.ctx, admin, signalCh, topic, "watermark-cg", "wm-part", 0)
24452463
assert.Equal(t, int64(0), lag, "lag should be 0 after acking all 5 messages")
24462464
t.Logf("After acking all 5: lag=%d", lag)
24472465

0 commit comments

Comments
 (0)