diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 45e2937a0..52c9f7375 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -23,13 +23,20 @@ concurrency: cancel-in-progress: true env: - POSTGRES_IMAGE: supabase/postgres:17.6.1.074 DENO_IMAGE: denoland/deno:alpine-2.5.6 jobs: tests: - name: Tests + name: Tests (${{ matrix.postgres_image }}) runs-on: blacksmith-8vcpu-ubuntu-2404 + strategy: + fail-fast: false + matrix: + postgres_image: + - supabase/postgres:17.6.1.074 + - supabase/postgres:17.6.0.072-orioledb + env: + POSTGRES_IMAGE: ${{ matrix.postgres_image }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c438b32e7..03908d942 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,16 +24,22 @@ concurrency: env: MIX_ENV: test - POSTGRES_IMAGE: supabase/postgres:17.6.1.074 jobs: tests: - name: Tests (Partition ${{ matrix.partition }}) + name: Tests (Partition ${{ matrix.partition }}, ${{ matrix.pg.label }}) runs-on: blacksmith-8vcpu-ubuntu-2404 strategy: fail-fast: false matrix: partition: [1, 2, 3, 4] + pg: + - image: supabase/postgres:17.6.1.074 + label: standard + - image: supabase/postgres:17.6.0.072-orioledb + label: orioledb + env: + POSTGRES_IMAGE: ${{ matrix.pg.image }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -79,6 +85,7 @@ jobs: - name: Run tests run: MIX_TEST_PARTITION=${{ matrix.partition }} mix coveralls.lcov --partitions 4 - name: Upload coverage artifact + if: matrix.pg.label == 'standard' uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: coverage-partition-${{ matrix.partition }} diff --git a/compose.dbs.yml b/compose.dbs.yml index 9624f8138..221218bb3 100644 --- a/compose.dbs.yml +++ b/compose.dbs.yml @@ -1,6 +1,6 @@ services: db: - image: supabase/postgres:17.6.1.074 + image: ${POSTGRES_IMAGE:-supabase/postgres:17.6.1.074} ports: - "5432:5432" volumes: @@ -16,7 +16,7 @@ services: retries: 5 tenant_db: - image: supabase/postgres:17.6.1.074 + image: ${POSTGRES_IMAGE:-supabase/postgres:17.6.1.074} ports: - "5433:5432" command: postgres -c config_file=/etc/postgresql/postgresql.conf diff --git a/compose.tests.yml b/compose.tests.yml index 16a01607f..281483b9c 100644 --- a/compose.tests.yml +++ b/compose.tests.yml @@ -1,7 +1,7 @@ services: # Supabase Realtime service test_db: - image: supabase/postgres:17.6.1.074 + image: ${POSTGRES_IMAGE:-supabase/postgres:17.6.1.074} container_name: test-realtime-db ports: - "5532:5432" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..2d2157fd3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,53 @@ +services: + db: + image: ${POSTGRES_IMAGE:-supabase/postgres:17.6.1.074} + container_name: realtime-db + ports: + - "5432:5432" + volumes: + - ./dev/postgres/00-supabase-schema.sql:/docker-entrypoint-initdb.d/00-supabase-schema.sql + command: postgres -c config_file=/etc/postgresql/postgresql.conf + environment: + POSTGRES_HOST: /var/run/postgresql + POSTGRES_PASSWORD: postgres + tenant_db: + image: ${POSTGRES_IMAGE:-supabase/postgres:17.6.1.074} + container_name: tenant-db + ports: + - "5433:5432" + command: postgres -c config_file=/etc/postgresql/postgresql.conf + environment: + POSTGRES_HOST: /var/run/postgresql + POSTGRES_PASSWORD: postgres + realtime: + depends_on: + - db + build: . + container_name: realtime-server + ports: + - "4000:4000" + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + PORT: 4000 + DB_HOST: host.docker.internal + DB_PORT: 5432 + DB_USER: supabase_admin + DB_PASSWORD: postgres + DB_NAME: postgres + DB_ENC_KEY: supabaserealtime + DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime' + API_JWT_SECRET: dc447559-996d-4761-a306-f47a5eab1623 + SECRET_KEY_BASE: UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq + ERL_AFLAGS: -proto_dist inet_tcp + RLIMIT_NOFILE: 1000000 + DNS_NODES: "''" + APP_NAME: realtime + RUN_JANITOR: true + JANITOR_INTERVAL: 60000 + LOG_LEVEL: "info" + SEED_SELF_HOST: true + METRICS_JWT_SECRET: dc447559-996d-4761-a306-f47a5eab1623 + DASHBOARD_USER: admin + DASHBOARD_PASSWORD: admin + diff --git a/test/realtime/tenants/connect_test.exs b/test/realtime/tenants/connect_test.exs index 92125b9e1..835eb2950 100644 --- a/test/realtime/tenants/connect_test.exs +++ b/test/realtime/tenants/connect_test.exs @@ -20,7 +20,7 @@ defmodule Realtime.Tenants.ConnectTest do %{tenant: tenant} end - defp assert_process_down(pid, timeout \\ 100, reason \\ nil) do + defp assert_process_down(pid, timeout \\ 500, reason \\ nil) do ref = Process.monitor(pid) if reason do @@ -824,9 +824,10 @@ defmodule Realtime.Tenants.ConnectTest do test "successfully unregisters a process", %{tenant: %{external_id: external_id}} do assert {:ok, _db_conn} = Connect.lookup_or_start_connection(external_id) - assert Registry.whereis_name({Realtime.Tenants.Connect.Registry, external_id}) + assert pid = Registry.whereis_name({Realtime.Tenants.Connect.Registry, external_id}) Connect.shutdown(external_id) - Process.sleep(100) + + assert_process_down(pid) assert :undefined = Registry.whereis_name({Realtime.Tenants.Connect.Registry, external_id}) end end diff --git a/test/realtime/tenants/replication_connection_test.exs b/test/realtime/tenants/replication_connection_test.exs index ad128bdea..0970d77de 100644 --- a/test/realtime/tenants/replication_connection_test.exs +++ b/test/realtime/tenants/replication_connection_test.exs @@ -54,8 +54,8 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do Application.put_env(:realtime, :replication_watchdog_timeout, replication_watchdog_timeout) end) - Application.put_env(:realtime, :replication_watchdog_interval, 100) - Application.put_env(:realtime, :replication_watchdog_timeout, 100) + Application.put_env(:realtime, :replication_watchdog_interval, 400) + Application.put_env(:realtime, :replication_watchdog_timeout, 400) end test "watchdog kills replication connection that is not responding to health checks", %{tenant: tenant} do @@ -66,7 +66,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do # Let's make it not reply to health checks :sys.suspend(pid) - reason = assert_process_down(pid, 400) + reason = assert_process_down(pid, 2000) assert reason == :watchdog_timeout end) @@ -116,7 +116,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do value = random_string() row = - message_fixture(tenant, %{ + message_fixture_with_conn(tenant, db_conn, %{ "topic" => topic, "private" => true, "event" => "INSERT", @@ -198,7 +198,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do value = random_string() row = - message_fixture(tenant, %{ + message_fixture_with_conn(tenant, db_conn, %{ "topic" => topic, "private" => false, "event" => "INSERT", @@ -264,7 +264,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do end end - test "replicates binary with exactly 16 bytes to test UUID conversion error", %{tenant: tenant} do + test "replicates binary with exactly 16 bytes to test UUID conversion error", %{tenant: tenant, db_conn: db_conn} do start_link_supervised!( {ReplicationConnection, %ReplicationConnection{tenant_id: tenant.external_id, monitored_pid: self()}}, restart: :transient @@ -276,7 +276,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do payload = %{"value" => random_string()} row = - message_fixture(tenant, %{ + message_fixture_with_conn(tenant, db_conn, %{ "topic" => topic, "private" => true, "event" => "UPDATE", @@ -340,7 +340,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do payload = %{"value" => random_string()} row = - message_fixture(tenant, %{ + message_fixture_with_conn(tenant, db_conn, %{ "topic" => topic, "private" => true, "event" => "UPDATE", @@ -789,7 +789,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do ) end - test "receives telemetry event", %{tenant: %{external_id: external_id} = tenant} do + test "receives telemetry event", %{tenant: %{external_id: external_id} = tenant, db_conn: db_conn} do start_link_supervised!( {ReplicationConnection, %ReplicationConnection{tenant_id: external_id, monitored_pid: self()}}, restart: :transient @@ -799,7 +799,7 @@ defmodule Realtime.Tenants.ReplicationConnectionTest do tenant_topic = Tenants.tenant_topic(external_id, topic, false) subscribe(tenant_topic, topic) - message_fixture(tenant, %{ + message_fixture_with_conn(tenant, db_conn, %{ "topic" => topic, "private" => true, "event" => "INSERT", diff --git a/test/support/containers.ex b/test/support/containers.ex index 4ff98a905..f92e07005 100644 --- a/test/support/containers.ex +++ b/test/support/containers.ex @@ -8,15 +8,17 @@ defmodule Containers do use GenServer @image "supabase/postgres:17.6.1.074" + def image(), do: System.get_env("POSTGRES_IMAGE", @image) + # Pull image if not available def pull do - case System.cmd("docker", ["image", "inspect", @image]) do + case System.cmd("docker", ["image", "inspect", image()]) do {_, 0} -> :ok _ -> - IO.puts("Pulling image #{@image}. This might take a while...") - {_, 0} = System.cmd("docker", ["pull", @image]) + IO.puts("Pulling image #{image()}. This might take a while...") + {_, 0} = System.cmd("docker", ["pull", image()]) end end @@ -304,7 +306,7 @@ defmodule Containers do "POSTGRES_PASSWORD=postgres", "-p", "#{port}:5432", - @image, + image(), "postgres", "-c", "config_file=/etc/postgresql/postgresql.conf", diff --git a/test/support/tenant_connection.ex b/test/support/tenant_connection.ex index 77328bdfc..656f178d2 100644 --- a/test/support/tenant_connection.ex +++ b/test/support/tenant_connection.ex @@ -8,7 +8,7 @@ defmodule TenantConnection do alias Realtime.Tenants.Connect alias RealtimeWeb.Endpoint - def create_message(attrs, conn, opts \\ [mode: :savepoint]) do + def create_message(attrs, conn, opts \\ []) do message = Message.changeset(%Message{}, attrs) {:ok, result} =