Skip to content

Commit cd8fe6d

Browse files
pfcoperezilidemiCopilot
authored
Tilt local env: Expand the set of tests that can run locally by adding Toxyproxy service and separating PG connections in tests (#4156)
This PR: 1. Adds `Toxiproxy` as Tilt resource, optionally initialized as other ancillary services. 2. Separates PG access in several tests that assumed PG DB for PeerDB catalog and Source DB to be the same. 3. Changes error matching from `==` to `errors.Is()` 4. Cleans-up Toxiproxy configuration when the tests using it complete. 5. Sets `PEERDB_VERSION_SHA_SHORT` to non-empty strings in Tilt environment. 6. Improves reliability of `TestResyncFailed` by: a. Cancelling the pipeline before tearing down PSQL. b. Limiting backend PID kill to `peer` db application as we want to test how the pipeline fails without affecting the client pool at test code side. c. Separating the catalog checks connection application from the one being killed. 7. Adds `ssh` as Tilt resource, optionally initialized as other ancillary services. This make the following e2e pass locally: - `env -f ../.envgo test ./e2e/... -v -test.run TestApiPg` - `env -f ../.envgo test ./e2e/... -v -test.run TestApiMy` - `env -f ../.envgo test ./e2e/... -v -test.run TestApiMongo` - `env -f ../.envgo test ./e2e/... -v -test.run ^TestPeerFlowE2ETestSuitePG_CH$` - `env -f ../.envgo test ./e2e/... -v -test.run ^TestPeerFlowE2ETestSuiteMySQL_CH$` - `env -f ../.envgo test ./e2e/... -v -test.run TestGenericCH_PG` - `env -f ../.envgo test ./e2e/... -v -test.run TestGenericCH_MySQL` - `env -f ../.envgo test ./e2e/... -v -test.run TestMongoClickhouseSuite` - `env -f ../.envgo test ./e2e/... -v -test.run TestSwitchboardMongo` - `env -f ../.envgo test ./e2e/... -v -test.run TestSwitchboardMySQL` - `env -f ../.envgo test ./e2e/... -v -test.run TestSwitchboardPostgres` - `env -f ../.envgo test ./connectors/postgres/... -v` - `env -f ../.envgo test ./connectors/clickhouse/... -v` -> ⚠️ Passing all but: - `env -f ../.envTestIAMRoleCanIssueSelectFromS3` This test uses AWS access credentials, I don't think it matches minio features, skipping when `FLOW_TESTS_AWS_S3_BUCKET_NAME` is not present. 📝 This PR doesn't address the env var injection with `godotenv` so `enf -f` doesn't need to be used. It doesn't expand the "Run through Tilt UI clicks" addition of all the supported cases, I am adding both in a follow-up PR. Closes: https://linear.app/clickhouse/issue/DBI-640 --------- Co-authored-by: Ilia Demianenko <ilia.demianenko@clickhouse.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 26bde72 commit cd8fe6d

13 files changed

Lines changed: 350 additions & 195 deletions

Tiltfile

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ docker_build('flow-api', '.',
66
dockerfile='stacks/flow.Dockerfile',
77
target='flow-api',
88
only=['flow/', 'stacks/flow.Dockerfile'],
9-
build_args={'PEERDB_VERSION_SHA_SHORT': os.getenv('PEERDB_VERSION_SHA_SHORT', '')},
9+
build_args={'PEERDB_VERSION_SHA_SHORT': os.getenv('PEERDB_VERSION_SHA_SHORT', 'unknown')},
1010
)
1111

1212
docker_build('flow-worker', '.',
@@ -149,6 +149,11 @@ dc_resource('dozzle', labels=['Monitoring'], links=[
149149
link('http://localhost:8118', 'Dozzle Container Monitor'),
150150
])
151151

152+
# Test services: Services supporting test execution that are not data stores, like proxies, mock servers, etc.
153+
154+
dc_resource('toxiproxy', labels=['TestInfra'], auto_init=False)
155+
dc_resource('openssh', labels=['TestInfra'], auto_init=False)
156+
152157
# Cleanup
153158

154159
load('ext://uibutton', 'cmd_button', 'location')
@@ -178,6 +183,8 @@ def e2e_test(name, test_run, extra_deps=[], vars_overrides={}):
178183
resource_deps=['flow-api', 'flow-worker', 'catalog', 'provision-clickhouse'] + extra_deps,
179184
)
180185

186+
# Generic e2e tests
187+
181188
# Postgres to ClickHouse generic tests
182189
e2e_test('postgres', 'TestGenericCH_PG', ['provision-postgres'])
183190

@@ -191,4 +198,8 @@ e2e_test('mysql-pos', 'TestGenericCH_MySQL', ['provision-mysql-pos'], vars_overr
191198
e2e_test('mariadb', 'TestGenericCH_MySQL', ['provision-mariadb'], vars_overrides={'CI_MYSQL_PORT': '$CI_MARIADB_PORT'})
192199

193200
# MongoDB to ClickHouse test suite
194-
e2e_test('mongodb', 'TestMongoClickhouseSuite', ['provision-mongodb'])
201+
e2e_test('mongodb', 'TestMongoClickhouseSuite', ['provision-mongodb'])
202+
203+
# API e2e tests
204+
205+
e2e_test('api-postgres', 'TestApiPg', ['provision-postgres'])

ancillary-docker-compose.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,53 @@ services:
129129
volumes:
130130
- /var/run/docker.sock:/var/run/docker.sock
131131

132+
toxiproxy:
133+
container_name: peerdb-test-toxiproxy
134+
# Same image as CI flow
135+
image: ghcr.io/shopify/toxiproxy:2.12.0@sha256:9378ed52a28bc50edc1350f936f518f31fa95f0d15917d6eb40b8e376d1a214e
136+
restart: unless-stopped
137+
ports:
138+
- 18474:8474
139+
- 9902:9902
140+
- 9904:9904
141+
- 9903:9903
142+
- 42001:42001
143+
- 42002:42002
144+
- 42003:42003
145+
- 49001:49001
146+
- 49002:49002
147+
- 49003:49003
148+
extra_hosts:
149+
- "host.docker.internal:host-gateway"
150+
healthcheck:
151+
test: ["CMD", "/toxiproxy-cli", "list"]
152+
interval: 2s
153+
timeout: 10s
154+
retries: 5
155+
156+
openssh:
157+
container_name: peerdb-test-ssh
158+
# Same image as CI flow
159+
image: linuxserver/openssh-server:latest@sha256:57c13941ef385d735cca18ee969eeba18e42ab95480c97af2182505aacdfe307
160+
restart: unless-stopped
161+
ports:
162+
- "2222:2222"
163+
environment:
164+
- PUID=1000
165+
- PGID=1000
166+
- TZ=Etc/UTC
167+
- USER_NAME=testuser
168+
- USER_PASSWORD=testpass
169+
- PASSWORD_ACCESS=true
170+
- DOCKER_MODS=linuxserver/mods:openssh-server-ssh-tunnel
171+
extra_hosts:
172+
- "host.docker.internal:host-gateway"
173+
healthcheck:
174+
test: ["CMD", "nc", "-z", "localhost", "2222"]
175+
interval: 2s
176+
timeout: 10s
177+
retries: 5
178+
132179
volumes:
133180
postgres_data:
134181
clickhouse_data:
@@ -140,3 +187,4 @@ volumes:
140187
networks:
141188
default:
142189
name: peerdb_network
190+
external: true

flow/connectors/clickhouse/s3_iam_role_test.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package connclickhouse
33
import (
44
"fmt"
55
"os"
6+
"strconv"
67
"testing"
78
"time"
89

@@ -13,6 +14,11 @@ import (
1314
)
1415

1516
func TestIAMRoleCanIssueSelectFromS3(t *testing.T) {
17+
const bucketNameEnvVar = "FLOW_TESTS_AWS_S3_BUCKET_NAME"
18+
if os.Getenv(bucketNameEnvVar) == "" {
19+
t.Skipf("skipping test since %s is not set", bucketNameEnvVar)
20+
}
21+
1622
for _, envVar := range []string{
1723
"AWS_ACCESS_KEY_ID",
1824
"AWS_SECRET_ACCESS_KEY",
@@ -34,13 +40,26 @@ func TestIAMRoleCanIssueSelectFromS3(t *testing.T) {
3440
} {
3541
t.Setenv(envVar, os.Getenv("FLOW_TESTS_"+envVar))
3642
}
37-
t.Setenv("PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME", os.Getenv("FLOW_TESTS_AWS_S3_BUCKET_NAME"))
43+
t.Setenv("PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME", os.Getenv(bucketNameEnvVar))
3844
ctx := t.Context()
3945

46+
chHost := "localhost"
47+
if host := os.Getenv("CI_CLICKHOUSE_HOST"); host != "" {
48+
chHost = host
49+
}
50+
var chPort uint32 = 9000
51+
if port := os.Getenv("CI_CLICKHOUSE_NATIVE_PORT"); port != "" {
52+
p, err := strconv.ParseUint(port, 10, 32)
53+
if err != nil {
54+
t.Fatalf("invalid CI_CLICKHOUSE_NATIVE_PORT %q: %v", port, err)
55+
}
56+
chPort = uint32(p)
57+
}
58+
4059
conn, err := NewClickHouseConnector(ctx, nil,
4160
&protos.ClickhouseConfig{
42-
Host: "localhost",
43-
Port: 9000,
61+
Host: chHost,
62+
Port: chPort,
4463
Database: "default",
4564
DisableTls: true,
4665
})

flow/connectors/mysql/ssh_keepalive_test.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package connmysql
33
import (
44
"context"
55
"os"
6+
"strconv"
7+
"strings"
68
"testing"
79

810
"github.com/stretchr/testify/require"
@@ -24,11 +26,28 @@ func setupMySQLConnectorWithSSH(ctx context.Context, t *testing.T, proxyName str
2426
toxiproxyClient := utils.NewToxiproxyClient(t)
2527
sshProxy := utils.CreateSSHProxy(t, toxiproxyClient, proxyName, proxyPort)
2628

29+
mysqlHost := "mysql"
30+
if envHost := os.Getenv("CI_MYSQL_HOST"); envHost != "" {
31+
mysqlHost = envHost
32+
}
33+
34+
var mysqlPort uint32 = 3306
35+
if envPortStr := os.Getenv("CI_MYSQL_PORT"); envPortStr != "" {
36+
envPort, err := strconv.ParseUint(strings.TrimSpace(strings.Split(envPortStr, "#")[0]), 10, 32)
37+
require.NoError(t, err, "Failed to parse CI_MYSQL_PORT")
38+
mysqlPort = uint32(envPort)
39+
}
40+
41+
mysqlRootPass := "cipass"
42+
if envPass := os.Getenv("CI_MYSQL_ROOT_PASSWORD"); envPass != "" {
43+
mysqlRootPass = envPass
44+
}
45+
2746
connector, err := NewMySqlConnector(ctx, &protos.MySqlConfig{
28-
Host: "mysql",
29-
Port: 3306,
47+
Host: mysqlHost,
48+
Port: mysqlPort,
3049
User: "root",
31-
Password: "cipass",
50+
Password: mysqlRootPass,
3251
Database: "mysql",
3352
SshConfig: &protos.SSHConfig{
3453
Host: "localhost",

flow/connectors/postgres/ssh_keepalive_test.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package connpostgres
22

33
import (
44
"context"
5+
"os"
6+
"strconv"
7+
"strings"
58
"testing"
69

710
"github.com/stretchr/testify/require"
@@ -23,9 +26,30 @@ func setupPostgresConnectorWithSSH(ctx context.Context, t *testing.T, proxyName
2326
toxiproxyClient := utils.NewToxiproxyClient(t)
2427
sshProxy := utils.CreateSSHProxy(t, toxiproxyClient, proxyName, proxyPort)
2528

29+
pgHost := "localhost" // Default for local environments
30+
31+
// In local set-up environments like Tilt, when a non catalog
32+
// instance of Postgres is present, we use it instead of the catalog.
33+
if envHost := os.Getenv("PG_HOST"); envHost != "" {
34+
pgHost = envHost
35+
}
36+
37+
// In CI, TOXIPROXY_POSTGRES_HOST is set, usually pointing to 'catalog'
38+
// network.
39+
if toxiproxyPgHost := os.Getenv("TOXIPROXY_POSTGRES_HOST"); toxiproxyPgHost != "" {
40+
pgHost = toxiproxyPgHost
41+
}
42+
43+
var pgPort uint32 = 5432
44+
if envPortStr := os.Getenv("PG_PORT"); envPortStr != "" {
45+
envPort, err := strconv.ParseUint(strings.TrimSpace(strings.Split(envPortStr, "#")[0]), 10, 32)
46+
require.NoError(t, err, "Failed to parse PG_PORT")
47+
pgPort = uint32(envPort)
48+
}
49+
2650
connector, err := NewPostgresConnector(ctx, nil, &protos.PostgresConfig{
27-
Host: "catalog",
28-
Port: 5432,
51+
Host: pgHost,
52+
Port: pgPort,
2953
User: "postgres",
3054
Password: "postgres",
3155
Database: "postgres",

0 commit comments

Comments
 (0)