oto/apps/runner/test/oto_agent_config_test.dart
toki 86afabb3eb refactor(runner): 런타임 패키지를 앱 하위로 이동한다
독립 control plane 구성을 위해 기존 Dart CLI/runtime을 runner 앱 경계로 옮기고, 후속 client/core/root 작업을 같은 마일스톤 task group에 연결한다.
2026-06-05 06:34:45 +09:00

224 lines
6.2 KiB
Dart

import 'dart:io';
import 'package:test/test.dart';
import 'package:oto/oto/agent/agent_config.dart';
void main() {
const validBootstrapYaml = '''
agent:
id: "agent-123"
alias: "my-test-agent"
enrollment_token: "token-abc-456"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
const validBootstrapYamlNoAlias = '''
agent:
id: "agent-123"
alias: ""
enrollment_token: "token-abc-456"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
const validBootstrapYamlMissingAlias = '''
agent:
id: "agent-123"
enrollment_token: "token-abc-456"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
test('AgentConfig parses bootstrap config yaml', () {
final config = AgentConfig.fromYamlContent(validBootstrapYaml);
expect(config.agent.id, 'agent-123');
expect(config.agent.alias, 'my-test-agent');
expect(config.agent.enrollmentToken, 'token-abc-456');
expect(config.edge.url, 'https://edge.toki-labs.com:8443');
expect(config.runtime.installDir, '/usr/local/bin');
expect(config.runtime.workspaceRoot, '/home/user/.oto/workspace');
expect(config.runtime.logDir, '/home/user/.oto/logs');
});
test('AgentConfig preserves empty alias', () {
final config = AgentConfig.fromYamlContent(validBootstrapYamlNoAlias);
expect(config.agent.id, 'agent-123');
expect(config.agent.alias, '');
expect(config.agent.enrollmentToken, 'token-abc-456');
});
test('AgentConfig parses missing alias as null', () {
final config = AgentConfig.fromYamlContent(validBootstrapYamlMissingAlias);
expect(config.agent.id, 'agent-123');
expect(config.agent.alias, isNull);
expect(config.agent.enrollmentToken, 'token-abc-456');
});
test('AgentConfig rejects missing required values', () {
const missingAgentId = '''
agent:
alias: "my-test-agent"
enrollment_token: "token-abc-456"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
expect(
() => AgentConfig.fromYamlContent(missingAgentId),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('agent.id'))));
const missingEnrollmentToken = '''
agent:
id: "agent-123"
alias: "my-test-agent"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
expect(
() => AgentConfig.fromYamlContent(missingEnrollmentToken),
throwsA(isA<AgentConfigException>().having(
(e) => e.message, 'message', contains('agent.enrollment_token'))));
const missingEdge = '''
agent:
id: "agent-123"
alias: "my-test-agent"
enrollment_token: "token-abc-456"
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
expect(
() => AgentConfig.fromYamlContent(missingEdge),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('edge'))));
const missingEdgeUrl = '''
agent:
id: "agent-123"
alias: "my-test-agent"
enrollment_token: "token-abc-456"
edge:
url: ""
runtime:
install_dir: "/usr/local/bin"
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
expect(
() => AgentConfig.fromYamlContent(missingEdgeUrl),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('edge.url'))));
const missingInstallDir = '''
agent:
id: "agent-123"
alias: "my-test-agent"
enrollment_token: "token-abc-456"
edge:
url: "https://edge.toki-labs.com:8443"
runtime:
workspace_root: "/home/user/.oto/workspace"
log_dir: "/home/user/.oto/logs"
''';
expect(
() => AgentConfig.fromYamlContent(missingInstallDir),
throwsA(isA<AgentConfigException>().having(
(e) => e.message, 'message', contains('runtime.install_dir'))));
});
test('AgentConfig rejects invalid field types', () {
const invalidIdYaml = '''
agent:
id: ["not-a-string"]
enrollment_token: "token-abc"
edge:
url: "http://edge"
runtime:
install_dir: "/bin"
workspace_root: "/work"
log_dir: "/log"
''';
expect(
() => AgentConfig.fromYamlContent(invalidIdYaml),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('agent.id'))));
const invalidAliasYaml = '''
agent:
id: "agent-1"
alias: true
enrollment_token: "token-abc"
edge:
url: "http://edge"
runtime:
install_dir: "/bin"
workspace_root: "/work"
log_dir: "/log"
''';
expect(
() => AgentConfig.fromYamlContent(invalidAliasYaml),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('agent.alias'))));
const invalidUrlYaml = '''
agent:
id: "agent-1"
enrollment_token: "token-abc"
edge:
url: 12345
runtime:
install_dir: "/bin"
workspace_root: "/work"
log_dir: "/log"
''';
expect(
() => AgentConfig.fromYamlContent(invalidUrlYaml),
throwsA(isA<AgentConfigException>()
.having((e) => e.message, 'message', contains('edge.url'))));
});
test('AgentConfig fromFile reads file correctly', () {
final tempFile =
File('${Directory.systemTemp.path}/agent_config_test_temp.yaml');
tempFile.writeAsStringSync(validBootstrapYaml);
try {
final config = AgentConfig.fromFile(tempFile.path);
expect(config.agent.id, 'agent-123');
expect(config.edge.url, 'https://edge.toki-labs.com:8443');
} finally {
if (tempFile.existsSync()) {
tempFile.deleteSync();
}
}
});
test('AgentConfig fromFile throws when file not found', () {
expect(
() => AgentConfig.fromFile('non_existent_file_path_1234.yaml'),
throwsA(isA<AgentConfigException>().having(
(e) => e.message, 'message', contains('does not exist at path'))));
});
}