| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.runner.browser.server; | 5 library test.runner.browser.server; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 | 10 |
| 11 import 'package:async/async.dart'; |
| 11 import 'package:http_multi_server/http_multi_server.dart'; | 12 import 'package:http_multi_server/http_multi_server.dart'; |
| 12 import 'package:path/path.dart' as p; | 13 import 'package:path/path.dart' as p; |
| 13 import 'package:pool/pool.dart'; | 14 import 'package:pool/pool.dart'; |
| 14 import 'package:shelf/shelf.dart' as shelf; | 15 import 'package:shelf/shelf.dart' as shelf; |
| 15 import 'package:shelf/shelf_io.dart' as shelf_io; | 16 import 'package:shelf/shelf_io.dart' as shelf_io; |
| 16 import 'package:shelf_static/shelf_static.dart'; | 17 import 'package:shelf_static/shelf_static.dart'; |
| 17 import 'package:shelf_web_socket/shelf_web_socket.dart'; | 18 import 'package:shelf_web_socket/shelf_web_socket.dart'; |
| 18 | 19 |
| 19 import '../../backend/metadata.dart'; | 20 import '../../backend/metadata.dart'; |
| 20 import '../../backend/suite.dart'; | 21 import '../../backend/suite.dart'; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 | 128 |
| 128 /// The thunk for running [close] exactly once. | 129 /// The thunk for running [close] exactly once. |
| 129 final _closeThunk = new AsyncThunk(); | 130 final _closeThunk = new AsyncThunk(); |
| 130 | 131 |
| 131 /// All currently-running browsers. | 132 /// All currently-running browsers. |
| 132 /// | 133 /// |
| 133 /// These are controlled by [_browserManager]s. | 134 /// These are controlled by [_browserManager]s. |
| 134 final _browsers = new Map<TestPlatform, Browser>(); | 135 final _browsers = new Map<TestPlatform, Browser>(); |
| 135 | 136 |
| 136 /// A map from browser identifiers to futures that will complete to the | 137 /// A map from browser identifiers to futures that will complete to the |
| 137 /// [BrowserManager]s for those browsers. | 138 /// [BrowserManager]s for those browsers, or the errors that occurred when |
| 139 /// trying to load those managers. |
| 138 /// | 140 /// |
| 139 /// This should only be accessed through [_browserManagerFor]. | 141 /// This should only be accessed through [_browserManagerFor]. |
| 140 final _browserManagers = new Map<TestPlatform, Future<BrowserManager>>(); | 142 final _browserManagers = |
| 143 new Map<TestPlatform, Future<Result<BrowserManager>>>(); |
| 141 | 144 |
| 142 /// A map from test suite paths to Futures that will complete once those | 145 /// A map from test suite paths to Futures that will complete once those |
| 143 /// suites are finished compiling. | 146 /// suites are finished compiling. |
| 144 /// | 147 /// |
| 145 /// This is used to make sure that a given test suite is only compiled once | 148 /// This is used to make sure that a given test suite is only compiled once |
| 146 /// per run, rather than once per browser per run. | 149 /// per run, rather than once per browser per run. |
| 147 final _compileFutures = new Map<String, Future>(); | 150 final _compileFutures = new Map<String, Future>(); |
| 148 | 151 |
| 149 final _mappers = new Map<String, StackTraceMapper>(); | 152 final _mappers = new Map<String, StackTraceMapper>(); |
| 150 | 153 |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 packageRoot: p.toUri(_packageRoot), | 404 packageRoot: p.toUri(_packageRoot), |
| 402 sdkRoot: p.toUri(sdkDir)); | 405 sdkRoot: p.toUri(sdkDir)); |
| 403 }); | 406 }); |
| 404 } | 407 } |
| 405 | 408 |
| 406 /// Returns the [BrowserManager] for [platform], which should be a browser. | 409 /// Returns the [BrowserManager] for [platform], which should be a browser. |
| 407 /// | 410 /// |
| 408 /// If no browser manager is running yet, starts one. | 411 /// If no browser manager is running yet, starts one. |
| 409 Future<BrowserManager> _browserManagerFor(TestPlatform platform) { | 412 Future<BrowserManager> _browserManagerFor(TestPlatform platform) { |
| 410 var manager = _browserManagers[platform]; | 413 var manager = _browserManagers[platform]; |
| 411 if (manager != null) return manager; | 414 if (manager != null) return Result.release(manager); |
| 412 | 415 |
| 413 var completer = new Completer(); | 416 var completer = new Completer(); |
| 414 | 417 |
| 415 // Swallow errors, since they're already being surfaced through the return | 418 // Capture errors and release them later to avoid Zone issues. This call to |
| 416 // value and [browser.onError]. | 419 // [_browserManagerFor] is running in a different [LoadSuite] than future |
| 417 _browserManagers[platform] = completer.future.catchError((_) {}); | 420 // calls, which means they're also running in different error zones so |
| 421 // errors can't be freely passed between them. Storing the error or value as |
| 422 // an explicit [Result] fixes that. |
| 423 _browserManagers[platform] = Result.capture(completer.future); |
| 418 var path = _webSocketHandler.create(webSocketHandler((webSocket) { | 424 var path = _webSocketHandler.create(webSocketHandler((webSocket) { |
| 419 completer.complete(new BrowserManager(platform, webSocket)); | 425 completer.complete(new BrowserManager(platform, webSocket)); |
| 420 })); | 426 })); |
| 421 | 427 |
| 422 var webSocketUrl = url.replace(scheme: 'ws').resolve(path); | 428 var webSocketUrl = url.replace(scheme: 'ws').resolve(path); |
| 423 | 429 |
| 424 var hostUrl = (_pubServeUrl == null ? url : _pubServeUrl) | 430 var hostUrl = (_pubServeUrl == null ? url : _pubServeUrl) |
| 425 .resolve('packages/test/src/runner/browser/static/index.html'); | 431 .resolve('packages/test/src/runner/browser/static/index.html'); |
| 426 | 432 |
| 427 var browser = _newBrowser(hostUrl.replace(queryParameters: { | 433 var browser = _newBrowser(hostUrl.replace(queryParameters: { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 await Future.wait(futures); | 481 await Future.wait(futures); |
| 476 | 482 |
| 477 if (_pubServeUrl == null) { | 483 if (_pubServeUrl == null) { |
| 478 new Directory(_compiledDir).deleteSync(recursive: true); | 484 new Directory(_compiledDir).deleteSync(recursive: true); |
| 479 } else { | 485 } else { |
| 480 _http.close(); | 486 _http.close(); |
| 481 } | 487 } |
| 482 }); | 488 }); |
| 483 } | 489 } |
| 484 } | 490 } |
| OLD | NEW |