blob: 8fb5401477212753e8f78e57c764dcebba3f7c88 [file] [log] [blame]
import 'dart:io';
import 'package:fxtest/fxtest.dart';
import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
class MockEnvReader extends Mock implements EnvReader {}
class FuchsiaTestCommandCliFake extends FuchsiaTestCommandCli {
FuchsiaTestCommandCliFake()
: super(
['--no-build'],
usage: (parser) => null,
);
@override
FuchsiaTestCommand buildCommand(TestsConfig testsConfig) {
return FuchsiaTestCommandFake(
testsConfig: testsConfig,
outputFormatter: StdOutClosingFormatter(),
);
}
}
class FuchsiaTestCommandFake extends FuchsiaTestCommand {
FuchsiaTestCommandFake({outputFormatter, testsConfig})
: super(
analyticsReporter: AnalyticsFaker(),
fuchsiaLocator: FuchsiaLocator.shared,
outputFormatter: outputFormatter,
testsConfig: testsConfig,
);
@override
Future<void> runTestSuite(TestsManifestReader manifestReader) async {
stream.listen(outputFormatter.update);
emitEvent(BeginningTests());
}
}
class StdOutClosingFormatter extends OutputFormatter {
@override
void update(TestEvent event) {
forcefullyClose();
}
}
class AnalyticsFaker extends AnalyticsReporter {
List<List<String>> reportHistory = [];
@override
Future<void> report({
@required String subcommand,
@required String action,
String label,
}) async {
reportHistory.add([subcommand, action, label]);
}
}
// Mock this because it creates processes
class FakeTestRunner extends Fake implements TestRunner {
final int exitCode;
FakeTestRunner(this.exitCode);
FakeTestRunner.passing() : exitCode = 0;
FakeTestRunner.failing() : exitCode = 2;
@override
Future<ProcessResult> run(
String command,
List<String> args, {
@required String fx,
@required String workingDirectory,
Function(String) realtimeOutputSink,
Function(String) realtimeErrorSink,
}) async {
String _stdout = args.join(' ');
if (realtimeOutputSink != null) {
realtimeOutputSink(_stdout);
}
String _stderr = workingDirectory.toString();
if (realtimeErrorSink != null) {
realtimeErrorSink(_stderr);
}
return Future.value(
ProcessResult(1, exitCode, _stdout, _stderr),
);
}
}
void main() {
group('fuchsia directories are located correctly', () {
test('when the build directory is inside the checkout', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/fuchsia');
when(envReader.getEnv('FUCHSIA_BUILD_DIR'))
.thenReturn('/root/path/fuchsia/out/default');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
expect(fuchsiaLocator.fuchsiaDir, '/root/path/fuchsia');
expect(fuchsiaLocator.buildDir, '/root/path/fuchsia/out/default');
expect(fuchsiaLocator.relativeBuildDir, '/out/default');
expect(fuchsiaLocator.userFriendlyBuildDir, '//out/default');
});
test('when the cwd is requested from the build dir itself', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/fuchsia');
when(envReader.getEnv('FUCHSIA_BUILD_DIR'))
.thenReturn('/root/path/fuchsia/out/default');
when(envReader.getCwd()).thenReturn('/root/path/fuchsia/out/default');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
expect(fuchsiaLocator.relativeCwd, '.');
});
test('when the cwd is requested from within the build dir', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/fuchsia');
when(envReader.getEnv('FUCHSIA_BUILD_DIR'))
.thenReturn('/root/path/fuchsia/out/default');
when(envReader.getCwd())
.thenReturn('/root/path/fuchsia/out/default/host_x64');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
expect(fuchsiaLocator.relativeCwd, 'host_x64');
});
test(
'when the cwd is requested from within the tree but not within '
'the build dir', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/fuchsia');
when(envReader.getEnv('FUCHSIA_BUILD_DIR'))
.thenReturn('/root/path/fuchsia/out/default');
when(envReader.getCwd()).thenReturn('/root/path/fuchsia/tools');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
expect(fuchsiaLocator.relativeCwd, '/root/path/fuchsia/tools');
});
test('when fuchsia tree directory path does not contain "fuchsia"', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/dev');
when(envReader.getEnv('FUCHSIA_BUILD_DIR'))
.thenReturn('/root/path/dev/out/default');
when(envReader.getCwd()).thenReturn('/root/path/dev/out/default');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
expect(fuchsiaLocator.relativeCwd, '.');
});
});
group('prechecks', () {
test('raise errors if fx is missing', () {
var logged = false;
var cmdCli = FuchsiaTestCommandCli([''], usage: (parser) {});
expect(
() => cmdCli.preRunChecks(
'/fake/fx',
(Object obj) => logged = true,
),
throwsA(TypeMatcher<MissingFxException>()),
);
expect(logged, false);
});
test('prints tests when asked', () async {
var logged = false;
var calledUsage = false;
var cmdCli = FuchsiaTestCommandCli(['--printtests'], usage: (parser) {
calledUsage = true;
});
bool shouldRun = await cmdCli.preRunChecks(
'/fake/fx',
(Object obj) => logged = true,
);
expect(calledUsage, false);
expect(shouldRun, false);
// Passing `--printtests` does its thing and exits before `/fake/fx` is
// validated, which would otherwise throw an exception
expect(logged, true);
});
});
group('command cli-wrapper', () {
test('throws OutputClosedException exception stdout is closed', () async {
var cmdCli = FuchsiaTestCommandCliFake();
expect(
cmdCli.run(),
throwsA(TypeMatcher<OutputClosedException>()),
);
});
});
group('test analytics are reporting', () {
var envReader = MockEnvReader();
when(envReader.getEnv('FUCHSIA_DIR')).thenReturn('/root/path/fuchsia');
var fuchsiaLocator = FuchsiaLocator(envReader: envReader);
var testBundles = <TestBundle>[
TestBundle(
TestDefinition(
buildDir: '/',
command: ['asdf'],
fx: fuchsiaLocator.fx,
name: 'Big Test',
os: 'linux',
),
workingDirectory: '.',
testRunner: FakeTestRunner.passing(),
),
];
test('functions on real test runs', () async {
var cmd = FuchsiaTestCommand(
analyticsReporter: AnalyticsFaker(),
fuchsiaLocator: fuchsiaLocator,
outputFormatter: null,
testsConfig: TestsConfig.fromRawArgs(rawArgs: []),
);
await cmd.runTests(testBundles).forEach((event) {});
await cmd.cleanUp();
expect(
// ignore: avoid_as
(cmd.analyticsReporter as AnalyticsFaker).reportHistory,
[
['test', 'number', '1']
],
);
});
test('is silent on dry runs', () async {
var cmd = FuchsiaTestCommand(
analyticsReporter: AnalyticsFaker(),
fuchsiaLocator: fuchsiaLocator,
outputFormatter: null,
testsConfig: TestsConfig.fromRawArgs(rawArgs: ['--dry']),
);
await cmd.runTests(testBundles).forEach((event) {});
await cmd.cleanUp();
expect(
// ignore: avoid_as
(cmd.analyticsReporter as AnalyticsFaker).reportHistory,
hasLength(0),
);
});
});
}