186 lines
5.1 KiB
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"
|
|
''');
|
|
}
|