Merge pull request #13569 from Budibase/make-reuse-containers-default
Make REUSE_CONTAINERS the default for running tests.
This commit is contained in:
commit
0624ba4925
|
@ -92,8 +92,6 @@ jobs:
|
||||||
|
|
||||||
test-libraries:
|
test-libraries:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
REUSE_CONTAINERS: true
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -150,8 +148,6 @@ jobs:
|
||||||
|
|
||||||
test-server:
|
test-server:
|
||||||
runs-on: budi-tubby-tornado-quad-core-150gb
|
runs-on: budi-tubby-tornado-quad-core-150gb
|
||||||
env:
|
|
||||||
REUSE_CONTAINERS: true
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
|
@ -1,16 +1,49 @@
|
||||||
import { GenericContainer, Wait } from "testcontainers"
|
import {
|
||||||
|
GenericContainer,
|
||||||
|
Wait,
|
||||||
|
getContainerRuntimeClient,
|
||||||
|
} from "testcontainers"
|
||||||
|
import { ContainerInfo } from "dockerode"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import lockfile from "proper-lockfile"
|
import lockfile from "proper-lockfile"
|
||||||
|
|
||||||
|
async function getBudibaseContainers() {
|
||||||
|
const client = await getContainerRuntimeClient()
|
||||||
|
const conatiners = await client.container.list()
|
||||||
|
return conatiners.filter(
|
||||||
|
container =>
|
||||||
|
container.Labels["com.budibase"] === "true" &&
|
||||||
|
container.Labels["org.testcontainers"] === "true"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function killContainers(containers: ContainerInfo[]) {
|
||||||
|
const client = await getContainerRuntimeClient()
|
||||||
|
for (const container of containers) {
|
||||||
|
const c = client.container.getById(container.Id)
|
||||||
|
await c.kill()
|
||||||
|
await c.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default async function setup() {
|
export default async function setup() {
|
||||||
const lockPath = path.resolve(__dirname, "globalSetup.ts")
|
const lockPath = path.resolve(__dirname, "globalSetup.ts")
|
||||||
if (process.env.REUSE_CONTAINERS) {
|
// If you run multiple tests at the same time, it's possible for the CouchDB
|
||||||
// If you run multiple tests at the same time, it's possible for the CouchDB
|
// shared container to get started multiple times despite having an
|
||||||
// shared container to get started multiple times despite having an
|
// identical reuse hash. To avoid that, we do a filesystem-based lock so
|
||||||
// identical reuse hash. To avoid that, we do a filesystem-based lock so
|
// that only one globalSetup.ts is running at a time.
|
||||||
// that only one globalSetup.ts is running at a time.
|
lockfile.lockSync(lockPath)
|
||||||
lockfile.lockSync(lockPath)
|
|
||||||
}
|
// Remove any containers that are older than 24 hours. This is to prevent
|
||||||
|
// containers getting full volumes or accruing any other problems from being
|
||||||
|
// left up for very long periods of time.
|
||||||
|
const threshold = new Date(Date.now() - 1000 * 60 * 60 * 24)
|
||||||
|
const containers = (await getBudibaseContainers()).filter(container => {
|
||||||
|
const created = new Date(container.Created * 1000)
|
||||||
|
return created < threshold
|
||||||
|
})
|
||||||
|
|
||||||
|
await killContainers(containers)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let couchdb = new GenericContainer("budibase/couchdb:v3.2.1-sqs")
|
let couchdb = new GenericContainer("budibase/couchdb:v3.2.1-sqs")
|
||||||
|
@ -28,20 +61,16 @@ export default async function setup() {
|
||||||
target: "/opt/couchdb/etc/local.d/test-couchdb.ini",
|
target: "/opt/couchdb/etc/local.d/test-couchdb.ini",
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
.withLabels({ "com.budibase": "true" })
|
||||||
|
.withReuse()
|
||||||
.withWaitStrategy(
|
.withWaitStrategy(
|
||||||
Wait.forSuccessfulCommand(
|
Wait.forSuccessfulCommand(
|
||||||
"curl http://budibase:budibase@localhost:5984/_up"
|
"curl http://budibase:budibase@localhost:5984/_up"
|
||||||
).withStartupTimeout(20000)
|
).withStartupTimeout(20000)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (process.env.REUSE_CONTAINERS) {
|
|
||||||
couchdb = couchdb.withReuse()
|
|
||||||
}
|
|
||||||
|
|
||||||
await couchdb.start()
|
await couchdb.start()
|
||||||
} finally {
|
} finally {
|
||||||
if (process.env.REUSE_CONTAINERS) {
|
lockfile.unlockSync(lockPath)
|
||||||
lockfile.unlockSync(lockPath)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,8 @@
|
||||||
"dev:all": "yarn run kill-all && lerna run --stream dev",
|
"dev:all": "yarn run kill-all && lerna run --stream dev",
|
||||||
"dev:built": "yarn run kill-all && cd packages/server && yarn dev:stack:up && cd ../../ && lerna run --stream dev:built",
|
"dev:built": "yarn run kill-all && cd packages/server && yarn dev:stack:up && cd ../../ && lerna run --stream dev:built",
|
||||||
"dev:docker": "./scripts/devDocker.sh",
|
"dev:docker": "./scripts/devDocker.sh",
|
||||||
"test": "REUSE_CONTAINERS=1 lerna run --concurrency 1 --stream test --stream",
|
"test": "lerna run --concurrency 1 --stream test --stream",
|
||||||
|
"test:containers:kill": "./scripts/killTestcontainers.sh",
|
||||||
"lint:eslint": "eslint packages --max-warnings=0",
|
"lint:eslint": "eslint packages --max-warnings=0",
|
||||||
"lint:prettier": "prettier --check \"packages/**/*.{js,ts,svelte}\" && prettier --write \"examples/**/*.{js,ts,svelte}\"",
|
"lint:prettier": "prettier --check \"packages/**/*.{js,ts,svelte}\" && prettier --write \"examples/**/*.{js,ts,svelte}\"",
|
||||||
"lint": "yarn run lint:eslint && yarn run lint:prettier",
|
"lint": "yarn run lint:eslint && yarn run lint:prettier",
|
||||||
|
|
|
@ -28,7 +28,11 @@ function getTestcontainers(): ContainerInfo[] {
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.filter(x => x.length > 0)
|
.filter(x => x.length > 0)
|
||||||
.map(x => JSON.parse(x) as ContainerInfo)
|
.map(x => JSON.parse(x) as ContainerInfo)
|
||||||
.filter(x => x.Labels.includes("org.testcontainers=true"))
|
.filter(
|
||||||
|
x =>
|
||||||
|
x.Labels.includes("org.testcontainers=true") &&
|
||||||
|
x.Labels.includes("com.budibase=true")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getContainerByImage(image: string) {
|
export function getContainerByImage(image: string) {
|
||||||
|
|
|
@ -65,9 +65,7 @@ export async function rawQuery(ds: Datasource, sql: string): Promise<any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startContainer(container: GenericContainer) {
|
export async function startContainer(container: GenericContainer) {
|
||||||
if (process.env.REUSE_CONTAINERS) {
|
container = container.withReuse().withLabels({ "com.budibase": "true" })
|
||||||
container = container.withReuse()
|
|
||||||
}
|
|
||||||
|
|
||||||
const startedContainer = await container.start()
|
const startedContainer = await container.start()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Find all Docker containers with the label "org.testcontainers=true"
|
||||||
|
containers=$(docker ps -q -f "label=org.testcontainers=true")
|
||||||
|
|
||||||
|
# Check if there are any containers to stop
|
||||||
|
if [ -z "$containers" ]; then
|
||||||
|
echo "No containers with label 'org.testcontainers=true' found."
|
||||||
|
else
|
||||||
|
# Stop the containers
|
||||||
|
echo "Stopping containers..."
|
||||||
|
docker stop $containers
|
||||||
|
|
||||||
|
# Remove the containers
|
||||||
|
echo "Removing containers..."
|
||||||
|
docker rm $containers
|
||||||
|
|
||||||
|
echo "Containers have been stopped and removed."
|
||||||
|
fi
|
Loading…
Reference in New Issue