|
| 1 | +import 'dart:io'; |
| 2 | + |
| 3 | +import 'package:path/path.dart' as p; |
| 4 | + |
| 5 | +/// Runs `all_tests.dart` as a single AOT-compiled executable with sanitizers |
| 6 | +/// enabled. |
| 7 | +/// |
| 8 | +/// To run tests with a sanitizer, use `dart tool/run_tests.dart |
| 9 | +/// --sanitizer $sanitizer`, where `$sanitizer` is either `asan` or `msan`. |
| 10 | +/// Note that sanitizers are only supported on X64 Linux hosts. |
| 11 | +/// |
| 12 | +/// Running tests with sanitizers also requires an instrumented build of SQLite |
| 13 | +/// and the core extension, which can be built with |
| 14 | +/// `tool/build_linux_sanitized.sh`. |
| 15 | +void main(List<String> args) async { |
| 16 | + Never invalidArgs() { |
| 17 | + print('Usage: dart tool/run_tests.dart asan|msan'); |
| 18 | + exit(1); |
| 19 | + } |
| 20 | + |
| 21 | + if (args.length != 1) { |
| 22 | + invalidArgs(); |
| 23 | + } |
| 24 | + |
| 25 | + final sanitizer = args.single; |
| 26 | + if (sanitizer != 'asan' && sanitizer != 'msan') invalidArgs(); |
| 27 | + final expandedName = switch (sanitizer) { |
| 28 | + 'asan' => 'address', |
| 29 | + 'msan' => 'memory', |
| 30 | + _ => throw AssertionError(), |
| 31 | + }; |
| 32 | + |
| 33 | + final dir = await Directory.systemTemp.createTemp('core-extension-tests'); |
| 34 | + final aotPath = p.join(dir.path, 'test.aot'); |
| 35 | + final assetsConfig = await _createNativeAssetsConfig(dir, expandedName); |
| 36 | + |
| 37 | + try { |
| 38 | + print('AOT-compiling tests'); |
| 39 | + final result = await Process.run(Platform.executable, [ |
| 40 | + 'compile', |
| 41 | + 'aot-snapshot', |
| 42 | + 'tool/all_tests.dart', |
| 43 | + '--output', |
| 44 | + aotPath, |
| 45 | + '--target-sanitizer=$sanitizer', |
| 46 | + '--extra-gen-kernel-options=--native-assets=${assetsConfig.path}', |
| 47 | + ]); |
| 48 | + |
| 49 | + if (result.exitCode != 0 || !await File(aotPath).exists()) { |
| 50 | + throw ''' |
| 51 | +could not compile test script |
| 52 | +
|
| 53 | +exitCode: ${result.exitCode} |
| 54 | +stdout: ${result.stdout} |
| 55 | +stderr: ${result.stderr} |
| 56 | +'''; |
| 57 | + } |
| 58 | + |
| 59 | + var runtimeName = 'dartaotruntime_$sanitizer'; |
| 60 | + |
| 61 | + print('Running with $runtimeName'); |
| 62 | + final runtime = p.join(p.dirname(Platform.resolvedExecutable), runtimeName); |
| 63 | + final process = await Process.start( |
| 64 | + runtime, |
| 65 | + [ |
| 66 | + aotPath, |
| 67 | + expandedName, |
| 68 | + ], |
| 69 | + mode: ProcessStartMode.inheritStdio); |
| 70 | + final exit = await process.exitCode; |
| 71 | + if (exit != 0) { |
| 72 | + throw 'Expected exit code 0, got $exit'; |
| 73 | + } |
| 74 | + } finally { |
| 75 | + await dir.delete(recursive: true); |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +Future<File> _createNativeAssetsConfig( |
| 80 | + Directory tmpForRun, |
| 81 | + String? expandedName, |
| 82 | +) async { |
| 83 | + final sqliteFile = p.normalize( |
| 84 | + p.absolute('../sanitized/sqlite', 'libsqlite3_$expandedName.so'), |
| 85 | + ); |
| 86 | + |
| 87 | + final yaml = ''' |
| 88 | +format-version: [1, 0, 0] |
| 89 | +native-assets: |
| 90 | + linux_x64: |
| 91 | + "package:sqlite3/src/ffi/libsqlite3.g.dart": |
| 92 | + - absolute |
| 93 | + - "$sqliteFile" |
| 94 | +'''; |
| 95 | + |
| 96 | + final file = File(p.join(tmpForRun.path, 'assets.yaml')); |
| 97 | + await file.writeAsString(yaml); |
| 98 | + return file; |
| 99 | +} |
0 commit comments