blob: 7fa9aba3d513d74c512aeffb9d21b6454ada9dca [file] [log] [blame]
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io' as io;
import 'package:process/process.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/test_helper.dart';
Future setupProcesses() async {
final dir = await io.Directory.systemTemp.createTemp('file_service');
final args = [
...io.Platform.executableArguments,
'--pause_isolates_on_start',
io.Platform.script.toFilePath(),
];
io.Process? process1;
io.Process? process2;
io.Process? process3;
void closeDown() {
if (process1 != null) {
process1!.kill();
}
if (process2 != null) {
process2!.kill();
}
if (process3 != null) {
process3!.kill();
}
dir.deleteSync(recursive: true);
}
Future<ServiceExtensionResponse> cleanup(ignored_a, ignored_b) {
closeDown();
final result = jsonEncode({'type': 'foobar'});
return Future.value(ServiceExtensionResponse.result(result));
}
Future<ServiceExtensionResponse> setup(ignored_a, ignored_b) async {
final processManager = LocalProcessManager();
try {
process1 = await processManager.start(
[io.Platform.resolvedExecutable, ...args],
);
process2 = await processManager.start([
io.Platform.resolvedExecutable,
...(args..add('foobar')),
]);
final codeFilePath = dir.path + io.Platform.pathSeparator + "other_file";
final codeFile = io.File(codeFilePath);
await codeFile.writeAsString('''
import "dart:io";
void main() async {
await stdin.drain();
}
''');
process3 = await processManager.start(
[
io.Platform.resolvedExecutable,
...io.Platform.executableArguments,
codeFilePath
],
);
} catch (_) {
closeDown();
rethrow;
}
final result = jsonEncode({
'type': 'foobar',
'pids': [process1!.pid, process2!.pid, process3!.pid]
});
return Future.value(ServiceExtensionResponse.result(result));
}
Future<ServiceExtensionResponse> closeStdin(ignored_a, ignored_b) {
process3!.stdin.close();
return process3!.exitCode.then<ServiceExtensionResponse>((int exit) {
final result = jsonEncode({'type': 'foobar'});
return ServiceExtensionResponse.result(result);
});
}
registerExtension('ext.dart.io.cleanup', cleanup);
registerExtension('ext.dart.io.setup', setup);
registerExtension('ext.dart.io.closeStdin', closeStdin);
}
final processTests = <IsolateTest>[
// Initial.
(VmService service, IsolateRef isolate) async {
final isolateId = isolate.id!;
final setup = await service.callServiceExtension(
'ext.dart.io.setup',
isolateId: isolateId,
);
try {
SpawnedProcessList all = await service.getSpawnedProcesses(isolateId);
expect(all.processes.length, equals(3));
final first = await service.getSpawnedProcessById(
isolateId,
all.processes[0].id,
);
expect(io.Platform.resolvedExecutable, contains(first.name.trim()));
expect(first.pid, equals(setup.json!['pids']![0]));
expect(first.arguments.contains('foobar'), isFalse);
expect(first.startedAt, greaterThan(0));
final second = await service.getSpawnedProcessById(
isolateId,
all.processes[1].id,
);
expect(io.Platform.resolvedExecutable, contains(second.name.trim()));
expect(second.pid, equals(setup.json!['pids']![1]));
expect(second.arguments.contains('foobar'), isTrue);
expect(second.pid != first.pid, isTrue);
expect(second.startedAt, greaterThan(0));
expect(second.startedAt, greaterThanOrEqualTo(first.startedAt));
final third = await service.getSpawnedProcessById(
isolateId,
all.processes[2].id,
);
expect(io.Platform.resolvedExecutable, contains(third.name.trim()));
expect(third.pid, equals(setup.json!['pids']![2]));
expect(third.pid != first.pid, isTrue);
expect(third.pid != second.pid, isTrue);
expect(third.startedAt, greaterThanOrEqualTo(second.startedAt));
await service.callServiceExtension(
'ext.dart.io.closeStdin',
isolateId: isolateId,
);
all = await service.getSpawnedProcesses(isolateId);
expect(all.processes.length, equals(2));
} finally {
await service.callServiceExtension(
'ext.dart.io.cleanup',
isolateId: isolateId,
);
}
},
];
main([args = const <String>[]]) async => runIsolateTests(
args,
processTests,
'process_service_test.dart',
testeeBefore: setupProcesses,
);