dew/packages/infra/test/dew_infra_test.dart

186 lines
5.1 KiB
Dart

import 'package:dew_core/dew_core.dart';
import 'package:dew_infra/dew_infra.dart';
import 'package:file/memory.dart';
import 'package:test/test.dart';
void main() {
group('Infra command registration', () {
test('registerCommands adds infra command', () {
final registry = CommandRegistry();
registerCommands(registry);
expect(
registry.commands.map((command) => command.name),
contains('infra'),
);
});
test('infra command exposes core subcommands', () {
final command = InfraCommand();
expect(
command.subcommands.keys,
containsAll([
'list',
'show',
'validate',
'configure',
'init',
'install',
'uninstall',
'up',
'down',
'restart',
'status',
'logs',
'delete',
]),
);
});
});
group('InfraRepository', () {
test('discovers service metadata', () async {
final fs = MemoryFileSystem.test();
_writeService(fs);
final repository = InfraRepository(
infraDir: '/project/.project/infrastructure',
fs: fs,
);
final manifests = await repository.list();
expect(manifests, hasLength(1));
expect(manifests.single.id, 'postgres');
expect(manifests.single.runtime, InfraRuntimeKind.podmanQuadlet);
expect(
manifests.single.containerFilePath,
'/project/.project/infrastructure/services/postgres/app_postgres.container',
);
});
});
group('InfraValidator', () {
test('accepts a complete service manifest', () async {
final fs = MemoryFileSystem.test();
_writeService(fs);
final manifest = await InfraRepository(
infraDir: '/project/.project/infrastructure',
fs: fs,
).get('postgres');
final issues = await InfraValidator(fs: fs).validate(manifest);
expect(issues, isEmpty);
});
test('reports service id and unit mismatches', () async {
final fs = MemoryFileSystem.test();
_writeService(fs, serviceId: 'wrong', unit: 'wrong.service');
final manifest =
await InfraRepository(
infraDir: '/project/.project/infrastructure',
fs: fs,
).loadFromMetadataPath(
'/project/.project/infrastructure/services/postgres/metadata.toml',
serviceDir: '/project/.project/infrastructure/services/postgres',
);
final issues = await InfraValidator(fs: fs).validate(manifest);
expect(
issues.map((issue) => issue.message).join('\n'),
contains('must match directory'),
);
expect(
issues.map((issue) => issue.message).join('\n'),
contains('must match container file unit'),
);
});
});
group('PodmanQuadletRuntime', () {
test(
'install dry-run reports symlink actions without writing files',
() async {
final fs = MemoryFileSystem.test();
_writeService(fs);
final manifest = await InfraRepository(
infraDir: '/project/.project/infrastructure',
fs: fs,
).get('postgres');
final runtime = PodmanQuadletRuntime(
fs: fs,
environment: const {'HOME': '/home/test'},
);
final result = await runtime.install(
manifest,
scope: InfraScope.user,
dryRun: true,
);
expect(result.actions.join('\n'), contains('app_postgres.container'));
expect(
await fs
.link(
'/home/test/.config/containers/systemd/app_postgres.container',
)
.exists(),
isFalse,
);
},
);
test('quadletSearchPath respects user and system scope', () {
expect(
quadletSearchPath(
InfraScope.user,
environment: const {'XDG_CONFIG_HOME': '/config'},
),
'/config/containers/systemd',
);
expect(quadletSearchPath(InfraScope.system), '/etc/containers/systemd');
});
});
}
void _writeService(
MemoryFileSystem fs, {
String serviceId = 'postgres',
String unit = 'app_postgres.service',
}) {
final serviceDir = fs.directory(
'/project/.project/infrastructure/services/postgres',
)..createSync(recursive: true);
fs.directory('${serviceDir.path}/app_postgres.container.d').createSync();
fs.directory('${serviceDir.path}/app_postgres.profiles.d').createSync();
fs
.file('${serviceDir.path}/app_postgres.container')
.writeAsStringSync('[Container]\nImage=postgres:16\n');
fs
.file('${serviceDir.path}/configure.schema.json')
.writeAsStringSync('{"type":"object"}');
fs
.file('${serviceDir.path}/init.schema.json')
.writeAsStringSync('{"type":"object"}');
fs.file('${serviceDir.path}/metadata.toml').writeAsStringSync('''
[service]
id = "$serviceId"
name = "PostgreSQL"
unit = "$unit"
container_name = "app_postgres"
[runtime]
type = "podman-quadlet"
[container]
file = "app_postgres.container"
dropins_dir = "app_postgres.container.d"
profiles_dir = "app_postgres.profiles.d"
[schemas]
configure = "configure.schema.json"
init = "init.schema.json"
''');
}