From aea1ec5eba5cf1217830099ce48615c7a8e111e7 Mon Sep 17 00:00:00 2001 From: RyuJongJin <266630912+RyuJongJin@users.noreply.github.com> Date: Fri, 23 Oct 2026 01:36:54 +0900 Subject: [PATCH] =?UTF-8?q?vault=5Fpage=5Ftest=20=ED=9D=94=EB=93=A4?= =?UTF-8?q?=EB=A6=BC=20=EA=B3=A0=EC=B9=A8=20(=EA=B8=B0=EB=8C=80=EA=B0=92?= =?UTF-8?q?=20=EA=B7=B8=EB=8C=80=EB=A1=9C):=20=EA=B8=B0=EB=8B=A4=EB=A6=BC?= =?UTF-8?q?=EC=9D=84=20=EC=8B=A4=EC=A0=9C=20=EC=8B=9C=EA=B0=84=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=C2=B7=20=EB=B3=B4=EA=B4=80=ED=95=A8=20=EC=93=B0?= =?UTF-8?q?=EA=B8=B0=EA=B0=80=20=EB=8B=A4=20=EB=81=9D=EB=82=A0=20=EB=95=8C?= =?UTF-8?q?=EA=B9=8C=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 원인: until 이 횟수 (200번) 로 끊겨 부하 때 일이 덜 끝난 채 넘어갔고, 끝맺음의 '.tmp 없음' 한 번 확인이 목록 저장과 빈 폴더 목록 저장 사이에 맞아 folders.jjd.tmp 쓰기가 연 채 남아 임시 폴더를 지우지 못했다 (errno 32, 6/18 재현) - until: 최대 60초 실제 시간, 안 되면 그 자리에서 실패 (조용히 넘어가지 않음). vaultQuiet: .tmp 없음이 10번 잇달아일 때 - 확인: 6개 동시 × 3회 18/18, 혼자 10회 연속 통과 Co-Authored-By: Claude Opus 5.5 --- test/vault_page_test.dart | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/test/vault_page_test.dart b/test/vault_page_test.dart index d5bef84..d43f02b 100644 --- a/test/vault_page_test.dart +++ b/test/vault_page_test.dart @@ -52,8 +52,12 @@ void main() { return c; } - Future until(WidgetTester t, bool Function() ok, {int rounds = 200}) async { - for (var i = 0; i < rounds && !ok(); i++) { + /// 실제 시간으로 기다린다 (암호화 · 파일 쓰기는 실제 IO - 시험을 여럿 함께 돌려 느릴 때 횟수로 끊으면 일이 덜 끝난 채 넘어가, + /// 시험이 끝난 뒤 남은 쓰기가 파일을 연 채 멈춰 임시 폴더를 지우지 못했다 - errno 32). 끝내 안 되면 그 자리에서 실패 + Future until(WidgetTester t, bool Function() ok, {Duration limit = const Duration(seconds: 60)}) async { + final w = Stopwatch()..start(); + while (!ok()) { + if (w.elapsed > limit) fail('기다린 일이 ${limit.inSeconds}초 안에 끝나지 않음'); await t.runAsync(() => Future.delayed(const Duration(milliseconds: 20))); await t.pump(const Duration(milliseconds: 20)); } @@ -63,6 +67,17 @@ void main() { } } + /// 보관함의 쓰기가 다 끝날 때까지: 쓰는 중인 파일 (.tmp) 이 없는 것이 10번 잇달아일 때 (사이마다 pump). + /// 한 번만 보면 목록 저장 → 빈 폴더 목록 저장 사이에 맞아, 남은 쓰기가 파일을 연 채 시험이 끝났다 (errno 32) + Future vaultQuiet(WidgetTester t) async { + var calm = 0; + await until(t, () { + final busy = Directory(p.join(tmp.path, 'vault')).listSync().any((f) => f.path.endsWith('.tmp')); + calm = busy ? 0 : calm + 1; + return calm >= 10; + }); + } + /// 진행 막대 · 글자 칸 깜빡임이 있으면 pumpAndSettle 이 끝나지 않는다 - 정한 만큼만 Future settle(WidgetTester t) async { for (var i = 0; i < 12; i++) { @@ -141,7 +156,7 @@ void main() { await until(t, () => find.text('보관함이 비어 있습니다').evaluate().isNotEmpty); expect(find.text('보관함이 비어 있습니다'), findsOneWidget); // 목록 쓰기 (index.jjv.tmp → index.jjv) 가 끝날 때까지 (화면은 먼저 바뀔 수 있다) - await until(t, () => !Directory(p.join(tmp.path, 'vault')).listSync().any((f) => f.path.endsWith('.tmp'))); + await vaultQuiet(t); await t.pumpWidget(const SizedBox()); }); @@ -202,7 +217,7 @@ void main() { await until(t, () => find.text('보관함이 비어 있습니다').evaluate().isNotEmpty); expect(find.text('보관함이 비어 있습니다'), findsOneWidget); // 목록 쓰기 (index.jjv.tmp → index.jjv) 가 끝날 때까지 (화면은 먼저 바뀔 수 있다) - await until(t, () => !Directory(p.join(tmp.path, 'vault')).listSync().any((f) => f.path.endsWith('.tmp'))); + await vaultQuiet(t); await t.pumpWidget(const SizedBox()); }); testWidgets('파일 탐색기: [보관함에 넣기] 는 보관함을 켰을 때 · 파일과 폴더 (2단계)', (t) async { @@ -414,7 +429,7 @@ void main() { await t.tap(find.widgetWithText(FilledButton, '지우기')); await until(t, () => find.text('album').evaluate().isEmpty); expect(find.text('remote.txt'), findsOneWidget); - await until(t, () => !Directory(p.join(tmp.path, 'vault')).listSync().any((f) => f.path.endsWith('.tmp'))); + await vaultQuiet(t); await t.pumpWidget(const SizedBox()); }); }