diff --git a/pkgs/test/test/utils.dart b/pkgs/test/test/utils.dart index 23d5b7e14..229167150 100644 --- a/pkgs/test/test/utils.dart +++ b/pkgs/test/test/utils.dart @@ -157,6 +157,7 @@ SuiteConfiguration suiteConfiguration( Map? tags, Map? onPlatform, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Test-level configuration Timeout? timeout, @@ -179,6 +180,7 @@ SuiteConfiguration suiteConfiguration( tags: tags, onPlatform: onPlatform, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, timeout: timeout, verboseTrace: verboseTrace, chainStackTraces: chainStackTraces, @@ -212,6 +214,7 @@ Configuration configuration( Map? defineRuntimes, bool? noRetry, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Suite-level configuration bool? allowDuplicateTestNames, @@ -262,6 +265,7 @@ Configuration configuration( defineRuntimes: defineRuntimes, noRetry: noRetry, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, allowDuplicateTestNames: allowDuplicateTestNames, allowTestRandomization: allowTestRandomization, jsTrace: jsTrace, diff --git a/pkgs/test_core/lib/src/runner/configuration.dart b/pkgs/test_core/lib/src/runner/configuration.dart index 8ba4aa810..b69ddacd4 100644 --- a/pkgs/test_core/lib/src/runner/configuration.dart +++ b/pkgs/test_core/lib/src/runner/configuration.dart @@ -287,6 +287,7 @@ class Configuration { required Map? tags, required Map? onPlatform, required bool? ignoreTimeouts, + required Timeout? suiteLoadTimeout, // Test-level configuration required Timeout? timeout, @@ -338,6 +339,7 @@ class Configuration { tags: tags, onPlatform: onPlatform, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, // Test-level configuration timeout: timeout, @@ -396,6 +398,7 @@ class Configuration { Map? tags, Map? onPlatform, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Test-level configuration Timeout? timeout, @@ -445,6 +448,7 @@ class Configuration { tags: tags, onPlatform: onPlatform, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, timeout: timeout, verboseTrace: verboseTrace, chainStackTraces: chainStackTraces, @@ -498,6 +502,7 @@ class Configuration { testRandomizeOrderingSeed: null, stopOnFirstFailure: null, ignoreTimeouts: null, + suiteLoadTimeout: null, allowDuplicateTestNames: null, allowTestRandomization: null, runSkipped: null, @@ -576,6 +581,7 @@ class Configuration { tags: null, onPlatform: null, ignoreTimeouts: null, + suiteLoadTimeout: null, timeout: null, verboseTrace: null, chainStackTraces: null, @@ -639,6 +645,7 @@ class Configuration { tags: null, onPlatform: null, ignoreTimeouts: null, + suiteLoadTimeout: null, timeout: null, verboseTrace: null, chainStackTraces: null, @@ -700,6 +707,7 @@ class Configuration { tags: null, onPlatform: null, ignoreTimeouts: null, + suiteLoadTimeout: null, timeout: null, verboseTrace: null, chainStackTraces: null, @@ -983,6 +991,7 @@ class Configuration { bool? noRetry, int? testRandomizeOrderingSeed, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Suite-level configuration bool? allowDuplicateTestNames, @@ -1051,6 +1060,7 @@ class Configuration { testOn: testOn, addTags: addTags, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, )); return config._resolvePresets(); } diff --git a/pkgs/test_core/lib/src/runner/configuration/args.dart b/pkgs/test_core/lib/src/runner/configuration/args.dart index e981bedc3..a961a089f 100644 --- a/pkgs/test_core/lib/src/runner/configuration/args.dart +++ b/pkgs/test_core/lib/src/runner/configuration/args.dart @@ -100,6 +100,10 @@ final ArgParser _parser = (() { parser.addOption('timeout', help: 'The default test timeout. For example: 15s, 2x, none', defaultsTo: '30s'); + parser.addOption('suite-load-timeout', + help: 'The timeout for loading a test suite. Loading the test suite ' + 'includes compiling the test suite. For example: 15s, 2x, none', + defaultsTo: '12m'); parser.addFlag('ignore-timeouts', help: 'Ignore all timeouts (useful if debugging)', negatable: false); parser.addFlag('pause-after-load', @@ -333,6 +337,7 @@ class _Parser { shardIndex: shardIndex, totalShards: totalShards, timeout: _parseOption('timeout', Timeout.parse), + suiteLoadTimeout: _parseOption('suite-load-timeout', Timeout.parse), globalPatterns: patterns, compilerSelections: compilerSelections, runtimes: runtimes, diff --git a/pkgs/test_core/lib/src/runner/load_suite.dart b/pkgs/test_core/lib/src/runner/load_suite.dart index 633739afc..ec795a4e1 100644 --- a/pkgs/test_core/lib/src/runner/load_suite.dart +++ b/pkgs/test_core/lib/src/runner/load_suite.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:stack_trace/stack_trace.dart'; -import 'package:test_api/scaffolding.dart' show Timeout; import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports @@ -20,14 +19,6 @@ import 'plugin/environment.dart'; import 'runner_suite.dart'; import 'suite.dart'; -/// The timeout for loading a test suite. -/// -/// We want this to be long enough that even a very large application being -/// compiled with dart2js doesn't trigger it, but short enough that it fires -/// before the host kills it. For example, Google's Forge service has a -/// 15-minute timeout. -final _timeout = const Duration(minutes: 12); - /// A [Suite] emitted by a [Loader] that provides a test-like interface for /// loading a test file. /// @@ -150,8 +141,9 @@ class LoadSuite extends Suite implements RunnerSuite { void Function() body, this._suiteAndZone, {required bool ignoreTimeouts, String? path}) : super( - Group.root( - [LocalTest(name, Metadata(timeout: Timeout(_timeout)), body)]), + Group.root([ + LocalTest(name, Metadata(timeout: config.suiteLoadTimeout), body) + ]), platform, path: path, ignoreTimeouts: ignoreTimeouts); diff --git a/pkgs/test_core/lib/src/runner/suite.dart b/pkgs/test_core/lib/src/runner/suite.dart index b5ee0bea5..7d96db7be 100644 --- a/pkgs/test_core/lib/src/runner/suite.dart +++ b/pkgs/test_core/lib/src/runner/suite.dart @@ -57,7 +57,8 @@ final class SuiteConfiguration { tags: null, onPlatform: null, metadata: null, - ignoreTimeouts: null); + ignoreTimeouts: null, + suiteLoadTimeout: null); /// Whether or not duplicate test (or group) names are allowed within the same /// test suite. @@ -149,6 +150,11 @@ final class SuiteConfiguration { final bool? _ignoreTimeouts; bool get ignoreTimeouts => _ignoreTimeouts ?? false; + /// The timeout for loading a test suite. + final Timeout? _suiteLoadTimeout; + Timeout get suiteLoadTimeout => + _suiteLoadTimeout ?? const Timeout(Duration(minutes: 12)); + factory SuiteConfiguration( {required bool? allowDuplicateTestNames, required bool? allowTestRandomization, @@ -161,7 +167,7 @@ final class SuiteConfiguration { required Map? tags, required Map? onPlatform, required bool? ignoreTimeouts, - + required Timeout? suiteLoadTimeout, // Test-level configuration required Timeout? timeout, required bool? verboseTrace, @@ -184,6 +190,7 @@ final class SuiteConfiguration { tags: tags, onPlatform: onPlatform, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, metadata: Metadata( timeout: timeout, verboseTrace: verboseTrace, @@ -212,6 +219,7 @@ final class SuiteConfiguration { Map? tags, Map? onPlatform, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Test-level configuration Timeout? timeout, @@ -234,6 +242,7 @@ final class SuiteConfiguration { tags: tags, onPlatform: onPlatform, ignoreTimeouts: ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, timeout: timeout, verboseTrace: verboseTrace, chainStackTraces: chainStackTraces, @@ -273,6 +282,7 @@ final class SuiteConfiguration { required Map? onPlatform, required Metadata? metadata, required bool? ignoreTimeouts, + required Timeout? suiteLoadTimeout, }) : _allowDuplicateTestNames = allowDuplicateTestNames, _allowTestRandomization = allowTestRandomization, _jsTrace = jsTrace, @@ -283,6 +293,7 @@ final class SuiteConfiguration { tags = _map(tags), onPlatform = _map(onPlatform), _ignoreTimeouts = ignoreTimeouts, + _suiteLoadTimeout = suiteLoadTimeout, _metadata = metadata ?? Metadata.empty; /// Creates a new [SuiteConfiguration] that takes its configuration from @@ -304,6 +315,7 @@ final class SuiteConfiguration { runtimes: null, compilerSelections: null, ignoreTimeouts: null, + suiteLoadTimeout: null, ); /// Returns an unmodifiable copy of [input]. @@ -348,7 +360,8 @@ final class SuiteConfiguration { tags: _mergeConfigMaps(tags, other.tags), onPlatform: _mergeConfigMaps(onPlatform, other.onPlatform), ignoreTimeouts: other._ignoreTimeouts ?? _ignoreTimeouts, - metadata: metadata.merge(other.metadata)); + metadata: metadata.merge(other.metadata), + suiteLoadTimeout: other._suiteLoadTimeout ?? _suiteLoadTimeout); return config._resolveTags(); } @@ -368,6 +381,7 @@ final class SuiteConfiguration { Map? tags, Map? onPlatform, bool? ignoreTimeouts, + Timeout? suiteLoadTimeout, // Test-level configuration Timeout? timeout, @@ -393,6 +407,7 @@ final class SuiteConfiguration { tags: tags ?? this.tags, onPlatform: onPlatform ?? this.onPlatform, ignoreTimeouts: ignoreTimeouts ?? _ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout ?? _suiteLoadTimeout, metadata: _metadata.change( timeout: timeout, verboseTrace: verboseTrace, @@ -428,6 +443,7 @@ final class SuiteConfiguration { tags: tags, onPlatform: onPlatform, ignoreTimeouts: _ignoreTimeouts, + suiteLoadTimeout: suiteLoadTimeout, metadata: _metadata); }