| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 // TODO(ahe): Copied from closure_conversion branch of kernel, remove this file | 5 // TODO(ahe): Copied from closure_conversion branch of kernel, remove this file |
| 6 // when closure_conversion is merged with master. | 6 // when closure_conversion is merged with master. |
| 7 | 7 |
| 8 library kernel.testing.kernel_chain; | 8 library fasta.testing.kernel_chain; |
| 9 | 9 |
| 10 import 'dart:async' show Future; | 10 import 'dart:async' show Future; |
| 11 | 11 |
| 12 import 'dart:io' show Directory, File, IOSink, Platform; | 12 import 'dart:io' show Directory, File, IOSink; |
| 13 | 13 |
| 14 import 'dart:typed_data' show Uint8List; | 14 import 'dart:typed_data' show Uint8List; |
| 15 | 15 |
| 16 import 'package:kernel/kernel.dart' show loadProgramFromBinary; | 16 import 'package:kernel/kernel.dart' show loadProgramFromBinary; |
| 17 | 17 |
| 18 import 'package:kernel/text/ast_to_text.dart' show Printer; | 18 import 'package:kernel/text/ast_to_text.dart' show Printer; |
| 19 | 19 |
| 20 import 'package:testing/testing.dart' show Result, StdioProcess, Step; | 20 import 'package:testing/testing.dart' show Result, StdioProcess, Step; |
| 21 | 21 |
| 22 import 'package:kernel/ast.dart' show Library, Program; | 22 import 'package:kernel/ast.dart' show Library, Program; |
| 23 | 23 |
| 24 import '../kernel/verifier.dart' show verifyProgram; | 24 import '../kernel/verifier.dart' show verifyProgram; |
| 25 | 25 |
| 26 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter; | 26 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter; |
| 27 | 27 |
| 28 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder; | 28 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder; |
| 29 | 29 |
| 30 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; | |
| 31 | |
| 32 import 'package:analyzer/src/kernel/loader.dart' | |
| 33 show DartLoader, DartOptions, createDartSdk; | |
| 34 | |
| 35 import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget; | |
| 36 | |
| 37 import 'package:testing/testing.dart' | 30 import 'package:testing/testing.dart' |
| 38 show Chain, ChainContext, Result, StdioProcess, Step, TestDescription; | 31 show ChainContext, Result, StdioProcess, Step; |
| 39 | 32 |
| 40 import 'package:kernel/ast.dart' show Program; | 33 import 'package:kernel/ast.dart' show Program; |
| 41 | 34 |
| 42 import 'package:package_config/discovery.dart' show loadPackagesFile; | 35 class Print extends Step<Program, Program, ChainContext> { |
| 43 | |
| 44 import '../environment_variable.dart' show EnvironmentVariable; | |
| 45 | |
| 46 const String STRONG_MODE = " strong mode "; | |
| 47 | |
| 48 typedef Future<TestContext> TestContextConstructor( | |
| 49 Chain suite, | |
| 50 Map<String, String> environment, | |
| 51 Uri sdk, | |
| 52 Uri vm, | |
| 53 Uri packages, | |
| 54 bool strongMode, | |
| 55 DartSdk dartSdk, | |
| 56 bool updateExpectations); | |
| 57 | |
| 58 Future<bool> fileExists(Uri base, String path) async { | |
| 59 return await new File.fromUri(base.resolve(path)).exists(); | |
| 60 } | |
| 61 | |
| 62 final EnvironmentVariable testConfigVariable = new EnvironmentVariable( | |
| 63 "DART_CONFIGURATION", | |
| 64 "It should be something like 'ReleaseX64', depending on which" | |
| 65 " configuration you're testing."); | |
| 66 | |
| 67 Future<Uri> computePatchedSdk() async { | |
| 68 String config = await testConfigVariable.value; | |
| 69 String path; | |
| 70 switch (Platform.operatingSystem) { | |
| 71 case "linux": | |
| 72 path = "out/$config/patched_sdk"; | |
| 73 break; | |
| 74 | |
| 75 case "macos": | |
| 76 path = "xcodebuild/$config/patched_sdk"; | |
| 77 break; | |
| 78 | |
| 79 case "windows": | |
| 80 path = "build/$config/patched_sdk"; | |
| 81 break; | |
| 82 | |
| 83 default: | |
| 84 throw "Unsupported operating system: '${Platform.operatingSystem}'."; | |
| 85 } | |
| 86 Uri sdk = Uri.base.resolve("$path/"); | |
| 87 const String asyncDart = "lib/async/async.dart"; | |
| 88 if (!await fileExists(sdk, asyncDart)) { | |
| 89 throw "Couldn't find '$asyncDart' in '$sdk'."; | |
| 90 } | |
| 91 const String asyncSources = "lib/async/async_sources.gypi"; | |
| 92 if (await fileExists(sdk, asyncSources)) { | |
| 93 throw "Found '$asyncSources' in '$sdk', so it isn't a patched SDK."; | |
| 94 } | |
| 95 return sdk; | |
| 96 } | |
| 97 | |
| 98 Uri computeDartVm(Uri patchedSdk) { | |
| 99 return patchedSdk.resolve(Platform.isWindows ? "../dart.exe" : "../dart"); | |
| 100 } | |
| 101 | |
| 102 abstract class TestContext extends ChainContext { | |
| 103 final Uri vm; | |
| 104 | |
| 105 final Uri packages; | |
| 106 | |
| 107 final DartOptions options; | |
| 108 | |
| 109 final DartSdk dartSdk; | |
| 110 | |
| 111 TestContext(Uri sdk, this.vm, Uri packages, bool strongMode, this.dartSdk) | |
| 112 : packages = packages, | |
| 113 options = new DartOptions( | |
| 114 strongMode: strongMode, | |
| 115 sdk: sdk.toFilePath(), | |
| 116 packagePath: packages.toFilePath()); | |
| 117 | |
| 118 Future<DartLoader> createLoader() async { | |
| 119 Program program = new Program(); | |
| 120 return new DartLoader(program, options, await loadPackagesFile(packages), | |
| 121 ignoreRedirectingFactories: false, dartSdk: dartSdk); | |
| 122 } | |
| 123 | |
| 124 static Future<TestContext> create( | |
| 125 Chain suite, | |
| 126 Map<String, String> environment, | |
| 127 TestContextConstructor constructor) async { | |
| 128 Uri sdk = await computePatchedSdk(); | |
| 129 Uri vm = computeDartVm(sdk); | |
| 130 Uri packages = Uri.base.resolve(".packages"); | |
| 131 bool strongMode = environment.containsKey(STRONG_MODE); | |
| 132 bool updateExpectations = environment["updateExpectations"] == "true"; | |
| 133 return constructor( | |
| 134 suite, | |
| 135 environment, | |
| 136 sdk, | |
| 137 vm, | |
| 138 packages, | |
| 139 strongMode, | |
| 140 createDartSdk(sdk.toFilePath(), strongMode: strongMode), | |
| 141 updateExpectations); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 class Kernel extends Step<TestDescription, Program, TestContext> { | |
| 146 const Kernel(); | |
| 147 | |
| 148 String get name => "kernel"; | |
| 149 | |
| 150 Future<Result<Program>> run( | |
| 151 TestDescription description, TestContext testContext) async { | |
| 152 try { | |
| 153 DartLoader loader = await testContext.createLoader(); | |
| 154 Target target = getTarget( | |
| 155 "vm", new TargetFlags(strongMode: testContext.options.strongMode)); | |
| 156 loader.loadProgram(description.uri, target: target); | |
| 157 Program program = loader.program; | |
| 158 for (var error in loader.errors) { | |
| 159 return fail(program, "$error"); | |
| 160 } | |
| 161 target.performModularTransformations(program); | |
| 162 target.performGlobalTransformations(program); | |
| 163 return pass(program); | |
| 164 } catch (e, s) { | |
| 165 return crash(e, s); | |
| 166 } | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 class Print extends Step<Program, Program, TestContext> { | |
| 171 const Print(); | 36 const Print(); |
| 172 | 37 |
| 173 String get name => "print"; | 38 String get name => "print"; |
| 174 | 39 |
| 175 Future<Result<Program>> run(Program program, _) async { | 40 Future<Result<Program>> run(Program program, _) async { |
| 176 StringBuffer sb = new StringBuffer(); | 41 StringBuffer sb = new StringBuffer(); |
| 177 for (Library library in program.libraries) { | 42 for (Library library in program.libraries) { |
| 178 Printer printer = new Printer(sb); | 43 Printer printer = new Printer(sb); |
| 179 if (library.importUri.scheme != "dart" && | 44 if (library.importUri.scheme != "dart" && |
| 180 library.importUri.scheme != "package") { | 45 library.importUri.scheme != "package") { |
| 181 printer.writeLibraryFile(library); | 46 printer.writeLibraryFile(library); |
| 182 } | 47 } |
| 183 } | 48 } |
| 184 print("$sb"); | 49 print("$sb"); |
| 185 return pass(program); | 50 return pass(program); |
| 186 } | 51 } |
| 187 } | 52 } |
| 188 | 53 |
| 189 class Verify extends Step<Program, Program, TestContext> { | 54 class Verify extends Step<Program, Program, ChainContext> { |
| 190 final bool fullCompile; | 55 final bool fullCompile; |
| 191 | 56 |
| 192 const Verify(this.fullCompile); | 57 const Verify(this.fullCompile); |
| 193 | 58 |
| 194 String get name => "verify"; | 59 String get name => "verify"; |
| 195 | 60 |
| 196 Future<Result<Program>> run(Program program, TestContext testContext) async { | 61 Future<Result<Program>> run(Program program, ChainContext context) async { |
| 197 var errors = verifyProgram(program, isOutline: !fullCompile); | 62 var errors = verifyProgram(program, isOutline: !fullCompile); |
| 198 if (errors.isEmpty) { | 63 if (errors.isEmpty) { |
| 199 return pass(program); | 64 return pass(program); |
| 200 } else { | 65 } else { |
| 201 return new Result<Program>( | 66 return new Result<Program>( |
| 202 null, testContext.expectationSet["VerificationError"], errors, null); | 67 null, context.expectationSet["VerificationError"], errors, null); |
| 203 } | 68 } |
| 204 } | 69 } |
| 205 } | 70 } |
| 206 | 71 |
| 207 class MatchExpectation extends Step<Program, Program, TestContext> { | 72 class MatchExpectation extends Step<Program, Program, ChainContext> { |
| 208 final String suffix; | 73 final String suffix; |
| 209 | 74 |
| 210 // TODO(ahe): This is true by default which doesn't match well with the class | 75 // TODO(ahe): This is true by default which doesn't match well with the class |
| 211 // name. | 76 // name. |
| 212 final bool updateExpectations; | 77 final bool updateExpectations; |
| 213 | 78 |
| 214 const MatchExpectation(this.suffix, {this.updateExpectations: false}); | 79 const MatchExpectation(this.suffix, {this.updateExpectations: false}); |
| 215 | 80 |
| 216 String get name => "match expectations"; | 81 String get name => "match expectations"; |
| 217 | 82 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 242 } else { | 107 } else { |
| 243 return fail( | 108 return fail( |
| 244 program, | 109 program, |
| 245 """ | 110 """ |
| 246 Please create file ${expectedFile.path} with this content: | 111 Please create file ${expectedFile.path} with this content: |
| 247 $buffer"""); | 112 $buffer"""); |
| 248 } | 113 } |
| 249 } | 114 } |
| 250 } | 115 } |
| 251 | 116 |
| 252 class WriteDill extends Step<Program, Uri, TestContext> { | 117 class WriteDill extends Step<Program, Uri, ChainContext> { |
| 253 const WriteDill(); | 118 const WriteDill(); |
| 254 | 119 |
| 255 String get name => "write .dill"; | 120 String get name => "write .dill"; |
| 256 | 121 |
| 257 Future<Result<Uri>> run(Program program, _) async { | 122 Future<Result<Uri>> run(Program program, _) async { |
| 258 Directory tmp = await Directory.systemTemp.createTemp(); | 123 Directory tmp = await Directory.systemTemp.createTemp(); |
| 259 Uri uri = tmp.uri.resolve("generated.dill"); | 124 Uri uri = tmp.uri.resolve("generated.dill"); |
| 260 File generated = new File.fromUri(uri); | 125 File generated = new File.fromUri(uri); |
| 261 IOSink sink = generated.openWrite(); | 126 IOSink sink = generated.openWrite(); |
| 262 try { | 127 try { |
| 263 try { | 128 try { |
| 264 new BinaryPrinter(sink).writeProgramFile(program); | 129 new BinaryPrinter(sink).writeProgramFile(program); |
| 265 } finally { | 130 } finally { |
| 266 program.unbindCanonicalNames(); | 131 program.unbindCanonicalNames(); |
| 267 } | 132 } |
| 268 } catch (e, s) { | 133 } catch (e, s) { |
| 269 return fail(uri, e, s); | 134 return fail(uri, e, s); |
| 270 } finally { | 135 } finally { |
| 271 print("Wrote `${generated.path}`"); | 136 print("Wrote `${generated.path}`"); |
| 272 await sink.close(); | 137 await sink.close(); |
| 273 } | 138 } |
| 274 return pass(uri); | 139 return pass(uri); |
| 275 } | 140 } |
| 276 } | 141 } |
| 277 | 142 |
| 278 class ReadDill extends Step<Uri, Uri, TestContext> { | 143 class ReadDill extends Step<Uri, Uri, ChainContext> { |
| 279 const ReadDill(); | 144 const ReadDill(); |
| 280 | 145 |
| 281 String get name => "read .dill"; | 146 String get name => "read .dill"; |
| 282 | 147 |
| 283 Future<Result<Uri>> run(Uri uri, _) async { | 148 Future<Result<Uri>> run(Uri uri, _) async { |
| 284 try { | 149 try { |
| 285 loadProgramFromBinary(uri.toFilePath()); | 150 loadProgramFromBinary(uri.toFilePath()); |
| 286 } catch (e, s) { | 151 } catch (e, s) { |
| 287 return fail(uri, e, s); | 152 return fail(uri, e, s); |
| 288 } | 153 } |
| 289 return pass(uri); | 154 return pass(uri); |
| 290 } | 155 } |
| 291 } | 156 } |
| 292 | 157 |
| 293 class Copy extends Step<Program, Program, TestContext> { | 158 class Copy extends Step<Program, Program, ChainContext> { |
| 294 const Copy(); | 159 const Copy(); |
| 295 | 160 |
| 296 String get name => "copy program"; | 161 String get name => "copy program"; |
| 297 | 162 |
| 298 Future<Result<Program>> run(Program program, _) async { | 163 Future<Result<Program>> run(Program program, _) async { |
| 299 BytesCollector sink = new BytesCollector(); | 164 BytesCollector sink = new BytesCollector(); |
| 300 new BinaryPrinter(sink).writeProgramFile(program); | 165 new BinaryPrinter(sink).writeProgramFile(program); |
| 301 program.unbindCanonicalNames(); | 166 program.unbindCanonicalNames(); |
| 302 Uint8List bytes = sink.collect(); | 167 Uint8List bytes = sink.collect(); |
| 303 new BinaryBuilder(bytes).readProgram(program); | 168 new BinaryBuilder(bytes).readProgram(program); |
| 304 return pass(program); | 169 return pass(program); |
| 305 } | 170 } |
| 306 } | 171 } |
| 307 | 172 |
| 308 class Run extends Step<Uri, int, TestContext> { | |
| 309 const Run(); | |
| 310 | |
| 311 String get name => "run"; | |
| 312 | |
| 313 bool get isAsync => true; | |
| 314 | |
| 315 bool get isRuntime => true; | |
| 316 | |
| 317 Future<Result<int>> run(Uri uri, TestContext context) async { | |
| 318 File generated = new File.fromUri(uri); | |
| 319 StdioProcess process; | |
| 320 try { | |
| 321 process = await StdioProcess | |
| 322 .run(context.vm.toFilePath(), [generated.path, "Hello, World!"]); | |
| 323 print(process.output); | |
| 324 } finally { | |
| 325 generated.parent.delete(recursive: true); | |
| 326 } | |
| 327 return process.toResult(); | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 class BytesCollector implements Sink<List<int>> { | 173 class BytesCollector implements Sink<List<int>> { |
| 332 final List<List<int>> lists = <List<int>>[]; | 174 final List<List<int>> lists = <List<int>>[]; |
| 333 | 175 |
| 334 int length = 0; | 176 int length = 0; |
| 335 | 177 |
| 336 void add(List<int> data) { | 178 void add(List<int> data) { |
| 337 lists.add(data); | 179 lists.add(data); |
| 338 length += data.length; | 180 length += data.length; |
| 339 } | 181 } |
| 340 | 182 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 361 | 203 |
| 362 Future openWrite(Uri uri, f(IOSink sink)) async { | 204 Future openWrite(Uri uri, f(IOSink sink)) async { |
| 363 IOSink sink = new File.fromUri(uri).openWrite(); | 205 IOSink sink = new File.fromUri(uri).openWrite(); |
| 364 try { | 206 try { |
| 365 await f(sink); | 207 await f(sink); |
| 366 } finally { | 208 } finally { |
| 367 await sink.close(); | 209 await sink.close(); |
| 368 } | 210 } |
| 369 print("Wrote $uri"); | 211 print("Wrote $uri"); |
| 370 } | 212 } |
| OLD | NEW |