Files
directus/tests/blackbox/setup/setup.ts
2024-09-26 10:00:39 +02:00

190 lines
5.2 KiB
TypeScript

/* eslint-disable no-console */
import axios from 'axios';
import { spawn, spawnSync } from 'child_process';
import knex from 'knex';
import { Listr } from 'listr2';
import { clone } from 'lodash-es';
import fs from 'node:fs/promises';
import { join } from 'node:path';
import config, { getUrl, paths } from '../common/config';
import vendors from '../common/get-dbs-to-test';
import { USER } from '../common/variables';
import { awaitDatabaseConnection, awaitDirectusConnection } from '../utils/await-connection';
import global from './global';
export async function setup() {
console.log(`👮‍♀️ Starting tests!\n`);
await new Listr([
{
title: 'Bootstrap databases and start servers',
task: async () => {
return new Listr(
vendors.map((vendor) => {
return {
title: config.names[vendor],
task: async () => {
const database = knex(config.knexConfig[vendor]);
await awaitDatabaseConnection(database, config.knexConfig[vendor].waitTestSQL);
if (vendor === 'sqlite3') {
await fs.writeFile(join(paths.cwd, 'test.db'), '');
}
const bootstrap = spawnSync('node', [paths.cli, 'bootstrap'], {
cwd: paths.cwd,
env: config.envs[vendor],
});
if (bootstrap.status !== null && bootstrap.status !== 0) {
throw new Error(
`Directus-${vendor} bootstrap failed (${bootstrap.status}): \n ${bootstrap.stderr.toString()}`,
);
}
await database.migrate.latest();
await database.seed.run();
await database.destroy();
if (!process.env['TEST_LOCAL']) {
const server = spawn('node', [paths.cli, 'start'], {
cwd: paths.cwd,
env: config.envs[vendor],
});
global.directus[vendor] = server;
let serverOutput = '';
server.stdout.setEncoding('utf8');
server.stdout.on('data', (data) => {
serverOutput += data.toString();
});
server.stderr.on('data', (data) => {
console.log(data.toString());
});
server.on('exit', async (code) => {
if (process.env['TEST_SAVE_LOGS']) {
await fs.writeFile(join(paths.cwd, `server-log-${vendor}.txt`), serverOutput);
}
if (code !== null)
throw new Error(`Directus-${vendor} server failed (${code}): \n ${serverOutput}`);
});
// Give the server some time to start
await awaitDirectusConnection(Number(config.envs[vendor].PORT));
// Set up separate directus instance without system cache
const noCacheEnv = clone(config.envs[vendor]);
noCacheEnv['CACHE_SCHEMA'] = 'false';
noCacheEnv['PORT'] = String(parseInt(noCacheEnv.PORT) + 50);
const serverNoCache = spawn('node', [paths.cli, 'start'], { cwd: paths.cwd, env: noCacheEnv });
global.directusNoCache[vendor] = serverNoCache;
let serverNoCacheOutput = '';
serverNoCache.stdout.setEncoding('utf8');
serverNoCache.stdout.on('data', (data) => {
serverNoCacheOutput += data.toString();
});
serverNoCache.on('exit', async (code) => {
if (process.env['TEST_SAVE_LOGS']) {
await fs.writeFile(join(paths.cwd, `server-log-${vendor}-no-cache.txt`), serverNoCacheOutput);
}
if (code !== null) {
throw new Error(`Directus-${vendor}-no-cache server failed (${code}): \n ${serverNoCacheOutput}`);
}
});
// Give the server some time to start
await awaitDirectusConnection(Number(noCacheEnv['PORT']));
}
},
};
}),
{ concurrent: true, rendererOptions: { collapseErrors: false } },
);
},
},
{
title: 'Test server connectivity',
task: async () => {
for (const vendor of vendors) {
try {
const serverUrl = getUrl(vendor);
const response = await axios.get(
`${serverUrl}/items/tests_flow_data?access_token=${USER.TESTS_FLOW.TOKEN}`,
);
if (response.status === 200) {
process.env['serverUrl'] = serverUrl;
break;
}
} catch {
continue;
}
}
if (!process.env['serverUrl']) {
throw new Error('Unable to connect to any Directus server');
}
},
},
])
.run()
.catch((reason) => {
for (const server of Object.values(global.directus)) {
server?.kill();
}
for (const serverNoCache of Object.values(global.directusNoCache)) {
serverNoCache?.kill();
}
throw new Error(reason);
});
console.log('\n');
}
export async function teardown() {
try {
await fs.unlink('sequencer-data.json');
} catch {
// Ignore
}
if (!process.env['TEST_LOCAL']) {
await new Listr([
{
title: 'Stop Directus servers',
task: () => {
return new Listr(
vendors.map((vendor) => {
return {
title: config.names[vendor]!,
task: async () => {
const directus = global.directus[vendor];
directus?.kill();
const directusNoCache = global.directusNoCache[vendor];
directusNoCache?.kill();
},
};
}),
{ concurrent: true, exitOnError: false },
);
},
},
]).run();
}
console.log('\n');
console.log(`👮‍♀️ Tests complete!\n`);
}