blob: 3c5f319181642117ba4306b07e1fc2c9dbbc0682 [file] [log] [blame]
// Copyright 2021 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 'package:test/test.dart';
import 'package:logging/logging.dart';
import 'package:sl4f/sl4f.dart' as sl4f;
import 'package:sl4f/trace_processing.dart' as trace_processing;
final _log = Logger('bt-a2dp-e2e-test');
const _timeout = Duration(seconds: 60);
const List<String> _defaultCategories = [
'bluetooth',
'bt-a2dp',
'stream-sink',
];
const String _trace2jsonPath = 'runtime_deps/trace2json';
void main() {
sl4f.Sl4f sl4fDriver;
sl4f.Performance performance;
sl4f.Modular basemgrController;
setUp(() async {
Logger.root
..level = Level.ALL
..onRecord.listen((rec) => print('[${rec.level}]: ${rec.message}'));
sl4fDriver = sl4f.Sl4f.fromEnvironment();
await sl4fDriver.startServer();
performance = sl4f.Performance(sl4fDriver);
basemgrController = sl4f.Modular(sl4fDriver);
await performance.terminateExistingTraceSession();
});
tearDown(() async {
await performance.terminateExistingTraceSession();
await sl4fDriver.stopServer();
sl4fDriver.close();
});
group(sl4f.Sl4f, () {
const testCase = 'fuchsia.bluetooth.a2dp';
test(testCase, () async {
await basemgrController.boot();
final traceSession =
await performance.initializeTracing(categories: _defaultCategories);
const testDurationSeconds = 10;
await traceSession.start();
expect(
await sl4f.Component(sl4fDriver).launch(
'fuchsia-pkg://fuchsia.com/bt-a2dp-loopback#meta/bt-a2dp-loopback.cmx',
['--duration', testDurationSeconds.toString()]),
'Success');
await traceSession.stop();
final traceFile = await traceSession.terminateAndDownload(testCase);
expect(traceFile.path, matches(RegExp('-$testCase-trace.fxt\$')));
final jsonTraceFile =
await performance.convertTraceFileToJson(_trace2jsonPath, traceFile);
_log.info('downloaded trace');
final traceModel =
await trace_processing.createModelFromFilePath(jsonTraceFile.path);
expect(traceModel, isNotNull);
_processA2DPTrace(traceModel, testDurationSeconds);
await basemgrController.shutdown(forceShutdownBasemgr: false);
});
}, timeout: Timeout(_timeout));
}
void _processA2DPTrace(
trace_processing.Model traceModel, int testDurationSeconds) {
const String a2dpCategory = 'bt-a2dp';
const String packetSentEventName = 'Media:PacketSent';
// Add plenty extra initiator delay since there is delay in getting components
// launched when running this test in CQ.
const initiatorDelayMilliseconds = 500 + 5000;
// 24ms chunks of data from source. This will need to be changed if the
// negotiated MTU changes such that source is sending different amounts per
// packet.
final expectedPackets =
(((testDurationSeconds * 1000) - initiatorDelayMilliseconds) / 24)
.floor();
int packetSentCount = 0;
for (final p in traceModel.processes) {
for (final t in p.threads) {
for (final e in t.events) {
if (e.name == packetSentEventName && e.category == a2dpCategory) {
packetSentCount++;
}
}
}
}
_log.info('packets sent $packetSentCount expectedPackets $expectedPackets');
expect(packetSentCount, greaterThanOrEqualTo(expectedPackets));
}