285 lines
8.7 KiB
Dart
285 lines
8.7 KiB
Dart
import 'package:podman/podman.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import 'support/fake_podman_transport.dart';
|
|
|
|
void main() {
|
|
group('PodmanClient pod API', () {
|
|
test('checks whether a pod exists', () async {
|
|
final transport = FakePodmanTransport()
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/groupware/exists',
|
|
statusCode: 204,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/missing/exists',
|
|
statusCode: 404,
|
|
);
|
|
|
|
final client = PodmanClient(transport: transport);
|
|
|
|
expect(await client.podExists('groupware'), isTrue);
|
|
expect(await client.podExists('missing'), isFalse);
|
|
transport.expectNoPending();
|
|
});
|
|
|
|
test('lists pods', () async {
|
|
final transport = FakePodmanTransport()
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/json',
|
|
responseBody: <Object?>[
|
|
<String, Object?>{
|
|
'Id': 'pod-1',
|
|
'Name': 'groupware',
|
|
'Status': 'Running',
|
|
'Cgroup': 'user.slice',
|
|
'NumberOfContainers': 3,
|
|
'Labels': <String, String>{'stack': 'groupware'},
|
|
},
|
|
],
|
|
);
|
|
|
|
final client = PodmanClient(transport: transport);
|
|
final pods = await client.listPods();
|
|
|
|
expect(pods, hasLength(1));
|
|
expect(pods.first.id, 'pod-1');
|
|
expect(pods.first.name, 'groupware');
|
|
expect(pods.first.containers, 3);
|
|
transport.expectNoPending();
|
|
});
|
|
|
|
test('supports create, inspect, start, stop, and remove', () async {
|
|
final transport = FakePodmanTransport()
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/create',
|
|
body: const <String, Object?>{
|
|
'name': 'groupware',
|
|
'labels': <String, String>{'stack': 'groupware'},
|
|
'infra': true,
|
|
},
|
|
statusCode: 201,
|
|
responseBody: const <String, Object?>{'Id': 'pod-1'},
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/pod-1/json',
|
|
responseBody: const <String, Object?>{
|
|
'Id': 'pod-1',
|
|
'Name': 'groupware',
|
|
'State': 'Created',
|
|
'Containers': <Object?>[],
|
|
'Labels': <String, String>{'stack': 'groupware'},
|
|
},
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/groupware/json',
|
|
responseBody: const <String, Object?>{
|
|
'Id': 'pod-1',
|
|
'Name': 'groupware',
|
|
'State': 'Created',
|
|
'Containers': <Object?>[],
|
|
},
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/start',
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/stop',
|
|
queryParameters: const <String, List<String>>{
|
|
't': <String>['3'],
|
|
},
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.delete,
|
|
path: '/v5.0.0/libpod/pods/groupware',
|
|
queryParameters: const <String, List<String>>{
|
|
'force': <String>['true'],
|
|
},
|
|
statusCode: 200,
|
|
);
|
|
|
|
final client = PodmanClient(transport: transport);
|
|
|
|
final created = await client.createPod(
|
|
const PodCreateOptions(
|
|
name: 'groupware',
|
|
labels: <String, String>{'stack': 'groupware'},
|
|
),
|
|
);
|
|
expect(created.id, 'pod-1');
|
|
|
|
final inspected = await client.inspectPod('groupware');
|
|
expect(inspected.name, 'groupware');
|
|
|
|
await client.startPod('groupware');
|
|
await client.stopPod('groupware', timeoutSeconds: 3);
|
|
await client.removePod('groupware', force: true);
|
|
transport.expectNoPending();
|
|
});
|
|
|
|
test('supports pod admin, top, stats, and prune endpoints', () async {
|
|
final transport = FakePodmanTransport()
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/kill',
|
|
queryParameters: const <String, List<String>>{
|
|
'signal': <String>['SIGTERM'],
|
|
},
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/pause',
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/restart',
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/groupware/unpause',
|
|
statusCode: 200,
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/groupware/top',
|
|
queryParameters: const <String, List<String>>{
|
|
'ps_args': <String>['aux'],
|
|
},
|
|
responseBody: const <String, Object?>{
|
|
'Titles': <String>['PID', 'USER', 'COMMAND'],
|
|
'Processes': <Object?>[
|
|
<Object?>['1', 'root', '/pause'],
|
|
],
|
|
},
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/stats',
|
|
queryParameters: const <String, List<String>>{
|
|
'namesOrIDs': <String>['groupware'],
|
|
},
|
|
responseBody: const <Object?>[
|
|
<String, Object?>{
|
|
'Pod': 'pod-1',
|
|
'CID': 'ctr-1',
|
|
'Name': 'groupware',
|
|
'CPU': '2.5%',
|
|
'MemUsage': '12MiB / 1GiB',
|
|
'MemUsageBytes': '12582912 / 1073741824',
|
|
'Mem': '1.2%',
|
|
'NetIO': '5kB / 2kB',
|
|
'BlockIO': '0B / 0B',
|
|
'PIDS': '4',
|
|
},
|
|
],
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.post,
|
|
path: '/v5.0.0/libpod/pods/prune',
|
|
responseBody: const <Object?>[
|
|
<String, Object?>{'Id': 'pod-old'},
|
|
],
|
|
);
|
|
|
|
final client = PodmanClient(transport: transport);
|
|
|
|
await client.killPod('groupware', signal: 'SIGTERM');
|
|
await client.pausePod('groupware');
|
|
await client.restartPod('groupware');
|
|
await client.unpausePod('groupware');
|
|
|
|
final top = await client.topPod(
|
|
'groupware',
|
|
options: const PodTopOptions(psArgs: 'aux'),
|
|
);
|
|
expect(top.titles, <String>['PID', 'USER', 'COMMAND']);
|
|
expect(top.processes, <List<String>>[
|
|
<String>['1', 'root', '/pause'],
|
|
]);
|
|
|
|
final stats = await client.podStats(
|
|
options: const PodStatsOptions(namesOrIds: <String>['groupware']),
|
|
);
|
|
expect(stats, hasLength(1));
|
|
expect(stats.single.podId, 'pod-1');
|
|
expect(stats.single.cpuPercent, '2.5%');
|
|
|
|
final pruned = await client.prunePods();
|
|
expect(pruned, hasLength(1));
|
|
expect(pruned.single.id, 'pod-old');
|
|
|
|
transport.expectNoPending();
|
|
});
|
|
|
|
test('watchPodStats and watchPodTop emit polling snapshots', () async {
|
|
final transport = FakePodmanTransport()
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/stats',
|
|
queryParameters: const <String, List<String>>{
|
|
'namesOrIDs': <String>['groupware'],
|
|
},
|
|
responseBody: const <Object?>[
|
|
<String, Object?>{
|
|
'Pod': 'pod-1',
|
|
'CID': 'ctr-1',
|
|
'Name': 'groupware',
|
|
'CPU': '1.0%',
|
|
'MemUsage': '10MiB / 1GiB',
|
|
'MemUsageBytes': '10485760 / 1073741824',
|
|
'Mem': '1.0%',
|
|
'NetIO': '1kB / 1kB',
|
|
'BlockIO': '0B / 0B',
|
|
'PIDS': '3',
|
|
},
|
|
],
|
|
)
|
|
..enqueue(
|
|
method: HttpMethod.get,
|
|
path: '/v5.0.0/libpod/pods/groupware/top',
|
|
responseBody: const <String, Object?>{
|
|
'Titles': <String>['PID', 'CMD'],
|
|
'Processes': <Object?>[
|
|
<Object?>['1', '/pause'],
|
|
],
|
|
},
|
|
);
|
|
|
|
final client = PodmanClient(transport: transport);
|
|
|
|
final stats = await client
|
|
.watchPodStats(
|
|
options: const PodStatsOptions(namesOrIds: <String>['groupware']),
|
|
pollInterval: const Duration(milliseconds: 1),
|
|
reconnect: false,
|
|
)
|
|
.first;
|
|
expect(stats, hasLength(1));
|
|
expect(stats.single.podId, 'pod-1');
|
|
|
|
final top = await client
|
|
.watchPodTop(
|
|
'groupware',
|
|
pollInterval: const Duration(milliseconds: 1),
|
|
reconnect: false,
|
|
)
|
|
.first;
|
|
expect(top.processes, hasLength(1));
|
|
|
|
transport.expectNoPending();
|
|
});
|
|
});
|
|
}
|