Make UVU tests time out (#265)
This commit is contained in:
parent
c711681cb6
commit
5292b08028
4 changed files with 100 additions and 107 deletions
|
@ -3,8 +3,17 @@ import * as assert from 'uvu/assert';
|
|||
import { runDevServer } from './helpers.js';
|
||||
|
||||
const ConfigPath = suite('Config path');
|
||||
const MAX_TEST_TIME = 10000; // max time this test suite may take
|
||||
|
||||
const root = new URL('./fixtures/config-path/', import.meta.url);
|
||||
const timers = {};
|
||||
|
||||
ConfigPath.before.each(({ __test__ }) => {
|
||||
timers[__test__] = setTimeout(() => {
|
||||
throw new Error(`Test "${__test__}" did not finish within allowed time`);
|
||||
}, MAX_TEST_TIME);
|
||||
});
|
||||
|
||||
ConfigPath('can be passed via --config', async (context) => {
|
||||
const configPath = new URL('./config/my-config.mjs', root).pathname;
|
||||
const args = ['--config', configPath];
|
||||
|
@ -21,4 +30,8 @@ ConfigPath('can be passed via --config', async (context) => {
|
|||
assert.ok(true, 'Server started');
|
||||
});
|
||||
|
||||
ConfigPath.after.each(({ __test__ }) => {
|
||||
clearTimeout(timers[__test__]);
|
||||
});
|
||||
|
||||
ConfigPath.run();
|
||||
|
|
|
@ -5,8 +5,16 @@ import { runDevServer } from './helpers.js';
|
|||
import { loadConfig } from '#astro/config';
|
||||
|
||||
const ConfigPort = suite('Config path');
|
||||
const MAX_TEST_TIME = 10000; // max time this test suite may take
|
||||
|
||||
const root = new URL('./fixtures/config-port/', import.meta.url);
|
||||
const timers = {};
|
||||
|
||||
ConfigPort.before.each(({ __test__ }) => {
|
||||
timers[__test__] = setTimeout(() => {
|
||||
throw new Error(`Test "${__test__}" did not finish within allowed time`);
|
||||
}, MAX_TEST_TIME);
|
||||
});
|
||||
|
||||
ConfigPort('can be specified in the astro config', async (context) => {
|
||||
const astroConfig = await loadConfig(fileURLToPath(root));
|
||||
|
@ -15,17 +23,21 @@ ConfigPort('can be specified in the astro config', async (context) => {
|
|||
|
||||
ConfigPort('can be specified via --port flag', async (context) => {
|
||||
const args = ['--port', '3002'];
|
||||
const process = runDevServer(root, args);
|
||||
const proc = runDevServer(root, args);
|
||||
|
||||
process.stdout.setEncoding('utf8');
|
||||
for await (const chunk of process.stdout) {
|
||||
proc.stdout.setEncoding('utf8');
|
||||
for await (const chunk of proc.stdout) {
|
||||
if (/Local:/.test(chunk)) {
|
||||
assert.ok(/:3002/.test(chunk), 'Using the right port');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
process.kill();
|
||||
proc.kill();
|
||||
});
|
||||
|
||||
ConfigPort.after.each(({ __test__ }) => {
|
||||
clearTimeout(timers[__test__]);
|
||||
});
|
||||
|
||||
ConfigPort.run();
|
||||
|
|
|
@ -3,65 +3,87 @@ import { build as astroBuild } from '#astro/build';
|
|||
import { readFile } from 'fs/promises';
|
||||
import { createRuntime } from '#astro/runtime';
|
||||
import { loadConfig } from '#astro/config';
|
||||
import * as assert from 'uvu/assert';
|
||||
import execa from 'execa';
|
||||
|
||||
const MAX_STARTUP_TIME = 7000; // max time startup may take
|
||||
const MAX_TEST_TIME = 10000; // max time an individual test may take
|
||||
const MAX_SHUTDOWN_TIME = 3000; // max time shutdown() may take
|
||||
|
||||
/** setup fixtures for tests */
|
||||
export function setup(Suite, fixturePath) {
|
||||
let runtime, setupError;
|
||||
let runtime;
|
||||
const timers = {};
|
||||
|
||||
Suite.before(async (context) => {
|
||||
let timeout = setTimeout(() => {
|
||||
throw new Error('Startup did not complete within allowed time');
|
||||
}, MAX_STARTUP_TIME);
|
||||
|
||||
const astroConfig = await loadConfig(fileURLToPath(new URL(fixturePath, import.meta.url)));
|
||||
|
||||
const logging = {
|
||||
level: 'error',
|
||||
dest: process.stderr,
|
||||
};
|
||||
|
||||
try {
|
||||
runtime = await createRuntime(astroConfig, { logging });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setupError = err;
|
||||
}
|
||||
runtime = await createRuntime(astroConfig, {
|
||||
logging: { level: 'error', dest: process.stderr },
|
||||
});
|
||||
|
||||
context.runtime = runtime;
|
||||
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
|
||||
Suite.before.each(({ __test__ }) => {
|
||||
if (timers[__test__]) throw new Error(`Test "${__test__}" already declared`);
|
||||
timers[__test__] = setTimeout(() => {
|
||||
throw new Error(`"${__test__}" did not finish within allowed time`);
|
||||
}, MAX_TEST_TIME);
|
||||
});
|
||||
|
||||
Suite.after(async () => {
|
||||
let timeout = setTimeout(() => {
|
||||
throw new Error('Shutdown did not complete within allowed time');
|
||||
}, MAX_SHUTDOWN_TIME);
|
||||
|
||||
(await runtime) && runtime.shutdown();
|
||||
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
|
||||
Suite('No errors creating a runtime', () => {
|
||||
assert.equal(setupError, undefined);
|
||||
Suite.after.each(({ __test__ }) => {
|
||||
clearTimeout(timers[__test__]);
|
||||
});
|
||||
}
|
||||
|
||||
export function setupBuild(Suite, fixturePath) {
|
||||
let build, setupError;
|
||||
const timers = {};
|
||||
|
||||
Suite.before(async (context) => {
|
||||
let timeout = setTimeout(() => {
|
||||
throw new Error('Startup did not complete within allowed time');
|
||||
}, MAX_STARTUP_TIME);
|
||||
|
||||
const astroConfig = await loadConfig(fileURLToPath(new URL(fixturePath, import.meta.url)));
|
||||
|
||||
const logging = {
|
||||
level: 'error',
|
||||
dest: process.stderr,
|
||||
};
|
||||
|
||||
build = () => astroBuild(astroConfig, logging);
|
||||
context.build = build;
|
||||
context.build = () => astroBuild(astroConfig, { level: 'error', dest: process.stderr });
|
||||
context.readFile = async (path) => {
|
||||
const resolved = fileURLToPath(new URL(`${fixturePath}/${astroConfig.dist}${path}`, import.meta.url));
|
||||
return readFile(resolved).then((r) => r.toString('utf8'));
|
||||
};
|
||||
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
|
||||
Suite.before.each(({ __test__ }) => {
|
||||
if (timers[__test__]) throw new Error(`Test "${__test__}" already declared`);
|
||||
timers[__test__] = setTimeout(() => {
|
||||
throw new Error(`"${__test__}" did not finish within allowed time`);
|
||||
}, MAX_TEST_TIME);
|
||||
});
|
||||
|
||||
Suite.after(async () => {
|
||||
// Shutdown i guess.
|
||||
});
|
||||
|
||||
Suite('No errors creating a runtime', () => {
|
||||
assert.equal(setupError, undefined);
|
||||
Suite.after.each(({ __test__ }) => {
|
||||
clearTimeout(timers[__test__]);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,91 +1,37 @@
|
|||
import path from 'path';
|
||||
import glob from 'tiny-glob/sync.js';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { suite } from 'uvu';
|
||||
import * as assert from 'uvu/assert';
|
||||
import { createRuntime } from '#astro/runtime';
|
||||
import { loadConfig } from '#astro/config';
|
||||
import { promises as fsPromises } from 'fs';
|
||||
import { relative as pathRelative } from 'path';
|
||||
|
||||
const { readdir, stat } = fsPromises;
|
||||
import { setup } from './helpers.js';
|
||||
|
||||
const SnowpackDev = suite('snowpack.dev');
|
||||
setup(SnowpackDev, '../../../examples/snowpack');
|
||||
|
||||
const snowpackDir = new URL('../../../examples/snowpack/', import.meta.url);
|
||||
|
||||
let runtime, cwd, setupError;
|
||||
|
||||
SnowpackDev.before(async () => {
|
||||
// Bug: Snowpack config is still loaded relative to the current working directory.
|
||||
cwd = process.cwd();
|
||||
process.chdir(fileURLToPath(snowpackDir));
|
||||
|
||||
const astroConfig = await loadConfig(fileURLToPath(snowpackDir));
|
||||
|
||||
const logging = {
|
||||
level: 'error',
|
||||
dest: process.stderr,
|
||||
};
|
||||
|
||||
try {
|
||||
runtime = await createRuntime(astroConfig, { logging });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setupError = err;
|
||||
}
|
||||
});
|
||||
|
||||
SnowpackDev.after(async () => {
|
||||
process.chdir(cwd);
|
||||
(await runtime) && runtime.shutdown();
|
||||
});
|
||||
/** create an iterator for all page files */
|
||||
async function* allPageFiles(root) {
|
||||
for (const filename of await readdir(root)) {
|
||||
const fullpath = new URL(filename, root);
|
||||
const info = await stat(fullpath);
|
||||
|
||||
if (info.isDirectory()) {
|
||||
yield* allPageFiles(new URL(fullpath + '/'));
|
||||
} else {
|
||||
yield fullpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** create an iterator for all pages and yield the relative paths */
|
||||
async function* allPages(root) {
|
||||
for await (let fileURL of allPageFiles(root)) {
|
||||
let bare = fileURLToPath(fileURL)
|
||||
.replace(/\.(astro|md)$/, '')
|
||||
.replace(/index$/, '');
|
||||
|
||||
yield '/' + pathRelative(fileURLToPath(root), bare);
|
||||
}
|
||||
// convert file path to its final url
|
||||
function formatURL(filepath) {
|
||||
return filepath
|
||||
.replace(/^\/?/, '/') // add / to beginning, if missing
|
||||
.replace(/(index)?\.(astro|md)$/, '') // remove .astro and .md extensions
|
||||
.replace(/\/$/, ''); // remove trailing slash, if any
|
||||
}
|
||||
|
||||
SnowpackDev('No error creating the runtime', () => {
|
||||
assert.equal(setupError, undefined);
|
||||
// declaring routes individually helps us run many quick tests rather than one giant slow test
|
||||
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../../examples/snowpack/src/pages');
|
||||
let pages = glob('**/*.{astro,md}', { cwd: root, onlyFiles: true })
|
||||
.filter((page) => !page.includes('proof-of-concept-dynamic'))
|
||||
.map(formatURL);
|
||||
|
||||
SnowpackDev('Pages successfully scanned', () => {
|
||||
assert.ok(pages.length > 0);
|
||||
});
|
||||
|
||||
SnowpackDev('Can load every page', async () => {
|
||||
const failed = [];
|
||||
|
||||
const pageRoot = new URL('./src/pages/', snowpackDir);
|
||||
for await (let pathname of allPages(pageRoot)) {
|
||||
if (pathname.includes('proof-of-concept-dynamic')) {
|
||||
continue;
|
||||
}
|
||||
for (const pathname of pages) {
|
||||
SnowpackDev(`Loads "${pathname}"`, async ({ runtime }) => {
|
||||
const result = await runtime.load(pathname);
|
||||
if (result.statusCode === 500) {
|
||||
failed.push({ ...result, pathname });
|
||||
continue;
|
||||
}
|
||||
assert.equal(result.statusCode, 200, `Loading ${pathname}`);
|
||||
}
|
||||
|
||||
if (failed.length > 0) {
|
||||
console.error(failed);
|
||||
}
|
||||
assert.equal(failed.length, 0, 'Failed pages');
|
||||
});
|
||||
assert.equal(result.statusCode, 200);
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
SnowpackDev.run();
|
||||
|
|
Loading…
Reference in a new issue