Skip to content

Commit 73cd754

Browse files
authored
Record the working directory for VM platform (#1804)
Towards #1803 A VM test can change the working directory for the entire process. If this happens it will change the result for the absolute path against the relative paths provided to the VM platform plugin. Record `Directory.current` when the platform plugin is instantiated. Any place where an absolute path is needed attempt to resolve against the original working directory. Move some top-level methods into the plugin so they can read the cached working directory. This only works for VM tests, since other test platforms may be instantiated after the VM tests have started running. Impacted users can workaround this by running VM tests separately from other platforms.
1 parent e40274a commit 73cd754

File tree

4 files changed

+75
-24
lines changed

4 files changed

+75
-24
lines changed

pkgs/test/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Add documentation for the `--ignore-timeouts` argument.
44
* Merge command lines args repeating the same test path to run the suite one
55
time with all the test cases across the different arguments.
6+
* Fix VM tests which run after some test has changed the working directory.
7+
There are still issues with browser tests after changing directory.
68

79
## 1.22.0
810

pkgs/test/test/runner/runner_test.dart

+40
Original file line numberDiff line numberDiff line change
@@ -891,4 +891,44 @@ void main() {
891891
}
892892
});
893893
});
894+
895+
group('runs tests after changing directories', () {
896+
setUp(() async {
897+
await d.file('a_test.dart', '''
898+
@TestOn('vm')
899+
import 'dart:io';
900+
901+
import 'package:test/test.dart';
902+
903+
void main() {
904+
test('changes directory', () {
905+
Directory.current = Directory.current.parent;
906+
});
907+
}
908+
''').create();
909+
await d.file('b_test.dart', '''
910+
import 'package:test/test.dart';
911+
912+
void main() {
913+
test('passes', () {
914+
expect(true, true);
915+
});
916+
}
917+
''').create();
918+
});
919+
test('on the VM platform', () async {
920+
var test = await runTest(['-p', 'vm', 'a_test.dart', 'b_test.dart']);
921+
await expectLater(
922+
test.stdout, emitsThrough(contains('+2: All tests passed!')));
923+
await test.shouldExit(0);
924+
});
925+
926+
test('on the browser platform', () async {
927+
var test =
928+
await runTest(['-p', 'vm,chrome', 'a_test.dart', 'b_test.dart']);
929+
await expectLater(
930+
test.stdout, emitsThrough(contains('+3: All tests passed!')));
931+
await test.shouldExit(0);
932+
}, skip: 'https://github.com/dart-lang/test/issues/1803');
933+
});
894934
}

pkgs/test_core/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
`Configuration`.
55
* Merge command lines args repeating the same test path to run the suite one
66
time with all the test cases across the different arguments.
7+
* Fix VM tests which run after some test has changed the working directory.
8+
There are still issues with browser tests after changing directory.
79

810
# 0.4.20
911

pkgs/test_core/lib/src/runner/vm/platform.dart

+31-24
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class VMPlatform extends PlatformPlugin {
3939
final _compiler = TestCompiler(
4040
p.join(p.current, '.dart_tool', 'test', 'incremental_kernel'));
4141
final _closeMemo = AsyncMemoizer<void>();
42+
final _workingDirectory = Directory.current.uri;
4243

4344
@override
4445
Future<RunnerSuite?> load(String path, SuitePlatform platform,
@@ -86,7 +87,7 @@ class VMPlatform extends PlatformPlugin {
8687
await Service.controlWebServer(enable: true, silenceOutput: true);
8788
var isolateID = Service.getIsolateID(isolate)!;
8889

89-
var libraryPath = p.toUri(p.absolute(path)).toString();
90+
var libraryPath = _absolute(path).toString();
9091
var serverUri = info.serverUri!;
9192
client = await vmServiceConnectUri(_wsUriFor(serverUri).toString());
9293
var isolateNumber = int.parse(isolateID.split('/').last);
@@ -126,6 +127,12 @@ class VMPlatform extends PlatformPlugin {
126127
@override
127128
Future close() => _closeMemo.runOnce(_compiler.dispose);
128129

130+
Uri _absolute(String path) {
131+
final uri = p.toUri(path);
132+
if (uri.isAbsolute) return uri;
133+
return _workingDirectory.resolveUri(uri);
134+
}
135+
129136
/// Spawns an isolate and passes it [message].
130137
///
131138
/// This isolate connects an [IsolateChannel] to [message] and sends the
@@ -153,48 +160,48 @@ class VMPlatform extends PlatformPlugin {
153160
/// isolate.
154161
Future<Isolate> _spawnKernelIsolate(
155162
String path, SendPort message, Metadata suiteMetadata) async {
156-
final response =
157-
await _compiler.compile(File(path).absolute.uri, suiteMetadata);
163+
final response = await _compiler.compile(_absolute(path), suiteMetadata);
158164
var compiledDill = response.kernelOutputUri?.toFilePath();
159165
if (compiledDill == null || response.errorCount > 0) {
160166
throw LoadException(path, response.compilerOutput ?? 'unknown error');
161167
}
162168
return await Isolate.spawnUri(p.toUri(compiledDill), [], message,
163169
packageConfig: await packageConfigUri, checked: true);
164170
}
165-
}
166171

167-
Future<Isolate> _spawnDataIsolate(
168-
String path, SendPort message, Metadata suiteMetadata) async {
169-
return await dart.runInIsolate('''
172+
Future<Isolate> _spawnDataIsolate(
173+
String path, SendPort message, Metadata suiteMetadata) async {
174+
return await dart.runInIsolate('''
170175
${suiteMetadata.languageVersionComment ?? await rootPackageLanguageVersionComment}
171176
import "dart:isolate";
172177
import "package:test_core/src/bootstrap/vm.dart";
173-
import "${p.toUri(p.absolute(path))}" as test;
178+
import "${_absolute(path)}" as test;
174179
void main(_, SendPort sendPort) {
175180
internalBootstrapVmTest(() => test.main, sendPort);
176181
}
177182
''', message);
178-
}
179-
180-
Future<Isolate> _spawnPrecompiledIsolate(
181-
String testPath, SendPort message, String precompiledPath) async {
182-
testPath = p.absolute('${p.join(precompiledPath, testPath)}.vm_test.dart');
183-
var dillTestpath =
184-
'${testPath.substring(0, testPath.length - '.dart'.length)}.vm.app.dill';
185-
if (await File(dillTestpath).exists()) {
186-
testPath = dillTestpath;
187183
}
188-
File? packageConfig =
189-
File(p.join(precompiledPath, '.dart_tool/package_config.json'));
190-
if (!(await packageConfig.exists())) {
191-
packageConfig = File(p.join(precompiledPath, '.packages'));
184+
185+
Future<Isolate> _spawnPrecompiledIsolate(
186+
String testPath, SendPort message, String precompiledPath) async {
187+
testPath =
188+
_absolute('${p.join(precompiledPath, testPath)}.vm_test.dart').path;
189+
var dillTestpath =
190+
'${testPath.substring(0, testPath.length - '.dart'.length)}.vm.app.dill';
191+
if (await File(dillTestpath).exists()) {
192+
testPath = dillTestpath;
193+
}
194+
File? packageConfig =
195+
File(p.join(precompiledPath, '.dart_tool/package_config.json'));
192196
if (!(await packageConfig.exists())) {
193-
packageConfig = null;
197+
packageConfig = File(p.join(precompiledPath, '.packages'));
198+
if (!(await packageConfig.exists())) {
199+
packageConfig = null;
200+
}
194201
}
202+
return await Isolate.spawnUri(p.toUri(testPath), [], message,
203+
packageConfig: packageConfig?.uri, checked: true);
195204
}
196-
return await Isolate.spawnUri(p.toUri(testPath), [], message,
197-
packageConfig: packageConfig?.uri, checked: true);
198205
}
199206

200207
Future<Map<String, dynamic>> _gatherCoverage(Environment environment) async {

0 commit comments

Comments
 (0)