qa: add e2e tests

This commit is contained in:
Morten Olsen
2024-01-17 00:16:21 +01:00
parent e5064ca905
commit d3ad83ddf7
68 changed files with 1560 additions and 583 deletions

4
packages/tests/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/dist/
/node_modules/
/coverage/
/e2e-tmp/

1
packages/tests/README.md Normal file
View File

@@ -0,0 +1 @@
[Go to documentation](https://github.com/morten-olsen/mini-loader)

View File

@@ -0,0 +1 @@
console.log('simple');

View File

@@ -0,0 +1,40 @@
{
"name": "@morten-olsen/mini-loader-tests",
"private": "true",
"version": "1.0.0",
"license": "GPL-3.0",
"main": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"type": "module",
"files": [
"./dist"
],
"exports": {
".": {
"import": "./dist/esm/index.js"
}
},
"devDependencies": {
"@morten-olsen/mini-loader-configs": "workspace:^",
"@types/node": "^20.10.8",
"fastify": "^4.25.2",
"sqlite3": "^5.1.7",
"typescript": "^5.3.3",
"vite": "^5.0.11"
},
"dependencies": {
"@morten-olsen/mini-loader": "workspace:^",
"@morten-olsen/mini-loader-cli": "workspace:^",
"@morten-olsen/mini-loader-server": "workspace:^",
"get-port": "^7.0.0",
"memfs": "^4.6.0",
"nanoid": "^5.0.4",
"typedi": "^0.10.0",
"vitest": "^1.2.0"
},
"homepage": "https://github.com/morten-olsen/mini-loader",
"repository": {
"type": "git",
"url": "https://github.com/morten-olsen/mini-loader"
}
}

View File

@@ -0,0 +1,56 @@
import { describe, it, beforeAll, afterAll, vi } from 'vitest';
import { TestEnv, createEnv } from './utils/env.js';
import { writeFile } from 'fs/promises';
import { resolve } from 'path';
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
describe('Quick start', () => {
let env: TestEnv;
beforeAll(async () => {
vi.mock('nanoid', () => {
let currentId = 0;
return {
nanoid: () => `id-${currentId++}`,
};
});
env = await createEnv();
});
afterAll(async () => {
vi.clearAllMocks();
await env.cleanup();
});
it('should be able to start the server', async () => {
const { server, port } = env;
await server.listen({ port });
});
it('should be able to login', async () => {
const { clientRun, port, token } = env;
await clientRun(['auth', 'login', '--host', `http://localhost:${port}`, '--token', token]);
});
it('should be able to push a load', async () => {
const { clientRun, location } = env;
const scriptPath = resolve(location, 'simple.js');
await writeFile(scriptPath, 'console.log("hello world")', 'utf-8');
await clientRun(['loads', 'push', scriptPath, '-i', 'demo', '-r']);
await sleep(100);
});
it('should be able to get the run', async () => {
const { clientRun } = env;
await clientRun(['runs', 'ls', 'demo']);
});
it('should be able to get logs', async () => {
const { clientRun, clientOutput } = env;
await clientRun(['logs', 'ls', '-l', 'demo']);
console.log(JSON.stringify(clientOutput, null, 2));
});
});

View File

@@ -0,0 +1,136 @@
import { Paths, Terminal, createClientCli } from '@morten-olsen/mini-loader-cli';
import { Runtime, createServer, Config } from '@morten-olsen/mini-loader-server';
import { FastifyInstance } from 'fastify';
import { ContainerInstance } from 'typedi';
import { join, resolve } from 'path';
import getPort from 'get-port';
import { rm } from 'fs/promises';
const cacheLocation = './e2e-tmp';
const getUniqueIdentifier = () => {
return Math.random().toString(36).substr(2, 9);
};
type CliActionOutput =
| {
type: 'stdout';
data: string;
}
| {
type: 'stderr';
data: string;
}
| {
type: 'step';
message: string;
state: 'pending' | 'success' | 'error';
}
| {
type: 'output';
data: unknown;
};
const createEnv = async () => {
const location = resolve(cacheLocation, getUniqueIdentifier());
const port = await getPort();
let clientOutput: CliActionOutput[] = [];
const serverContainer = new ContainerInstance(getUniqueIdentifier());
const clientRun = async (params: string[]) => {
const clientContainer = new ContainerInstance(getUniqueIdentifier());
clientContainer.set(Paths, {
config: join(location, 'client', 'config'),
cache: join(location, 'client', 'cache'),
});
clientContainer.set(Terminal, {
log: async (message: any) => {
clientOutput.push({
type: 'stdout',
data: message,
});
},
output: async (data: any) => {
clientOutput.push({
type: 'output',
data,
});
},
step: async (message: any, action: any) => {
clientOutput.push({
type: 'step',
message,
state: 'pending',
});
try {
const result = await action();
clientOutput.push({
type: 'step',
message,
state: 'success',
});
return result;
} catch (err) {
clientOutput.push({
type: 'step',
message,
state: 'error',
});
throw err;
}
},
});
const client = createClientCli(clientContainer);
client.configureOutput({
writeOut: (data) => {
clientOutput.push({
type: 'stdout',
data,
});
},
writeErr: (data) => {
clientOutput.push({
type: 'stderr',
data,
});
throw new Error(`Error in client ${data}`);
},
});
await client.parseAsync(['', '', ...params]);
};
serverContainer.set(Config, {
database: {
client: 'sqlite3',
connection: {
filename: join(location, 'server', 'data', 'db.sqlite'),
},
useNullAsDefault: true,
},
files: {
data: join(location, 'server', 'data'),
cache: join(location, 'server', 'cache'),
},
});
const server = await createServer(serverContainer);
const runtime = serverContainer.get(Runtime);
const token = await runtime.auth.createToken({
policy: {
'*:*': ['*'],
},
});
const cleanup = async () => {
await server.close();
await rm(location, { recursive: true, force: true });
};
return { clientRun, clientOutput, runtime, server, token, location, port, cleanup };
};
type TestEnv = Awaited<ReturnType<typeof createEnv>>;
export type { TestEnv, FastifyInstance };
export { createEnv };

View File

@@ -0,0 +1,9 @@
{
"extends": "@morten-olsen/mini-loader-configs/tsconfig.esm.json",
"compilerOptions": {
"outDir": "dist/esm",
},
"include": [
"src"
],
}

View File

@@ -0,0 +1,22 @@
/// <reference types="vitest" />
import { createRequire } from 'module';
import { defineConfig } from 'vite';
const require = createRequire(import.meta.url);
const server = require.resolve('../server/src/index.ts');
const cli = require.resolve('../cli/src/index.ts');
const runner = require.resolve('../runner/src/index.ts');
const sdk = require.resolve('../mini-loader/src/index.ts');
export default defineConfig({
test: {
alias: {
'@morten-olsen/mini-loader-server': server,
'@morten-olsen/mini-loader-cli': cli,
'@morten-olsen/mini-loader-runner': runner,
'@morten-olsen/mini-loader': sdk,
},
},
});