This commit is contained in:
2026-08-31 18:35:58 +08:00
parent 36dc258224
commit dbe31b94a3
18 changed files with 822 additions and 58 deletions
+39
View File
@@ -11,6 +11,13 @@ const _modelBytes = [1, 2, 3, 4, 5, 6, 7, 8];
String _shaHex(List<int> bytes) => sha256.convert(bytes).toString();
/// 分两段到达的下载流(中间 50ms 停顿,供取消测试在下载中触发)
Stream<List<int>> _delayedChunks() async* {
yield [1, 2, 3, 4];
await Future<void>.delayed(const Duration(milliseconds: 50));
yield [5, 6, 7, 8];
}
Map<String, dynamic> _catalog(List<Map<String, dynamic>> models) => {
'code': 0,
'message': 'ok',
@@ -194,4 +201,36 @@ void main() {
expect(broken.ready, isFalse);
expect(broken.error, isNotNull);
});
test('取消下载:中断后恢复未下载、不记错误', () async {
final m = manager(MockClient((req) async {
if (req.url.path == '/api/v1/app/update') {
return http.Response.bytes(
utf8.encode(jsonEncode(_catalog([_item()]))), 200);
}
if (req.url.path.startsWith('/download/models/')) {
downloadHits++;
return http.Response.fromStream(http.StreamedResponse(
_delayedChunks(), 200,
contentLength: _modelBytes.length));
}
return http.Response('not found', 404);
}));
await m.refresh();
final fut = m.downloadModel(m.catalog.first);
// 首个分块到达后取消(模拟用户在下载中点取消)
await Future<void>.delayed(const Duration(milliseconds: 20));
m.cancelDownload(7);
final ok = await fut;
expect(ok, isFalse);
expect(downloadHits, 1);
expect(m.isDownloaded(7), isFalse);
expect(m.isActive(7), isFalse);
expect(m.progressOf(7), isNull);
expect(m.errorOf(7), isNull, reason: '取消不记错误');
expect(await File('${root.path}/7/model.tflite.part').exists(), isFalse,
reason: '取消后 .part 残留应被清理');
});
}