Skip to content

Commit 00f2054

Browse files
committed
Add --repeat flag to test.py, so tests can be run multiple times
Change-Id: I827774a829c1a9d97bd1eb82b9ef52640a1ae6d5 Reviewed-on: https://dart-review.googlesource.com/75521 Reviewed-by: William Hesse <[email protected]> Reviewed-by: Jonas Termansen <[email protected]>
1 parent cf5cdea commit 00f2054

File tree

5 files changed

+203
-70
lines changed

5 files changed

+203
-70
lines changed

tools/testing/dart/command.dart

Lines changed: 141 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,21 @@ class Command {
114114
Uri workingDirectory) {
115115
return new FastaCompilationCommand._(
116116
compilerLocation,
117-
outputFile,
117+
outputFile.toFilePath(),
118118
bootstrapDependencies,
119-
executable,
119+
executable.toFilePath(),
120120
arguments,
121121
environment,
122-
workingDirectory);
122+
workingDirectory?.toFilePath());
123123
}
124124

125125
/// A descriptive name for this command.
126126
final String displayName;
127127

128+
/// When cloning a command object to run it multiple times, we give
129+
/// the different copies distinct values for index.
130+
int index;
131+
128132
/// Number of times this command *can* be retried.
129133
int get maxNumRetries => 2;
130134

@@ -135,7 +139,15 @@ class Command {
135139
/// be expensive to compute (and hashCode is called often).
136140
int _cachedHashCode;
137141

138-
Command._(this.displayName);
142+
Command._(this.displayName, {this.index = 0});
143+
144+
/// A virtual clone method for a member of the Command hierarchy.
145+
/// Two clones with the same index will be equal, with different indices
146+
/// will be distinct. Used to run tests multiple times, since identical
147+
/// commands are only run once by the dependency graph scheduler.
148+
Command indexedCopy(int index) {
149+
return Command._(displayName, index: index);
150+
}
139151

140152
int get hashCode {
141153
if (_cachedHashCode == null) {
@@ -152,10 +164,13 @@ class Command {
152164

153165
void _buildHashCode(HashCodeBuilder builder) {
154166
builder.addJson(displayName);
167+
builder.add(index);
155168
}
156169

157170
bool _equal(covariant Command other) =>
158-
hashCode == other.hashCode && displayName == other.displayName;
171+
hashCode == other.hashCode &&
172+
displayName == other.displayName &&
173+
index == other.index;
159174

160175
String toString() => reproductionCommand;
161176

@@ -176,8 +191,8 @@ class ProcessCommand extends Command {
176191
final String workingDirectory;
177192

178193
ProcessCommand._(String displayName, this.executable, this.arguments,
179-
[this.environmentOverrides, this.workingDirectory])
180-
: super._(displayName) {
194+
[this.environmentOverrides, this.workingDirectory, int index = 0])
195+
: super._(displayName, index: index) {
181196
if (io.Platform.operatingSystem == 'windows') {
182197
// Windows can't handle the first command if it is a .bat file or the like
183198
// with the slashes going the other direction.
@@ -186,6 +201,11 @@ class ProcessCommand extends Command {
186201
}
187202
}
188203

204+
ProcessCommand indexedCopy(int index) {
205+
return ProcessCommand._(displayName, executable, arguments,
206+
environmentOverrides, workingDirectory, index);
207+
}
208+
189209
void _buildHashCode(HashCodeBuilder builder) {
190210
super._buildHashCode(builder);
191211
builder.addJson(executable);
@@ -240,9 +260,21 @@ class CompilationCommand extends ProcessCommand {
240260
String executable,
241261
List<String> arguments,
242262
Map<String, String> environmentOverrides,
243-
{String workingDirectory})
263+
{String workingDirectory,
264+
int index = 0})
244265
: super._(displayName, executable, arguments, environmentOverrides,
245-
workingDirectory);
266+
workingDirectory, index);
267+
268+
CompilationCommand indexedCopy(int index) => CompilationCommand._(
269+
displayName,
270+
_outputFile,
271+
_alwaysCompile,
272+
_bootstrapDependencies,
273+
executable,
274+
arguments,
275+
environmentOverrides,
276+
workingDirectory: workingDirectory,
277+
index: index);
246278

247279
bool get outputIsUpToDate {
248280
if (_alwaysCompile) return false;
@@ -294,15 +326,27 @@ class FastaCompilationCommand extends CompilationCommand {
294326

295327
FastaCompilationCommand._(
296328
this._compilerLocation,
297-
Uri outputFile,
329+
String outputFile,
298330
List<Uri> bootstrapDependencies,
299-
Uri executable,
331+
String executable,
300332
List<String> arguments,
301333
Map<String, String> environmentOverrides,
302-
Uri workingDirectory)
303-
: super._("fasta", outputFile.toFilePath(), true, bootstrapDependencies,
304-
executable.toFilePath(), arguments, environmentOverrides,
305-
workingDirectory: workingDirectory?.toFilePath());
334+
String workingDirectory,
335+
{int index = 0})
336+
: super._("fasta", outputFile, true, bootstrapDependencies, executable,
337+
arguments, environmentOverrides,
338+
workingDirectory: workingDirectory, index: index);
339+
340+
@override
341+
FastaCompilationCommand indexedCopy(int index) => FastaCompilationCommand._(
342+
_compilerLocation,
343+
_outputFile,
344+
_bootstrapDependencies,
345+
executable,
346+
arguments,
347+
environmentOverrides,
348+
workingDirectory,
349+
index: index);
306350

307351
@override
308352
List<String> get batchArguments {
@@ -370,13 +414,20 @@ class FastaCompilationCommand extends CompilationCommand {
370414
class VMKernelCompilationCommand extends CompilationCommand {
371415
VMKernelCompilationCommand._(
372416
String outputFile,
373-
bool neverSkipCompilation,
417+
bool alwaysCompile,
374418
List<Uri> bootstrapDependencies,
375419
String executable,
376420
List<String> arguments,
377-
Map<String, String> environmentOverrides)
378-
: super._('vm_compile_to_kernel', outputFile, neverSkipCompilation,
379-
bootstrapDependencies, executable, arguments, environmentOverrides);
421+
Map<String, String> environmentOverrides,
422+
{int index = 0})
423+
: super._('vm_compile_to_kernel', outputFile, alwaysCompile,
424+
bootstrapDependencies, executable, arguments, environmentOverrides,
425+
index: index);
426+
427+
VMKernelCompilationCommand indexedCopy(int index) =>
428+
VMKernelCompilationCommand._(_outputFile, _alwaysCompile,
429+
_bootstrapDependencies, executable, arguments, environmentOverrides,
430+
index: index);
380431

381432
int get maxNumRetries => 1;
382433
}
@@ -398,8 +449,12 @@ class BrowserTestCommand extends Command {
398449
final TestConfiguration configuration;
399450
final bool retry;
400451

401-
BrowserTestCommand._(this.url, this.configuration, this.retry)
402-
: super._(configuration.runtime.name);
452+
BrowserTestCommand._(this.url, this.configuration, this.retry,
453+
{int index = 0})
454+
: super._(configuration.runtime.name, index: index);
455+
456+
BrowserTestCommand indexedCopy(int index) =>
457+
BrowserTestCommand._(url, configuration, retry, index: index);
403458

404459
void _buildHashCode(HashCodeBuilder builder) {
405460
super._buildHashCode(builder);
@@ -431,27 +486,45 @@ class BrowserTestCommand extends Command {
431486

432487
class AnalysisCommand extends ProcessCommand {
433488
AnalysisCommand._(String executable, List<String> arguments,
434-
Map<String, String> environmentOverrides)
435-
: super._('dart2analyzer', executable, arguments, environmentOverrides);
489+
Map<String, String> environmentOverrides, {int index = 0})
490+
: super._('dart2analyzer', executable, arguments, environmentOverrides,
491+
null, index);
492+
493+
AnalysisCommand indexedCopy(int index) =>
494+
AnalysisCommand._(executable, arguments, environmentOverrides,
495+
index: index);
436496
}
437497

438498
class CompareAnalyzerCfeCommand extends ProcessCommand {
439499
CompareAnalyzerCfeCommand._(String executable, List<String> arguments,
440-
Map<String, String> environmentOverrides)
500+
Map<String, String> environmentOverrides, {int index = 0})
441501
: super._('compare_analyzer_cfe', executable, arguments,
442-
environmentOverrides);
502+
environmentOverrides, null, index);
503+
504+
CompareAnalyzerCfeCommand indexedCopy(int index) =>
505+
CompareAnalyzerCfeCommand._(executable, arguments, environmentOverrides,
506+
index: index);
443507
}
444508

445509
class SpecParseCommand extends ProcessCommand {
446510
SpecParseCommand._(String executable, List<String> arguments,
447-
Map<String, String> environmentOverrides)
448-
: super._('spec_parser', executable, arguments, environmentOverrides);
511+
Map<String, String> environmentOverrides, {int index = 0})
512+
: super._('spec_parser', executable, arguments, environmentOverrides,
513+
null, index);
514+
515+
SpecParseCommand indexedCopy(int index) =>
516+
SpecParseCommand._(executable, arguments, environmentOverrides,
517+
index: index);
449518
}
450519

451520
class VmCommand extends ProcessCommand {
452521
VmCommand._(String executable, List<String> arguments,
453-
Map<String, String> environmentOverrides)
454-
: super._('vm', executable, arguments, environmentOverrides);
522+
Map<String, String> environmentOverrides,
523+
{int index = 0})
524+
: super._('vm', executable, arguments, environmentOverrides, null, index);
525+
526+
VmCommand indexedCopy(int index) =>
527+
VmCommand._(executable, arguments, environmentOverrides, index: index);
455528
}
456529

457530
class VmBatchCommand extends ProcessCommand implements VmCommand {
@@ -460,9 +533,14 @@ class VmBatchCommand extends ProcessCommand implements VmCommand {
460533

461534
VmBatchCommand._(String executable, String dartFile, List<String> arguments,
462535
Map<String, String> environmentOverrides,
463-
{this.checked: true})
536+
{this.checked: true, int index = 0})
464537
: this.dartFile = dartFile,
465-
super._('vm-batch', executable, arguments, environmentOverrides);
538+
super._('vm-batch', executable, arguments, environmentOverrides, null,
539+
index);
540+
541+
VmBatchCommand indexedCopy(int index) =>
542+
VmBatchCommand._(executable, dartFile, arguments, environmentOverrides,
543+
checked: checked, index: index);
466544

467545
@override
468546
List<String> get batchArguments =>
@@ -495,10 +573,18 @@ class AdbPrecompilationCommand extends Command {
495573
this.processTestFilename,
496574
this.precompiledTestDirectory,
497575
this.arguments,
498-
this.useBlobs)
499-
: super._("adb_precompilation");
500-
501-
void _buildHashCode(HashCodeBuilder builder) {
576+
this.useBlobs,
577+
{int index = 0})
578+
: super._("adb_precompilation", index: index);
579+
580+
AdbPrecompilationCommand indexedCopy(int index) => AdbPrecompilationCommand._(
581+
precompiledRunnerFilename,
582+
processTestFilename,
583+
precompiledTestDirectory,
584+
arguments,
585+
useBlobs,
586+
index: index);
587+
_buildHashCode(HashCodeBuilder builder) {
502588
super._buildHashCode(builder);
503589
builder.add(precompiledRunnerFilename);
504590
builder.add(precompiledTestDirectory);
@@ -520,13 +606,18 @@ class AdbPrecompilationCommand extends Command {
520606
class JSCommandlineCommand extends ProcessCommand {
521607
JSCommandlineCommand._(
522608
String displayName, String executable, List<String> arguments,
523-
[Map<String, String> environmentOverrides = null])
524-
: super._(displayName, executable, arguments, environmentOverrides);
609+
[Map<String, String> environmentOverrides = null, int index = 0])
610+
: super._(displayName, executable, arguments, environmentOverrides, null,
611+
index);
612+
613+
JSCommandlineCommand indexedCopy(int index) => JSCommandlineCommand._(
614+
displayName, executable, arguments, environmentOverrides, index);
525615
}
526616

527617
/// [ScriptCommand]s are executed by dart code.
528618
abstract class ScriptCommand extends Command {
529-
ScriptCommand._(String displayName) : super._(displayName);
619+
ScriptCommand._(String displayName, {int index = 0})
620+
: super._(displayName, index: index);
530621

531622
Future<ScriptCommandOutput> run();
532623
}
@@ -535,8 +626,13 @@ class CleanDirectoryCopyCommand extends ScriptCommand {
535626
final String _sourceDirectory;
536627
final String _destinationDirectory;
537628

538-
CleanDirectoryCopyCommand._(this._sourceDirectory, this._destinationDirectory)
539-
: super._('dir_copy');
629+
CleanDirectoryCopyCommand._(this._sourceDirectory, this._destinationDirectory,
630+
{int index = 0})
631+
: super._('dir_copy', index: index);
632+
633+
CleanDirectoryCopyCommand indexedCopy(int index) =>
634+
CleanDirectoryCopyCommand._(_sourceDirectory, _destinationDirectory,
635+
index: index);
540636

541637
String get reproductionCommand =>
542638
"Copying '$_sourceDirectory' to '$_destinationDirectory'.";
@@ -581,7 +677,11 @@ class MakeSymlinkCommand extends ScriptCommand {
581677
String _link;
582678
String _target;
583679

584-
MakeSymlinkCommand._(this._link, this._target) : super._('make_symlink');
680+
MakeSymlinkCommand._(this._link, this._target, {int index = 0})
681+
: super._('make_symlink', index: index);
682+
683+
MakeSymlinkCommand indexedCopy(int index) =>
684+
MakeSymlinkCommand._(_link, _target, index: index);
585685

586686
String get reproductionCommand =>
587687
"Make symbolic link '$_link' (target: $_target)'.";

tools/testing/dart/configuration.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class TestConfiguration {
2727
this.selectors,
2828
this.testList,
2929
this.appendLogs,
30+
this.repeat,
3031
this.batch,
3132
this.batchDart2JS,
3233
this.copyCoreDumps,
@@ -133,6 +134,7 @@ class TestConfiguration {
133134
final int taskCount;
134135
final int shardCount;
135136
final int shard;
137+
final int repeat;
136138
final String stepName;
137139

138140
final int testServerPort;

tools/testing/dart/dependency_graph.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ class Graph<T> {
7070
/// Adds a new node to the graph with [dependencies] and [userData].
7171
///
7272
/// The node is in the [NodeState.initialized] state.
73-
Node<T> add(T userData, Iterable<Node<T>> dependencies) {
73+
Node<T> add(T userData, Iterable<Node<T>> dependencies,
74+
{bool timingDependency = false}) {
7475
assert(!_isSealed);
7576

76-
var node = new Node._(userData);
77+
var node = new Node._(userData, timingDependency);
7778
_nodes.add(node);
7879

7980
for (var dependency in dependencies) {
@@ -114,11 +115,12 @@ class Graph<T> {
114115
/// A single node in a [Graph].
115116
class Node<T> extends UniqueObject {
116117
final T data;
118+
final bool timingDependency;
117119
NodeState _state = NodeState.initialized;
118120
final Set<Node<T>> _dependencies = new Set();
119121
final Set<Node<T>> _neededFor = new Set();
120122

121-
Node._(this.data);
123+
Node._(this.data, this.timingDependency);
122124

123125
NodeState get state => _state;
124126
Iterable<Node<T>> get dependencies => _dependencies;

tools/testing/dart/options.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ compact, color, line, verbose, silent, status, buildbot, diff''',
220220
'shard', 'The index of this instance when running in sharded mode.',
221221
defaultsTo: 1, hide: true),
222222
new _Option.bool('help', 'Print list of options.', abbr: 'h'),
223+
new _Option.int('repeat', 'How many times each test is run', defaultsTo: 1),
223224
new _Option.bool('verbose', 'Verbose output.', abbr: 'v'),
224225
new _Option.bool('verify-ir', 'Verify kernel IR.', hide: true),
225226
new _Option.bool('no-tree-shake', 'Disable kernel IR tree shaking.',
@@ -668,6 +669,7 @@ compiler.''',
668669
selectors: selectors,
669670
testList: data["test_list_contents"] as List<String>,
670671
appendLogs: data["append_logs"] as bool,
672+
repeat: data["repeat"] as int,
671673
batch: !(data["noBatch"] as bool),
672674
batchDart2JS: data["dart2js_batch"] as bool,
673675
copyCoreDumps: data["copy_coredumps"] as bool,

0 commit comments

Comments
 (0)