| // Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | import 'dart:convert'; | 
 | import 'dart:isolate' show Isolate, ReceivePort, SendPort; | 
 |  | 
 | import 'package:testing/src/log.dart' show Logger; | 
 | import 'package:testing/src/suite.dart'; | 
 | import 'package:testing/testing.dart' as testing; | 
 |  | 
 | import 'presubmit_helper.dart'; | 
 | import 'test/deps_git_test.dart' as deps_test; | 
 | import 'test/compile_and_lint_impl.dart' show runCompileAndLintTest; | 
 | import 'test/messages_suite.dart' as messages_suite; | 
 | import 'test/lint_suite.dart' as lint_suite; | 
 | import 'test/spelling_test_not_src_suite.dart' as spelling_test_not_src; | 
 | import 'test/spelling_test_src_suite.dart' as spelling_test_src; | 
 |  | 
 | Future<void> main(List<String> args, [SendPort? sendPort]) async { | 
 |   if (sendPort == null) throw "Need a send-port."; | 
 |   var isolateReceivePort = ReceivePort(); | 
 |   isolateReceivePort.listen((rawData) async { | 
 |     if (rawData is! String) { | 
 |       print("Got unexpected data of type ${rawData.runtimeType}"); | 
 |       sendPort.send(false); | 
 |       return; | 
 |     } | 
 |     Work work = Work.workFromJson(json.decode(rawData)); | 
 |     Stopwatch stopwatch = new Stopwatch()..start(); | 
 |     switch (work) { | 
 |       case CompileAndLintWork(): | 
 |         int compileAndLintErrorsFound = -1; | 
 |         try { | 
 |           compileAndLintErrorsFound = await Isolate.run(() => | 
 |               runCompileAndLintTest( | 
 |                   includedFiles: work.includedFiles, | 
 |                   includedDirectoryUris: work.includedDirectoryUris, | 
 |                   repoDir: work.repoDir)); | 
 |         } catch (e, st) { | 
 |           // This will make it send false. | 
 |           compileAndLintErrorsFound = -1; | 
 |  | 
 |           StringBuffer sb = new StringBuffer(); | 
 |           sb.writeln("void main() {"); | 
 |           sb.writeln("  runCompileAndLintTest(includedFiles: {"); | 
 |           String comma = ""; | 
 |           for (Uri uri in work.includedFiles) { | 
 |             sb.writeln("    ${comma}Uri.parse('$uri')"); | 
 |             comma = ", "; | 
 |           } | 
 |           sb.writeln("    }, includedDirectoryUris: {"); | 
 |           comma = ""; | 
 |           for (Uri uri in work.includedDirectoryUris) { | 
 |             sb.writeln("    ${comma}Uri.parse('$uri')"); | 
 |             comma = ", "; | 
 |           } | 
 |           sb.writeln("    }, repoDir: Uri.parse('${work.repoDir}'));"); | 
 |           sb.writeln("}"); | 
 |  | 
 |           print(""" | 
 | WARNING: '${work.name}' crashed: | 
 | ============ | 
 | ${e.toString().trim()} | 
 | ============ | 
 | $st | 
 | ============ | 
 |  | 
 | To reproduce open up compile_and_lint_impl.dart and insert | 
 |  | 
 | $sb | 
 |  | 
 | Then run that file through your debugger or similar. | 
 |  | 
 | """); | 
 |           print("Got error for ${work.name}: $e"); | 
 |         } | 
 |         print("Sending ok = ${compileAndLintErrorsFound == 0} " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(compileAndLintErrorsFound == 0); | 
 |  | 
 |       case MessagesWork(): | 
 |         bool ok; | 
 |         try { | 
 |           ok = await Isolate.run(() async { | 
 |             ErrorNotingLogger logger = new ErrorNotingLogger(); | 
 |             await testing.runMe( | 
 |               const ["-DfastOnly=true"], | 
 |               messages_suite.createContext, | 
 |               me: work.repoDir | 
 |                   .resolve("pkg/front_end/test/messages_suite.dart"), | 
 |               configurationPath: "../testing.json", | 
 |               logger: logger, | 
 |             ); | 
 |             return !logger.gotFailure; | 
 |           }); | 
 |         } catch (e) { | 
 |           ok = false; | 
 |         } | 
 |         print("Sending ok = $ok " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(ok); | 
 |       case SpellNotSourceWork(): | 
 |         bool ok; | 
 |         try { | 
 |           ok = await Isolate.run(() async { | 
 |             ErrorNotingLogger logger = new ErrorNotingLogger(); | 
 |             await testing.runMe( | 
 |               ["--", ...work.filters], | 
 |               spelling_test_not_src.createContext, | 
 |               me: work.repoDir.resolve( | 
 |                   "pkg/front_end/test/spelling_test_not_src_suite.dart"), | 
 |               configurationPath: "../testing.json", | 
 |               logger: logger, | 
 |             ); | 
 |             return !logger.gotFailure; | 
 |           }); | 
 |         } catch (e) { | 
 |           ok = false; | 
 |         } | 
 |         print("Sending ok = $ok " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(ok); | 
 |       case SpellSourceWork(): | 
 |         bool ok; | 
 |         try { | 
 |           ok = await Isolate.run(() async { | 
 |             ErrorNotingLogger logger = new ErrorNotingLogger(); | 
 |             await testing.runMe( | 
 |               ["--", ...work.filters], | 
 |               spelling_test_src.createContext, | 
 |               me: work.repoDir | 
 |                   .resolve("pkg/front_end/test/spelling_test_src_suite.dart"), | 
 |               configurationPath: "../testing.json", | 
 |               logger: logger, | 
 |             ); | 
 |             return !logger.gotFailure; | 
 |           }); | 
 |         } catch (e) { | 
 |           ok = false; | 
 |         } | 
 |         print("Sending ok = $ok " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(ok); | 
 |       case LintWork(): | 
 |         bool ok; | 
 |         try { | 
 |           ok = await Isolate.run(() async { | 
 |             ErrorNotingLogger logger = new ErrorNotingLogger(); | 
 |             await testing.runMe( | 
 |               ["--", ...work.filters], | 
 |               lint_suite.createContext, | 
 |               me: work.repoDir.resolve("pkg/front_end/test/lint_suite.dart"), | 
 |               configurationPath: "../testing.json", | 
 |               logger: logger, | 
 |             ); | 
 |             return !logger.gotFailure; | 
 |           }); | 
 |         } catch (e) { | 
 |           ok = false; | 
 |         } | 
 |         print("Sending ok = $ok " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(ok); | 
 |       case DepsTestWork(): | 
 |         bool ok; | 
 |         try { | 
 |           ok = await Isolate.run(() { | 
 |             return deps_test.main(); | 
 |           }); | 
 |         } catch (e) { | 
 |           ok = false; | 
 |         } | 
 |         print("Sending ok = $ok " | 
 |             "for ${work.name} after ${stopwatch.elapsed}"); | 
 |         sendPort.send(ok); | 
 |     } | 
 |   }); | 
 |   sendPort.send(isolateReceivePort.sendPort); | 
 | } | 
 |  | 
 | class ErrorNotingLogger implements Logger { | 
 |   bool gotFailure = false; | 
 |  | 
 |   @override | 
 |   void logExpectedResult(Suite suite, testing.TestDescription description, | 
 |       testing.Result result, Set<testing.Expectation> expectedOutcomes) {} | 
 |  | 
 |   @override | 
 |   void logMessage(Object message) {} | 
 |  | 
 |   @override | 
 |   void logNumberedLines(String text) {} | 
 |  | 
 |   @override | 
 |   void logProgress(String message) {} | 
 |  | 
 |   @override | 
 |   void logStepComplete( | 
 |       int completed, | 
 |       int failed, | 
 |       int total, | 
 |       Suite suite, | 
 |       testing.TestDescription description, | 
 |       testing.Step<dynamic, dynamic, testing.ChainContext> step) {} | 
 |  | 
 |   @override | 
 |   void logStepStart( | 
 |       int completed, | 
 |       int failed, | 
 |       int total, | 
 |       Suite suite, | 
 |       testing.TestDescription description, | 
 |       testing.Step<dynamic, dynamic, testing.ChainContext> step) {} | 
 |  | 
 |   @override | 
 |   void logSuiteComplete(Suite suite) {} | 
 |  | 
 |   @override | 
 |   void logSuiteStarted(Suite suite) {} | 
 |  | 
 |   @override | 
 |   void logTestComplete(int completed, int failed, int total, Suite suite, | 
 |       testing.TestDescription description) {} | 
 |  | 
 |   @override | 
 |   void logTestStart(int completed, int failed, int total, Suite suite, | 
 |       testing.TestDescription description) {} | 
 |  | 
 |   @override | 
 |   void logUncaughtError(error, StackTrace stackTrace) { | 
 |     print("Uncaught Error: $error\n$stackTrace"); | 
 |     gotFailure = true; | 
 |   } | 
 |  | 
 |   // package:testing logs the result twice: As it happens and at the end. | 
 |   // I don't want that so for now I'll maintain a set of already reported | 
 |   // test results. | 
 |   Set<testing.Result> alreadyReportedResults = {}; | 
 |  | 
 |   @override | 
 |   void logUnexpectedResult(Suite suite, testing.TestDescription description, | 
 |       testing.Result result, Set<testing.Expectation> expectedOutcomes) { | 
 |     if (!alreadyReportedResults.add(result)) return; | 
 |  | 
 |     String log = result.log; | 
 |     if (log.isNotEmpty) { | 
 |       print(log); | 
 |     } | 
 |     if (result.error != null) { | 
 |       print(result.error); | 
 |       if (result.trace != null) { | 
 |         print(result.trace); | 
 |       } | 
 |     } | 
 |  | 
 |     gotFailure = true; | 
 |   } | 
 |  | 
 |   @override | 
 |   void noticeFrameworkCatchError(error, StackTrace stackTrace) { | 
 |     print("Framework Catch Error: $error\n$stackTrace"); | 
 |     gotFailure = true; | 
 |   } | 
 | } |