WIP 시험 흔들림: batch_test P0 (931) 묶음을 239 처럼 조건이 될 때까지 기다리기 · 한도 4분 (관리자 지시) (검토 대기)

전체 시험 중 PC 가 바쁘면 (Windows 통합 시험과 겹침) "240 집계" 가 정해진 횟수 (800 × 25ms) 안에 v2 가 시작하지 않아
기본 30초 한도에 걸렸다. 시간으로 기다리고 (최대 90초), 이 묶음 세 시험의 한도를 4분으로. 기대값은 그대로.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review_fix
RyuJongJin 2026-10-18 02:58:16 +09:00
parent 00e9685a33
commit e7cd30ef41
1 changed files with 14 additions and 9 deletions

View File

@ -298,6 +298,14 @@ void main() {
return true; return true;
} }
// 관리자 지적 (10/18): 전체 시험 중 PC 가 바쁘면 정해진 횟수 안에 오지 않아 30초 한도에 걸렸다 (240) - 239 처럼 될 때까지 기다린다
Future<void> until(bool Function() ok, {Duration max = const Duration(seconds: 90)}) async {
final end = DateTime.now().add(max);
while (!ok() && DateTime.now().isBefore(end)) {
await Future<void>.delayed(const Duration(milliseconds: 20));
}
}
File out(int i) => File(outputMkvPath(files[i])); File out(int i) => File(outputMkvPath(files[i]));
void writeOld(int i) => (out(i)..createSync(recursive: true)).writeAsStringSync('OLD COMPLETE MKV'); void writeOld(int i) => (out(i)..createSync(recursive: true)).writeAsStringSync('OLD COMPLETE MKV');
List<String> parts() => [ List<String> parts() => [
@ -310,16 +318,14 @@ void main() {
final v1 = c.videos.first; final v1 = c.videos.first;
writeOld(0); writeOld(0);
final building = c.buildVideos([v1], onExisting: 'overwrite'); final building = c.buildVideos([v1], onExisting: 'overwrite');
for (var i = 0; i < 400 && !(v1.status == JobStatus.running && v1.progress > 0.02); i++) { await until(() => v1.status == JobStatus.running && v1.progress > 0.02);
await Future<void>.delayed(const Duration(milliseconds: 25));
}
expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '만드는 동안에도 예전 것은 그대로 (임시 이름에 씀)'); expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '만드는 동안에도 예전 것은 그대로 (임시 이름에 씀)');
c.cancel(); c.cancel();
await building; await building;
expect(v1.status, JobStatus.cancelled); expect(v1.status, JobStatus.cancelled);
expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '취소해도 예전 완성본은 남는다'); expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '취소해도 예전 완성본은 남는다');
expect(parts(), isEmpty, reason: '만들다 만 임시 파일은 지움'); expect(parts(), isEmpty, reason: '만들다 만 임시 파일은 지움');
}); }, timeout: const Timeout(Duration(minutes: 4)));
test('덮어쓰기 · 건너뛰기 · 다른 이름', () async { test('덮어쓰기 · 건너뛰기 · 다른 이름', () async {
if (!await prepare()) return markTestSkipped('FFmpeg 없음'); if (!await prepare()) return markTestSkipped('FFmpeg 없음');
@ -337,7 +343,7 @@ void main() {
expect(File(p.join(p.dirname(out(2).path), 'b3 (2).mkv')).lengthSync(), greaterThan(100)); expect(File(p.join(p.dirname(out(2).path), 'b3 (2).mkv')).lengthSync(), greaterThan(100));
expect(v3.outputPath, endsWith('b3 (2).mkv')); expect(v3.outputPath, endsWith('b3 (2).mkv'));
expect(parts(), isEmpty); expect(parts(), isEmpty);
}); }, timeout: const Timeout(Duration(minutes: 4)));
test('240 집계: 다시 만들다 [남은 것 모두 취소] - 앞 실행의 ✓ 가 섞이지 않고 시작 못 한 것은 취소 (성공 1 · 취소 2)', () async { test('240 집계: 다시 만들다 [남은 것 모두 취소] - 앞 실행의 ✓ 가 섞이지 않고 시작 못 한 것은 취소 (성공 1 · 취소 2)', () async {
if (!await prepare(seconds: [1, 60, 1])) return markTestSkipped('FFmpeg 없음'); if (!await prepare(seconds: [1, 60, 1])) return markTestSkipped('FFmpeg 없음');
@ -346,14 +352,13 @@ void main() {
v2.status = JobStatus.done; // 앞 실행에서 ✓ 였던 것 v2.status = JobStatus.done; // 앞 실행에서 ✓ 였던 것
v3.status = JobStatus.done; v3.status = JobStatus.done;
final building = c.buildVideos([v1, v2, v3], onExisting: 'overwrite'); final building = c.buildVideos([v1, v2, v3], onExisting: 'overwrite');
for (var i = 0; i < 800 && !(v2.status == JobStatus.running && v2.progress > 0.01); i++) { await until(() => v2.status == JobStatus.running && v2.progress > 0.01);
await Future<void>.delayed(const Duration(milliseconds: 25)); expect(v2.status, JobStatus.running, reason: '기다린 끝에도 v2 가 시작하지 않음');
}
c.cancel(); c.cancel();
await building; await building;
expect([v1.status, v2.status, v3.status], [JobStatus.done, JobStatus.cancelled, JobStatus.cancelled]); expect([v1.status, v2.status, v3.status], [JobStatus.done, JobStatus.cancelled, JobStatus.cancelled]);
expect(c.logs.last, contains('성공 1 · 취소 2 · 실패 0 / 전체 3')); expect(c.logs.last, contains('성공 1 · 취소 2 · 실패 0 / 전체 3'));
}); }, timeout: const Timeout(Duration(minutes: 4)));
}); });
test('239: 취소 창을 연 뒤 그 동영상이 끝나고 다음 것이 시작했으면 [지금 것만 취소] 는 다음 것을 취소하지 않는다', () async { test('239: 취소 창을 연 뒤 그 동영상이 끝나고 다음 것이 시작했으면 [지금 것만 취소] 는 다음 것을 취소하지 않는다', () async {