feat: publish av-tools 0.1.0
This commit is contained in:
124
tests/unit/ffmpeg-engine-arguments.test.ts
Normal file
124
tests/unit/ffmpeg-engine-arguments.test.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
DEFAULT_JOB_TIMEOUT_MILLISECONDS,
|
||||
MAX_CONTACT_SHEETS_PER_ENGINE,
|
||||
MAX_EXECUTIONS_PER_ENGINE,
|
||||
MULTITHREAD_CODEC_THREAD_LIMIT,
|
||||
engineJobTimeoutMilliseconds,
|
||||
prepareEngineArguments,
|
||||
shouldRecycleExecutionCore,
|
||||
} from '../../src/ffmpeg/EngineManager';
|
||||
|
||||
describe('prepareEngineArguments', () => {
|
||||
it('leaves single-thread commands unchanged', () => {
|
||||
const args = ['-i', '/input/source.mp4', '/work/output.mp4'];
|
||||
expect(
|
||||
prepareEngineArguments(
|
||||
args,
|
||||
'single-thread',
|
||||
['/input/source.mp4'],
|
||||
['/work/output.mp4']
|
||||
)
|
||||
).toEqual(args);
|
||||
});
|
||||
|
||||
it('bounds multithread input and output codec threads', () => {
|
||||
expect(
|
||||
prepareEngineArguments(
|
||||
['-i', '/input/source.mp4', '-c:v', 'libx264', '/work/output.mp4'],
|
||||
'multithread',
|
||||
['/input/source.mp4'],
|
||||
['/work/output.mp4']
|
||||
)
|
||||
).toEqual([
|
||||
'-threads',
|
||||
String(MULTITHREAD_CODEC_THREAD_LIMIT),
|
||||
'-i',
|
||||
'/input/source.mp4',
|
||||
'-c:v',
|
||||
'libx264',
|
||||
'-threads',
|
||||
String(MULTITHREAD_CODEC_THREAD_LIMIT),
|
||||
'/work/output.mp4',
|
||||
]);
|
||||
});
|
||||
|
||||
it('bounds a generated output pattern in the final output position', () => {
|
||||
expect(
|
||||
prepareEngineArguments(
|
||||
['-i', '/input/source.mp4', '-f', 'segment', '/work/part-%03d.mp4'],
|
||||
'multithread',
|
||||
['/input/source.mp4'],
|
||||
['/work/part-001.mp4', '/work/part-002.mp4']
|
||||
)
|
||||
).toEqual([
|
||||
'-threads',
|
||||
'2',
|
||||
'-i',
|
||||
'/input/source.mp4',
|
||||
'-f',
|
||||
'segment',
|
||||
'-threads',
|
||||
'2',
|
||||
'/work/part-%03d.mp4',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('engineJobTimeoutMilliseconds', () => {
|
||||
it('uses a bounded duration-aware watchdog', () => {
|
||||
expect(engineJobTimeoutMilliseconds({ expectedDurationSeconds: 2 })).toBe(
|
||||
120_000
|
||||
);
|
||||
expect(
|
||||
engineJobTimeoutMilliseconds({ expectedDurationSeconds: 10_000 })
|
||||
).toBe(DEFAULT_JOB_TIMEOUT_MILLISECONDS);
|
||||
});
|
||||
|
||||
it('honors a shorter explicit timeout and caps a longer one', () => {
|
||||
expect(
|
||||
engineJobTimeoutMilliseconds({
|
||||
expectedDurationSeconds: 30,
|
||||
timeoutMilliseconds: 5_000,
|
||||
})
|
||||
).toBe(5_000);
|
||||
expect(
|
||||
engineJobTimeoutMilliseconds({
|
||||
timeoutMilliseconds: DEFAULT_JOB_TIMEOUT_MILLISECONDS * 2,
|
||||
})
|
||||
).toBe(DEFAULT_JOB_TIMEOUT_MILLISECONDS);
|
||||
});
|
||||
});
|
||||
|
||||
describe('execution core recycling policy', () => {
|
||||
it('refreshes only after the bounded idle-core job budget is exhausted', () => {
|
||||
expect(shouldRecycleExecutionCore(MAX_EXECUTIONS_PER_ENGINE - 1)).toBe(
|
||||
false
|
||||
);
|
||||
expect(shouldRecycleExecutionCore(MAX_EXECUTIONS_PER_ENGINE)).toBe(true);
|
||||
});
|
||||
|
||||
it('refreshes before a fourth contact sheet hits retained tile-filter state', () => {
|
||||
expect(
|
||||
shouldRecycleExecutionCore(
|
||||
3,
|
||||
'contact-sheet',
|
||||
MAX_CONTACT_SHEETS_PER_ENGINE - 1
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldRecycleExecutionCore(
|
||||
3,
|
||||
'contact-sheet',
|
||||
MAX_CONTACT_SHEETS_PER_ENGINE
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldRecycleExecutionCore(
|
||||
3,
|
||||
'thumbnail-series',
|
||||
MAX_CONTACT_SHEETS_PER_ENGINE
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user