mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 05:16:40 +00:00
[pkg/testing] Replace top-level logging functions with an interface.
Change-Id: Id896436ab869d52c6e9befff885494b87690a342 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118382 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Karl Klose <karlklose@google.com>
This commit is contained in:
parent
209180d280
commit
96f1abdaca
|
@ -21,15 +21,7 @@ import 'zone_helper.dart' show runGuarded;
|
||||||
|
|
||||||
import 'error_handling.dart' show withErrorHandling;
|
import 'error_handling.dart' show withErrorHandling;
|
||||||
|
|
||||||
import 'log.dart'
|
import 'log.dart' show Logger, StdoutLogger, splitLines;
|
||||||
show
|
|
||||||
logMessage,
|
|
||||||
logStepComplete,
|
|
||||||
logStepStart,
|
|
||||||
logSuiteComplete,
|
|
||||||
logTestComplete,
|
|
||||||
logUnexpectedResult,
|
|
||||||
splitLines;
|
|
||||||
|
|
||||||
import 'multitest.dart' show MultitestTransformer, isError;
|
import 'multitest.dart' show MultitestTransformer, isError;
|
||||||
|
|
||||||
|
@ -112,7 +104,9 @@ abstract class ChainContext {
|
||||||
ExpectationSet get expectationSet => ExpectationSet.Default;
|
ExpectationSet get expectationSet => ExpectationSet.Default;
|
||||||
|
|
||||||
Future<Null> run(Chain suite, Set<String> selectors,
|
Future<Null> run(Chain suite, Set<String> selectors,
|
||||||
{int shards = 1, int shard = 0}) async {
|
{int shards = 1,
|
||||||
|
int shard = 0,
|
||||||
|
Logger logger: const StdoutLogger()}) async {
|
||||||
assert(shards >= 1, "Invalid shards count: $shards");
|
assert(shards >= 1, "Invalid shards count: $shards");
|
||||||
assert(0 <= shard && shard < shards,
|
assert(0 <= shard && shard < shards,
|
||||||
"Invalid shard index: $shard, not in range [0,$shards[.");
|
"Invalid shard index: $shard, not in range [0,$shards[.");
|
||||||
|
@ -182,8 +176,8 @@ abstract class ChainContext {
|
||||||
Step step = iterator.current;
|
Step step = iterator.current;
|
||||||
lastStepRun = step;
|
lastStepRun = step;
|
||||||
isAsync = step.isAsync;
|
isAsync = step.isAsync;
|
||||||
logStepStart(completed, unexpectedResults.length, descriptions.length,
|
logger.logStepStart(completed, unexpectedResults.length,
|
||||||
suite, description, step);
|
descriptions.length, suite, description, step);
|
||||||
// TODO(ahe): It's important to share the zone error reporting zone
|
// TODO(ahe): It's important to share the zone error reporting zone
|
||||||
// between all the tasks. Otherwise, if a future completes with an
|
// between all the tasks. Otherwise, if a future completes with an
|
||||||
// error in one zone, and gets stored, it becomes an uncaught error
|
// error in one zone, and gets stored, it becomes an uncaught error
|
||||||
|
@ -201,7 +195,7 @@ abstract class ChainContext {
|
||||||
future = future.then((_currentResult) async {
|
future = future.then((_currentResult) async {
|
||||||
Result currentResult = _currentResult;
|
Result currentResult = _currentResult;
|
||||||
if (currentResult != null) {
|
if (currentResult != null) {
|
||||||
logStepComplete(completed, unexpectedResults.length,
|
logger.logStepComplete(completed, unexpectedResults.length,
|
||||||
descriptions.length, suite, description, lastStepRun);
|
descriptions.length, suite, description, lastStepRun);
|
||||||
result = currentResult;
|
result = currentResult;
|
||||||
if (currentResult.outcome == Expectation.Pass) {
|
if (currentResult.outcome == Expectation.Pass) {
|
||||||
|
@ -217,12 +211,13 @@ abstract class ChainContext {
|
||||||
result.addLog("$sb");
|
result.addLog("$sb");
|
||||||
unexpectedResults[description] = result;
|
unexpectedResults[description] = result;
|
||||||
unexpectedOutcomes[description] = expectedOutcomes;
|
unexpectedOutcomes[description] = expectedOutcomes;
|
||||||
logUnexpectedResult(suite, description, result, expectedOutcomes);
|
logger.logUnexpectedResult(
|
||||||
|
suite, description, result, expectedOutcomes);
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
} else {
|
} else {
|
||||||
logMessage(sb);
|
logger.logMessage(sb);
|
||||||
}
|
}
|
||||||
logTestComplete(++completed, unexpectedResults.length,
|
logger.logTestComplete(++completed, unexpectedResults.length,
|
||||||
descriptions.length, suite, description);
|
descriptions.length, suite, description);
|
||||||
});
|
});
|
||||||
if (isAsync) {
|
if (isAsync) {
|
||||||
|
@ -233,14 +228,16 @@ abstract class ChainContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.logTestStart(completed, unexpectedResults.length,
|
||||||
|
descriptions.length, suite, description);
|
||||||
// The input of the first step is [description].
|
// The input of the first step is [description].
|
||||||
await doStep(description);
|
await doStep(description);
|
||||||
}
|
}
|
||||||
await Future.wait(futures);
|
await Future.wait(futures);
|
||||||
logSuiteComplete();
|
logger.logSuiteComplete();
|
||||||
if (unexpectedResults.isNotEmpty) {
|
if (unexpectedResults.isNotEmpty) {
|
||||||
unexpectedResults.forEach((TestDescription description, Result result) {
|
unexpectedResults.forEach((TestDescription description, Result result) {
|
||||||
logUnexpectedResult(
|
logger.logUnexpectedResult(
|
||||||
suite, description, result, unexpectedOutcomes[description]);
|
suite, description, result, unexpectedOutcomes[description]);
|
||||||
});
|
});
|
||||||
print("${unexpectedResults.length} failed:");
|
print("${unexpectedResults.length} failed:");
|
||||||
|
|
|
@ -38,6 +38,42 @@ void enableVerboseOutput() {
|
||||||
_isVerbose = true;
|
_isVerbose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class Logger {
|
||||||
|
void logTestStart(int completed, int failed, int total, Suite suite,
|
||||||
|
TestDescription description);
|
||||||
|
|
||||||
|
void logTestComplete(int completed, int failed, int total, Suite suite,
|
||||||
|
TestDescription description);
|
||||||
|
|
||||||
|
void logStepStart(int completed, int failed, int total, Suite suite,
|
||||||
|
TestDescription description, Step step);
|
||||||
|
|
||||||
|
void logStepComplete(int completed, int failed, int total, Suite suite,
|
||||||
|
TestDescription description, Step step);
|
||||||
|
|
||||||
|
void logProgress(String message);
|
||||||
|
|
||||||
|
void logMessage(Object message);
|
||||||
|
|
||||||
|
void logNumberedLines(String text);
|
||||||
|
|
||||||
|
void logExpectedResult(Suite suite, TestDescription description,
|
||||||
|
Result result, Set<Expectation> expectedOutcomes);
|
||||||
|
|
||||||
|
void logUnexpectedResult(Suite suite, TestDescription description,
|
||||||
|
Result result, Set<Expectation> expectedOutcomes);
|
||||||
|
|
||||||
|
void logSuiteComplete();
|
||||||
|
|
||||||
|
void logUncaughtError(error, StackTrace stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
class StdoutLogger implements Logger {
|
||||||
|
const StdoutLogger();
|
||||||
|
|
||||||
|
void logTestStart(int completed, int failed, int total, Suite suite,
|
||||||
|
TestDescription description) {}
|
||||||
|
|
||||||
void logTestComplete(int completed, int failed, int total, Suite suite,
|
void logTestComplete(int completed, int failed, int total, Suite suite,
|
||||||
TestDescription description) {
|
TestDescription description) {
|
||||||
String message = formatProgress(completed, failed, total);
|
String message = formatProgress(completed, failed, total);
|
||||||
|
@ -103,6 +139,9 @@ void logNumberedLines(String text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logExpectedResult(Suite suite, TestDescription description,
|
||||||
|
Result result, Set<Expectation> expectedOutcomes) {}
|
||||||
|
|
||||||
void logUnexpectedResult(Suite suite, TestDescription description,
|
void logUnexpectedResult(Suite suite, TestDescription description,
|
||||||
Result result, Set<Expectation> expectedOutcomes) {
|
Result result, Set<Expectation> expectedOutcomes) {
|
||||||
print("${eraseLine}UNEXPECTED: ${suite.name}/${description.shortName}");
|
print("${eraseLine}UNEXPECTED: ${suite.name}/${description.shortName}");
|
||||||
|
@ -140,6 +179,7 @@ void logUncaughtError(error, StackTrace stackTrace) {
|
||||||
logMessage(stackTrace);
|
logMessage(stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String pad(Object o, int pad, {String filler: " "}) {
|
String pad(Object o, int pad, {String filler: " "}) {
|
||||||
String result = (filler * pad) + "$o";
|
String result = (filler * pad) + "$o";
|
||||||
|
|
|
@ -24,12 +24,7 @@ import '../testing.dart'
|
||||||
import 'analyze.dart' show Analyze;
|
import 'analyze.dart' show Analyze;
|
||||||
|
|
||||||
import 'log.dart'
|
import 'log.dart'
|
||||||
show
|
show enableVerboseOutput, isVerbose, Logger, splitLines, StdoutLogger;
|
||||||
enableVerboseOutput,
|
|
||||||
isVerbose,
|
|
||||||
logMessage,
|
|
||||||
logNumberedLines,
|
|
||||||
splitLines;
|
|
||||||
|
|
||||||
import 'suite.dart' show Dart, Suite;
|
import 'suite.dart' show Dart, Suite;
|
||||||
|
|
||||||
|
@ -55,7 +50,11 @@ Future<TestRoot> computeTestRoot(String configurationPath, Uri base) {
|
||||||
/// `testing.json` isn't located in the current working directory and is a path
|
/// `testing.json` isn't located in the current working directory and is a path
|
||||||
/// relative to [me] which defaults to `Platform.script`.
|
/// relative to [me] which defaults to `Platform.script`.
|
||||||
Future<Null> runMe(List<String> arguments, CreateContext f,
|
Future<Null> runMe(List<String> arguments, CreateContext f,
|
||||||
{String configurationPath, Uri me, int shards = 1, int shard = 0}) {
|
{String configurationPath,
|
||||||
|
Uri me,
|
||||||
|
int shards = 1,
|
||||||
|
int shard = 0,
|
||||||
|
Logger logger: const StdoutLogger()}) {
|
||||||
me ??= Platform.script;
|
me ??= Platform.script;
|
||||||
return withErrorHandling(() async {
|
return withErrorHandling(() async {
|
||||||
TestRoot testRoot = await computeTestRoot(configurationPath, me);
|
TestRoot testRoot = await computeTestRoot(configurationPath, me);
|
||||||
|
@ -66,7 +65,7 @@ Future<Null> runMe(List<String> arguments, CreateContext f,
|
||||||
print("Running suite ${suite.name}...");
|
print("Running suite ${suite.name}...");
|
||||||
ChainContext context = await f(suite, cl.environment);
|
ChainContext context = await f(suite, cl.environment);
|
||||||
await context.run(suite, new Set<String>.from(cl.selectors),
|
await context.run(suite, new Set<String>.from(cl.selectors),
|
||||||
shards: shards, shard: shard);
|
shards: shards, shard: shard, logger: logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -117,8 +116,8 @@ Future<Null> run(List<String> arguments, List<String> suiteNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> runProgram(String program, Uri packages) async {
|
Future<Null> runProgram(String program, Uri packages) async {
|
||||||
logMessage("Running:");
|
const StdoutLogger().logMessage("Running:");
|
||||||
logNumberedLines(program);
|
const StdoutLogger().logNumberedLines(program);
|
||||||
Uri dataUri = new Uri.dataFromString(program);
|
Uri dataUri = new Uri.dataFromString(program);
|
||||||
ReceivePort exitPort = new ReceivePort();
|
ReceivePort exitPort = new ReceivePort();
|
||||||
Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null,
|
Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null,
|
||||||
|
|
|
@ -18,13 +18,7 @@ import 'test_root.dart' show TestRoot;
|
||||||
|
|
||||||
import 'zone_helper.dart' show runGuarded;
|
import 'zone_helper.dart' show runGuarded;
|
||||||
|
|
||||||
import 'log.dart'
|
import 'log.dart' show enableVerboseOutput, isVerbose, StdoutLogger;
|
||||||
show
|
|
||||||
enableVerboseOutput,
|
|
||||||
isVerbose,
|
|
||||||
logMessage,
|
|
||||||
logSuiteComplete,
|
|
||||||
logTestComplete;
|
|
||||||
|
|
||||||
import 'run.dart' show SuiteRunner, runProgram;
|
import 'run.dart' show SuiteRunner, runProgram;
|
||||||
|
|
||||||
|
@ -115,7 +109,8 @@ class CommandLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logMessage("Reading configuration file '$configurationPath'.");
|
const StdoutLogger()
|
||||||
|
.logMessage("Reading configuration file '$configurationPath'.");
|
||||||
Uri configuration =
|
Uri configuration =
|
||||||
await Isolate.resolvePackageUri(Uri.base.resolve(configurationPath));
|
await Isolate.resolvePackageUri(Uri.base.resolve(configurationPath));
|
||||||
if (configuration == null ||
|
if (configuration == null ||
|
||||||
|
@ -177,18 +172,21 @@ Future<void> runTests(Map<String, Function> tests) =>
|
||||||
withErrorHandling<void>(() async {
|
withErrorHandling<void>(() async {
|
||||||
int completed = 0;
|
int completed = 0;
|
||||||
for (String name in tests.keys) {
|
for (String name in tests.keys) {
|
||||||
|
const StdoutLogger()
|
||||||
|
.logTestStart(completed, 0, tests.length, null, null);
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
try {
|
try {
|
||||||
await runGuarded(() {
|
await runGuarded(() {
|
||||||
print("Running test $name");
|
print("Running test $name");
|
||||||
return tests[name]();
|
return tests[name]();
|
||||||
}, printLineOnStdout: sb.writeln);
|
}, printLineOnStdout: sb.writeln);
|
||||||
logMessage(sb);
|
const StdoutLogger().logMessage(sb);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(sb);
|
print(sb);
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
logTestComplete(++completed, 0, tests.length, null, null);
|
const StdoutLogger()
|
||||||
|
.logTestComplete(++completed, 0, tests.length, null, null);
|
||||||
}
|
}
|
||||||
logSuiteComplete();
|
const StdoutLogger().logSuiteComplete();
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ import 'dart:io' show exit, stderr;
|
||||||
|
|
||||||
import 'dart:isolate' show Capability, Isolate, ReceivePort;
|
import 'dart:isolate' show Capability, Isolate, ReceivePort;
|
||||||
|
|
||||||
import 'log.dart' show logUncaughtError;
|
import 'log.dart' show StdoutLogger;
|
||||||
|
|
||||||
Future runGuarded(Future f(),
|
Future runGuarded(Future f(),
|
||||||
{void printLineOnStdout(line),
|
{void printLineOnStdout(line),
|
||||||
|
@ -26,7 +26,7 @@ Future runGuarded(Future f(),
|
||||||
Completer completer = new Completer();
|
Completer completer = new Completer();
|
||||||
|
|
||||||
handleUncaughtError(error, StackTrace stackTrace) {
|
handleUncaughtError(error, StackTrace stackTrace) {
|
||||||
logUncaughtError(error, stackTrace);
|
StdoutLogger().logUncaughtError(error, stackTrace);
|
||||||
if (!completer.isCompleted) {
|
if (!completer.isCompleted) {
|
||||||
completer.completeError(error, stackTrace);
|
completer.completeError(error, stackTrace);
|
||||||
} else if (handleLateError != null) {
|
} else if (handleLateError != null) {
|
||||||
|
|
Loading…
Reference in a new issue