Add Prettier and ESLint tooling (Refs #77)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { putFileBlob } from '../../src/lib/server/db/file-blobs.js';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { chmod, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
||||
import { existsSync, writeFileSync } from 'node:fs';
|
||||
import { chmod, readFile, stat, writeFile } from 'node:fs/promises';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
|
||||
@@ -11,7 +11,8 @@ vi.mock('node:fs', async (importOriginal) => {
|
||||
});
|
||||
|
||||
vi.mock('../../src/lib/server/integrations/rcon.js', () => ({
|
||||
rconGetPlayerCount: vi.fn(), rconStatusResult: vi.fn()
|
||||
rconGetPlayerCount: vi.fn(),
|
||||
rconStatusResult: vi.fn()
|
||||
}));
|
||||
|
||||
let fixture: Fixture;
|
||||
@@ -20,7 +21,8 @@ const relPath = 'staged.gsc';
|
||||
const before = Buffer.from('main(){ /* current live script */ }');
|
||||
const after = Buffer.from('main(){ /* reviewed replacement */ }');
|
||||
type Source = 'campaign' | 'beta';
|
||||
const destination = (server = servers[0]) => join(fixture.t5, server, 'runtime/plutonium/storage/t5/raw/scripts/sp', relPath);
|
||||
const destination = (server = servers[0]) =>
|
||||
join(fixture.t5, server, 'runtime/plutonium/storage/t5/raw/scripts/sp', relPath);
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
@@ -35,10 +37,12 @@ beforeEach(async () => {
|
||||
vi.stubEnv('DEPLOYMENT_RESTART_CONCURRENCY', '1');
|
||||
const { seedServerRegistry } = await import('../../src/lib/server/fleet/servers.js');
|
||||
await seedServerRegistry();
|
||||
const { rconGetPlayerCount, rconStatusResult } = await import('../../src/lib/server/integrations/rcon.js');
|
||||
const { rconGetPlayerCount, rconStatusResult } =
|
||||
await import('../../src/lib/server/integrations/rcon.js');
|
||||
vi.mocked(rconGetPlayerCount).mockResolvedValue(0);
|
||||
vi.mocked(rconStatusResult).mockResolvedValue({
|
||||
ok: true, endpoint: { host: 'test', port: 28960 },
|
||||
ok: true,
|
||||
endpoint: { host: 'test', port: 28960 },
|
||||
status: { players: 0, map: 'zombie_theater', gametype: 'zom', roster: [] }
|
||||
});
|
||||
});
|
||||
@@ -51,27 +55,48 @@ afterEach(async () => {
|
||||
|
||||
async function queueChange(source: Source, targets = [servers[0]]) {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { createScript, uploadNewVersion } = await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { recordScript, getServerScript } = await import('../../src/lib/server/fleet/inventory.js');
|
||||
const original = createScript({ name: 'Staged script', kind: 'script', targetRelPath: relPath,
|
||||
scopeType: 'game', scopeValue: 't5', content: before });
|
||||
const { createScript, uploadNewVersion } =
|
||||
await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { recordScript, getServerScript } =
|
||||
await import('../../src/lib/server/fleet/inventory.js');
|
||||
const original = createScript({
|
||||
name: 'Staged script',
|
||||
kind: 'script',
|
||||
targetRelPath: relPath,
|
||||
scopeType: 'game',
|
||||
scopeValue: 't5',
|
||||
content: before
|
||||
});
|
||||
const replacement = uploadNewVersion(original.script.id, after);
|
||||
for (const server of targets) {
|
||||
await writeFile(destination(server), before);
|
||||
recordScript(server, relPath, original.version.id, original.version.sha256, before.length, 'fixture');
|
||||
recordScript(
|
||||
server,
|
||||
relPath,
|
||||
original.version.id,
|
||||
original.version.sha256,
|
||||
before.length,
|
||||
'fixture'
|
||||
);
|
||||
}
|
||||
const inventory = getServerScript(targets[0], relPath);
|
||||
let sourceId: string;
|
||||
if (source === 'campaign') {
|
||||
db().prepare('UPDATE scripts SET current_version_id = ? WHERE id = ?').run(replacement.id, original.script.id);
|
||||
db()
|
||||
.prepare('UPDATE scripts SET current_version_id = ? WHERE id = ?')
|
||||
.run(replacement.id, original.script.id);
|
||||
const { runDriftDeployment } = await import('../../src/lib/server/fleet/drift.js');
|
||||
const result = await runDriftDeployment({ servers: targets });
|
||||
expect(result.deploymentId).toBeTruthy();
|
||||
sourceId = result.deploymentId!;
|
||||
} else {
|
||||
const { openBeta } = await import('../../src/lib/server/fleet/beta.js');
|
||||
const result = await openBeta({ scripts: [{ scriptId: original.script.id, scriptVersionId: replacement.id }],
|
||||
servers: targets, waitForHealth: false, waitForMatch: false });
|
||||
const result = await openBeta({
|
||||
scripts: [{ scriptId: original.script.id, scriptVersionId: replacement.id }],
|
||||
servers: targets,
|
||||
waitForHealth: false,
|
||||
waitForMatch: false
|
||||
});
|
||||
sourceId = String(result.betaId);
|
||||
}
|
||||
return { sourceId, inventory, replacement };
|
||||
@@ -82,18 +107,24 @@ async function queueChange(source: Source, targets = [servers[0]]) {
|
||||
async function tick(source: Source) {
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { activateFiles } = await import('../helpers/staged-files.js');
|
||||
const sources = db().prepare('SELECT DISTINCT source_id FROM staged_file_changes WHERE source_kind=? AND state=\'pending\'').all(source) as { source_id: string }[];
|
||||
const sources = db()
|
||||
.prepare(
|
||||
"SELECT DISTINCT source_id FROM staged_file_changes WHERE source_kind=? AND state='pending'"
|
||||
)
|
||||
.all(source) as { source_id: string }[];
|
||||
for (const row of sources) await activateFiles(source, row.source_id);
|
||||
}
|
||||
|
||||
async function expectLiveUnchanged(inventory: Awaited<ReturnType<typeof queueChange>>['inventory'], server = servers[0]) {
|
||||
async function expectLiveUnchanged(
|
||||
inventory: Awaited<ReturnType<typeof queueChange>>['inventory'],
|
||||
server = servers[0]
|
||||
) {
|
||||
const { getServerScript } = await import('../../src/lib/server/fleet/inventory.js');
|
||||
expect(await readFile(destination(server))).toEqual(before);
|
||||
expect(getServerScript(server, relPath)).toEqual(inventory);
|
||||
}
|
||||
|
||||
describe.each<Source>(['campaign', 'beta'])('%s staged file activation', (source) => {
|
||||
|
||||
it('preserves existing file permissions when activating staged bytes', async () => {
|
||||
await queueChange(source);
|
||||
await chmod(destination(), 0o640);
|
||||
@@ -105,7 +136,8 @@ describe.each<Source>(['campaign', 'beta'])('%s staged file activation', (source
|
||||
it('applies the exact queued bytes even if artifact storage changes while waiting', async () => {
|
||||
const { replacement } = await queueChange(source);
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
db().prepare('UPDATE script_versions SET content_hash = ? WHERE id = ?')
|
||||
db()
|
||||
.prepare('UPDATE script_versions SET content_hash = ? WHERE id = ?')
|
||||
.run(putFileBlob(Buffer.from('changed after review'), db()), replacement.id);
|
||||
await tick(source);
|
||||
expect(await readFile(destination())).toEqual(after);
|
||||
|
||||
Reference in New Issue
Block a user