diff --git a/packages/server/src/integrations/tests/utils/mongodb.ts b/packages/server/src/integrations/tests/utils/mongodb.ts index ebd76e4baf..0baafc6276 100644 --- a/packages/server/src/integrations/tests/utils/mongodb.ts +++ b/packages/server/src/integrations/tests/utils/mongodb.ts @@ -11,7 +11,9 @@ export async function start(): Promise { MONGO_INITDB_ROOT_PASSWORD: "password", }) .withWaitStrategy( - Wait.forSuccessfulCommand(`mongosh --eval "db.version()"`) + Wait.forSuccessfulCommand( + `mongosh --eval "db.version()"` + ).withStartupTimeout(10000) ) .start() } diff --git a/packages/server/src/integrations/tests/utils/mysql.ts b/packages/server/src/integrations/tests/utils/mysql.ts index 474819287e..8d5563c6dd 100644 --- a/packages/server/src/integrations/tests/utils/mysql.ts +++ b/packages/server/src/integrations/tests/utils/mysql.ts @@ -1,26 +1,37 @@ import { Datasource, SourceName } from "@budibase/types" import { GenericContainer, Wait, StartedTestContainer } from "testcontainers" +import { + AbstractWaitStrategy, + WaitStrategy, +} from "testcontainers/build/wait-strategies/wait-strategy" let container: StartedTestContainer | undefined +class MySQLWaitStrategy extends AbstractWaitStrategy { + async waitUntilReady(container: any, boundPorts: any, startTime?: Date) { + // Because MySQL first starts itself up, runs an init script, then restarts, + // it's possible for the mysqladmin ping to succeed early and then tests to + // run against a MySQL that's mid-restart and fail. To get around this, we + // wait for logs and then do a ping check. + + const logs = Wait.forLogMessage( + "/usr/sbin/mysqld: ready for connections", + 2 + ) + await logs.waitUntilReady(container, boundPorts, startTime) + + const command = Wait.forSuccessfulCommand( + `mysqladmin ping -h localhost -P 3306 -u root -ppassword` + ) + await command.waitUntilReady(container) + } +} + export async function start(): Promise { return await new GenericContainer("mysql:8.3") .withExposedPorts(3306) .withEnvironment({ MYSQL_ROOT_PASSWORD: "password" }) - .withWaitStrategy( - Wait.forSuccessfulCommand( - // Because MySQL first starts itself up, runs an init script, then restarts, - // it's possible for the mysqladmin ping to succeed early and then tests to - // run against a MySQL that's mid-restart and fail. To avoid this, we run - // the ping command three times with a small delay between each. - ` - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword && sleep 1 && - mysqladmin ping -h localhost -P 3306 -u root -ppassword - ` - ) - ) + .withWaitStrategy(new MySQLWaitStrategy().withStartupTimeout(10000)) .start() } diff --git a/packages/server/src/integrations/tests/utils/postgres.ts b/packages/server/src/integrations/tests/utils/postgres.ts index 4bf42c7f88..82a62e3916 100644 --- a/packages/server/src/integrations/tests/utils/postgres.ts +++ b/packages/server/src/integrations/tests/utils/postgres.ts @@ -8,7 +8,9 @@ export async function start(): Promise { .withExposedPorts(5432) .withEnvironment({ POSTGRES_PASSWORD: "password" }) .withWaitStrategy( - Wait.forSuccessfulCommand("pg_isready -h localhost -p 5432") + Wait.forSuccessfulCommand( + "pg_isready -h localhost -p 5432" + ).withStartupTimeout(10000) ) .start() }