diff --git a/dwds/test/build_daemon_breakpoint_test.dart b/dwds/test/build_daemon_breakpoint_test.dart index 2af540472..2ce7b9ffb 100644 --- a/dwds/test/build_daemon_breakpoint_test.dart +++ b/dwds/test/build_daemon_breakpoint_test.dart @@ -6,18 +6,20 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testPackageWithSoundNullSafety()); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; + final context = + TestContext(TestProject.testPackageWithSoundNullSafety(), provider); -void main() { group('shared context', () { setUpAll(() async { await context.setUp(); @@ -35,8 +37,10 @@ void main() { late ScriptRef mainScript; late String mainScriptUri; late Stream stream; + late VmServiceInterface service; setUp(() async { + service = context.service; vm = await service.getVM(); isolate = await service.getIsolate(vm.isolates!.first.id!); isolateId = isolate.id!; diff --git a/dwds/test/build_daemon_callstack_test.dart b/dwds/test/build_daemon_callstack_test.dart index e98f02ee5..f425e9c82 100644 --- a/dwds/test/build_daemon_callstack_test.dart +++ b/dwds/test/build_daemon_callstack_test.dart @@ -4,17 +4,19 @@ @TestOn('vm') @Timeout(Duration(minutes: 2)) -import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + group( 'shared context |', () { @@ -24,7 +26,7 @@ void main() { for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { final project = TestProject.testPackage(nullSafety: nullSafety); - final context = TestContext(project); + final context = TestContext(project, provider); setUpAll(() async { setCurrentLogWriter(debug: debug); @@ -40,7 +42,7 @@ void main() { }); group('callStack |', () { - late ChromeProxyService service; + late VmServiceInterface service; VM vm; late Isolate isolate; ScriptList scripts; @@ -58,7 +60,7 @@ void main() { await service.streamListen('Debug'); stream = service.onEvent('Debug'); - final testPackage = project.packageName; + final testPackage = context.project.packageName; mainScript = scripts.scripts! .firstWhere((each) => each.uri!.contains('main.dart')); testLibraryScript = scripts.scripts!.firstWhere((each) => diff --git a/dwds/test/build_daemon_circular_evaluate_test.dart b/dwds/test/build_daemon_circular_evaluate_test.dart index db3192365..9111f14e7 100644 --- a/dwds/test/build_daemon_circular_evaluate_test.dart +++ b/dwds/test/build_daemon_circular_evaluate_test.dart @@ -6,6 +6,7 @@ @Timeout(Duration(minutes: 2)) import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'evaluate_circular_common.dart'; import 'fixtures/context.dart'; @@ -15,9 +16,13 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { testAll( + provider: provider, compilationMode: CompilationMode.buildDaemon, nullSafety: nullSafety, debug: debug, diff --git a/dwds/test/build_daemon_evaluate_test.dart b/dwds/test/build_daemon_evaluate_test.dart index 6c0bde0b7..daab203f7 100644 --- a/dwds/test/build_daemon_evaluate_test.dart +++ b/dwds/test/build_daemon_evaluate_test.dart @@ -6,6 +6,7 @@ @Timeout(Duration(minutes: 2)) import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'evaluate_common.dart'; import 'fixtures/context.dart'; @@ -15,9 +16,13 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { testAll( + provider: provider, compilationMode: CompilationMode.buildDaemon, nullSafety: nullSafety, debug: debug, diff --git a/dwds/test/chrome_proxy_service_test.dart b/dwds/test/chrome_proxy_service_test.dart index 4a860fe9c..cc657e27c 100644 --- a/dwds/test/chrome_proxy_service_test.dart +++ b/dwds/test/chrome_proxy_service_test.dart @@ -8,7 +8,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:dwds/src/connections/debug_connection.dart'; import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:dwds/src/utilities/dart_uri.dart'; @@ -17,20 +16,22 @@ import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - -ChromeProxyService get service => context.service; -WipConnection get tabConnection => context.tabConnection; - void main() { // Change to true to see verbose output from the tests. final debug = false; + + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + group('shared context', () { setUpAll(() async { setCurrentLogWriter(debug: debug); @@ -45,6 +46,7 @@ void main() { }); group('breakpoints', () { + late VmServiceInterface service; VM vm; late Isolate isolate; @@ -53,17 +55,15 @@ void main() { setUp(() async { setCurrentLogWriter(debug: debug); - vm = await fetchChromeProxyService(context.debugConnection).getVM(); - isolate = await fetchChromeProxyService(context.debugConnection) - .getIsolate(vm.isolates!.first.id!); - scripts = await fetchChromeProxyService(context.debugConnection) - .getScripts(isolate.id!); + service = context.service; + vm = await service.getVM(); + isolate = await service.getIsolate(vm.isolates!.first.id!); + scripts = await service.getScripts(isolate.id!); mainScript = scripts.scripts! .firstWhere((each) => each.uri!.contains('main.dart')); }); test('addBreakpoint', () async { - // TODO: Much more testing. final line = await context.findBreakpointLine( 'printHelloWorld', isolate.id!, mainScript); final firstBp = @@ -125,8 +125,7 @@ void main() { }); test('addBreakpointWithScriptUri absolute file URI', () async { - final current = context.workingDirectory; - final test = path.join(path.dirname(current), '_testSound'); + final test = context.project.absolutePackageDirectory; final scriptPath = Uri.parse(mainScript.uri!).path.substring(1); final fullPath = path.join(test, scriptPath); final fileUri = Uri.file(fullPath); @@ -163,13 +162,16 @@ void main() { }); group('callServiceExtension', () { + late ChromeProxyService service; + setUp(() { setCurrentLogWriter(debug: debug); + service = context.service; }); test('success', () async { final serviceMethod = 'ext.test.callServiceExtension'; - await tabConnection.runtime + await context.tabConnection.runtime .evaluate('registerExtension("$serviceMethod");'); // The non-string keys/values get auto json-encoded to match the vm @@ -196,7 +198,7 @@ void main() { test('failure', () async { final serviceMethod = 'ext.test.callServiceExtensionWithError'; - await tabConnection.runtime + await context.tabConnection.runtime .evaluate('registerExtensionWithError("$serviceMethod");'); final errorDetails = {'intentional': 'error'}; @@ -215,8 +217,11 @@ void main() { }); group('VMTimeline', () { + late VmServiceInterface service; + setUp(() { setCurrentLogWriter(debug: debug); + service = context.service; }); test('clearVMTimeline', () async { @@ -242,6 +247,7 @@ void main() { }); test('getMemoryUsage', () async { + final service = context.service; final vm = await service.getVM(); final isolate = await service.getIsolate(vm.isolates!.first.id!); @@ -254,11 +260,13 @@ void main() { }); group('evaluate', () { + late VmServiceInterface service; late Isolate isolate; LibraryRef? bootstrap; setUpAll(() async { setCurrentLogWriter(debug: debug); + service = context.service; final vm = await service.getVM(); isolate = await service.getIsolate(vm.isolates!.first.id!); bootstrap = isolate.rootLib; @@ -362,29 +370,36 @@ void main() { }); test('evaluateInFrame', () async { + final service = context.service; await expectLater( service.evaluateInFrame('', 0, ''), throwsSentinelException); }); test('getAllocationProfile', () async { + final service = context.service; await expectLater(service.getAllocationProfile(''), throwsRPCError); }); test('getClassList', () async { + final service = context.service; await expectLater(service.getClassList(''), throwsRPCError); }); test('getFlagList', () async { + final service = context.service; expect(await service.getFlagList(), isA()); }); test('getInstances', () async { + final service = context.service; await expectLater(service.getInstances('', '', 0), throwsRPCError); }); group('getIsolate', () { + late VmServiceInterface service; setUp(() { setCurrentLogWriter(debug: debug); + service = context.service; }); test('works for existing isolates', () async { @@ -412,6 +427,7 @@ void main() { }); group('getObject', () { + late ChromeProxyService service; late Isolate isolate; LibraryRef? bootstrap; @@ -419,6 +435,7 @@ void main() { setUpAll(() async { setCurrentLogWriter(debug: debug); + service = context.service; final vm = await service.getVM(); isolate = await service.getIsolate(vm.isolates!.first.id!); bootstrap = isolate.rootLib; @@ -1062,6 +1079,7 @@ void main() { }); test('getScripts', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; final scripts = await service.getScripts(isolateId); @@ -1084,8 +1102,11 @@ void main() { }); group('getSourceReport', () { + late VmServiceInterface service; + setUp(() { setCurrentLogWriter(debug: debug); + service = context.service; }); test('Coverage report', () async { @@ -1136,6 +1157,7 @@ void main() { }); group('Pausing', () { + late VmServiceInterface service; String? isolateId; late Stream stream; ScriptList scripts; @@ -1143,6 +1165,7 @@ void main() { setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id; scripts = await service.getScripts(isolateId!); @@ -1172,6 +1195,7 @@ void main() { }); group('Step', () { + late VmServiceInterface service; String? isolateId; late Stream stream; ScriptList scripts; @@ -1179,6 +1203,7 @@ void main() { setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id; scripts = await service.getScripts(isolateId!); @@ -1242,6 +1267,7 @@ void main() { }); group('getStack', () { + late VmServiceInterface service; String? isolateId; late Stream stream; ScriptList scripts; @@ -1249,6 +1275,7 @@ void main() { setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id; scripts = await service.getScripts(isolateId!); @@ -1387,6 +1414,7 @@ void main() { }); test('getVM', () async { + final service = context.service; final vm = await service.getVM(); expect(vm.name, isNotNull); expect(vm.version, Platform.version); @@ -1398,12 +1426,14 @@ void main() { }); test('getVersion', () async { + final service = context.service; final version = await service.getVersion(); expect(version, isNotNull); expect(version.major, greaterThan(0)); }); group('invoke', () { + late ChromeProxyService service; VM vm; late Isolate isolate; LibraryRef? bootstrap; @@ -1411,6 +1441,7 @@ void main() { setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; vm = await service.getVM(); isolate = await service.getIsolate(vm.isolates!.first.id!); bootstrap = isolate.rootLib; @@ -1514,24 +1545,27 @@ void main() { }); test('kill', () async { + final service = context.service; await expectLater(service.kill(''), throwsRPCError); }); test('onEvent', () async { + final service = context.service; expect(() => service.onEvent(''), throwsRPCError); }); test('pause / resume', () async { + final service = context.service; await service.streamListen('Debug'); final stream = service.onEvent('Debug'); final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; final pauseCompleter = Completer(); - final pauseSub = tabConnection.debugger.onPaused.listen((_) { + final pauseSub = context.tabConnection.debugger.onPaused.listen((_) { pauseCompleter.complete(); }); final resumeCompleter = Completer(); - final resumeSub = tabConnection.debugger.onResumed.listen((_) { + final resumeSub = context.tabConnection.debugger.onResumed.listen((_) { resumeCompleter.complete(); }); expect(await service.pause(isolateId), const TypeMatcher()); @@ -1550,16 +1584,19 @@ void main() { }); test('getInboundReferences', () async { + final service = context.service; await expectLater( service.getInboundReferences('', '', 0), throwsRPCError); }); test('getRetainingPath', () async { + final service = context.service; await expectLater(service.getRetainingPath('', '', 0), throwsRPCError); }); test('lookupResolvedPackageUris converts package and org-dartlang-app uris', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; final scriptList = await service.getScripts(isolateId); @@ -1579,6 +1616,7 @@ void main() { test('lookupResolvedPackageUris does not translate non-existent paths', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; @@ -1591,6 +1629,7 @@ void main() { }); test('lookupResolvedPackageUris translates dart uris', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; @@ -1607,6 +1646,7 @@ void main() { test('lookupPackageUris finds package and org-dartlang-app paths', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; final scriptList = await service.getScripts(isolateId); @@ -1627,6 +1667,7 @@ void main() { }); test('lookupPackageUris ignores local parameter', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; final scriptList = await service.getScripts(isolateId); @@ -1660,6 +1701,7 @@ void main() { }); test('lookupPackageUris does not translate non-existent paths', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; @@ -1672,6 +1714,7 @@ void main() { }); test('lookupPackageUris translates dart uris', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; @@ -1686,16 +1729,19 @@ void main() { ]); }, skip: 'https://github.com/dart-lang/webdev/issues/1584'); - test('registerService', () async { + test('registerservice', () async { + final service = context.service; await expectLater( service.registerService('ext.foo.bar', ''), throwsRPCError); }); test('reloadSources', () async { + final service = context.service; await expectLater(service.reloadSources(''), throwsRPCError); }); test('setIsolatePauseMode', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; expect(await service.setIsolatePauseMode(isolateId), _isSuccess); @@ -1718,15 +1764,18 @@ void main() { }); test('setFlag', () async { + final service = context.service; await expectLater(service.setFlag('', ''), throwsRPCError); }); test('setLibraryDebuggable', () async { + final service = context.service; await expectLater( service.setLibraryDebuggable('', '', false), throwsRPCError); }); test('setName', () async { + final service = context.service; final vm = await service.getVM(); final isolateId = vm.isolates!.first.id!; expect(service.setName(isolateId, 'test'), completion(_isSuccess)); @@ -1735,21 +1784,26 @@ void main() { }); test('setVMName', () async { + final service = context.service; expect(service.setVMName('foo'), completion(_isSuccess)); final vm = await service.getVM(); expect(vm.name, 'foo'); }); test('streamCancel', () async { + final service = context.service; await expectLater(service.streamCancel(''), throwsRPCError); }); group('streamListen/onEvent', () { + late ChromeProxyService service; + group('Debug', () { late Stream eventStream; setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; expect(await service.streamListen('Debug'), const TypeMatcher()); eventStream = service.onEvent('Debug'); @@ -1758,12 +1812,12 @@ void main() { test('basic Pause/Resume', () async { expect(service.streamListen('Debug'), completion(_isSuccess)); final stream = service.onEvent('Debug'); - safeUnawaited(tabConnection.debugger.pause()); + safeUnawaited(context.tabConnection.debugger.pause()); await expectLater( stream, emitsThrough(const TypeMatcher() .having((e) => e.kind, 'kind', EventKind.kPauseInterrupted))); - safeUnawaited(tabConnection.debugger.resume()); + safeUnawaited(context.tabConnection.debugger.resume()); expect( eventStream, emitsThrough(const TypeMatcher() @@ -1782,15 +1836,17 @@ void main() { .having((instance) => instance.id, 'id', isNotNull) .having((instance) => instance.kind, 'inspectee.kind', InstanceKind.kPlainInstance)))); - await tabConnection.runtime.evaluate('inspectInstance()'); + await context.tabConnection.runtime.evaluate('inspectInstance()'); }); }); group('Extension', () { + late VmServiceInterface service; late Stream eventStream; setUp(() async { setCurrentLogWriter(debug: debug); + service = context.service; expect(await service.streamListen('Extension'), const TypeMatcher()); eventStream = service.onEvent('Extension'); @@ -1804,7 +1860,8 @@ void main() { event.kind == EventKind.kExtension && event.extensionKind == eventKind && event.extensionData!.data['example'] == 'data'))); - await tabConnection.runtime.evaluate("postEvent('$eventKind');"); + await context.tabConnection.runtime + .evaluate("postEvent('$eventKind');"); }); test('Batched debug events from injected client', () async { @@ -1837,11 +1894,11 @@ void main() { ])); for (var data in batch1) { - await tabConnection.runtime.evaluate(emitDebugEvent(data)); + await context.tabConnection.runtime.evaluate(emitDebugEvent(data)); } await Future.delayed(delay); for (var data in batch2) { - await tabConnection.runtime.evaluate(emitDebugEvent(data)); + await context.tabConnection.runtime.evaluate(emitDebugEvent(data)); } }); }); @@ -1858,14 +1915,14 @@ void main() { isolateEventStream = service.onEvent(EventStreams.kIsolate); }); - test('ServiceExtensionAdded', () async { + test('serviceExtensionAdded', () async { final extensionMethod = 'ext.foo.bar'; expect( isolateEventStream, emitsThrough(predicate((Event event) => event.kind == EventKind.kServiceExtensionAdded && event.extensionRPC == extensionMethod))); - await tabConnection.runtime + await context.tabConnection.runtime .evaluate("registerExtension('$extensionMethod');"); }); @@ -1907,7 +1964,8 @@ void main() { expect( isolateEventStream, emitsInOrder(extensions.map(eventMatcher))); for (var extension in extensions) { - await tabConnection.runtime.evaluate(emitRegisterEvent(extension)); + await context.tabConnection.runtime + .evaluate(emitRegisterEvent(extension)); } }); }); @@ -1924,7 +1982,7 @@ void main() { event.kind == EventKind.kWriteEvent && String.fromCharCodes(base64.decode(event.bytes!)) .contains('hello')))); - await tabConnection.runtime.evaluate('console.log("hello");'); + await context.tabConnection.runtime.evaluate('console.log("hello");'); }); test('Stderr', () async { @@ -1936,7 +1994,7 @@ void main() { event.kind == EventKind.kWriteEvent && String.fromCharCodes(base64.decode(event.bytes!)) .contains('Error')))); - await tabConnection.runtime.evaluate('console.error("Error");'); + await context.tabConnection.runtime.evaluate('console.error("Error");'); }); test('exception stack trace mapper', () async { @@ -1948,7 +2006,8 @@ void main() { event.kind == EventKind.kWriteEvent && String.fromCharCodes(base64.decode(event.bytes!)) .contains('main.dart')))); - await tabConnection.runtime.evaluate('throwUncaughtException();'); + await context.tabConnection.runtime + .evaluate('throwUncaughtException();'); }); test('VM', () async { @@ -1964,12 +2023,14 @@ void main() { }); test('Logging', () async { + final service = context.service; expect( service.streamListen(EventStreams.kLogging), completion(_isSuccess)); final stream = service.onEvent(EventStreams.kLogging); final message = 'myMessage'; - safeUnawaited(tabConnection.runtime.evaluate("sendLog('$message');")); + safeUnawaited( + context.tabConnection.runtime.evaluate("sendLog('$message');")); final event = await stream.first; expect(event.kind, EventKind.kLogging); diff --git a/dwds/test/dart_uri_file_uri_test.dart b/dwds/test/dart_uri_file_uri_test.dart index 293501f41..f4ceb2df6 100644 --- a/dwds/test/dart_uri_file_uri_test.dart +++ b/dwds/test/dart_uri_file_uri_test.dart @@ -8,26 +8,31 @@ import 'package:dwds/src/utilities/dart_uri.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final testProject = TestProject.testWithSoundNullSafety; -final testPackageProject = TestProject.testPackageWithSoundNullSafety(); -final context = TestContext(testPackageProject); - -/// The directory for the general _test package. -final testDir = testProject.absolutePackageDirectory; - -/// The directory for the _testPackage package (contained within dwds), which -/// imports _test. -final testPackageDir = testPackageProject.absolutePackageDirectory; - // This tests converting file Uris into our internal paths. // // These tests are separated out because we need a running isolate in order to // look up packages. void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final testProject = TestProject.testWithSoundNullSafety; + final testPackageProject = TestProject.testPackageWithSoundNullSafety(); + + /// The directory for the general _test package. + final testDir = testProject.absolutePackageDirectory; + + /// The directory for the _testPackage package (contained within dwds), + /// which imports _test. + final testPackageDir = testPackageProject.absolutePackageDirectory; + + final context = TestContext(testPackageProject, provider); + for (final compilationMode in CompilationMode.values) { group('$compilationMode |', () { for (final useDebuggerModuleNames in [false, true]) { diff --git a/dwds/test/debug_extension_test.dart b/dwds/test/debug_extension_test.dart index 4df26f09f..5950eeb35 100644 --- a/dwds/test/debug_extension_test.dart +++ b/dwds/test/debug_extension_test.dart @@ -14,6 +14,7 @@ import 'package:dwds/src/connections/debug_connection.dart'; import 'package:dwds/src/handlers/injector.dart'; import 'package:http/http.dart' as http; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; // ignore: deprecated_member_use import 'package:webdriver/io.dart'; @@ -31,9 +32,12 @@ import 'fixtures/utilities.dart'; // Remove the key before pushing code to GitHub. // See go/extension-identification. -final context = TestContext(TestProject.testWithSoundNullSafety); - void main() async { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + Future waitForDartDevToolsWithRetry({ int retryCount = 6, Duration retryWait = const Duration(seconds: 1), @@ -205,7 +209,6 @@ void main() async { } group('With encoding', () { - final context = TestContext(TestProject.testWithSoundNullSafety); setUp(() async { await context.setUp( enableDebugExtension: true, @@ -226,7 +229,6 @@ void main() async { }); group('With "any" hostname', () { - final context = TestContext(TestProject.testWithSoundNullSafety); final uriPattern = RegExp(r'dartExtensionUri = "([^"]+)";'); setUp(() async { diff --git a/dwds/test/debug_service_test.dart b/dwds/test/debug_service_test.dart index 9db319331..5ecc447b8 100644 --- a/dwds/test/debug_service_test.dart +++ b/dwds/test/debug_service_test.dart @@ -9,13 +9,17 @@ import 'dart:convert'; import 'dart:io'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + setUpAll(() async { // Disable DDS as we're testing DWDS behavior. await context.setUp(spawnDds: false); diff --git a/dwds/test/debugger_test.dart b/dwds/test/debugger_test.dart index ce55a2fa2..c6514e4aa 100644 --- a/dwds/test/debugger_test.dart +++ b/dwds/test/debugger_test.dart @@ -18,12 +18,9 @@ import 'package:vm_service/vm_service.dart' hide LogRecord; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart' show CallFrame, DebuggerPausedEvent, StackTrace, WipCallFrame, WipScript; -import 'fixtures/context.dart'; import 'fixtures/debugger_data.dart'; import 'fixtures/fakes.dart'; -import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); late AppInspector inspector; late Debugger debugger; late FakeWebkitDebugger webkitDebugger; diff --git a/dwds/test/devtools_test.dart b/dwds/test/devtools_test.dart index 58024df59..d869158e1 100644 --- a/dwds/test/devtools_test.dart +++ b/dwds/test/devtools_test.dart @@ -7,6 +7,7 @@ import 'dart:io'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; // ignore: deprecated_member_use import 'package:webdriver/io.dart'; @@ -14,8 +15,6 @@ import 'package:webdriver/io.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - Future _waitForPageReady(TestContext context) async { var attempt = 100; while (attempt-- > 0) { @@ -27,6 +26,11 @@ Future _waitForPageReady(TestContext context) async { } void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + group('Injected client', () { setUp(() async { await context.setUp( diff --git a/dwds/test/evaluate_circular_common.dart b/dwds/test/evaluate_circular_common.dart index 43ec19915..0561758b0 100644 --- a/dwds/test/evaluate_circular_common.dart +++ b/dwds/test/evaluate_circular_common.dart @@ -8,12 +8,14 @@ import 'dart:async'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; void testAll({ + required TestSdkConfigurationProvider provider, CompilationMode compilationMode = CompilationMode.buildDaemon, IndexBaseMode indexBaseMode = IndexBaseMode.noBase, NullSafety nullSafety = NullSafety.sound, @@ -26,10 +28,11 @@ void testAll({ 'build daemon scenario does not support non-empty base in index file'); } - final project1 = TestProject.testCircular1(nullSafety: nullSafety); - final project2 = TestProject.testCircular2( + final testCircular1 = TestProject.testCircular1(nullSafety: nullSafety); + final testCircular2 = TestProject.testCircular2( nullSafety: nullSafety, baseMode: indexBaseMode); - final context = TestContext(project2); + + final context = TestContext(testCircular2, provider); Future onBreakPoint(String isolate, ScriptRef script, String breakPointId, Future Function() body) async { @@ -66,6 +69,7 @@ void testAll({ setUp(() => setCurrentLogWriter(debug: debug)); group('evaluateInFrame', () { + late VmServiceInterface service; VM vm; late Isolate isolate; late String isolateId; @@ -76,16 +80,17 @@ void testAll({ setUp(() async { setCurrentLogWriter(debug: debug); - vm = await context.service.getVM(); - isolate = await context.service.getIsolate(vm.isolates!.first.id!); + service = context.service; + vm = await service.getVM(); + isolate = await service.getIsolate(vm.isolates!.first.id!); isolateId = isolate.id!; - scripts = await context.service.getScripts(isolateId); + scripts = await service.getScripts(isolateId); - await context.service.streamListen('Debug'); - stream = context.service.onEvent('Debug'); + await service.streamListen('Debug'); + stream = service.onEvent('Debug'); - final test1 = project1.packageName; - final test2 = project2.packageName; + final test1 = testCircular1.packageName; + final test2 = testCircular2.packageName; test1LibraryScript = scripts.scripts!.firstWhere( (each) => each.uri!.contains('package:$test1/library1.dart')); @@ -94,7 +99,7 @@ void testAll({ }); tearDown(() async { - await context.service.resume(isolateId); + await service.resume(isolateId); }); test('evaluate expression in _test_circular1/library', () async { diff --git a/dwds/test/evaluate_common.dart b/dwds/test/evaluate_common.dart index f889a6e7b..49613c976 100644 --- a/dwds/test/evaluate_common.dart +++ b/dwds/test/evaluate_common.dart @@ -8,12 +8,14 @@ import 'dart:async'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; void testAll({ + required TestSdkConfigurationProvider provider, CompilationMode compilationMode = CompilationMode.buildDaemon, IndexBaseMode indexBaseMode = IndexBaseMode.noBase, NullSafety nullSafety = NullSafety.sound, @@ -25,10 +27,12 @@ void testAll({ throw StateError( 'build daemon scenario does not support non-empty base in index file'); } + final testProject = TestProject.test(nullSafety: nullSafety); final testPackageProject = TestProject.testPackage(nullSafety: nullSafety, baseMode: indexBaseMode); - final context = TestContext(testPackageProject); + + final context = TestContext(testPackageProject, provider); Future onBreakPoint(String isolate, ScriptRef script, String breakPointId, Future Function() body) async { @@ -47,7 +51,7 @@ void testAll({ } } - group('shared context with evaluation |', () { + group('Shared context with evaluation |', () { setUpAll(() async { setCurrentLogWriter(debug: debug); await context.setUp( @@ -527,11 +531,12 @@ void testAll({ setUp(() async { setCurrentLogWriter(debug: debug); - vm = await context.service.getVM(); - isolate = await context.service.getIsolate(vm.isolates!.first.id!); + final service = context.service; + vm = await service.getVM(); + isolate = await service.getIsolate(vm.isolates!.first.id!); isolateId = isolate.id!; - await context.service.streamListen('Debug'); + await service.streamListen('Debug'); }); tearDown(() async {}); @@ -659,13 +664,14 @@ void testAll({ late Stream stream; setUp(() async { - vm = await context.service.getVM(); - isolate = await context.service.getIsolate(vm.isolates!.first.id!); + final service = context.service; + vm = await service.getVM(); + isolate = await service.getIsolate(vm.isolates!.first.id!); isolateId = isolate.id!; - scripts = await context.service.getScripts(isolateId); + scripts = await service.getScripts(isolateId); - await context.service.streamListen('Debug'); - stream = context.service.onEvent('Debug'); + await service.streamListen('Debug'); + stream = service.onEvent('Debug'); mainScript = scripts.scripts! .firstWhere((each) => each.uri!.contains('main.dart')); diff --git a/dwds/test/events_test.dart b/dwds/test/events_test.dart index 31faad5a2..272ba4ead 100644 --- a/dwds/test/events_test.dart +++ b/dwds/test/events_test.dart @@ -7,21 +7,22 @@ import 'dart:async'; import 'dart:io'; import 'package:dwds/src/events.dart'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:dwds/src/utilities/server.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webdriver/async_core.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; + final context = TestContext(TestProject.testWithSoundNullSafety, provider); -void main() { group('serve requests', () { late HttpServer server; @@ -168,11 +169,13 @@ void main() { }); group('evaluate', () { + late VmServiceInterface service; late String isolateId; late String bootstrapId; setUpAll(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); final isolate = await service.getIsolate(vm.isolates!.first.id!); isolateId = isolate.id!; @@ -212,12 +215,14 @@ void main() { }); group('evaluateInFrame', () { + late VmServiceInterface service; late String isolateId; late Stream stream; late ScriptRef mainScript; setUpAll(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; @@ -302,11 +307,13 @@ void main() { }); group('getSourceReport', () { + late VmServiceInterface service; late String isolateId; late ScriptRef mainScript; setUp(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; final scriptList = await service.getScripts(isolateId); @@ -327,10 +334,12 @@ void main() { }); group('getSripts', () { + late VmServiceInterface service; late String isolateId; setUp(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; }); @@ -345,10 +354,12 @@ void main() { }); group('getIsolate', () { + late VmServiceInterface service; late String isolateId; setUp(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; }); @@ -372,7 +383,7 @@ void main() { matchesEvent(DwdsEventKind.getVM, { 'elapsedMilliseconds': isNotNull, }), - () => service.getVM()); + () => context.service.getVM()); }); }); @@ -393,10 +404,12 @@ void main() { }); group('resume', () { + late VmServiceInterface service; late String isolateId; setUp(() async { setCurrentLogWriter(); + service = context.service; final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; await service.streamListen('Debug'); diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index de2168f49..518209c2b 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -35,8 +35,7 @@ import 'package:test/test.dart'; import 'package:test_common/logging.dart'; import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; -// ignore: deprecated_member_use -import 'package:webdriver/io.dart'; +import 'package:webdriver/async_io.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import 'project.dart'; @@ -56,6 +55,7 @@ enum CompilationMode { buildDaemon, frontendServer } class TestContext { final TestProject project; final NullSafety nullSafety; + final TestSdkConfigurationProvider sdkConfigurationProvider; /// Top level directory in which we run the test server, e.g. /// "/workstation/webdev/fixtures/_testSound". @@ -144,7 +144,8 @@ class TestContext { /// External VM service. VmServiceInterface get vmService => debugConnection.vmService; - TestContext(this.project) : nullSafety = project.nullSafety { + TestContext(this.project, this.sdkConfigurationProvider) + : nullSafety = project.nullSafety { DartUri.currentDirectory = workingDirectory; project.validate(); @@ -175,14 +176,13 @@ class TestContext { bool isInternalBuild = false, List experiments = const [], }) async { - // Generate missing SDK assets if needed. - final sdkConfigurationProvider = - TestSdkConfigurationProvider(verboseCompiler: verboseCompiler); final sdkLayout = sdkConfigurationProvider.sdkLayout; - final configuration = await sdkConfigurationProvider.configuration; - configuration.validate(); try { + // Make sure configuration was created correctly. + final configuration = await sdkConfigurationProvider.configuration; + configuration.validate(); + DartUri.currentDirectory = workingDirectory; configureLogWriter(); @@ -222,7 +222,7 @@ class TestContext { 'Could not start ChromeDriver. Is it installed?\nError: $e'); } - await Process.run(dartPath, ['pub', 'upgrade'], + await Process.run(sdkLayout.dartPath, ['pub', 'upgrade'], workingDirectory: workingDirectory); ExpressionCompiler? expressionCompiler; @@ -244,8 +244,8 @@ class TestContext { '--enable-experiment=$experiment', '--verbose', ]; - _daemonClient = - await connectClient(workingDirectory, options, (log) { + _daemonClient = await connectClient( + sdkLayout.dartPath, workingDirectory, options, (log) { final record = log.toLogRecord(); final name = record.loggerName == '' ? '' : '${record.loggerName}: '; @@ -390,6 +390,7 @@ class TestContext { ddcService, isFlutterApp, isInternalBuild, + sdkLayout, ); _appUrl = basePath.isEmpty diff --git a/dwds/test/fixtures/server.dart b/dwds/test/fixtures/server.dart index 9c17b9567..57b511ded 100644 --- a/dwds/test/fixtures/server.dart +++ b/dwds/test/fixtures/server.dart @@ -16,10 +16,9 @@ import 'package:dwds/src/services/expression_compiler_service.dart'; import 'package:dwds/src/utilities/server.dart'; import 'package:logging/logging.dart'; import 'package:shelf/shelf.dart'; +import 'package:test_common/test_sdk_layout.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; -import 'utilities.dart'; - Logger _logger = Logger('TestServer'); Handler _interceptFavicon(Handler handler) { @@ -82,6 +81,7 @@ class TestServer { ExpressionCompilerService? ddcService, bool isFlutterApp, bool isInternalBuild, + TestSdkLayout sdkLayout, ) async { var pipeline = const Pipeline(); @@ -122,7 +122,7 @@ class TestServer { final server = await DevToolsServer().serveDevTools( hostname: hostname, enableStdinCommands: false, - customDevToolsPath: devToolsPath, + customDevToolsPath: sdkLayout.devToolsDirectory, ); if (server == null) { throw StateError('DevTools server could not be started.'); diff --git a/dwds/test/fixtures/test_sdk_layout.dart b/dwds/test/fixtures/test_sdk_layout.dart deleted file mode 100644 index 488fdd009..000000000 --- a/dwds/test/fixtures/test_sdk_layout.dart +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) 2023, 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. - -// TODO:(annagrin) Move to a test_common package. -import 'package:dwds/src/utilities/sdk_configuration.dart'; -import 'package:path/path.dart' as p; - -/// Test Dart SDK layout. -/// -/// Contains definition of the default SDK layout required for tests. -/// We keep all the path constants in one place for ease of update. -class TestSdkLayout { - static final defaultSdkDirectory = SdkLayout.defaultSdkDirectory; - static TestSdkLayout defaultSdkLayout = - TestSdkLayout.createDefault(defaultSdkDirectory); - static SdkConfiguration defaultSdkConfiguration = - createConfiguration(defaultSdkLayout); - - factory TestSdkLayout.createDefault(String sdkDirectory) => - TestSdkLayout.createDefaultFromSdkLayout( - SdkLayout.createDefault(sdkDirectory)); - - factory TestSdkLayout.createDefaultFromSdkLayout(SdkLayout sdkLayout) => - TestSdkLayout( - sdkDirectory: sdkLayout.sdkDirectory, - soundSummaryPath: sdkLayout.soundSummaryPath, - soundFullDillPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - '_internal', - 'ddc_platform.dill', - ), - soundJsPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'kernel', - 'amd', - 'dart_sdk.js', - ), - soundJsMapPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'kernel', - 'amd', - 'dart_sdk.js.map', - ), - weakSummaryPath: sdkLayout.weakSummaryPath, - weakFullDillPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - '_internal', - 'ddc_platform_unsound.dill', - ), - weakJsPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'kernel', - 'amd', - 'dart_sdk_unsound.js', - ), - weakJsMapPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'kernel', - 'amd', - 'dart_sdk_unsound.js.map', - ), - requireJsPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'amd', - 'require.js', - ), - stackTraceMapperPath: p.join( - sdkLayout.sdkDirectory, - 'lib', - 'dev_compiler', - 'web', - 'dart_stack_trace_mapper.js', - ), - dartPath: p.join(sdkLayout.sdkDirectory, 'bin', 'dart'), - frontendServerSnapshotPath: p.join( - sdkLayout.sdkDirectory, - 'bin', - 'snapshots', - 'frontend_server.dart.snapshot', - ), - dartdevcSnapshotPath: sdkLayout.dartdevcSnapshotPath, - kernelWorkerSnapshotPath: p.join( - sdkLayout.sdkDirectory, - 'bin', - 'snapshots', - 'kernel_worker.dart.snapshot', - ), - ); - - final String sdkDirectory; - - String get soundJsFileName => p.basename(soundJsPath); - String get soundJsMapFileName => p.basename(soundJsMapPath); - String get soundSummaryFileName => p.basename(soundSummaryPath); - String get soundFullDillFileName => p.basename(soundFullDillPath); - - final String soundJsPath; - final String soundJsMapPath; - final String soundSummaryPath; - final String soundFullDillPath; - - String get weakJsFileName => p.basename(weakJsPath); - String get weakJsMapFileName => p.basename(weakJsMapPath); - String get weakSummaryFileName => p.basename(weakSummaryPath); - String get weakFullDillFileName => p.basename(weakFullDillPath); - - final String weakJsPath; - final String weakJsMapPath; - final String weakSummaryPath; - final String weakFullDillPath; - - final String requireJsPath; - final String stackTraceMapperPath; - - final String dartPath; - final String frontendServerSnapshotPath; - final String dartdevcSnapshotPath; - final String kernelWorkerSnapshotPath; - - const TestSdkLayout({ - required this.sdkDirectory, - required this.soundJsPath, - required this.soundJsMapPath, - required this.soundSummaryPath, - required this.soundFullDillPath, - required this.weakJsPath, - required this.weakJsMapPath, - required this.weakSummaryPath, - required this.weakFullDillPath, - required this.requireJsPath, - required this.stackTraceMapperPath, - required this.dartPath, - required this.frontendServerSnapshotPath, - required this.dartdevcSnapshotPath, - required this.kernelWorkerSnapshotPath, - }); - - /// Creates configuration from sdk layout. - static SdkConfiguration createConfiguration(TestSdkLayout sdkLayout) => - SdkConfiguration( - sdkDirectory: sdkLayout.sdkDirectory, - weakSdkSummaryPath: sdkLayout.weakSummaryPath, - soundSdkSummaryPath: sdkLayout.soundSummaryPath, - compilerWorkerPath: sdkLayout.dartdevcSnapshotPath, - ); -} diff --git a/dwds/test/fixtures/utilities.dart b/dwds/test/fixtures/utilities.dart index 1f153da02..4c5db3f5b 100644 --- a/dwds/test/fixtures/utilities.dart +++ b/dwds/test/fixtures/utilities.dart @@ -68,25 +68,15 @@ String absolutePath({ } /// Connects to the `build_runner` daemon. -Future connectClient(String workingDirectory, - List options, Function(ServerLog) logHandler) => +Future connectClient( + String dartPath, + String workingDirectory, + List options, + Function(ServerLog) logHandler) => BuildDaemonClient.connect(workingDirectory, [dartPath, 'run', 'build_runner', 'daemon', ...options], logHandler: logHandler); -/// The path to the root directory of the SDK. -final String _sdkDir = (() { - // The Dart executable is in "/path/to/sdk/bin/dart", so two levels up is - // "/path/to/sdk". - final aboveExecutable = p.dirname(p.dirname(Platform.resolvedExecutable)); - assert(FileSystemEntity.isFileSync(p.join(aboveExecutable, 'version'))); - return aboveExecutable; -})(); - -final String dartSdkPath = _sdkDir; -final String dartPath = p.join(_sdkDir, 'bin', 'dart'); -final String devToolsPath = p.join(_sdkDir, 'bin', 'resources', 'devtools'); - /// Returns the port of the daemon asset server. int daemonPort(String workingDirectory) { final portFile = File(_assetServerPortFilePath(workingDirectory)); diff --git a/dwds/test/frontend_server_breakpoint_test.dart b/dwds/test/frontend_server_breakpoint_test.dart index 4adc5fe3b..5519a87ea 100644 --- a/dwds/test/frontend_server_breakpoint_test.dart +++ b/dwds/test/frontend_server_breakpoint_test.dart @@ -6,22 +6,24 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testPackageWithSoundNullSafety()); - -ChromeProxyService get service => context.service; - void main() { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + + final context = + TestContext(TestProject.testPackageWithSoundNullSafety(), provider); + // Change to 'true' to print expression compiler messages to console. // // Note: expression compiler runs in an isolate, so its output is not @@ -42,6 +44,7 @@ void main() { }); group('breakpoint', () { + late VmServiceInterface service; VM vm; late Isolate isolate; late String isolateId; @@ -51,6 +54,7 @@ void main() { late Stream stream; setUp(() async { + service = context.service; setCurrentLogWriter(debug: debug); vm = await service.getVM(); isolate = await service.getIsolate(vm.isolates!.first.id!); diff --git a/dwds/test/frontend_server_callstack_test.dart b/dwds/test/frontend_server_callstack_test.dart index 3159449d5..c02e4a2ec 100644 --- a/dwds/test/frontend_server_callstack_test.dart +++ b/dwds/test/frontend_server_callstack_test.dart @@ -6,23 +6,26 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; void main() { - group('shared context |', () { - // Enable verbose logging for debugging. - final debug = false; + // Enable verbose logging for debugging. + final debug = false; + + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + group('shared context |', () { for (var nullSafety in NullSafety.values) { group('${nullSafety.name} null safety |', () { final project = TestProject.testPackage(nullSafety: nullSafety); - final context = TestContext(project); + final context = TestContext(project, provider); setUpAll(() async { setCurrentLogWriter(debug: debug); @@ -37,7 +40,7 @@ void main() { }); group('callStack |', () { - late ChromeProxyService service; + late VmServiceInterface service; VM vm; late Isolate isolate; late String isolateId; diff --git a/dwds/test/frontend_server_circular_evaluate_test.dart b/dwds/test/frontend_server_circular_evaluate_test.dart index 437583be9..7efabf0dd 100644 --- a/dwds/test/frontend_server_circular_evaluate_test.dart +++ b/dwds/test/frontend_server_circular_evaluate_test.dart @@ -7,8 +7,8 @@ import 'dart:io'; -import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'evaluate_circular_common.dart'; import 'fixtures/context.dart'; @@ -18,10 +18,8 @@ void main() async { // Enable verbose logging for debugging. final debug = false; - // TODO(annagrin): Remove when 2.19.0-150.0.dev is in stable. - final debuggerModuleNamesSupported = - Version.parse(Platform.version.split(' ').first) >= - Version.parse('2.19.0-150.0.dev'); + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); group('Context with circular dependencies |', () { for (var nullSafety in NullSafety.values) { @@ -29,6 +27,7 @@ void main() async { for (var indexBaseMode in IndexBaseMode.values) { group('with ${indexBaseMode.name} |', () { testAll( + provider: provider, compilationMode: CompilationMode.frontendServer, indexBaseMode: indexBaseMode, nullSafety: nullSafety, @@ -38,9 +37,7 @@ void main() async { }, skip: // https://github.com/dart-lang/sdk/issues/49277 - indexBaseMode == IndexBaseMode.base && Platform.isWindows || - // Needs debugger module names change in the SDK to work. - !debuggerModuleNamesSupported); + indexBaseMode == IndexBaseMode.base && Platform.isWindows); } }); } diff --git a/dwds/test/frontend_server_evaluate_sound_test.dart b/dwds/test/frontend_server_evaluate_sound_test.dart index 4642748fa..f4fa02130 100644 --- a/dwds/test/frontend_server_evaluate_sound_test.dart +++ b/dwds/test/frontend_server_evaluate_sound_test.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'evaluate_common.dart'; import 'fixtures/context.dart'; @@ -17,6 +18,9 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var useDebuggerModuleNames in [false, true]) { group('Debugger module names: $useDebuggerModuleNames |', () { final nullSafety = NullSafety.sound; @@ -24,6 +28,7 @@ void main() async { for (var indexBaseMode in IndexBaseMode.values) { group('with ${indexBaseMode.name} |', () { testAll( + provider: provider, compilationMode: CompilationMode.frontendServer, indexBaseMode: indexBaseMode, nullSafety: nullSafety, diff --git a/dwds/test/frontend_server_evaluate_weak_test.dart b/dwds/test/frontend_server_evaluate_weak_test.dart index 1b88cfb7a..c6bcc83d3 100644 --- a/dwds/test/frontend_server_evaluate_weak_test.dart +++ b/dwds/test/frontend_server_evaluate_weak_test.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'evaluate_common.dart'; import 'fixtures/context.dart'; @@ -17,6 +18,9 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var useDebuggerModuleNames in [false, true]) { group('Debugger module names: $useDebuggerModuleNames |', () { final nullSafety = NullSafety.weak; @@ -24,6 +28,7 @@ void main() async { for (var indexBaseMode in IndexBaseMode.values) { group('with ${indexBaseMode.name} |', () { testAll( + provider: provider, compilationMode: CompilationMode.frontendServer, indexBaseMode: indexBaseMode, nullSafety: nullSafety, diff --git a/dwds/test/handlers/asset_handler_test.dart b/dwds/test/handlers/asset_handler_test.dart index ab2a34cea..301136bca 100644 --- a/dwds/test/handlers/asset_handler_test.dart +++ b/dwds/test/handlers/asset_handler_test.dart @@ -7,13 +7,15 @@ import 'package:shelf/shelf.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; void main() { group('Asset handler', () { - final context = TestContext(TestProject.testWithSoundNullSafety); + final provider = TestSdkConfigurationProvider(); + final context = TestContext(TestProject.testWithSoundNullSafety, provider); setUpAll(() async { setCurrentLogWriter(); @@ -25,6 +27,7 @@ void main() { tearDownAll(() async { await context.tearDown(); + provider.dispose(); }); setUp(setCurrentLogWriter); diff --git a/dwds/test/inspector_test.dart b/dwds/test/inspector_test.dart index 894dc1684..f40adeb0a 100644 --- a/dwds/test/inspector_test.dart +++ b/dwds/test/inspector_test.dart @@ -6,27 +6,31 @@ @Timeout(Duration(minutes: 2)) import 'package:dwds/dwds.dart'; -import 'package:dwds/src/connections/debug_connection.dart'; import 'package:dwds/src/debugging/debugger.dart'; import 'package:dwds/src/debugging/inspector.dart'; import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/utilities/conversions.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testScopesWithSoundNullSafety); - void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = + TestContext(TestProject.testScopesWithSoundNullSafety, provider); + late AppInspector inspector; late Debugger debugger; setUpAll(() async { await context.setUp(); - final service = fetchChromeProxyService(context.debugConnection); + final service = context.service; inspector = service.inspector; debugger = await service.debuggerFuture; }); diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 7cf729015..782a44ca6 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -7,6 +7,7 @@ import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; @@ -17,8 +18,12 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var compilationMode in CompilationMode.values) { await _runTests( + provider: provider, compilationMode: compilationMode, debug: debug, ); @@ -26,10 +31,12 @@ void main() async { } Future _runTests({ + required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required bool debug, }) async { - final context = TestContext(TestProject.testPackageWithSoundNullSafety()); + final context = + TestContext(TestProject.testPackageWithSoundNullSafety(), provider); late VmServiceInterface service; late Stream stream; late String isolateId; @@ -60,7 +67,8 @@ Future _runTests({ verboseCompiler: debug, experiments: ['records'], ); - service = context.service; + service = context.debugConnection.vmService; + final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; final scripts = await service.getScripts(isolateId); diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index d4072aa9a..2aa94061a 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -5,28 +5,30 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/connections/debug_connection.dart'; import 'package:dwds/src/debugging/debugger.dart'; import 'package:dwds/src/debugging/inspector.dart'; import 'package:dwds/src/loaders/strategy.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -final context = TestContext(TestProject.testScopesWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -WipConnection get tabConnection => context.tabConnection; + final context = + TestContext(TestProject.testScopesWithSoundNullSafety, provider); -void main() { late AppInspector inspector; late Debugger debugger; setUpAll(() async { await context.setUp(); - final chromeProxyService = fetchChromeProxyService(context.debugConnection); + final chromeProxyService = context.service; inspector = chromeProxyService.inspector; debugger = await chromeProxyService.debuggerFuture; }); diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index 86fa0b18f..7cf0c8216 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -7,6 +7,7 @@ import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; @@ -17,8 +18,12 @@ void main() async { // Enable verbose logging for debugging. final debug = false; + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + for (var compilationMode in CompilationMode.values) { await _runTests( + provider: provider, compilationMode: compilationMode, debug: debug, ); @@ -26,10 +31,12 @@ void main() async { } Future _runTests({ + required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required bool debug, }) async { - final context = TestContext(TestProject.testExperimentWithSoundNullSafety); + final context = + TestContext(TestProject.testExperimentWithSoundNullSafety, provider); final testInspector = TestInspector(context); late VmServiceInterface service; @@ -60,7 +67,8 @@ Future _runTests({ verboseCompiler: debug, experiments: ['records'], ); - service = context.service; + service = context.debugConnection.vmService; + final vm = await service.getVM(); isolateId = vm.isolates!.first.id!; final scripts = await service.getScripts(isolateId); @@ -72,7 +80,9 @@ Future _runTests({ .firstWhere((each) => each.uri!.contains('main.dart')); }); - tearDownAll(context.tearDown); + tearDownAll(() async { + await context.tearDown(); + }); setUp(() => setCurrentLogWriter(debug: debug)); tearDown(() => service.resume(isolateId)); diff --git a/dwds/test/listviews_test.dart b/dwds/test/listviews_test.dart index 1ec528bda..2f039022e 100644 --- a/dwds/test/listviews_test.dart +++ b/dwds/test/listviews_test.dart @@ -5,13 +5,17 @@ @Timeout(Duration(minutes: 2)) import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + setUpAll(() async { await context.setUp(); }); @@ -43,7 +47,5 @@ void main() { expect(result.json, expected); }, - // TODO(https://github.com/dart-lang/webdev/issues/1741): Re-enable when resolved. - skip: true, ); } diff --git a/dwds/test/package_uri_mapper_test.dart b/dwds/test/package_uri_mapper_test.dart index f4185b0a7..8270d4ca7 100644 --- a/dwds/test/package_uri_mapper_test.dart +++ b/dwds/test/package_uri_mapper_test.dart @@ -16,6 +16,7 @@ import 'fixtures/project.dart'; void main() { final project = TestProject.testPackageWithSoundNullSafety(); + for (final useDebuggerModuleNames in [true, false]) { group( 'Package uri mapper with debugger module names: ' @@ -33,7 +34,6 @@ void main() { '/webdev/fixtures/${project.packageDirectory}/lib/test_library.dart'; final testPackageSoundPath = project.absolutePackageDirectory; - final packageConfigFile = Uri.file(p.join( testPackageSoundPath, '.dart_tool', diff --git a/dwds/test/puppeteer/extension_test.dart b/dwds/test/puppeteer/extension_test.dart index feb097ccf..c660e564e 100644 --- a/dwds/test/puppeteer/extension_test.dart +++ b/dwds/test/puppeteer/extension_test.dart @@ -18,6 +18,7 @@ import 'package:dwds/data/debug_info.dart'; import 'package:path/path.dart' as p; import 'package:puppeteer/puppeteer.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import '../../debug_extension_mv3/web/data_serializers.dart'; import '../../debug_extension_mv3/web/data_types.dart'; @@ -35,11 +36,13 @@ import 'test_utils.dart'; // To run the MV2 tests only: // dart test test/puppeteer/extension_test.dart --r=expanded --no-retry --n="MV2 Debug Extension" -final context = TestContext(TestProject.testWithSoundNullSafety); - enum Panel { debugger, inspector } void main() async { + final provider = TestSdkConfigurationProvider(); + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + tearDownAll(provider.dispose); + for (var isMV3 in [true, false]) { group('${isMV3 ? 'MV3' : 'MV2'} Debug Extension', () { late String extensionPath; @@ -84,6 +87,7 @@ void main() async { tearDownAll(() async { await browser.close(); + await context.tearDown(); }); test('the debug info for a Dart app is saved in session storage', diff --git a/dwds/test/puppeteer/lifeline_test.dart b/dwds/test/puppeteer/lifeline_test.dart index dc4f95d37..c50e4bc4e 100644 --- a/dwds/test/puppeteer/lifeline_test.dart +++ b/dwds/test/puppeteer/lifeline_test.dart @@ -8,20 +8,23 @@ import 'dart:async'; import 'package:puppeteer/puppeteer.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'test_utils.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - void main() async { + final provider = TestSdkConfigurationProvider(); + final context = TestContext(TestProject.testWithSoundNullSafety, provider); late Worker worker; late Browser browser; late String extensionPath; int connectionCount = 0; + tearDownAll(provider.dispose); + group('MV3 Debug Extension Lifeline Connection', () { setUpAll(() async { extensionPath = await buildDebugExtension(isMV3: true); @@ -35,6 +38,7 @@ void main() async { tearDownAll(() async { await browser.close(); + await context.tearDown(); }); test('connects to a lifeline port', () async { diff --git a/dwds/test/readers/frontend_server_asset_reader_test.dart b/dwds/test/readers/frontend_server_asset_reader_test.dart index 619038873..53506a6c3 100644 --- a/dwds/test/readers/frontend_server_asset_reader_test.dart +++ b/dwds/test/readers/frontend_server_asset_reader_test.dart @@ -9,11 +9,11 @@ import 'dart:io'; import 'package:dwds/src/readers/frontend_server_asset_reader.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_layout.dart'; +import '../fixtures/project.dart'; import '../fixtures/utilities.dart'; -final packagesDir = absolutePath(pathFromFixtures: '_test'); - final fixturesDir = absolutePath(pathFromDwds: p.join('test', 'fixtures')); void main() { @@ -22,6 +22,9 @@ void main() { late File jsonOriginal; late File mapOriginal; + final testProject = TestProject.testWithSoundNullSafety; + final packagesDir = testProject.absolutePackageDirectory; + Future createTempFixtures() async { tempFixtures = await Directory.systemTemp.createTemp('dwds_test_fixtures'); await tempFixtures.create(); @@ -32,7 +35,8 @@ void main() { } setUpAll(() async { - await Process.run(dartPath, ['pub', 'upgrade'], + final sdkLayout = TestSdkLayout.defaultSdkLayout; + await Process.run(sdkLayout.dartPath, ['pub', 'upgrade'], workingDirectory: packagesDir); }); diff --git a/dwds/test/readers/proxy_server_asset_reader_test.dart b/dwds/test/readers/proxy_server_asset_reader_test.dart index b2363bb11..9f0e0887e 100644 --- a/dwds/test/readers/proxy_server_asset_reader_test.dart +++ b/dwds/test/readers/proxy_server_asset_reader_test.dart @@ -6,18 +6,28 @@ import 'package:dwds/src/readers/proxy_server_asset_reader.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; void main() { group('ProxyServerAssetReader', () { - final context = TestContext(TestProject.testWithSoundNullSafety); + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + late ProxyServerAssetReader assetReader; setUpAll(() async { await context.setUp(); assetReader = context.testServer.assetReader as ProxyServerAssetReader; }); + + tearDownAll(() async { + await context.tearDown(); + }); + test('returns null if the dart path does not exist', () async { final result = await assetReader.dartSourceContents('some/path/foo.dart'); expect(result, isNull); diff --git a/dwds/test/refresh_test.dart b/dwds/test/refresh_test.dart index e7d1eaf6a..2bfedb312 100644 --- a/dwds/test/refresh_test.dart +++ b/dwds/test/refresh_test.dart @@ -10,22 +10,25 @@ library refresh_test; import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; + final context = TestContext(TestProject.testWithSoundNullSafety, provider); -void main() { group('fresh context', () { + late VmServiceInterface service; late VM vm; setUpAll(() async { await context.setUp(); + service = context.service; vm = await service.getVM(); }); diff --git a/dwds/test/reload_test.dart b/dwds/test/reload_test.dart index 5dd30e98a..212621b69 100644 --- a/dwds/test/reload_test.dart +++ b/dwds/test/reload_test.dart @@ -7,19 +7,40 @@ import 'package:dwds/src/loaders/strategy.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testAppendBodyWithSoundNullSafety); - const originalString = 'Hello World!'; const newString = 'Bonjour le monde!'; void main() { // set to true for debug logging. final debug = false; + + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + + final context = + TestContext(TestProject.testAppendBodyWithSoundNullSafety, provider); + + Future makeEditAndWaitForRebuild() async { + context.makeEditToDartEntryFile( + toReplace: originalString, + replaceWith: newString, + ); + await context.waitForSuccessfulBuild(propagateToBrowser: true); + } + + void undoEdit() { + context.makeEditToDartEntryFile( + toReplace: newString, + replaceWith: originalString, + ); + } + group('Injected client with live reload', () { group('and with debugging', () { setUp(() async { @@ -438,20 +459,5 @@ void main() { }); } -Future makeEditAndWaitForRebuild() async { - context.makeEditToDartEntryFile( - toReplace: originalString, - replaceWith: newString, - ); - await context.waitForSuccessfulBuild(propagateToBrowser: true); -} - -void undoEdit() { - context.makeEditToDartEntryFile( - toReplace: newString, - replaceWith: originalString, - ); -} - TypeMatcher _hasKind(String kind) => isA().having((e) => e.kind, 'kind', kind); diff --git a/dwds/test/restore_breakpoints_test.dart b/dwds/test/restore_breakpoints_test.dart index 1629c22d6..0be78bca6 100644 --- a/dwds/test/restore_breakpoints_test.dart +++ b/dwds/test/restore_breakpoints_test.dart @@ -6,20 +6,20 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/connections/debug_connection.dart'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; + final context = TestContext(TestProject.testWithSoundNullSafety, provider); -void main() { setUpAll(() async { setCurrentLogWriter(); await context.setUp(); @@ -30,6 +30,7 @@ void main() { }); group('breakpoints', () { + late VmServiceInterface service; VM vm; late Isolate isolate; ScriptList scripts; @@ -38,11 +39,10 @@ void main() { setUp(() async { setCurrentLogWriter(); - vm = await fetchChromeProxyService(context.debugConnection).getVM(); - isolate = await fetchChromeProxyService(context.debugConnection) - .getIsolate(vm.isolates!.first.id!); - scripts = await fetchChromeProxyService(context.debugConnection) - .getScripts(isolate.id!); + service = context.service; + vm = await service.getVM(); + isolate = await service.getIsolate(vm.isolates!.first.id!); + scripts = await service.getScripts(isolate.id!); mainScript = scripts.scripts! .firstWhere((each) => each.uri!.contains('main.dart')); isolateEventStream = service.onEvent('Isolate'); diff --git a/dwds/test/run_request_test.dart b/dwds/test/run_request_test.dart index 8cb878396..0d393ae32 100644 --- a/dwds/test/run_request_test.dart +++ b/dwds/test/run_request_test.dart @@ -5,21 +5,24 @@ @Timeout(Duration(minutes: 2)) import 'dart:async'; -import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; + final context = TestContext(TestProject.testWithSoundNullSafety, provider); -void main() { group('while debugger is attached', () { + late VmServiceInterface service; setUp(() async { await context.setUp(autoRun: false); + service = context.service; }); tearDown(() async { @@ -56,8 +59,10 @@ void main() { }); group('while debugger is not attached', () { + late VmServiceInterface service; setUp(() async { await context.setUp(autoRun: false, waitToDebug: true); + service = context.service; }); tearDown(() async { diff --git a/dwds/test/screenshot_test.dart b/dwds/test/screenshot_test.dart index 84a2c4814..db9e4c4e5 100644 --- a/dwds/test/screenshot_test.dart +++ b/dwds/test/screenshot_test.dart @@ -5,13 +5,17 @@ @Timeout(Duration(minutes: 2)) import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testWithSoundNullSafety); - void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + final context = TestContext(TestProject.testWithSoundNullSafety, provider); + setUpAll(() async { await context.setUp(); }); diff --git a/dwds/test/sdk_configuration_test.dart b/dwds/test/sdk_configuration_test.dart index 89b2abe55..b24e55651 100644 --- a/dwds/test/sdk_configuration_test.dart +++ b/dwds/test/sdk_configuration_test.dart @@ -10,6 +10,7 @@ import 'package:dwds/src/utilities/sdk_configuration.dart'; import 'package:file/memory.dart'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; var _throwsDoesNotExistException = throwsA( isA() @@ -21,7 +22,7 @@ void main() { final defaultConfiguration = await DefaultSdkConfigurationProvider().configuration; defaultConfiguration.validateSdkDir(); - defaultConfiguration.validate(); + defaultConfiguration.validateSoundSummaries(); }); test('Cannot validate an empty configuration layout', () async { @@ -48,16 +49,13 @@ void main() { await DefaultSdkConfigurationProvider().configuration; final sdkDirectory = outputDir.path; - final sdkLayout = TestSdkLayout(sdkDirectory); - final sdkConfiguration = TestSdkLayout.createConfiguration(sdkLayout); + final sdkLayout = FakeSdkLayout(sdkDirectory); + final sdkConfiguration = FakeSdkLayout.createConfiguration(sdkLayout); - final weakSdkSummaryPath = sdkLayout.weakSummaryPath; final soundSdkSummaryPath = sdkLayout.soundSummaryPath; final summariesDir = p.dirname(soundSdkSummaryPath); Directory(summariesDir).createSync(recursive: true); - File(defaultSdkConfiguration.weakSdkSummaryPath!) - .copySync(weakSdkSummaryPath); File(defaultSdkConfiguration.soundSdkSummaryPath!) .copySync(soundSdkSummaryPath); @@ -69,26 +67,25 @@ void main() { .copySync(compilerWorkerPath); expect(sdkConfiguration.sdkDirectory, equals(sdkDirectory)); - expect(sdkConfiguration.weakSdkSummaryPath, equals(weakSdkSummaryPath)); expect(sdkConfiguration.soundSdkSummaryPath, equals(soundSdkSummaryPath)); expect(sdkConfiguration.compilerWorkerPath, equals(compilerWorkerPath)); sdkConfiguration.validateSdkDir(); - sdkConfiguration.validate(); + sdkConfiguration.validateSoundSummaries(); }); test('Cannot validate non-existing configuration layout', () async { final sdkDirectory = outputDir.path; - final sdkLayout = TestSdkLayout(sdkDirectory); - final sdkConfiguration = TestSdkLayout.createConfiguration(sdkLayout); + final sdkLayout = FakeSdkLayout(sdkDirectory); + final sdkConfiguration = FakeSdkLayout.createConfiguration(sdkLayout); sdkConfiguration.validateSdkDir(); expect(sdkConfiguration.validate, _throwsDoesNotExistException); }); }); - group('SDK configuration', () { + group('SDK configuration with memory file system', () { late MemoryFileSystem fs; final root = '/root'; @@ -118,12 +115,23 @@ void main() { sdkConfiguration.validate(fileSystem: fs); }); }); + + group('Test configuration', () { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); + + test('Can validate configuration layout with generated assets', () async { + final sdkConfiguration = await provider.configuration; + sdkConfiguration.validateSdkDir(); + sdkConfiguration.validate(); + }); + }); } -class TestSdkLayout { +class FakeSdkLayout { final String sdkDirectory; - static SdkConfiguration createConfiguration(TestSdkLayout sdkLayout) => + static SdkConfiguration createConfiguration(FakeSdkLayout sdkLayout) => SdkConfiguration( sdkDirectory: sdkLayout.sdkDirectory, soundSdkSummaryPath: sdkLayout.soundSummaryPath, @@ -131,7 +139,7 @@ class TestSdkLayout { compilerWorkerPath: sdkLayout.compilerWorkerPath, ); - TestSdkLayout(this.sdkDirectory); + FakeSdkLayout(this.sdkDirectory); String get weakSummaryPath => p.join(sdkDirectory, 'summaries', 'unsound.dill'); diff --git a/dwds/test/variable_scope_test.dart b/dwds/test/variable_scope_test.dart index 40c2c2cd0..188a9fc42 100644 --- a/dwds/test/variable_scope_test.dart +++ b/dwds/test/variable_scope_test.dart @@ -4,22 +4,22 @@ @TestOn('vm') @Timeout(Duration(minutes: 2)) - import 'package:dwds/src/debugging/dart_scope.dart'; import 'package:dwds/src/services/chrome_proxy_service.dart'; import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; import 'package:vm_service/vm_service.dart'; -import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import 'fixtures/context.dart'; import 'fixtures/project.dart'; -final context = TestContext(TestProject.testScopesWithSoundNullSafety); +void main() { + final provider = TestSdkConfigurationProvider(); + tearDownAll(provider.dispose); -ChromeProxyService get service => context.service; -WipConnection get tabConnection => context.tabConnection; + final context = + TestContext(TestProject.testScopesWithSoundNullSafety, provider); -void main() { setUpAll(() async { await context.setUp(); }); @@ -48,6 +48,7 @@ void main() { }); group('variable scope', () { + late ChromeProxyService service; VM vm; String? isolateId; late Stream stream; @@ -108,6 +109,7 @@ void main() { } setUp(() async { + service = context.service; vm = await service.getVM(); isolateId = vm.isolates!.first.id; scripts = await service.getScripts(isolateId!); diff --git a/fixtures/_experimentSound/pubspec.yaml b/fixtures/_experimentSound/pubspec.yaml index 66555faa8..c86678ce3 100644 --- a/fixtures/_experimentSound/pubspec.yaml +++ b/fixtures/_experimentSound/pubspec.yaml @@ -1,4 +1,4 @@ -name: _experiment +name: _experiment_sound version: 1.0.0 description: >- A fake package used for testing experimental language features. diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index 6e56e9478..2731d1d30 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -14,8 +14,7 @@ import 'package:file/file.dart'; import 'package:logging/logging.dart'; import 'package:mime/mime.dart' as mime; import 'package:shelf/shelf.dart' as shelf; - -import 'utilities.dart'; +import 'package:test_common/test_sdk_layout.dart'; class TestAssetServer implements AssetReader { late final String basePath; @@ -34,6 +33,7 @@ class TestAssetServer implements AssetReader { late String _mergedMetadata; final PackageUriMapper _packageUriMapper; final InternetAddress internetAddress; + final TestSdkLayout _sdkLayout; TestAssetServer( this.index, @@ -41,6 +41,7 @@ class TestAssetServer implements AssetReader { this._packageUriMapper, this.internetAddress, this._fileSystem, + this._sdkLayout, ) { basePath = _parseBasePathFromIndexHtml(index); } @@ -59,6 +60,7 @@ class TestAssetServer implements AssetReader { /// Unhandled exceptions will throw a exception with the error and stack /// trace. static Future start( + String sdkDirectory, FileSystem fileSystem, String index, String hostname, @@ -66,10 +68,11 @@ class TestAssetServer implements AssetReader { UrlEncoder? urlTunneler, PackageUriMapper packageUriMapper, ) async { - var address = (await InternetAddress.lookup(hostname)).first; - var httpServer = await HttpServer.bind(address, port); - var server = TestAssetServer( - index, httpServer, packageUriMapper, address, fileSystem); + final address = (await InternetAddress.lookup(hostname)).first; + final httpServer = await HttpServer.bind(address, port); + final sdkLayout = TestSdkLayout.createDefault(sdkDirectory); + final server = TestAssetServer( + index, httpServer, packageUriMapper, address, fileSystem, sdkLayout); return server; } @@ -257,7 +260,7 @@ class TestAssetServer implements AssetReader { } // Otherwise it must be a Dart SDK source. - var dartSdkParent = _fileSystem.directory(dartSdkPath).parent; + var dartSdkParent = _fileSystem.directory(_sdkLayout.sdkDirectory).parent; var dartSdkFile = _fileSystem.file( _fileSystem.path.joinAll([dartSdkParent.path, ...segments])); return dartSdkFile; diff --git a/frontend_server_common/lib/src/devfs.dart b/frontend_server_common/lib/src/devfs.dart index 9bd7c9cbc..1c1c71db5 100644 --- a/frontend_server_common/lib/src/devfs.dart +++ b/frontend_server_common/lib/src/devfs.dart @@ -43,7 +43,7 @@ class WebDevFS { fileSystem.currentDirectory = projectDirectory.toFilePath(); - assetServer = await TestAssetServer.start( + assetServer = await TestAssetServer.start(sdkLayout.sdkDirectory, fileSystem, index, hostname, port, urlTunneler, packageUriMapper); return Uri.parse('http://$hostname:$port'); } diff --git a/frontend_server_common/lib/src/frontend_server_client.dart b/frontend_server_common/lib/src/frontend_server_client.dart index 5aa733b32..3a5300d23 100644 --- a/frontend_server_common/lib/src/frontend_server_client.dart +++ b/frontend_server_common/lib/src/frontend_server_client.dart @@ -396,7 +396,7 @@ class ResidentCompiler { _logger.info(args.join(' ')); final workingDirectory = projectDirectory.toFilePath(); - _server = await Process.start(Platform.resolvedExecutable, args, + _server = await Process.start(sdkLayout.dartPath, args, workingDirectory: workingDirectory); var server = _server!; diff --git a/frontend_server_common/lib/src/resident_runner.dart b/frontend_server_common/lib/src/resident_runner.dart index 1c9af81d1..826fc6a38 100644 --- a/frontend_server_common/lib/src/resident_runner.dart +++ b/frontend_server_common/lib/src/resident_runner.dart @@ -15,7 +15,6 @@ import 'package:test_common/test_sdk_layout.dart'; import 'devfs.dart'; import 'frontend_server_client.dart'; -import 'utilities.dart'; class ResidentWebRunner { final _logger = Logger('ResidentWebRunner'); @@ -39,7 +38,7 @@ class ResidentWebRunner { : sdkLayout.weakSummaryPath); generator = ResidentCompiler( - dartSdkPath, + sdkLayout.sdkDirectory, projectDirectory: projectDirectory, packageConfigFile: packageConfigFile, useDebuggerModuleNames: packageUriMapper.useDebuggerModuleNames, diff --git a/frontend_server_common/lib/src/utilities.dart b/frontend_server_common/lib/src/utilities.dart index 1c68b52e6..eddc3b40a 100644 --- a/frontend_server_common/lib/src/utilities.dart +++ b/frontend_server_common/lib/src/utilities.dart @@ -2,21 +2,7 @@ // 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:io'; - import 'package:file/file.dart' as fs; import 'package:file/local.dart'; -import 'package:path/path.dart' as p; - -/// The path to the root directory of the SDK. -final String _sdkDir = (() { - // The Dart executable is in "/path/to/sdk/bin/dart", so two levels up is - // "/path/to/sdk". - var aboveExecutable = p.dirname(p.dirname(Platform.resolvedExecutable)); - assert(FileSystemEntity.isFileSync(p.join(aboveExecutable, 'version'))); - return aboveExecutable; -})(); - -final String dartSdkPath = _sdkDir; const fs.FileSystem localFileSystem = LocalFileSystem(); diff --git a/test_common/lib/sdk_asset_generator.dart b/test_common/lib/sdk_asset_generator.dart index 21bcf55ec..5d6061137 100644 --- a/test_common/lib/sdk_asset_generator.dart +++ b/test_common/lib/sdk_asset_generator.dart @@ -13,7 +13,7 @@ import 'package:test_common/test_sdk_layout.dart'; /// - sound null safety: js, source map, full dill. /// - weak null safety: js, source map, full dill, summary. class SdkAssetGenerator { - static bool _sdkAssetsGenerated = false; + bool _sdkAssetsGenerated = false; final _logger = Logger('SdkAssetGenerator'); final FileSystem fileSystem; @@ -88,10 +88,7 @@ class SdkAssetGenerator { 'org-dartlang-sdk:///lib/libraries.json', '--modules', 'amd', - if (soundNullSafety) - '--sound-null-safety' - else - '--no-sound-null-safety', + soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety', 'dart:core', '-o', jsPath, @@ -99,7 +96,7 @@ class SdkAssetGenerator { final output = []; _logger.fine('Executing dart ${args.join(' ')}'); - final process = await Process.start(Platform.resolvedExecutable, args, + final process = await Process.start(sdkLayout.dartPath, args, workingDirectory: sdkLayout.sdkDirectory); process.stdout @@ -187,7 +184,7 @@ class SdkAssetGenerator { ]; _logger.fine('Executing dart ${args.join(' ')}'); - final process = await Process.start(Platform.resolvedExecutable, args, + final process = await Process.start(sdkLayout.dartPath, args, workingDirectory: sdkLayout.sdkDirectory); final output = []; diff --git a/test_common/lib/test_sdk_configuration.dart b/test_common/lib/test_sdk_configuration.dart index f93fe691d..02618529f 100644 --- a/test_common/lib/test_sdk_configuration.dart +++ b/test_common/lib/test_sdk_configuration.dart @@ -2,8 +2,10 @@ // 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. -// TODO:(annagrin) Move to a test_common package. +import 'dart:io'; + import 'package:dwds/sdk_configuration.dart'; +import 'package:logging/logging.dart'; import 'package:test_common/sdk_asset_generator.dart'; import 'package:test_common/test_sdk_layout.dart'; @@ -19,26 +21,61 @@ import 'package:test_common/test_sdk_layout.dart'; /// TODO(annagrin): update to only generating missing sound artifacts /// for frontend server after we have no uses of weak null safety. class TestSdkConfigurationProvider extends SdkConfigurationProvider { - final bool _verboseCompiler; + final _logger = Logger('TestSdkConfigurationProvider'); + + final bool _verbose; + late final Directory _sdkDirectory; SdkConfiguration? _configuration; - final sdkLayout = TestSdkLayout.defaultSdkLayout; + late final TestSdkLayout sdkLayout; - TestSdkConfigurationProvider({bool verboseCompiler = false}) - : _verboseCompiler = verboseCompiler; + TestSdkConfigurationProvider({bool verbose = false}) : _verbose = verbose { + _sdkDirectory = Directory.systemTemp.createTempSync('sdk copy'); + sdkLayout = TestSdkLayout.createDefault(_sdkDirectory.path); + } @override Future get configuration async => _configuration ??= await _create(); /// Generate missing assets in the default SDK layout. + /// + /// Creates a copy of the SDK directory where all the missing assets + /// are generated. Tests using this configuration run using the copy + /// sdk layout to make sure the actual SDK is not modified. Future _create() async { - final assetGenerator = SdkAssetGenerator( - sdkLayout: sdkLayout, - verboseCompiler: _verboseCompiler, - ); + try { + await copyDirectory( + TestSdkLayout.defaultSdkDirectory, _sdkDirectory.path); + } catch (e, s) { + _logger.severe('Failed to create SDK directory copy', e, s); + dispose(); + rethrow; + } + + try { + final assetGenerator = SdkAssetGenerator( + sdkLayout: sdkLayout, + verboseCompiler: _verbose, + ); + + await assetGenerator.generateSdkAssets(); + return TestSdkLayout.createConfiguration(sdkLayout); + } catch (e, s) { + _logger.severe('Failed generate missing assets', e, s); + dispose(); + rethrow; + } + } - await assetGenerator.generateSdkAssets(); - return TestSdkLayout.defaultSdkConfiguration; + void dispose({bool retry = true}) { + try { + if (_sdkDirectory.existsSync()) { + _sdkDirectory.deleteSync(recursive: true); + } + } catch (e, s) { + _logger.warning('Failed delete SDK directory copy', e, s); + dispose(retry: false); + } } } diff --git a/test_common/lib/test_sdk_layout.dart b/test_common/lib/test_sdk_layout.dart index 78a00c1d4..04da509fb 100644 --- a/test_common/lib/test_sdk_layout.dart +++ b/test_common/lib/test_sdk_layout.dart @@ -2,6 +2,8 @@ // 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:io'; + import 'package:dwds/sdk_configuration.dart'; import 'package:path/path.dart' as p; @@ -83,7 +85,11 @@ class TestSdkLayout { 'web', 'dart_stack_trace_mapper.js', ), - dartPath: p.join(sdkLayout.sdkDirectory, 'bin', 'dart'), + dartPath: p.join( + sdkLayout.sdkDirectory, + 'bin', + 'dart', + ), frontendServerSnapshotPath: p.join( sdkLayout.sdkDirectory, 'bin', @@ -97,6 +103,12 @@ class TestSdkLayout { 'snapshots', 'kernel_worker.dart.snapshot', ), + devToolsDirectory: p.join( + sdkLayout.sdkDirectory, + 'bin', + 'resources', + 'devtools', + ), ); final String sdkDirectory; @@ -128,6 +140,7 @@ class TestSdkLayout { final String frontendServerSnapshotPath; final String dartdevcSnapshotPath; final String kernelWorkerSnapshotPath; + final String devToolsDirectory; const TestSdkLayout({ required this.sdkDirectory, @@ -145,6 +158,7 @@ class TestSdkLayout { required this.frontendServerSnapshotPath, required this.dartdevcSnapshotPath, required this.kernelWorkerSnapshotPath, + required this.devToolsDirectory, }); /// Creates configuration from sdk layout. @@ -156,3 +170,20 @@ class TestSdkLayout { compilerWorkerPath: sdkLayout.dartdevcSnapshotPath, ); } + +// Update modified files. +Future copyDirectory(String from, String to) async { + if (!Directory(from).existsSync()) return; + await Directory(to).create(recursive: true); + + await for (final file in Directory(from).list(followLinks: false)) { + final copyTo = p.join(to, p.relative(file.path, from: from)); + if (file is Directory) { + await copyDirectory(file.path, copyTo); + } else if (file is File) { + await File(file.path).copy(copyTo); + } else if (file is Link) { + await Link(copyTo).create(await file.target(), recursive: true); + } + } +} diff --git a/test_common/test/sdk_asset_generator_test.dart b/test_common/test/sdk_asset_generator_test.dart index 5a7cad7aa..5c54ceadd 100644 --- a/test_common/test/sdk_asset_generator_test.dart +++ b/test_common/test/sdk_asset_generator_test.dart @@ -7,7 +7,6 @@ import 'dart:io'; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; import 'package:test_common/sdk_asset_generator.dart'; @@ -44,7 +43,7 @@ void main() { compilerWorkerPath = copySdkLayout.dartdevcSnapshotPath; // Copy the SDK directory into a temp directory. - await _copy(TestSdkLayout.defaultSdkDirectory, sdkDirectory); + await copyDirectory(TestSdkLayout.defaultSdkDirectory, sdkDirectory); // Simulate missing sound assets. soundSdkFullDillPath = copySdkLayout.soundFullDillPath; @@ -112,7 +111,8 @@ void main() { }); } -Matcher _exists = predicate((String path) => File(path).existsSync()); +Matcher _exists = + predicate((String path) => File(path).existsSync(), 'File exists'); void _deleteIfExists(String path) { final file = File(path); @@ -120,20 +120,3 @@ void _deleteIfExists(String path) { file.deleteSync(); } } - -// Update modified files. -Future _copy(String from, String to) async { - if (!Directory(from).existsSync()) return; - await Directory(to).create(recursive: true); - - await for (final file in Directory(from).list()) { - final copyTo = p.join(to, p.relative(file.path, from: from)); - if (file is Directory) { - await _copy(file.path, copyTo); - } else if (file is File) { - await File(file.path).copy(copyTo); - } else if (file is Link) { - await Link(copyTo).create(await file.target(), recursive: true); - } - } -} diff --git a/test_common/test/test_sdk_configuration_test.dart b/test_common/test/test_sdk_configuration_test.dart new file mode 100644 index 000000000..8a701fc45 --- /dev/null +++ b/test_common/test/test_sdk_configuration_test.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2019, 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. + +@TestOn('vm') +@Timeout(Duration(minutes: 2)) + +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +void main() { + final debug = false; + + group('Test SDK configuration provider |', () { + setUpAll(() { + setCurrentLogWriter(debug: debug); + }); + + test('Creates and deletes SDK directory copy', () async { + final provider = TestSdkConfigurationProvider(verbose: debug); + final sdkDirectory = provider.sdkLayout.sdkDirectory; + final weakSdkSummary = provider.sdkLayout.weakSummaryPath; + try { + expect(sdkDirectory, _directoryExists, + reason: 'SDK directory should be created'); + expect(weakSdkSummary, isNot(_fileExists), + reason: 'Weak SDK summary should not be generated yet.'); + + await provider.configuration; + expect(weakSdkSummary, _fileExists, + reason: 'Weak SDK summary should be generated'); + } finally { + provider.dispose(); + expect(sdkDirectory, isNot(_directoryExists), + reason: 'SDK directory copy should be deleted on dispose'); + } + }); + }); + + group('Test SDK configuration |', () { + setCurrentLogWriter(debug: debug); + final provider = TestSdkConfigurationProvider(verbose: debug); + tearDownAll(provider.dispose); + + test('Can validate configuration with generated assets', () async { + final sdkConfiguration = await provider.configuration; + sdkConfiguration.validateSdkDir(); + sdkConfiguration.validate(); + }); + + test('SDK layout exists', () async { + await provider.configuration; + final sdkLayout = provider.sdkLayout; + + expect(sdkLayout.sdkDirectory, _directoryExists); + expect(sdkLayout.soundJsPath, _fileExists); + expect(sdkLayout.soundJsMapPath, _fileExists); + expect(sdkLayout.soundSummaryPath, _fileExists); + expect(sdkLayout.soundFullDillPath, _fileExists); + + expect(sdkLayout.weakJsPath, _fileExists); + expect(sdkLayout.weakJsMapPath, _fileExists); + expect(sdkLayout.weakSummaryPath, _fileExists); + expect(sdkLayout.weakFullDillPath, _fileExists); + + expect(sdkLayout.requireJsPath, _fileExists); + expect(sdkLayout.stackTraceMapperPath, _fileExists); + + expect(sdkLayout.dartPath, _fileExists); + expect(sdkLayout.frontendServerSnapshotPath, _fileExists); + expect(sdkLayout.dartdevcSnapshotPath, _fileExists); + expect(sdkLayout.kernelWorkerSnapshotPath, _fileExists); + expect(sdkLayout.devToolsDirectory, _directoryExists); + }); + }); +} + +Matcher _fileExists = + predicate((String path) => File(path).existsSync(), 'File exists'); + +Matcher _directoryExists = predicate( + (String path) => Directory(path).existsSync(), 'Directory exists'); diff --git a/webdev/test/daemon/app_domain_test.dart b/webdev/test/daemon/app_domain_test.dart index ad6f6735e..546172400 100644 --- a/webdev/test/daemon/app_domain_test.dart +++ b/webdev/test/daemon/app_domain_test.dart @@ -14,39 +14,43 @@ import 'utils.dart'; void main() { late String exampleDirectory; + final testRunner = TestRunner(); setUpAll(() async { - exampleDirectory = await prepareWorkspace(); + await testRunner.setUpAll(); + exampleDirectory = await testRunner.prepareWorkspace(); }); + tearDownAll(testRunner.tearDownAll); + group('AppDomain', () { group('Events', () { test('.start', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); await expectLater( webdev.stdout, emitsThrough(startsWith('[{"event":"app.start"'))); await exitWebdev(webdev); }); test('.started', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); await expectLater( webdev.stdout, emitsThrough(startsWith('[{"event":"app.started"'))); await exitWebdev(webdev); }); test('.debugPort', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); await expectLater(webdev.stdout, emitsThrough(startsWith('[{"event":"app.debugPort"'))); await exitWebdev(webdev); }); test('.log', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); // The example app does an initial print. await expectLater( @@ -60,8 +64,8 @@ void main() { group('Methods', () { test('.callServiceExtension', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); if (Platform.isWindows) { // Windows takes a bit longer to run the application and register @@ -81,8 +85,8 @@ void main() { }); test('.reload', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); var extensionCall = '[{"method":"app.restart","id":0,' '"params" : { "appId" : "$appId", "fullRestart" : false}}]'; @@ -97,8 +101,8 @@ void main() { }); test('.restart', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); var extensionCall = '[{"method":"app.restart","id":0,' '"params" : { "appId" : "$appId", "fullRestart" : true}}]'; @@ -117,8 +121,8 @@ void main() { }); test('.stop', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); var stopCall = '[{"method":"app.stop","id":0,' '"params" : { "appId" : "$appId"}}]'; diff --git a/webdev/test/daemon/daemon_domain_test.dart b/webdev/test/daemon/daemon_domain_test.dart index a7102a622..45cfdf07d 100644 --- a/webdev/test/daemon/daemon_domain_test.dart +++ b/webdev/test/daemon/daemon_domain_test.dart @@ -14,15 +14,19 @@ import 'utils.dart'; void main() { late String exampleDirectory; + final testRunner = TestRunner(); setUpAll(() async { - exampleDirectory = await prepareWorkspace(); + await testRunner.setUpAll(); + exampleDirectory = await testRunner.prepareWorkspace(); }); + tearDownAll(testRunner.tearDownAll); + group('Daemon', () { group('Events', () { test('.connected', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); await expectLater( webdev.stdout, emits(startsWith('[{"event":"daemon.connected"'))); await exitWebdev(webdev); @@ -31,8 +35,8 @@ void main() { group('Methods', () { test('.version', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); webdev.stdin.add(utf8.encode('[{"method":"daemon.version","id":0}]\n')); await expectLater( webdev.stdout, emitsThrough(equals('[{"id":0,"result":"0.4.2"}]'))); @@ -40,8 +44,8 @@ void main() { }); test('.shutdown', () async { - var webdev = - await runWebDev(['daemon'], workingDirectory: exampleDirectory); + var webdev = await testRunner + .runWebDev(['daemon'], workingDirectory: exampleDirectory); webdev.stdin .add(utf8.encode('[{"method":"daemon.shutdown","id":0}]\n')); await expectLater(webdev.stdout, emitsThrough(equals('[{"id":0}]'))); diff --git a/webdev/test/daemon/launch_app_test.dart b/webdev/test/daemon/launch_app_test.dart index 9818e7ba9..d37e74ac0 100644 --- a/webdev/test/daemon/launch_app_test.dart +++ b/webdev/test/daemon/launch_app_test.dart @@ -11,12 +11,17 @@ import 'utils.dart'; void main() { late String exampleDirectory; + final testRunner = TestRunner(); setUpAll(() async { - exampleDirectory = await prepareWorkspace(); + await testRunner.setUpAll(); + exampleDirectory = await testRunner.prepareWorkspace(); }); + tearDownAll(testRunner.tearDownAll); + test('--launch-app launches the specified app', () async { - var webdev = await runWebDev(['daemon', '--launch-app=web/scopes.html'], + var webdev = await testRunner.runWebDev( + ['daemon', '--launch-app=web/scopes.html'], workingDirectory: exampleDirectory); var appId = await waitForAppId(webdev); diff --git a/webdev/test/daemon/utils.dart b/webdev/test/daemon/utils.dart index f124a2fcd..edc856ce7 100644 --- a/webdev/test/daemon/utils.dart +++ b/webdev/test/daemon/utils.dart @@ -5,13 +5,9 @@ import 'dart:async'; import 'dart:convert'; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:test_process/test_process.dart'; import 'package:vm_service/vm_service.dart'; -import 'package:webdev/src/util.dart'; - -import '../test_utils.dart'; const isRPCError = TypeMatcher(); @@ -37,17 +33,6 @@ Future waitForAppId(TestProcess webdev) async { return appId; } -Future prepareWorkspace() async { - var exampleDirectory = - p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSoundSmoke')); - - var process = await TestProcess.start(dartPath, ['pub', 'upgrade'], - workingDirectory: exampleDirectory, environment: getPubEnvironment()); - - await process.shouldExit(0); - return exampleDirectory; -} - String? getDebugServiceUri(String line) { var regex = RegExp(r'Debug service listening on (?[^\s^\\]*)'); var match = regex.firstMatch(line); diff --git a/webdev/test/e2e_test.dart b/webdev/test/e2e_test.dart index 8d706a434..6c6d09248 100644 --- a/webdev/test/e2e_test.dart +++ b/webdev/test/e2e_test.dart @@ -36,10 +36,12 @@ void main() { // Change to true for debugging. final debug = false; + final testRunner = TestRunner(); late String exampleDirectory; late String soundExampleDirectory; setUpAll(() async { configureLogWriter(debug); + await testRunner.setUpAll(); exampleDirectory = p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSmoke')); soundExampleDirectory = @@ -62,6 +64,8 @@ void main() { await d.file('pubspec.lock', isNotEmpty).validate(soundExampleDirectory); }); + tearDownAll(testRunner.tearDownAll); + test('smoke test is configured properly', () async { var smokeYaml = loadYaml( await File('$soundExampleDirectory/pubspec.yaml').readAsString()) @@ -81,8 +85,8 @@ void main() { var args = ['build', '-o', 'web:${d.sandbox}']; - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); // NOTE: We'd like this to be more useful // See https://github.com/dart-lang/build/issues/1283 @@ -109,8 +113,8 @@ void main() { '--delete-conflicting-outputs' ]; - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); await checkProcessStdout(process, ['Succeeded']); await process.shouldExit(0); @@ -124,8 +128,8 @@ void main() { args.add('--no-release'); } - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); var expectedItems = ['Succeeded']; @@ -152,8 +156,8 @@ void main() { '--null-safety=sound' ]; - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); var expectedItems = ['Succeeded']; @@ -172,7 +176,8 @@ void main() { '--null-safety=unsound' ]; - var process = await runWebDev(args, workingDirectory: exampleDirectory); + var process = + await testRunner.runWebDev(args, workingDirectory: exampleDirectory); var expectedItems = ['Succeeded']; @@ -191,8 +196,8 @@ void main() { args.add('--no-release'); } - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); var expectedItems = ['Succeeded']; @@ -214,8 +219,8 @@ void main() { args.add('--release'); } - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); var hostUrl = 'http://localhost:$openPort'; @@ -256,8 +261,8 @@ void main() { if (command == 'build') '--output=$dir:foo' else dir ]; - var process = - await runWebDev(args, workingDirectory: soundExampleDirectory); + var process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); await expectLater( process.stdout, emitsThrough(contains( @@ -294,7 +299,7 @@ void main() { '--null-safety=$nullSafetyOption', '--verbose', ]; - var process = await runWebDev(args, + var process = await testRunner.runWebDev(args, workingDirectory: soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService? vmService; @@ -360,7 +365,7 @@ void main() { '--enable-expression-evaluation', '--verbose', ]; - var process = await runWebDev(args, + var process = await testRunner.runWebDev(args, workingDirectory: soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService? vmService; @@ -418,7 +423,7 @@ void main() { '--no-enable-expression-evaluation', '--verbose', ]; - var process = await runWebDev(args, + var process = await testRunner.runWebDev(args, workingDirectory: soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService? vmService; @@ -473,7 +478,7 @@ void main() { '--no-enable-expression-evaluation', '--verbose', ]; - var process = await runWebDev(args, + var process = await testRunner.runWebDev(args, workingDirectory: soundNullSafety ? soundExampleDirectory : exampleDirectory); VmService? vmService; diff --git a/webdev/test/integration_test.dart b/webdev/test/integration_test.dart index 2e9154388..6739b8bdf 100644 --- a/webdev/test/integration_test.dart +++ b/webdev/test/integration_test.dart @@ -18,8 +18,12 @@ void main() { var pubCommand = sdkVersion.compareTo(firstSdkVersionWithoutPub) < 0 ? 'pub' : 'dart pub'; + final testRunner = TestRunner(); + setUpAll(testRunner.setUpAll); + tearDownAll(testRunner.tearDownAll); + test('non-existant commands create errors', () async { - var process = await runWebDev(['monkey']); + var process = await testRunner.runWebDev(['monkey']); await expectLater( process.stdout, emits('Could not find a command named "monkey".')); @@ -28,7 +32,7 @@ void main() { }); test('passing extra args to build fails with bad usage', () async { - var process = await runWebDev(['build', 'extra', 'args']); + var process = await testRunner.runWebDev(['build', 'extra', 'args']); await expectLater(process.stdout, emits('Arguments were provided that are not supported: "extra args".')); @@ -55,7 +59,8 @@ name: sample await d.file('.dart_tool/package_config.json', ''' ''').create(); - var process = await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = + await testRunner.runWebDev(['serve'], workingDirectory: d.sandbox); var output = await process.stdout.rest.toList(); @@ -87,7 +92,8 @@ name: sample await d.file('.dart_tool/package_config.json', ''' ''').create(); - var process = await runWebDev([command], workingDirectory: d.sandbox); + var process = await testRunner + .runWebDev([command], workingDirectory: d.sandbox); await checkProcessStdout(process, [ 'webdev could not run for this project.', @@ -110,7 +116,8 @@ name: sample await d.file('.dart_tool/package_config.json', ''' ''').create(); - var process = await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = await testRunner + .runWebDev(['serve'], workingDirectory: d.sandbox); await checkProcessStdout(process, [ 'webdev could not run for this project.', @@ -138,7 +145,8 @@ name: sample // Required for webdev to not complain about nothing to serve. await d.dir('web').create(); - var process = await runWebDev(['serve', '--no-build-web-compilers'], + var process = await testRunner.runWebDev( + ['serve', '--no-build-web-compilers'], workingDirectory: d.sandbox); // Fails since this is a fake package @@ -187,8 +195,8 @@ name: sample await d.file('.dart_tool/package_config.json', ''' ''').create(); - var process = - await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = await testRunner + .runWebDev(['serve'], workingDirectory: d.sandbox); if (entry.key == 'build_daemon') { await checkProcessStdout(process, [ @@ -212,7 +220,8 @@ name: sample } test('no pubspec.yaml', () async { - var process = await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = + await testRunner.runWebDev(['serve'], workingDirectory: d.sandbox); await checkProcessStdout(process, [ 'webdev could not run for this project.', @@ -226,7 +235,8 @@ name: sample name: sample ''').create(); - var process = await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = + await testRunner.runWebDev(['serve'], workingDirectory: d.sandbox); await checkProcessStdout(process, [ 'webdev could not run for this project.', @@ -250,7 +260,8 @@ dependencies: args: ^1.0.0 ''').create(); - var process = await runWebDev(['serve'], workingDirectory: d.sandbox); + var process = + await testRunner.runWebDev(['serve'], workingDirectory: d.sandbox); await checkProcessStdout(process, [ 'webdev could not run for this project.', diff --git a/webdev/test/readme_test.dart b/webdev/test/readme_test.dart index 0f57f0f96..77def258a 100644 --- a/webdev/test/readme_test.dart +++ b/webdev/test/readme_test.dart @@ -15,14 +15,18 @@ import 'package:test/test.dart'; import 'test_utils.dart'; void main() { - test('help build', () => _readmeCheck(['help', 'build'])); - test('help serve', () => _readmeCheck(['help', 'serve'])); + final testRunner = TestRunner(); + setUpAll(testRunner.setUpAll); + tearDownAll(testRunner.tearDownAll); + + test('help build', () => _readmeCheck(testRunner, ['help', 'build'])); + test('help serve', () => _readmeCheck(testRunner, ['help', 'serve'])); } final _readmeContents = File('README.md').readAsStringSync(); -Future _readmeCheck(List args) async { - var process = await runWebDev(args); +Future _readmeCheck(TestRunner testRunner, List args) async { + var process = await testRunner.runWebDev(args); var output = (await process.stdoutStream().map((line) => line.trimRight()).join('\n')) .trim(); diff --git a/webdev/test/test_utils.dart b/webdev/test/test_utils.dart index 67ee55813..0b8615dde 100644 --- a/webdev/test/test_utils.dart +++ b/webdev/test/test_utils.dart @@ -8,21 +8,53 @@ import 'dart:io'; import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; +import 'package:test_common/test_sdk_layout.dart'; import 'package:test_process/test_process.dart'; -import 'package:webdev/src/util.dart'; final _webdevBin = p.absolute(p.join('bin', 'webdev.dart')); -final _sdkConfigurationProvider = TestSdkConfigurationProvider(); -Future runWebDev(List args, - {String? workingDirectory}) async { - // Generate missing test assets in the SDK. - await _sdkConfigurationProvider.configuration; +class TestRunner { + late TestSdkConfigurationProvider sdkConfigurationProvider; + late TestSdkLayout sdkLayout; - var fullArgs = [_webdevBin, ...args]; + Future setUpAll({bool verbose = false}) async { + // Generate missing SDK assets if needed. + sdkConfigurationProvider = TestSdkConfigurationProvider(verbose: verbose); + sdkLayout = sdkConfigurationProvider.sdkLayout; - return TestProcess.start(dartPath, fullArgs, - workingDirectory: workingDirectory); + try { + // Make sure configuration was created correctly. + final configuration = await sdkConfigurationProvider.configuration; + configuration.validate(); + } catch (_) { + tearDownAll(); + rethrow; + } + } + + void tearDownAll() { + sdkConfigurationProvider.dispose(); + } + + Future runWebDev(List args, + {String? workingDirectory}) async { + var fullArgs = [_webdevBin, ...args]; + + return TestProcess.start(sdkLayout.dartPath, fullArgs, + workingDirectory: workingDirectory); + } + + Future prepareWorkspace() async { + var exampleDirectory = + p.absolute(p.join(p.current, '..', 'fixtures', '_webdevSoundSmoke')); + + var process = await TestProcess.start( + sdkLayout.dartPath, ['pub', 'upgrade'], + workingDirectory: exampleDirectory, environment: getPubEnvironment()); + + await process.shouldExit(0); + return exampleDirectory; + } } Future checkProcessStdout(TestProcess process, List items) async {