import 'package:podman/podman.dart'; import 'package:test/test.dart'; import 'support/fake_podman_transport.dart'; void main() { group('PodmanClient container checkpoint API', () { test('supports checkpoint/export/restore flows', () async { final checkpointArchiveBytes = [1, 2, 3, 4]; final restoreArchiveBytes = [9, 8, 7, 6]; final transport = FakePodmanTransport() ..enqueue( method: HttpMethod.post, path: '/v5.0.0/libpod/containers/web/checkpoint', queryParameters: const >{ 'keep': ['true'], 'leaveRunning': ['true'], 'tcpEstablished': ['true'], 'ignoreRootFS': ['true'], 'printStats': ['true'], 'preCheckpoint': ['true'], 'withPrevious': ['true'], 'fileLocks': ['true'], 'createImage': ['checkpoint/web:v1'], }, responseBody: const { 'Id': 'container-123', 'runtime_checkpoint_duration': 42, 'criu_statistics': {'freezing_time': 2}, }, ) ..enqueue( method: HttpMethod.post, path: '/v5.0.0/libpod/containers/web/checkpoint', queryParameters: const >{ 'keep': ['true'], 'export': ['true'], }, responseBody: checkpointArchiveBytes, ) ..enqueue( method: HttpMethod.post, path: '/v5.0.0/libpod/containers/web/restore', queryParameters: const >{ 'keep': ['true'], 'tcpEstablished': ['true'], 'ignoreStaticIP': ['true'], 'printStats': ['true'], 'publishPorts': ['8080:80'], 'pod': ['groupware-services'], }, responseBody: const { 'Id': 'container-123', 'runtime_restore_duration': 55, 'criu_statistics': {'restore_time': 3}, }, ) ..enqueue( method: HttpMethod.post, path: '/v5.0.0/libpod/containers/import/restore', queryParameters: const >{ 'name': ['web-restored'], 'import': ['true'], 'ignoreRootFS': ['true'], 'ignoreVolumes': ['true'], }, body: restoreArchiveBytes, responseBody: const { 'Id': 'container-456', 'runtime_restore_duration': 12, 'criu_statistics': {}, }, ); final client = PodmanClient(transport: transport); final checkpoint = await client.checkpointContainer( 'web', options: const ContainerCheckpointOptions( keep: true, leaveRunning: true, tcpEstablished: true, ignoreRootFs: true, printStats: true, preCheckpoint: true, withPrevious: true, fileLocks: true, createImage: 'checkpoint/web:v1', ), ); expect(checkpoint.id, 'container-123'); expect(checkpoint.runtimeDuration, 42); expect(checkpoint.criuStatistics['freezing_time'], 2); final exported = await client.exportContainerCheckpoint( 'web', options: const ContainerCheckpointOptions(keep: true), ); expect(exported, checkpointArchiveBytes); final restored = await client.restoreContainer( 'web', options: const ContainerRestoreOptions( keep: true, tcpEstablished: true, ignoreStaticIp: true, printStats: true, publishPorts: ['8080:80'], pod: 'groupware-services', ), ); expect(restored.id, 'container-123'); expect(restored.runtimeDuration, 55); expect(restored.criuStatistics['restore_time'], 3); final imported = await client.restoreContainerFromArchive( restoreArchiveBytes, options: const ContainerRestoreOptions( name: 'web-restored', ignoreRootFs: true, ignoreVolumes: true, ), ); expect(imported.id, 'container-456'); expect(imported.runtimeDuration, 12); transport.expectNoPending(); }); test('restoreContainerFromArchive validates non-empty bytes', () async { final client = PodmanClient(transport: FakePodmanTransport()); expect( () => client.restoreContainerFromArchive(const []), throwsArgumentError, ); }); }); }