blob: 396cdd56ae7a961622d2ba556076de8c8c3e95b6 [file] [log] [blame]
// Copyright 2019 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.
// ignore_for_file: implementation_imports
import 'dart:io' as dartio;
import 'package:fidl_fuchsia_modular/fidl_async.dart';
import 'package:fidl_fuchsia_modular_testing/fidl_async.dart';
import 'package:fidl_fuchsia_sys/fidl_async.dart';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:fuchsia_remote_debug_protocol/logging.dart';
import 'package:fuchsia_services/services.dart';
import 'package:glob/glob.dart';
import 'package:glob/list_local_fs.dart';
import 'package:test/test.dart';
import 'package:zircon/zircon.dart' show Channel;
// With the current test harness, the program's directory name has to be
// the same as the program's name.
const String _testProgramName = 'inspect_flutter_integration_tester';
const Pattern _testAppName = '$_testProgramName.cmx';
const _testAppUrl =
'fuchsia-pkg://fuchsia.com/$_testProgramName#meta/$_testAppName';
const _modularTestHarnessURL =
'fuchsia-pkg://fuchsia.com/modular_test_harness#meta/modular_test_harness.cmx';
TestHarnessProxy testHarnessProxy = TestHarnessProxy();
ComponentControllerProxy testHarnessController = ComponentControllerProxy();
// Starts Modular TestHarness with dev shells. This should be called from within
// a try/finally or similar construct that closes the component controller.
// TODO(fxbug.dev/4487): Use launchTestHarness() from test_harness_fixtures.dart.
Future<void> _startTestHarness() async {
final launcher = LauncherProxy();
final incoming = Incoming();
// launch TestHarness component
final svc = Incoming.fromSvcPath()..connectToService(launcher);
await launcher.createComponent(
LaunchInfo(
url: _modularTestHarnessURL,
directoryRequest: incoming.request().passChannel()),
testHarnessController.ctrl.request());
// connect to TestHarness service
incoming.connectToService(testHarnessProxy);
/// Converts a Service to URL map into list of [ComponentService].
List<ComponentService> _toComponentServices(
Map<String, String> serviceToUrl) {
final componentServices = <ComponentService>[];
for (final svcName in serviceToUrl.keys) {
componentServices
.add(ComponentService(name: svcName, url: serviceToUrl[svcName]));
}
return componentServices;
}
final testHarnessSpec = TestHarnessSpec(
envServicesToInherit: [
'fuchsia.sysmem.Allocator',
'fuchsia.vulkan.loader.Loader',
],
envServices: EnvironmentServicesSpec(
servicesFromComponents: _toComponentServices({
'fuchsia.identity.account.AccountManager':
'fuchsia-pkg://fuchsia.com/account_manager#meta/account_manager.cmx',
'fuchsia.devicesettings.DeviceSettingsManager':
'fuchsia-pkg://fuchsia.com/device_settings_manager#meta/device_settings_manager.cmx',
'fuchsia.fonts.Provider':
'fuchsia-pkg://fuchsia.com/fonts#meta/fonts.cmx',
'fuchsia.tracelink.Registry':
'fuchsia-pkg://fuchsia.com/trace_manager#meta/trace_manager.cmx',
'fuchsia.ui.input.ImeService':
'fuchsia-pkg://fuchsia.com/text_manager#meta/text_manager.cmx',
'fuchsia.ui.policy.Presenter':
'fuchsia-pkg://fuchsia.com/root_presenter#meta/root_presenter.cmx',
'fuchsia.ui.scenic.Scenic':
'fuchsia-pkg://fuchsia.com/scenic#meta/scenic.cmx',
}),
serviceDir: Channel.fromFile('/svc')));
// run the test harness which will create an encapsulated test env
await testHarnessProxy.run(testHarnessSpec);
await svc.close();
}
Future<void> _launchModUnderTest() async {
// get the puppetMaster service from the encapsulated test env
final puppetMasterProxy = PuppetMasterProxy();
await testHarnessProxy.connectToModularService(
ModularService.withPuppetMaster(puppetMasterProxy.ctrl.request()));
// use puppetMaster to start a fake story an launch the mod under test
final storyPuppetMasterProxy = StoryPuppetMasterProxy();
await puppetMasterProxy.controlStory(
'fooStoryName', storyPuppetMasterProxy.ctrl.request());
await storyPuppetMasterProxy.enqueue(<StoryCommand>[
StoryCommand.withAddMod(AddMod(
modName: ['my_integration_test_mod'],
modNameTransitional: 'root',
intent: Intent(action: 'action', handler: _testAppUrl),
surfaceRelation: SurfaceRelation()))
]);
await storyPuppetMasterProxy.execute();
}
void main() {
final controller = ComponentControllerProxy();
FlutterDriver driver;
// The following boilerplate is a one time setup required to make
// flutter_driver work in Fuchsia.
//
// When a module built using Flutter starts up in debug mode, it creates an
// instance of the Dart VM, and spawns an Isolate (isolated Dart execution
// context) containing your module.
setUpAll(() async {
Logger.globalLevel = LoggingLevel.all;
await _startTestHarness();
await _launchModUnderTest();
// Creates an object you can use to search for your mod on the machine
driver = await FlutterDriver.connect(
fuchsiaModuleTarget: _testAppName,
printCommunication: true,
logCommunicationToFile: false);
});
tearDownAll(() async {
await driver?.close();
controller.ctrl.close();
testHarnessProxy.ctrl.close();
testHarnessController.ctrl.close();
});
Future<int> inspectVmoSize() async {
// TODO(fxbug.dev/4487): Make this less brittle.
// TODO(fxb/38305): Address and/or update above TODO, and reenable test in //topaz/BUILD.gn.
// CL should have landed so stories reuse session envs. This breaks hardcoded inspect paths.
var globs = [
'/hub/r/modular_test_harness_*/*/r/session-*/*/r/*/*/c/flutter*/*/c/$_testAppName/*/out/diagnostics/*',
'/hub/r/mth_*/*/r/session-*/*/r/*/*/c/flutter*/*/c/$_testAppName/*/out/diagnostics/*'
];
for (final globString in globs) {
var fileEntity = await Glob(globString).list().toList();
if (fileEntity.isNotEmpty) {
var f = dartio.File(fileEntity[0].path);
var vmoBytes = await f.readAsBytes();
return vmoBytes.length;
}
}
throw Exception('could not find inspect node');
}
Future<void> tapAndWait(String buttonName, String nextState) async {
await driver.tap(find.text(buttonName));
await driver.waitFor(find.byValueKey(nextState));
}
test('Put the program through its paces', () async {
await tapAndWait('Config 4k', 'VMO set to 4k');
await tapAndWait('Config 16k', 'VMO set to 16k');
await tapAndWait('Test Inspect Instance', 'Inspect is correct');
expect(await inspectVmoSize(), 16384);
await tapAndWait('Config 16k', 'ERROR setting 16k');
});
}