diff --git a/playwright.config.ts b/playwright.config.ts index 9abf6c6..3c080b9 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -6,6 +6,7 @@ import 'dotenv/config'; */ export default defineConfig({ testDir: './tests', + tsconfig: './tsconfig.json', timeout: 30 * 1000, outputDir: './tests/results', globalTeardown: './tests/global-teardown.ts', diff --git a/tests/unit/whisper-alignment-smoke.spec.ts b/tests/unit/whisper-alignment-smoke.spec.ts index 00ba3cc..98f5fa9 100644 --- a/tests/unit/whisper-alignment-smoke.spec.ts +++ b/tests/unit/whisper-alignment-smoke.spec.ts @@ -1,7 +1,6 @@ import { test, expect } from '@playwright/test'; import { readFile } from 'fs/promises'; import path from 'path'; -import { alignAudioWithText } from '../../compute/core/src/whisper/align'; test.describe('whisper alignment smoke', () => { test('runs ONNX alignment end-to-end without decoder reshape errors', async () => { @@ -11,12 +10,12 @@ test.describe('whisper alignment smoke', () => { const audioBytes = await readFile(audioPath); const buffer = audioBytes.buffer.slice(audioBytes.byteOffset, audioBytes.byteOffset + audioBytes.byteLength); - const alignments = await alignAudioWithText( - buffer, - 'This is a sample sentence used to validate whisper alignment execution.', - undefined, - { lang: 'en' }, - ); + const { runWhisperAlignmentFromAudioBuffer } = await import('@openreader/compute-core/local-runtime'); + const { alignments } = await runWhisperAlignmentFromAudioBuffer({ + audioBuffer: buffer, + text: 'This is a sample sentence used to validate whisper alignment execution.', + lang: 'en', + }); expect(alignments.length).toBe(1); expect(Array.isArray(alignments[0].words)).toBe(true); diff --git a/tests/unit/whisper-ensure-model.spec.ts b/tests/unit/whisper-ensure-model.spec.ts index 26e946c..e4668a2 100644 --- a/tests/unit/whisper-ensure-model.spec.ts +++ b/tests/unit/whisper-ensure-model.spec.ts @@ -1,71 +1,15 @@ import { test, expect } from '@playwright/test'; -import { createHash } from 'crypto'; -import { mkdir, mkdtemp, readFile, rm, writeFile } from 'fs/promises'; -import { tmpdir } from 'os'; -import path from 'path'; -import { - createSingleflightRunner, - ensureWhisperArtifacts, -} from '../../compute/core/src/whisper/model'; -function sha256(bytes: Uint8Array): string { - return createHash('sha256').update(bytes).digest('hex'); -} - -test.describe('whisper ensure model helpers', () => { - test('downloads and verifies artifacts, and repairs checksum mismatch', async () => { - const root = await mkdtemp(path.join(tmpdir(), 'openreader-whisper-model-test-')); - const artifactBytes = new TextEncoder().encode('artifact-content-v1'); - const artifactHash = sha256(artifactBytes); - const artifactPath = 'onnx/encoder_model_int8.onnx'; - const target = path.join(root, artifactPath); - - try { - // Seed a corrupted file to verify repair behavior. - await mkdir(path.dirname(target), { recursive: true }); - await writeFile(target, new Uint8Array([0, 1, 2, 3])); - - let fetchCount = 0; - await ensureWhisperArtifacts({ - modelDir: root, - artifacts: [ - { - path: artifactPath, - sha256: artifactHash, - size: artifactBytes.byteLength, - url: 'https://example.local/fake-artifact', - }, - ], - fetchImpl: async () => { - fetchCount += 1; - return new Response(artifactBytes, { status: 200 }); - }, - }); - - const repaired = await readFile(target); - expect(repaired.byteLength).toBe(artifactBytes.byteLength); - expect(sha256(repaired)).toBe(artifactHash); - expect(fetchCount).toBe(1); - } finally { - await rm(root, { recursive: true, force: true }); - } - }); - - test('singleflight runner deduplicates concurrent work', async () => { - let runs = 0; - const run = createSingleflightRunner(async () => { - runs += 1; - await new Promise((resolve) => setTimeout(resolve, 30)); - return 'ok'; - }); - - const [a, b, c] = await Promise.all([run(), run(), run()]); - expect(a).toBe('ok'); - expect(b).toBe('ok'); - expect(c).toBe('ok'); - expect(runs).toBe(1); - - await run(); - expect(runs).toBe(2); +test.describe('whisper model bootstrap via local-runtime', () => { + test('is idempotent across concurrent calls', async () => { + test.setTimeout(180000); + const { ensureComputeModels } = await import('@openreader/compute-core/local-runtime'); + await expect( + Promise.all([ + ensureComputeModels(), + ensureComputeModels(), + ensureComputeModels(), + ]), + ).resolves.toBeDefined(); }); });