독립 control plane 구성을 위해 기존 Dart CLI/runtime을 runner 앱 경계로 옮기고, 후속 client/core/root 작업을 같은 마일스톤 task group에 연결한다.
155 lines
4.6 KiB
Dart
155 lines
4.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:test/test.dart';
|
|
import 'package:oto/oto/agent/agent_config.dart';
|
|
import 'package:oto/oto/agent/agent_runner.dart';
|
|
import 'package:oto/oto/agent/edge_registration_client.dart';
|
|
|
|
class FakeEdgeAgentSession implements EdgeAgentSession {
|
|
@override
|
|
final RegistrationResult result;
|
|
bool closed = false;
|
|
|
|
FakeEdgeAgentSession(this.result);
|
|
|
|
@override
|
|
Future<void> close() async {
|
|
closed = true;
|
|
}
|
|
}
|
|
|
|
class FakeEdgeRegistrationClient extends EdgeRegistrationClient {
|
|
final RegistrationResult Function(AgentConfig config) _onRegister;
|
|
FakeEdgeAgentSession? lastSession;
|
|
|
|
FakeEdgeRegistrationClient(this._onRegister);
|
|
|
|
@override
|
|
Future<EdgeAgentSession> openSession(AgentConfig config) async {
|
|
final session = FakeEdgeAgentSession(_onRegister(config));
|
|
lastSession = session;
|
|
return session;
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
const validBootstrapYaml = '''
|
|
agent:
|
|
id: "agent-123"
|
|
alias: "my-agent"
|
|
enrollment_token: "token-456"
|
|
edge:
|
|
url: "127.0.0.1:8080"
|
|
runtime:
|
|
install_dir: "/usr/bin"
|
|
workspace_root: "/var/oto"
|
|
log_dir: "/var/log/oto"
|
|
''';
|
|
|
|
late AgentConfig validConfig;
|
|
|
|
setUp(() {
|
|
validConfig = AgentConfig.fromYamlContent(validBootstrapYaml);
|
|
});
|
|
|
|
group('EdgeEndpoint', () {
|
|
test('EdgeEndpoint parses host and port from config edge url', () {
|
|
final endpoint1 = EdgeEndpoint.parse('127.0.0.1:8080');
|
|
expect(endpoint1.host, '127.0.0.1');
|
|
expect(endpoint1.port, 8080);
|
|
|
|
final endpoint2 = EdgeEndpoint.parse('http://edge-server:9000');
|
|
expect(endpoint2.host, 'edge-server');
|
|
expect(endpoint2.port, 9000);
|
|
|
|
final endpoint3 = EdgeEndpoint.parse('https://secure-edge');
|
|
expect(endpoint3.host, 'secure-edge');
|
|
expect(endpoint3.port, 443);
|
|
|
|
final endpoint4 = EdgeEndpoint.parse('edge-no-port');
|
|
expect(endpoint4.host, 'edge-no-port');
|
|
expect(endpoint4.port, 80);
|
|
});
|
|
});
|
|
|
|
group('EdgeRegistrationClient.register one-shot', () {
|
|
test('register returns session result and closes the session', () async {
|
|
final fakeClient = FakeEdgeRegistrationClient((config) {
|
|
return RegistrationResult.accepted(
|
|
'node-123', 'alias-123', {'concurrency': 1});
|
|
});
|
|
|
|
final result = await fakeClient.register(validConfig);
|
|
|
|
expect(result.accepted, isTrue);
|
|
expect(result.nodeId, 'node-123');
|
|
expect(fakeClient.lastSession, isNotNull);
|
|
expect(fakeClient.lastSession!.closed, isTrue);
|
|
});
|
|
});
|
|
|
|
group('AgentRunner', () {
|
|
test('AgentRunner maps config token to register request', () async {
|
|
AgentConfig? capturedConfig;
|
|
final fakeClient = FakeEdgeRegistrationClient((config) {
|
|
capturedConfig = config;
|
|
return RegistrationResult.accepted(
|
|
'node-123', 'alias-123', {'concurrency': 1});
|
|
});
|
|
|
|
final runner = DefaultAgentRunner(
|
|
client: fakeClient,
|
|
onLog: (msg) {},
|
|
waitForShutdown: () async {},
|
|
);
|
|
await runner.run(validConfig);
|
|
|
|
expect(capturedConfig, isNotNull);
|
|
expect(capturedConfig!.agent.enrollmentToken, 'token-456');
|
|
});
|
|
|
|
test('AgentRunner keeps session open until shutdown then closes', () async {
|
|
final fakeClient = FakeEdgeRegistrationClient((config) {
|
|
return RegistrationResult.accepted(
|
|
'node-123', 'alias-123', {'concurrency': 1});
|
|
});
|
|
|
|
final shutdown = Completer<void>();
|
|
final runner = DefaultAgentRunner(
|
|
client: fakeClient,
|
|
onLog: (msg) {},
|
|
waitForShutdown: () => shutdown.future,
|
|
);
|
|
|
|
final runFuture = runner.run(validConfig);
|
|
// 종료 신호 전에는 session이 살아 있어야 한다.
|
|
await Future<void>.delayed(Duration.zero);
|
|
expect(fakeClient.lastSession, isNotNull);
|
|
expect(fakeClient.lastSession!.closed, isFalse);
|
|
|
|
shutdown.complete();
|
|
await runFuture;
|
|
expect(fakeClient.lastSession!.closed, isTrue);
|
|
});
|
|
|
|
test('AgentRunner reports rejected registration and closes session',
|
|
() async {
|
|
final fakeClient = FakeEdgeRegistrationClient((config) {
|
|
return RegistrationResult.rejected('Invalid token');
|
|
});
|
|
|
|
final runner = DefaultAgentRunner(
|
|
client: fakeClient,
|
|
onLog: (msg) {},
|
|
waitForShutdown: () async {},
|
|
);
|
|
await expectLater(
|
|
() => runner.run(validConfig),
|
|
throwsA(isA<RegistrationException>()
|
|
.having((e) => e.message, 'message', 'Invalid token')),
|
|
);
|
|
expect(fakeClient.lastSession, isNotNull);
|
|
expect(fakeClient.lastSession!.closed, isTrue);
|
|
});
|
|
});
|
|
}
|