Unverified Commit 6dc1e83f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] ensure track-widget-creation can be disabled on Android/macOS (#56203)

Ensure --no-track-widget-creation is piped through android/macOS. Adds integration testing for iOS/android/macOS
parent 22239f41
// Copyright 2014 The Flutter 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:async';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/tasks/track_widget_creation_enabled_task.dart';
/// Verify that twc can be enabled/disabled on Android
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android;
await task(TrackWidgetCreationEnabledTask().task);
}
// Copyright 2014 The Flutter 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:async';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/tasks/track_widget_creation_enabled_task.dart';
/// Verify that twc can be enabled/disabled on iOS
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.ios;
await task(TrackWidgetCreationEnabledTask().task);
}
// Copyright 2014 The Flutter 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:async';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/tasks/track_widget_creation_enabled_task.dart';
/// Verify that twc can be enabled/disabled on macOS
Future<void> main() async {
await task(TrackWidgetCreationEnabledTask('macos').task);
}
// Copyright 2014 The Flutter 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:async';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/tasks/track_widget_creation_enabled_task.dart';
/// Verify that twc can be enabled/disabled on the web.
Future<void> main() async {
await task(TrackWidgetCreationEnabledTask('chrome').task);
}
// Copyright 2014 The Flutter 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';
import 'dart:io';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:path/path.dart' as path;
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart';
final Directory integrationTestDir = Directory(
path.join(flutterDirectory.path, 'dev/integration_tests/ui'),
);
/// Verifies that track-widget-creation can be enabled and disabled.
class TrackWidgetCreationEnabledTask {
TrackWidgetCreationEnabledTask([this.deviceIdOverride]);
String deviceIdOverride;
Future<TaskResult> task() async {
final File file = File(path.join(integrationTestDir.path, 'info'));
if (file.existsSync()) {
file.deleteSync();
}
bool failed = false;
String message = '';
if (deviceIdOverride == null) {
final Device device = await devices.workingDevice;
await device.unlock();
deviceIdOverride = device.deviceId;
}
await inDirectory<void>(integrationTestDir, () async {
section('Running with track-widget-creation enabled');
final Process runProcess = await startProcess(
path.join(flutterDirectory.path, 'bin', 'flutter'),
flutterCommandArgs('run', <String>[
'--vmservice-out-file=info',
'--track-widget-creation',
'-v',
'-d',
deviceIdOverride,
path.join('lib/track_widget_creation.dart'),
]),
environment: <String, String>{
'FLUTTER_WEB': 'true',
'FLUTTER_MACOS': 'true'
}
);
runProcess.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen(print);
final File file = await waitForFile(path.join(integrationTestDir.path, 'info'));
final VmService vmService = await vmServiceConnectUri(file.readAsStringSync());
final VM vm = await vmService.getVM();
final Response result = await vmService.callMethod(
'ext.devicelab.test',
isolateId: vm.isolates.single.id,
);
if (result.json['result'] != 2) {
message += result.json.toString();
failed = true;
}
runProcess.stdin.write('q');
vmService.dispose();
file.deleteSync();
await runProcess.exitCode;
});
await inDirectory<void>(integrationTestDir, () async {
section('Running with track-widget-creation disabled');
final Process runProcess = await startProcess(
path.join(flutterDirectory.path, 'bin', 'flutter'),
flutterCommandArgs('run', <String>[
'--vmservice-out-file=info',
'--no-track-widget-creation',
'-v',
'-d',
deviceIdOverride,
path.join('lib/track_widget_creation.dart'),
]),
environment: <String, String>{
'FLUTTER_WEB': 'true',
'FLUTTER_MACOS': 'true'
}
);
runProcess.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen(print);
final File file = await waitForFile(path.join(integrationTestDir.path, 'info'));
final VmService vmService = await vmServiceConnectUri(file.readAsStringSync());
final VM vm = await vmService.getVM();
final Response result = await vmService.callMethod(
'ext.devicelab.test',
isolateId: vm.isolates.single.id,
);
if (result.json['result'] != 1) {
message += result.json.toString();
failed = true;
}
runProcess.stdin.write('q');
vmService.dispose();
file.deleteSync();
await runProcess.exitCode;
});
return failed
? TaskResult.failure(message)
: TaskResult.success(null);
}
}
/// Wait for up to 400 seconds for the file to appear.
Future<File> waitForFile(String path) async {
for (int i = 0; i < 20; i += 1) {
final File file = File(path);
print('looking for ${file.path}');
if (file.existsSync()) {
return file;
}
await Future<void>.delayed(const Duration(seconds: 20));
}
throw StateError('Did not find vmservice out file after 400 seconds');
}
......@@ -346,6 +346,13 @@ tasks:
stage: devicelab
required_agent_capabilities: ["mac/android"]
android_enable_twc:
description: >
Verifies that track-widget-creation can be enabled and disabled.
stage: devicelab
required_agent_capabilities: ["mac/android"]
flaky: true
android_defines_test:
description: >
Builds an APK with a --dart-define and verifies it can be used as a constant
......@@ -591,6 +598,20 @@ tasks:
stage: devicelab_ios
required_agent_capabilities: ["mac/ios"]
ios_enable_twc:
description: >
Verifies that track-widget-creation can be enabled and disabled.
stage: devicelab_ios
required_agent_capabilities: ["mac/ios"]
flaky: true
mac_enable_twc:
description: >
Verifies that track-widget-creation can be enabled and disabled.
stage: devicelab_ios
required_agent_capabilities: ["mac/ios"]
flaky: true
# TODO(fujino): does not pass on iOS13 https://github.com/flutter/flutter/issues/43029
# system_debug_ios:
# description: >
......@@ -797,6 +818,15 @@ tasks:
stage: devicelab
required_agent_capabilities: ["linux-vm"]
# TODO(jonahwilliams): This should stay off until
# https://github.com/flutter/flutter/issues/56212 is fixed.
# web_enable_twc:
# description: >
# Verifies that track-widget-creation can be enabled and disabled.
# stage: devicelab
# required_agent_capabilities: ["linux-vm"]
# flaky: true
# run_without_leak_linux:
# description: >
# Checks that `flutter run` does not leak dart on Linux.
......
// Copyright 2014 The Flutter 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:developer';
import 'package:flutter/widgets.dart';
void main() {
final Set<Widget> widgets = <Widget>{};
widgets.add(const Text('same'));
widgets.add(const Text('same'));
// If track-widget-creation is enabled, the set will have 2 members.
// Otherwise is will only have one.
registerExtension('ext.devicelab.test', (String method, Map<String, Object> params) async {
return ServiceExtensionResponse.result('{"result":${widgets.length}}');
});
}
......@@ -3,7 +3,7 @@ description: Flutter non-plugin UI integration tests.
environment:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk: ">=2.0.0-dev.68.0 <3.0.0"
sdk: ">=2.8.0 <3.0.0"
dependencies:
image: 2.1.12
......
<!DOCTYPE HTML>
<!-- Copyright 2014 The Flutter Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>web_integration</title>
<script defer src="main.dart.js" type="application/javascript"></script>
</head>
<body>
</body>
</html>
......@@ -79,6 +79,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" \
-dTreeShakeIcons="${TREE_SHAKE_ICONS}" \
-dDartObfuscation="${DART_OBFUSCATION}" \
-dSplitDebugInfo="${SPLIT_DEBUG_INFO}" \
-dTrackWidgetCreation="${TRACK_WIDGET_CREATION}" \
--DartDefines="${DART_DEFINES}" \
--ExtraGenSnapshotOptions="${EXTRA_GEN_SNAPSHOT_OPTIONS}" \
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
......
......@@ -922,6 +922,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (extraFrontEndOptions != null) {
args "-dExtraFrontEndOptions=${extraFrontEndOptions}"
}
if (trackWidgetCreation != null) {
args "-dTrackWidgetCreation=${trackWidgetCreation}"
}
if (splitDebugInfo != null) {
args "-dSplitDebugInfo=${splitDebugInfo}"
}
......
......@@ -713,6 +713,11 @@ class _ResidentWebRunner extends ResidentWebRunner {
}
}
if (websocketUri != null) {
if (debuggingOptions.vmserviceOutFile != null) {
globals.fs.file(debuggingOptions.vmserviceOutFile)
..createSync(recursive: true)
..writeAsStringSync(websocketUri.toString());
}
globals.printStatus('Debug service listening on $websocketUri');
}
appStartedCompleter?.complete();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment