mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-04 08:10:55 +00:00
209 lines
6.4 KiB
Dart
209 lines
6.4 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:gopeed/api/model/task.dart';
|
|
import 'package:gopeed/api/model/task_stats.dart';
|
|
|
|
void main() {
|
|
test('HTTP stats parse the current Go connection payload', () {
|
|
final stats =
|
|
TaskStats.fromJson(Protocol.http, {
|
|
'snapshot': {
|
|
'connections': [
|
|
{'downloaded': 1024, 'total': 4096, 'completed': false, 'failed': false, 'retryTimes': 2},
|
|
{'downloaded': 2048, 'total': 2048, 'completed': true, 'failed': false, 'retryTimes': 0},
|
|
],
|
|
},
|
|
'runtime': null,
|
|
})
|
|
as HttpTaskStats;
|
|
|
|
expect(stats.connections, hasLength(2));
|
|
expect(stats.connections.first.downloaded, 1024);
|
|
expect(stats.connections.first.total, 4096);
|
|
expect(stats.connections.first.retryTimes, 2);
|
|
expect(stats.connections.last.completed, isTrue);
|
|
});
|
|
|
|
test('FTP stats use the HTTP connection layout', () {
|
|
final stats =
|
|
TaskStats.fromJson(Protocol.ftp, {
|
|
'snapshot': {
|
|
'connections': [
|
|
{'downloaded': 512, 'total': 1024, 'completed': false, 'failed': false, 'retryTimes': 1},
|
|
],
|
|
},
|
|
'runtime': null,
|
|
})
|
|
as HttpTaskStats;
|
|
|
|
expect(stats.connections.single.downloaded, 512);
|
|
expect(stats.connections.single.retryTimes, 1);
|
|
});
|
|
|
|
test('BT stats decode the ordered completion bitset and peer transport', () {
|
|
final stats =
|
|
TaskStats.fromJson(Protocol.bt, {
|
|
'snapshot': {
|
|
'seedBytes': 820,
|
|
'seedRatio': 0.64,
|
|
'seedTime': 3723,
|
|
'pieceMap': {
|
|
'encoding': 'bitset-v1',
|
|
'pieceCount': 8,
|
|
'pieceSize': 16384,
|
|
'completedPieces': 3,
|
|
'data': 'hQ==',
|
|
},
|
|
},
|
|
'runtime': {
|
|
'totalPeers': 128,
|
|
'activePeers': 16,
|
|
'connectedSeeders': 8,
|
|
'connectedLeechers': 8,
|
|
'peers': [
|
|
{
|
|
'address': '127.0.0.1:6881',
|
|
'client': 'Gopeed',
|
|
'downloadSpeed': 2048,
|
|
'uploadSpeed': 1024,
|
|
'pieceCount': 12,
|
|
'completion': 0.75,
|
|
'relevance': 0.25,
|
|
'source': 'PEX',
|
|
'transport': 'utp',
|
|
},
|
|
],
|
|
},
|
|
})
|
|
as BtTaskStats;
|
|
|
|
expect(stats.activePeers, 16);
|
|
expect(stats.connectedLeechers, 8);
|
|
expect(stats.seedTime, 3723);
|
|
expect(stats.pieceMap.toStates(), [
|
|
TaskPieceState.completed,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.completed,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.completed,
|
|
]);
|
|
expect(stats.pieceMap.completedPieces, 3);
|
|
expect(stats.pieceMap.pieceSize, 16384);
|
|
expect(stats.peers.single.downloadSpeed, 2048);
|
|
expect(stats.peers.single.pieceCount, 12);
|
|
expect(stats.peers.single.completion, 0.75);
|
|
expect(stats.peers.single.relevance, 0.25);
|
|
expect(stats.peers.single.transport, 'utp');
|
|
});
|
|
|
|
test('BT persisted snapshot remains useful when runtime is absent', () {
|
|
final stats =
|
|
TaskStats.fromJson(Protocol.bt, {
|
|
'snapshot': {
|
|
'seedBytes': 820,
|
|
'seedRatio': 0.64,
|
|
'seedTime': 65,
|
|
'pieceMap': {
|
|
'encoding': 'bitset-v1',
|
|
'pieceCount': 4,
|
|
'pieceSize': 16384,
|
|
'completedPieces': 2,
|
|
'data': 'Aw==',
|
|
},
|
|
},
|
|
'runtime': null,
|
|
})
|
|
as BtTaskStats;
|
|
|
|
expect(stats.totalPeers, 0);
|
|
expect(stats.activePeers, 0);
|
|
expect(stats.connectedLeechers, 0);
|
|
expect(stats.seedTime, 65);
|
|
expect(stats.peers, isEmpty);
|
|
expect(stats.pieceMap.completedPieces, 2);
|
|
expect(stats.pieceMap.toStates(), [
|
|
TaskPieceState.completed,
|
|
TaskPieceState.completed,
|
|
TaskPieceState.pending,
|
|
TaskPieceState.pending,
|
|
]);
|
|
});
|
|
|
|
test('piece map rejects unsupported versions and malformed byte lengths', () {
|
|
expect(
|
|
TaskPieceMap.fromJson({
|
|
'encoding': 'bitset-v2',
|
|
'pieceCount': 4,
|
|
'pieceSize': 1024,
|
|
'completedPieces': 0,
|
|
'data': 'AA==',
|
|
}),
|
|
isNull,
|
|
);
|
|
expect(
|
|
TaskPieceMap.fromJson({
|
|
'encoding': 'bitset-v1',
|
|
'pieceCount': 9,
|
|
'pieceSize': 1024,
|
|
'completedPieces': 0,
|
|
'data': 'AA==',
|
|
}),
|
|
isNull,
|
|
);
|
|
});
|
|
|
|
test('stats models ignore fields that are not part of the Go response contract', () {
|
|
final http =
|
|
TaskStats.fromJson(Protocol.http, {
|
|
'snapshot': {
|
|
'connections': [
|
|
{'received': 1024, 'completed': false, 'failed': false, 'retries': 2},
|
|
],
|
|
},
|
|
})
|
|
as HttpTaskStats;
|
|
final bt =
|
|
TaskStats.fromJson(Protocol.bt, {
|
|
'snapshot': {
|
|
'uploaded': 1024,
|
|
'shareRatio': 0.5,
|
|
'pieces': [2, 1, 0],
|
|
},
|
|
'runtime': {'seeders': 8},
|
|
})
|
|
as BtTaskStats;
|
|
|
|
expect(http.connections.single.downloaded, 0);
|
|
expect(http.connections.single.retryTimes, 0);
|
|
expect(bt.connectedSeeders, 0);
|
|
expect(bt.seedBytes, 0);
|
|
expect(bt.seedRatio, 0);
|
|
expect(bt.pieceMap.isEmpty, isTrue);
|
|
});
|
|
|
|
test('ED2K stats parse the existing aggregate fields', () {
|
|
final stats =
|
|
TaskStats.fromJson(Protocol.ed2k, {
|
|
'snapshot': {'upload': 320, 'totalDone': 68, 'totalWanted': 100},
|
|
'runtime': {'activePeers': 12, 'totalPeers': 86, 'downloadRate': 4800000, 'uploadRate': 320000},
|
|
})
|
|
as Ed2kTaskStats;
|
|
|
|
expect(stats.totalPeers, 86);
|
|
expect(stats.downloadRate, 4800000);
|
|
expect(stats.totalDone / stats.totalWanted, 0.68);
|
|
expect(stats.peers, isEmpty);
|
|
});
|
|
|
|
test('a missing protocol has no statistics panel', () {
|
|
expect(
|
|
TaskStats.fromJson(null, {
|
|
'snapshot': {'value': 1},
|
|
}),
|
|
isNull,
|
|
);
|
|
});
|
|
}
|