blob: bac7e8aa9bfc25b511b3d3bef04ee14c7de2dcb8 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert' show json;
import 'dart:io' show File, Platform;
import 'package:mockito/mockito.dart';
import 'package:sl4f/sl4f.dart' as sl4f;
import 'package:test/test.dart';
import 'package:sl4f/sl4f.dart';
class MockDump extends Mock implements Dump {}
class MockPerformance extends Mock implements Performance {}
class MockFile extends Mock implements File {}
final _fakeZedmonPath =
Platform.script.resolve('runtime_deps/fake_zedmon').toFilePath();
const String _converterPath = '/path/to/catapult_converter';
// Paths to files that specify stderr and stdout for the fake_zedmon binary.
final _stderrPath = '$_fakeZedmonPath.stderr.testdata';
final _stdoutPath = '$_fakeZedmonPath.stdout.testdata';
/// Writes a file from the provided lines.
Future<void> _writeFile(String path, List<String> lines) async {
final file = File(path);
await file.create();
final sink = file.openWrite();
lines.forEach(sink.writeln);
await sink.close();
}
/// Writes stderr and stdout data for the fake_zedmon process. stderr is
/// currently unused by this test, so it is always left empty.
Future<void> _setupTestData(List<String> stdoutLines) async {
await Future.wait(<Future>[
_writeFile(_stderrPath, <String>[]),
_writeFile(_stdoutPath, stdoutLines)
]);
}
/// Waits until we have processed data from the fake_zedmon process up to the
/// specified data timestamp.
Future<void> _waitForZedmon(sl4f.Power power, int zedmonTimestamp) async {
assert(zedmonTimestamp >= 0);
for (;;) {
await Future.delayed(Duration(milliseconds: 10));
final timestamp = power.zedmonLatestTimestamp()?.inMicroseconds ?? -1;
if (timestamp >= zedmonTimestamp) {
return;
}
}
}
void _deleteTestData() {
final stderrFile = File(_stderrPath);
if (stderrFile.existsSync()) {
stderrFile.deleteSync();
}
final stdoutFile = File(_stdoutPath);
if (stdoutFile.existsSync()) {
stdoutFile.deleteSync();
}
}
void main(List<String> args) {
setUp(_deleteTestData);
tearDown(_deleteTestData);
// Confirm that average power and duration are as expected when power readings
// are (unrealistically) constant.
test('constant power', () async {
final stderrLines = <String>[
'0,0.0015,14.0,2.0',
'1000,0.0015,14.0,2.0',
'2000,0.0015,14.0,2.0',
'3000,0.0015,14.0,2.0',
'4000,0.0015,14.0,2.0',
'5000,0.0015,14.0,2.0',
'6000,0.0015,14.0,2.0',
'7000,0.0015,14.0,2.0',
'8000,0.0015,14.0,2.0',
'9000,0.0015,14.0,2.0',
'10000,0.0015,14.0,2.0',
];
await _setupTestData(stderrLines);
final dump = MockDump();
final performance = MockPerformance();
final power = sl4f.Power(_fakeZedmonPath, dump, performance);
await power.startRecording();
await _waitForZedmon(power, 10000);
final mockFile = MockFile();
when(dump.writeAsString('power', 'fuchsiaperf.json', any))
.thenAnswer((_) => Future.value(mockFile));
await power.stopRecording(_converterPath);
// Make sure the average power written to power.fuchsiaperf.json is correct.
final encoded =
verify(dump.writeAsString('power', 'fuchsiaperf.json', captureAny))
.captured
.single;
final data = json.decode(encoded);
expect(data.length, 1);
expect(data[0]['values'].length, 1);
expect(data[0]['values'][0], closeTo(2.0, 1e-8));
verify(performance.convertResults(
_converterPath, argThat(same(mockFile)), any));
});
// Confirm that average power and duration are as expected when power readings
// vary.
test('varying power', () async {
expect(File(_stderrPath).existsSync(), false);
final stderrLines = <String>[
'0,0.0015,14.0,2.0',
'1000,0.0015,14.0,2.1',
'2000,0.0015,14.0,2.2',
'3000,0.0015,14.0,2.3',
'4000,0.0015,14.0,2.4',
'5000,0.0015,14.0,2.5',
'6000,0.0015,14.0,2.6',
'7000,0.0015,14.0,2.7',
'8000,0.0015,14.0,2.8',
'9000,0.0015,14.0,2.9',
];
await _setupTestData(stderrLines);
final dump = MockDump();
final performance = MockPerformance();
final power = sl4f.Power(_fakeZedmonPath, dump, performance);
await power.startRecording();
await _waitForZedmon(power, 9000);
final mockFile = MockFile();
when(dump.writeAsString('power', 'fuchsiaperf.json', any))
.thenAnswer((_) => Future.value(mockFile));
await power.stopRecording(_converterPath);
// Make sure the average power written to power.fuchsiaperf.json is correct.
final encoded =
verify(dump.writeAsString('power', 'fuchsiaperf.json', captureAny))
.captured
.single;
final data = json.decode(encoded);
expect(data.length, 1);
expect(data[0]['values'].length, 1);
expect(data[0]['values'][0], closeTo(2.4, 1e-8));
verify(performance.convertResults(
_converterPath, argThat(same(mockFile)), any));
});
}