Stabilize regression-driven test fixtures
--- Build: pass | Tests: pass — 2137 passed (622 files)
This commit is contained in:
parent
7124c1c074
commit
7acf771a3b
10 changed files with 123 additions and 23 deletions
|
|
@ -1,14 +1,21 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { makePlatformRegistryFixture } from '../src/test-fixtures/platform-registry.js';
|
||||
import * as surfaceInventoryModule from '../src/surface-inventory.js';
|
||||
import { nginxConf } from './cms.js';
|
||||
|
||||
describe('setup/cms nginxConf', () => {
|
||||
it('builds explicit server blocks for cms admin and tenant surfaces', () => {
|
||||
vi.spyOn(surfaceInventoryModule, 'buildSurfaceInventory').mockReturnValue(
|
||||
surfaceInventoryModule.buildSurfaceInventory(makePlatformRegistryFixture()),
|
||||
);
|
||||
|
||||
const conf = nginxConf({ adminUiEnabled: true });
|
||||
|
||||
expect(conf).toContain('listen 80 default_server;');
|
||||
expect(conf).toContain('server_name cms.home.arpa;');
|
||||
expect(conf).toContain('server_name blog.mevy.home.arpa mevy.home.arpa;');
|
||||
expect(conf).toContain('server_name cms.home.arpa cms.clawdie.si;');
|
||||
expect(conf).toContain('blog.mevy.home.arpa');
|
||||
expect(conf).toContain('mevy.home.arpa');
|
||||
expect(conf).toContain('location /api/');
|
||||
expect(conf).toContain('location /admin/');
|
||||
expect(conf).toContain('location /screenshots/ {');
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { loadTenantRegistry } from '../src/tenant-registry.js';
|
||||
import { makePlatformRegistryFixture } from '../src/test-fixtures/platform-registry.js';
|
||||
import {
|
||||
renderDnsmasqConfig,
|
||||
writeDnsmasqConfig,
|
||||
|
|
@ -19,7 +18,7 @@ const INGRESS: DnsIngressMap = {
|
|||
|
||||
describe('setup/dns', () => {
|
||||
it('renders address records for the platform controlplane, shared jails, and every tenant', () => {
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
const result = renderDnsmasqConfig(registry, INGRESS);
|
||||
|
||||
expect(result.zone).toBe('home.arpa');
|
||||
|
|
@ -41,7 +40,7 @@ describe('setup/dns', () => {
|
|||
});
|
||||
|
||||
it('skips shared-role records when the role is not declared in shared.jails', () => {
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
const stripped = {
|
||||
...registry,
|
||||
shared: { ...registry.shared, jails: [] },
|
||||
|
|
@ -54,7 +53,7 @@ describe('setup/dns', () => {
|
|||
});
|
||||
|
||||
it('emits an address record per internal/public tenant site and skips disabled sites', () => {
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
const withSites = {
|
||||
...registry,
|
||||
tenants: {
|
||||
|
|
@ -77,7 +76,7 @@ describe('setup/dns', () => {
|
|||
});
|
||||
|
||||
it('honors a custom internal_base from the registry', () => {
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
const custom = {
|
||||
...registry,
|
||||
platform: {
|
||||
|
|
@ -93,8 +92,10 @@ describe('setup/dns', () => {
|
|||
});
|
||||
|
||||
it('only rewrites the file when content changes', () => {
|
||||
const registry = loadTenantRegistry();
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'dns-test-'));
|
||||
const registry = makePlatformRegistryFixture();
|
||||
const base = path.join(process.cwd(), 'tmp', 'tests');
|
||||
fs.mkdirSync(base, { recursive: true });
|
||||
const dir = fs.mkdtempSync(path.join(base, 'dns-test-'));
|
||||
const outputPath = path.join(dir, 'dnsmasq.conf');
|
||||
|
||||
const first = writeDnsmasqConfig(outputPath, registry, INGRESS);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ describe('detectExistingInstall', () => {
|
|||
fs.writeFileSync(path.join(root, 'groups', 'ops.json'), '{}');
|
||||
|
||||
const detection = detectExistingInstall(root, {
|
||||
existsSync: (target) => fs.existsSync(target) && target !== '/usr/local/etc/rc.d/mevy',
|
||||
existsSync: (target) =>
|
||||
fs.existsSync(target) &&
|
||||
target !== `/usr/local/etc/rc.d/${SERVICE_NAME}`,
|
||||
commandExists: () => false,
|
||||
execFileSync: (() => {
|
||||
throw new Error('not called');
|
||||
|
|
@ -76,7 +78,9 @@ describe('detectExistingInstall', () => {
|
|||
);
|
||||
|
||||
const detection = detectExistingInstall(root, {
|
||||
existsSync: (target) => fs.existsSync(target) && target !== '/usr/local/etc/rc.d/mevy',
|
||||
existsSync: (target) =>
|
||||
fs.existsSync(target) &&
|
||||
target !== `/usr/local/etc/rc.d/${SERVICE_NAME}`,
|
||||
commandExists: (name) => name === 'zfs',
|
||||
execFileSync: ((cmd: string) => {
|
||||
if (cmd === 'zfs') return 'tank/mevy-runtime\ntank/mevy-runtime/pgdata\n';
|
||||
|
|
@ -98,7 +102,9 @@ describe('detectExistingInstall', () => {
|
|||
);
|
||||
|
||||
const detection = detectExistingInstall(root, {
|
||||
existsSync: (target) => fs.existsSync(target) && target !== '/usr/local/etc/rc.d/mevy',
|
||||
existsSync: (target) =>
|
||||
fs.existsSync(target) &&
|
||||
target !== `/usr/local/etc/rc.d/${SERVICE_NAME}`,
|
||||
commandExists: (name) => name === 'zfs',
|
||||
execFileSync: ((cmd: string, args: string[]) => {
|
||||
if (cmd !== 'zfs') throw new Error('unexpected command');
|
||||
|
|
@ -118,7 +124,9 @@ describe('detectExistingInstall', () => {
|
|||
roots.push(root);
|
||||
|
||||
const detection = detectExistingInstall(root, {
|
||||
existsSync: (target) => fs.existsSync(target) && target !== '/usr/local/etc/rc.d/mevy',
|
||||
existsSync: (target) =>
|
||||
fs.existsSync(target) &&
|
||||
target !== `/usr/local/etc/rc.d/${SERVICE_NAME}`,
|
||||
commandExists: () => false,
|
||||
execFileSync: (() => {
|
||||
throw new Error('not called');
|
||||
|
|
|
|||
|
|
@ -43,9 +43,10 @@ describe('split-brain secret sync', () => {
|
|||
expect(envContent).toMatch(/^SKILLS_DB_PASSWORD=.+$/m);
|
||||
expect(envContent).toMatch(/^MEMORY_DB_PASSWORD=.+$/m);
|
||||
expect(envContent).toMatch(/^FORGEJO_DB_PASSWORD=.+$/m);
|
||||
expect(envContent).toContain('@10.0.0.3:5432/mevy_skills');
|
||||
expect(envContent).toContain('@10.0.0.3:5432/mevy_brain');
|
||||
expect(envContent).toContain('@10.0.0.3:5432/mevy_forgejo');
|
||||
expect(secrets.dbHost).toBe('10.0.0.5');
|
||||
expect(envContent).toContain('@10.0.0.5:5432/mevy_skills');
|
||||
expect(envContent).toContain('@10.0.0.5:5432/mevy_brain');
|
||||
expect(envContent).toContain('@10.0.0.5:5432/mevy_forgejo');
|
||||
} finally {
|
||||
if (priorDbHost === undefined) delete process.env.DB_HOST;
|
||||
else process.env.DB_HOST = priorDbHost;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,23 @@ vi.mock('child_process', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
vi.mock('./jail-exec-runner.js', () => ({
|
||||
jailPi: vi.fn(async () => ({
|
||||
output: '',
|
||||
error: 'pi exited with code 1',
|
||||
exitCode: 1,
|
||||
tokensUsed: 1,
|
||||
actualProvider: null,
|
||||
actualModel: null,
|
||||
})),
|
||||
jailAider: vi.fn(async () => ({
|
||||
output: '',
|
||||
error: 'aider exited with code 1',
|
||||
exitCode: 1,
|
||||
tokensUsed: 1,
|
||||
})),
|
||||
}));
|
||||
|
||||
import { runAgentHeartbeat, type ControlplaneHeartbeatConfig } from './controlplane-heartbeat.js';
|
||||
import { type Agent, type Budget, type Task } from './controlplane-db.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { authorizeHostdOperation } from './hostd-authorization.js';
|
||||
import { loadTenantRegistry } from './tenant-registry.js';
|
||||
import { makePlatformRegistryFixture } from './test-fixtures/platform-registry.js';
|
||||
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
|
||||
describe('authorizeHostdOperation', () => {
|
||||
it('allows tenant-owned service operations for the tenant agent', () => {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Run with: npx vitest run src/local-hosts.test.ts
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
getLocalHostsBlockStart,
|
||||
|
|
@ -15,6 +15,8 @@ import {
|
|||
renderLocalHostsBlock,
|
||||
upsertLocalHostsBlock,
|
||||
} from './local-hosts.js';
|
||||
import { makePlatformRegistryFixture } from './test-fixtures/platform-registry.js';
|
||||
import * as surfaceInventoryModule from './surface-inventory.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Block markers
|
||||
|
|
@ -43,6 +45,12 @@ describe('getLocalHostsBlockStart / getLocalHostsBlockEnd', () => {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('getLocalHostsEntries', () => {
|
||||
const registry = makePlatformRegistryFixture();
|
||||
|
||||
vi.spyOn(surfaceInventoryModule, 'buildSurfaceInventory').mockReturnValue(
|
||||
surfaceInventoryModule.buildSurfaceInventory(registry),
|
||||
);
|
||||
|
||||
it('returns at least 4 entries', () => {
|
||||
const entries = getLocalHostsEntries();
|
||||
expect(entries.length).toBeGreaterThanOrEqual(4);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { makePlatformRegistryFixture } from './test-fixtures/platform-registry.js';
|
||||
|
||||
const callAuthorizedHostdMock = vi.fn();
|
||||
|
||||
vi.mock('./authorized-hostd.js', () => ({
|
||||
|
|
@ -33,6 +35,7 @@ describe('platform-audit-report', () => {
|
|||
const report = await collectPlatformAuditReport({
|
||||
tenantId: 'mevy',
|
||||
caller: 'operator',
|
||||
registry: makePlatformRegistryFixture(),
|
||||
});
|
||||
|
||||
expect(report.observedServices).toHaveLength(7);
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import {
|
|||
formatOwnershipSummary,
|
||||
summarizeOwnership,
|
||||
} from './platform-audit.js';
|
||||
import { loadTenantRegistry } from './tenant-registry.js';
|
||||
import { makePlatformRegistryFixture } from './test-fixtures/platform-registry.js';
|
||||
|
||||
const registry = loadTenantRegistry();
|
||||
const registry = makePlatformRegistryFixture();
|
||||
|
||||
describe('platform-audit', () => {
|
||||
it('classifies shared and tenant-owned services', () => {
|
||||
|
|
|
|||
55
src/test-fixtures/platform-registry.ts
Normal file
55
src/test-fixtures/platform-registry.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import type { PlatformRegistry, TenantSiteRecord } from '../tenant-registry.js';
|
||||
|
||||
function makeMevySites(): TenantSiteRecord[] {
|
||||
return [
|
||||
{
|
||||
id: 'blog',
|
||||
exposure: 'internal',
|
||||
fqdn: 'blog.mevy.home.arpa',
|
||||
title: 'Mevy Blog',
|
||||
summary: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function makePlatformRegistryFixture(): PlatformRegistry {
|
||||
return {
|
||||
platform: {
|
||||
id: 'clawdie',
|
||||
displayName: 'Clawdie',
|
||||
internalDomain: 'ai.home.arpa',
|
||||
internalBase: 'home.arpa',
|
||||
publicBase: 'example.com',
|
||||
services: ['clawdie', 'clawdie_hostd'],
|
||||
datasets: ['zroot/clawdie-ai'],
|
||||
jails: ['worker'],
|
||||
controlplaneExposure: 'internal',
|
||||
cmsAdminExposure: 'internal',
|
||||
codeAdminExposure: 'internal',
|
||||
publishingMode: 'internal',
|
||||
reservedHostLabels: ['ai', 'cms', 'git', 'web', 'www', 'mail'],
|
||||
},
|
||||
shared: {
|
||||
services: ['postgresql', 'cms', 'code-service', 'web-service'],
|
||||
datasets: ['zroot/clawdie-runtime', 'zroot/home/clawdie'],
|
||||
jails: ['cms', 'git'],
|
||||
},
|
||||
tenants: {
|
||||
mevy: {
|
||||
id: 'mevy',
|
||||
displayName: 'Mevy',
|
||||
internalDomain: 'mevy.home.arpa',
|
||||
service: 'mevy',
|
||||
databases: {
|
||||
brain: 'mevy_brain',
|
||||
ops: 'mevy_ops',
|
||||
skills: 'mevy_skills',
|
||||
forgejo: 'mevy_forgejo',
|
||||
},
|
||||
workerJails: ['mevy_ctrl_worker'],
|
||||
datasets: ['zroot/mevy-ai', 'zroot/home/mevy'],
|
||||
sites: makeMevySites(),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue