blob: 6b7f7b555482608802b1da24c4cd0f572bf4dacd [file] [log] [blame]
Ian Hickson449f4a62019-11-27 15:04:02 -08001// Copyright 2014 The Flutter Authors. All rights reserved.
Alexander Aprelev5b1e9722017-05-21 15:15:44 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Jonah Williams74bd7b62021-01-27 15:17:53 -08005// @dart = 2.8
6
Alexander Aprelev5b1e9722017-05-21 15:15:44 -07007import 'dart:async';
Jonah Williamsadf45d12019-07-09 13:10:26 -07008
Ben Konyi89ef88c2020-12-04 17:16:30 -08009import 'package:dds/dds.dart' as dds;
Jonah Williamse22d4aa2019-10-15 13:05:47 -070010import 'package:file/memory.dart';
Jonah Williams6d8ec352020-05-29 15:43:03 -070011import 'package:file_testing/file_testing.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070012import 'package:flutter_tools/src/application_package.dart';
Jonah Williams79a985f2019-10-22 20:35:05 -070013import 'package:flutter_tools/src/artifacts.dart';
Jonah Williams8beee472021-05-24 11:59:03 -070014import 'package:flutter_tools/src/asset.dart';
Zachary Anderson23ce1922020-01-09 08:18:03 -080015import 'package:flutter_tools/src/base/command_help.dart';
Jonah Williamse3ee5c62019-07-13 16:02:09 -070016import 'package:flutter_tools/src/base/common.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070017import 'package:flutter_tools/src/base/dds.dart';
Jonah Williams1957c662019-07-18 10:40:40 -070018import 'package:flutter_tools/src/base/file_system.dart';
Jenn Magder2e7d9132019-11-01 14:37:17 -070019import 'package:flutter_tools/src/base/io.dart' as io;
Phil Quitslund61c30c42021-04-21 13:49:03 -070020import 'package:flutter_tools/src/base/logger.dart';
21import 'package:flutter_tools/src/base/platform.dart';
Alexander Aprelevd7759082019-04-15 21:02:20 -070022import 'package:flutter_tools/src/build_info.dart';
Jonah Williams79a985f2019-10-22 20:35:05 -070023import 'package:flutter_tools/src/compile.dart';
Jonah Williams08fe78f2020-04-07 12:17:39 -070024import 'package:flutter_tools/src/convert.dart';
Jonah Williamsadf45d12019-07-09 13:10:26 -070025import 'package:flutter_tools/src/devfs.dart';
Alexander Aprelev5b1e9722017-05-21 15:15:44 -070026import 'package:flutter_tools/src/device.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070027import 'package:flutter_tools/src/device_port_forwarder.dart';
28import 'package:flutter_tools/src/features.dart';
Jenn Magder9e88fe32021-11-01 17:18:03 -070029import 'package:flutter_tools/src/globals.dart' as globals;
Zachary Andersonef146f62019-07-29 07:24:02 -070030import 'package:flutter_tools/src/reporting/reporting.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070031import 'package:flutter_tools/src/resident_devtools_handler.dart';
Alexander Aprelev5b1e9722017-05-21 15:15:44 -070032import 'package:flutter_tools/src/resident_runner.dart';
Jonah Williamse22d4aa2019-10-15 13:05:47 -070033import 'package:flutter_tools/src/run_cold.dart';
Jonah Williamsadf45d12019-07-09 13:10:26 -070034import 'package:flutter_tools/src/run_hot.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070035import 'package:flutter_tools/src/version.dart';
Jonah Williamsadf45d12019-07-09 13:10:26 -070036import 'package:flutter_tools/src/vmservice.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070037import 'package:meta/meta.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070038import 'package:package_config/package_config.dart';
Jonah Williams73df0692021-06-14 16:29:02 -070039import 'package:test/fake.dart';
Phil Quitslund61c30c42021-04-21 13:49:03 -070040import 'package:vm_service/vm_service.dart' as vm_service;
Alexander Aprelev5b1e9722017-05-21 15:15:44 -070041
Ian Hicksond919e692019-07-13 11:51:44 -070042import '../src/common.dart';
Todd Volkertadb2aee2019-07-18 15:29:06 -070043import '../src/context.dart';
Jenn Magdera2f67722021-04-06 22:55:03 -070044import '../src/fake_vm_services.dart';
Jonah Williams29513632021-02-26 11:13:32 -080045import '../src/fakes.dart';
Ian Hicksond919e692019-07-13 11:51:44 -070046import '../src/testbed.dart';
Alexander Aprelev5b1e9722017-05-21 15:15:44 -070047
Jonah Williamsffcf1db2020-04-27 17:41:42 -070048final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
49 id: '1',
50 pauseEvent: vm_service.Event(
51 kind: vm_service.EventKind.kResume,
52 timestamp: 0
53 ),
54 breakpoints: <vm_service.Breakpoint>[],
55 exceptionPauseMode: null,
Kenzie Schmollc89d6492021-01-25 10:40:14 -080056 extensionRPCs: <String>[],
Jonah Williams07caa0f2020-07-20 14:03:44 -070057 libraries: <vm_service.LibraryRef>[
58 vm_service.LibraryRef(
59 id: '1',
60 uri: 'file:///hello_world/main.dart',
61 name: '',
62 ),
63 ],
Jonah Williamsffcf1db2020-04-27 17:41:42 -070064 livePorts: 0,
65 name: 'test',
66 number: '1',
67 pauseOnExit: false,
68 runnable: true,
69 startTime: 0,
Jonah Williams18f0a222020-10-27 13:55:32 -070070 isSystemIsolate: false,
Ben Konyi4cbafda2020-11-17 16:03:18 -080071 isolateFlags: <vm_service.IsolateFlag>[],
Jonah Williamsffcf1db2020-04-27 17:41:42 -070072);
73
74final vm_service.Isolate fakePausedIsolate = vm_service.Isolate(
75 id: '1',
76 pauseEvent: vm_service.Event(
77 kind: vm_service.EventKind.kPauseException,
78 timestamp: 0
79 ),
Jonah Williamsc6dce232020-07-24 15:34:55 -070080 breakpoints: <vm_service.Breakpoint>[
81 vm_service.Breakpoint(
82 breakpointNumber: 123,
83 id: 'test-breakpoint',
84 location: vm_service.SourceLocation(
85 tokenPos: 0,
Jonah Williams0afddf32020-10-12 09:47:41 -070086 script: vm_service.ScriptRef(id: 'test-script', uri: 'foo.dart'),
Jonah Williamsc6dce232020-07-24 15:34:55 -070087 ),
Jonah Williamscd13c912021-06-15 11:08:57 -070088 enabled: true,
Jonah Williamsc6dce232020-07-24 15:34:55 -070089 resolved: true,
90 ),
91 ],
Jonah Williamsffcf1db2020-04-27 17:41:42 -070092 exceptionPauseMode: null,
93 libraries: <vm_service.LibraryRef>[],
94 livePorts: 0,
95 name: 'test',
96 number: '1',
97 pauseOnExit: false,
98 runnable: true,
99 startTime: 0,
Jonah Williams18f0a222020-10-27 13:55:32 -0700100 isSystemIsolate: false,
Ben Konyi4cbafda2020-11-17 16:03:18 -0800101 isolateFlags: <vm_service.IsolateFlag>[],
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700102);
103
Jonah Williams07caa0f2020-07-20 14:03:44 -0700104final vm_service.VM fakeVM = vm_service.VM(
105 isolates: <vm_service.IsolateRef>[fakeUnpausedIsolate],
106 pid: 1,
107 hostCPU: '',
108 isolateGroups: <vm_service.IsolateGroupRef>[],
109 targetCPU: '',
110 startTime: 0,
111 name: 'dart',
112 architectureBits: 64,
113 operatingSystem: '',
114 version: '',
Jonah Williams18f0a222020-10-27 13:55:32 -0700115 systemIsolateGroups: <vm_service.IsolateGroupRef>[],
116 systemIsolates: <vm_service.IsolateRef>[],
Jonah Williams07caa0f2020-07-20 14:03:44 -0700117);
118
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700119final FlutterView fakeFlutterView = FlutterView(
120 id: 'a',
121 uiIsolate: fakeUnpausedIsolate,
122);
123
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700124final FakeVmServiceRequest listViews = FakeVmServiceRequest(
125 method: kListViewsMethod,
126 jsonResponse: <String, Object>{
127 'views': <Object>[
128 fakeFlutterView.toJson(),
129 ],
130 },
131);
132
Jonah Williams3300a1b2020-10-27 09:20:05 -0700133const FakeVmServiceRequest setAssetBundlePath = FakeVmServiceRequest(
134 method: '_flutter.setAssetBundlePath',
135 args: <String, Object>{
136 'viewId': 'a',
137 'assetDirectory': 'build/flutter_assets',
138 'isolateId': '1',
139 }
140);
141
Lau Ching Junaf42e7d2021-06-28 13:16:04 -0700142const FakeVmServiceRequest evict = FakeVmServiceRequest(
143 method: 'ext.flutter.evict',
144 args: <String, Object>{
145 'value': 'asset',
146 'isolateId': '1',
147 }
148);
149
Jonah Williams6efe8e92021-01-29 14:27:42 -0800150final Uri testUri = Uri.parse('foo://bar');
151
Alexander Aprelev5b1e9722017-05-21 15:15:44 -0700152void main() {
Jonah Williams1957c662019-07-18 10:40:40 -0700153 Testbed testbed;
Jonah Williams73df0692021-06-14 16:29:02 -0700154 FakeFlutterDevice flutterDevice;
155 FakeDevFS devFS;
Jonah Williams1957c662019-07-18 10:40:40 -0700156 ResidentRunner residentRunner;
Jonah Williams73df0692021-06-14 16:29:02 -0700157 FakeDevice device;
Jonah Williams9202e542020-04-20 15:15:54 -0700158 FakeVmServiceHost fakeVmServiceHost;
Alexander Aprelev5b1e9722017-05-21 15:15:44 -0700159
Jonah Williams1957c662019-07-18 10:40:40 -0700160 setUp(() {
161 testbed = Testbed(setup: () {
Jonah Williams82a6f9b2020-06-25 12:52:14 -0700162 globals.fs.file('.packages')
163 .writeAsStringSync('\n');
Jonah Williamsee7a37f2020-01-06 11:04:20 -0800164 globals.fs.file(globals.fs.path.join('build', 'app.dill'))
Jonah Williams1fec30e2019-09-12 12:45:53 -0700165 ..createSync(recursive: true)
166 ..writeAsStringSync('ABC');
Jonah Williams1957c662019-07-18 10:40:40 -0700167 residentRunner = HotRunner(
168 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700169 flutterDevice,
Jonah Williams1957c662019-07-18 10:40:40 -0700170 ],
171 stayResident: false,
172 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800173 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800174 devtoolsHandler: createNoOpHandler,
Jonah Williamsadf45d12019-07-09 13:10:26 -0700175 );
Jonah Williams1957c662019-07-18 10:40:40 -0700176 });
Jonah Williams73df0692021-06-14 16:29:02 -0700177 device = FakeDevice();
178 devFS = FakeDevFS();
179 flutterDevice = FakeFlutterDevice()
180 ..testUri = testUri
181 ..vmServiceHost = (() => fakeVmServiceHost)
182 ..device = device
183 .._devFS = devFS;
Alexander Aprelev5b1e9722017-05-21 15:15:44 -0700184 });
Jonah Williams1957c662019-07-18 10:40:40 -0700185
Jenn Magder88631332020-06-08 11:28:02 -0700186 testUsingContext('ResidentRunner can attach to device successfully', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700187 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
188 listViews,
189 listViews,
190 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800191 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
192 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams1957c662019-07-18 10:40:40 -0700193 final Future<int> result = residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800194 appStartedCompleter: futureAppStart,
195 connectionInfoCompleter: futureConnectionInfo,
196 enableDevTools: true,
Jonah Williams1957c662019-07-18 10:40:40 -0700197 );
Ian Hickson8acac062021-02-01 16:06:02 -0800198 final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
Jonah Williams1957c662019-07-18 10:40:40 -0700199
200 expect(await result, 0);
Ian Hickson8acac062021-02-01 16:06:02 -0800201 expect(futureConnectionInfo.isCompleted, true);
Jonah Williams1957c662019-07-18 10:40:40 -0700202 expect((await connectionInfo).baseUri, 'foo://bar');
Ian Hickson8acac062021-02-01 16:06:02 -0800203 expect(futureAppStart.isCompleted, true);
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700204 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700205 }));
Jonah Williams1957c662019-07-18 10:40:40 -0700206
Jenn Magder88631332020-06-08 11:28:02 -0700207 testUsingContext('ResidentRunner suppresses errors for the initial compilation', () => testbed.run(() async {
Jonah Williamse216eec2020-06-03 12:00:03 -0700208 globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
209 .createSync(recursive: true);
210 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
211 listViews,
212 listViews,
213 ]);
Jonah Williams73df0692021-06-14 16:29:02 -0700214 final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
215 ..nextOutput = const CompilerOutput('foo', 0 ,<Uri>[]);
Jonah Williamse216eec2020-06-03 12:00:03 -0700216 residentRunner = HotRunner(
217 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700218 flutterDevice,
Jonah Williamse216eec2020-06-03 12:00:03 -0700219 ],
220 stayResident: false,
221 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800222 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800223 devtoolsHandler: createNoOpHandler,
Jonah Williamse216eec2020-06-03 12:00:03 -0700224 );
Jonah Williams73df0692021-06-14 16:29:02 -0700225 flutterDevice.generator = residentCompiler;
Jonah Williamse216eec2020-06-03 12:00:03 -0700226
Ian Hickson8acac062021-02-01 16:06:02 -0800227 expect(await residentRunner.run(enableDevTools: true), 0);
Jonah Williams73df0692021-06-14 16:29:02 -0700228 expect(residentCompiler.didSuppressErrors, true);
Jonah Williamse216eec2020-06-03 12:00:03 -0700229 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700230 }));
Jonah Williamse216eec2020-06-03 12:00:03 -0700231
Jonah Williams21881962020-06-30 12:26:18 -0700232 // Regression test for https://github.com/flutter/flutter/issues/60613
233 testUsingContext('ResidentRunner calls appFailedToStart if initial compilation fails', () => testbed.run(() async {
234 globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
235 .createSync(recursive: true);
236 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams73df0692021-06-14 16:29:02 -0700237 final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
238 ..nextOutput = const CompilerOutput('foo', 1 ,<Uri>[]);
Jonah Williams21881962020-06-30 12:26:18 -0700239 residentRunner = HotRunner(
240 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700241 flutterDevice,
Jonah Williams21881962020-06-30 12:26:18 -0700242 ],
243 stayResident: false,
244 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800245 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800246 devtoolsHandler: createNoOpHandler,
Jonah Williams21881962020-06-30 12:26:18 -0700247 );
Jonah Williams73df0692021-06-14 16:29:02 -0700248 flutterDevice.generator = residentCompiler;
Jonah Williams21881962020-06-30 12:26:18 -0700249
250 expect(await residentRunner.run(), 1);
251 // Completing this future ensures that the daemon can exit correctly.
252 expect(await residentRunner.waitForAppToFinish(), 1);
253 }));
254
255 // Regression test for https://github.com/flutter/flutter/issues/60613
256 testUsingContext('ResidentRunner calls appFailedToStart if initial compilation fails - cold mode', () => testbed.run(() async {
257 globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
258 .createSync(recursive: true);
259 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
260 residentRunner = ColdRunner(
261 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700262 flutterDevice,
Jonah Williams21881962020-06-30 12:26:18 -0700263 ],
264 stayResident: false,
265 debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
Jonah Williams613a9592020-11-20 14:17:11 -0800266 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800267 devtoolsHandler: createNoOpHandler,
Jonah Williams21881962020-06-30 12:26:18 -0700268 );
Jonah Williams73df0692021-06-14 16:29:02 -0700269 flutterDevice.runColdCode = 1;
Jonah Williams21881962020-06-30 12:26:18 -0700270
271 expect(await residentRunner.run(), 1);
272 // Completing this future ensures that the daemon can exit correctly.
273 expect(await residentRunner.waitForAppToFinish(), 1);
274 }));
275
276 // Regression test for https://github.com/flutter/flutter/issues/60613
277 testUsingContext('ResidentRunner calls appFailedToStart if exception is thrown - cold mode', () => testbed.run(() async {
278 globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
279 .createSync(recursive: true);
280 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
281 residentRunner = ColdRunner(
282 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700283 flutterDevice,
Jonah Williams21881962020-06-30 12:26:18 -0700284 ],
285 stayResident: false,
286 debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
Jonah Williams613a9592020-11-20 14:17:11 -0800287 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800288 devtoolsHandler: createNoOpHandler,
Jonah Williams21881962020-06-30 12:26:18 -0700289 );
Jonah Williams73df0692021-06-14 16:29:02 -0700290 flutterDevice.runColdError = Exception('BAD STUFF');
291
Jonah Williams21881962020-06-30 12:26:18 -0700292
293 expect(await residentRunner.run(), 1);
294 // Completing this future ensures that the daemon can exit correctly.
295 expect(await residentRunner.waitForAppToFinish(), 1);
296 }));
297
Jenn Magder88631332020-06-08 11:28:02 -0700298 testUsingContext('ResidentRunner does not suppressErrors if running with an applicationBinary', () => testbed.run(() async {
Jonah Williamse216eec2020-06-03 12:00:03 -0700299 globals.fs.file(globals.fs.path.join('lib', 'main.dart'))
300 .createSync(recursive: true);
301 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
302 listViews,
303 listViews,
304 ]);
Jonah Williams73df0692021-06-14 16:29:02 -0700305 final FakeResidentCompiler residentCompiler = FakeResidentCompiler()
306 ..nextOutput = const CompilerOutput('foo', 0 ,<Uri>[]);
Jonah Williamse216eec2020-06-03 12:00:03 -0700307 residentRunner = HotRunner(
308 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700309 flutterDevice,
Jonah Williamse216eec2020-06-03 12:00:03 -0700310 ],
311 applicationBinary: globals.fs.file('app.apk'),
312 stayResident: false,
313 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800314 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800315 devtoolsHandler: createNoOpHandler,
Jonah Williamse216eec2020-06-03 12:00:03 -0700316 );
Jonah Williams73df0692021-06-14 16:29:02 -0700317 flutterDevice.generator = residentCompiler;
Jonah Williamse216eec2020-06-03 12:00:03 -0700318
Ian Hickson8acac062021-02-01 16:06:02 -0800319 expect(await residentRunner.run(enableDevTools: true), 0);
Jonah Williams73df0692021-06-14 16:29:02 -0700320 expect(residentCompiler.didSuppressErrors, false);
Jonah Williamse216eec2020-06-03 12:00:03 -0700321 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700322 }));
Jonah Williamse216eec2020-06-03 12:00:03 -0700323
Jenn Magder88631332020-06-08 11:28:02 -0700324 testUsingContext('ResidentRunner can attach to device successfully with --fast-start', () => testbed.run(() async {
Jonah Williams9202e542020-04-20 15:15:54 -0700325 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700326 listViews,
327 listViews,
328 listViews,
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700329 FakeVmServiceRequest(
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700330 method: 'getIsolate',
331 args: <String, Object>{
332 'isolateId': fakeUnpausedIsolate.id,
333 },
334 jsonResponse: fakeUnpausedIsolate.toJson(),
335 ),
336 FakeVmServiceRequest(
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700337 method: 'getVM',
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700338 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
339 ),
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700340 listViews,
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700341 const FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -0700342 method: 'streamListen',
343 args: <String, Object>{
344 'streamId': 'Isolate',
345 }
346 ),
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700347 FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -0700348 method: kRunInViewMethod,
349 args: <String, Object>{
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700350 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -0700351 'mainScript': 'main.dart.dill',
Jonah Williams9202e542020-04-20 15:15:54 -0700352 'assetDirectory': 'build/flutter_assets',
353 }
354 ),
355 FakeVmServiceStreamResponse(
356 streamId: 'Isolate',
357 event: vm_service.Event(
358 timestamp: 0,
359 kind: vm_service.EventKind.kIsolateRunnable,
360 )
361 ),
362 ]);
Jonah Williamsbda9d902019-12-10 10:26:14 -0800363 residentRunner = HotRunner(
364 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700365 flutterDevice,
Jonah Williamsbda9d902019-12-10 10:26:14 -0800366 ],
367 stayResident: false,
Jonah Williams9202e542020-04-20 15:15:54 -0700368 debuggingOptions: DebuggingOptions.enabled(
369 BuildInfo.debug,
370 fastStart: true,
371 startPaused: true,
372 ),
Jonah Williams613a9592020-11-20 14:17:11 -0800373 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800374 devtoolsHandler: createNoOpHandler,
Jonah Williamsbda9d902019-12-10 10:26:14 -0800375 );
Ian Hickson8acac062021-02-01 16:06:02 -0800376 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
377 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williamsbda9d902019-12-10 10:26:14 -0800378 final Future<int> result = residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800379 appStartedCompleter: futureAppStart,
380 connectionInfoCompleter: futureConnectionInfo,
381 enableDevTools: true,
Jonah Williamsbda9d902019-12-10 10:26:14 -0800382 );
Ian Hickson8acac062021-02-01 16:06:02 -0800383 final Future<DebugConnectionInfo> connectionInfo = futureConnectionInfo.future;
Jonah Williamsbda9d902019-12-10 10:26:14 -0800384
385 expect(await result, 0);
Ian Hickson8acac062021-02-01 16:06:02 -0800386 expect(futureConnectionInfo.isCompleted, true);
Jonah Williamsbda9d902019-12-10 10:26:14 -0800387 expect((await connectionInfo).baseUri, 'foo://bar');
Ian Hickson8acac062021-02-01 16:06:02 -0800388 expect(futureAppStart.isCompleted, true);
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700389 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700390 }));
Jonah Williamsbda9d902019-12-10 10:26:14 -0800391
Jenn Magder88631332020-06-08 11:28:02 -0700392 testUsingContext('ResidentRunner can handle an RPC exception from hot reload', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700393 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
394 listViews,
395 listViews,
396 listViews,
397 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800398 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
399 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams1957c662019-07-18 10:40:40 -0700400 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800401 appStartedCompleter: futureAppStart,
402 connectionInfoCompleter: futureConnectionInfo,
403 enableDevTools: true,
Jonah Williams1957c662019-07-18 10:40:40 -0700404 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800405 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700406 flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
Jonah Williams1957c662019-07-18 10:40:40 -0700407
Ian Hickson61a0add2021-10-08 09:25:14 -0700408 final OperationResult result = await residentRunner.restart();
Jonah Williams1957c662019-07-18 10:40:40 -0700409 expect(result.fatal, true);
410 expect(result.code, 1);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800411 expect((globals.flutterUsage as TestUsage).events, contains(
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700412 TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
413 hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
414 hotEventSdkName: 'Android',
415 hotEventEmulator: false,
416 hotEventFullRestart: false,
Ian Hickson61a0add2021-10-08 09:25:14 -0700417 fastReassemble: false,
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700418 )),
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800419 ));
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700420 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams1957c662019-07-18 10:40:40 -0700421 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800422 Usage: () => TestUsage(),
Jonah Williams8beee472021-05-24 11:59:03 -0700423 }));
Jonah Williams1957c662019-07-18 10:40:40 -0700424
Jonah Williams50dfd132021-01-06 15:54:04 -0800425 testUsingContext('ResidentRunner fails its operation if the device initialization is not complete', () => testbed.run(() async {
426 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
427 listViews,
428 listViews,
Jonah Williams50dfd132021-01-06 15:54:04 -0800429 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800430 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
431 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams50dfd132021-01-06 15:54:04 -0800432 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800433 appStartedCompleter: futureAppStart,
434 connectionInfoCompleter: futureConnectionInfo,
Jonah Williams50dfd132021-01-06 15:54:04 -0800435 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800436 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700437 flutterDevice._devFS = null;
Jonah Williams50dfd132021-01-06 15:54:04 -0800438
Ian Hickson61a0add2021-10-08 09:25:14 -0700439 final OperationResult result = await residentRunner.restart();
Jonah Williams50dfd132021-01-06 15:54:04 -0800440 expect(result.fatal, false);
441 expect(result.code, 1);
442 expect(result.message, contains('Device initialization has not completed.'));
443 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Ian Hickson8acac062021-02-01 16:06:02 -0800444 }));
Jonah Williams50dfd132021-01-06 15:54:04 -0800445
Jonah Williams3300a1b2020-10-27 09:20:05 -0700446 testUsingContext('ResidentRunner can handle an reload-barred exception from hot reload', () => testbed.run(() async {
447 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
448 listViews,
449 listViews,
Jonah Williams3300a1b2020-10-27 09:20:05 -0700450 listViews,
451 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800452 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
453 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams3300a1b2020-10-27 09:20:05 -0700454 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800455 appStartedCompleter: futureAppStart,
456 connectionInfoCompleter: futureConnectionInfo,
457 enableDevTools: true,
Jonah Williams3300a1b2020-10-27 09:20:05 -0700458 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800459 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700460 flutterDevice.reportError = vm_service.RPCError('something bad happened', kIsolateReloadBarred, '');
Jonah Williams3300a1b2020-10-27 09:20:05 -0700461
Ian Hickson61a0add2021-10-08 09:25:14 -0700462 final OperationResult result = await residentRunner.restart();
Jonah Williams3300a1b2020-10-27 09:20:05 -0700463 expect(result.fatal, true);
464 expect(result.code, kIsolateReloadBarred);
465 expect(result.message, contains('Unable to hot reload application due to an unrecoverable error'));
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800466
467 expect((globals.flutterUsage as TestUsage).events, contains(
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700468 TestUsageEvent('hot', 'reload-barred', parameters: CustomDimensions(
469 hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
470 hotEventSdkName: 'Android',
471 hotEventEmulator: false,
472 hotEventFullRestart: false,
Ian Hickson61a0add2021-10-08 09:25:14 -0700473 fastReassemble: false,
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700474 )),
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800475 ));
Jonah Williams3300a1b2020-10-27 09:20:05 -0700476 expect(fakeVmServiceHost.hasRemainingExpectations, false);
477 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800478 Usage: () => TestUsage(),
Jonah Williams8beee472021-05-24 11:59:03 -0700479 }));
Jonah Williams3300a1b2020-10-27 09:20:05 -0700480
Jonah Williams55abbb62020-06-22 17:05:01 -0700481 testUsingContext('ResidentRunner reports hot reload event with null safety analytics', () => testbed.run(() async {
482 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
483 listViews,
484 listViews,
485 listViews,
486 ]);
487 residentRunner = HotRunner(
488 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700489 flutterDevice,
Jonah Williams55abbb62020-06-22 17:05:01 -0700490 ],
491 stayResident: false,
Jonah Williams613a9592020-11-20 14:17:11 -0800492 target: 'main.dart',
Jonah Williams55abbb62020-06-22 17:05:01 -0700493 debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
494 BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: <String>[
495 '--enable-experiment=non-nullable',
496 ],
497 )),
Jonah Williams7ab85172021-02-10 17:04:47 -0800498 devtoolsHandler: createNoOpHandler,
Jonah Williams55abbb62020-06-22 17:05:01 -0700499 );
Ian Hickson8acac062021-02-01 16:06:02 -0800500 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
501 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams55abbb62020-06-22 17:05:01 -0700502 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800503 appStartedCompleter: futureAppStart,
504 connectionInfoCompleter: futureConnectionInfo,
505 enableDevTools: true,
Jonah Williams55abbb62020-06-22 17:05:01 -0700506 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800507 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700508 flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
Jonah Williams55abbb62020-06-22 17:05:01 -0700509
Ian Hickson61a0add2021-10-08 09:25:14 -0700510 final OperationResult result = await residentRunner.restart();
Jonah Williams55abbb62020-06-22 17:05:01 -0700511 expect(result.fatal, true);
512 expect(result.code, 1);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800513
514 expect((globals.flutterUsage as TestUsage).events, contains(
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700515 TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
516 hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
517 hotEventSdkName: 'Android',
518 hotEventEmulator: false,
519 hotEventFullRestart: false,
Ian Hickson61a0add2021-10-08 09:25:14 -0700520 fastReassemble: false,
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700521 )),
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800522 ));
Jonah Williams55abbb62020-06-22 17:05:01 -0700523 expect(fakeVmServiceHost.hasRemainingExpectations, false);
524 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800525 Usage: () => TestUsage(),
Jonah Williams55abbb62020-06-22 17:05:01 -0700526 }));
527
Jonah Williams6cec03c2020-11-04 11:15:30 -0800528 testUsingContext('ResidentRunner does not reload sources if no sources changed', () => testbed.run(() async {
529 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
530 listViews,
531 listViews,
Jonah Williams6cec03c2020-11-04 11:15:30 -0800532 listViews,
533 FakeVmServiceRequest(
534 method: 'getIsolate',
535 args: <String, Object>{
536 'isolateId': '1',
537 },
538 jsonResponse: fakeUnpausedIsolate.toJson(),
539 ),
540 FakeVmServiceRequest(
541 method: 'ext.flutter.reassemble',
542 args: <String, Object>{
543 'isolateId': fakeUnpausedIsolate.id,
544 },
545 ),
546 ]);
547 residentRunner = HotRunner(
548 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -0700549 flutterDevice,
Jonah Williams6cec03c2020-11-04 11:15:30 -0800550 ],
551 stayResident: false,
552 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800553 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800554 devtoolsHandler: createNoOpHandler,
Jonah Williams6cec03c2020-11-04 11:15:30 -0800555 );
Ian Hickson8acac062021-02-01 16:06:02 -0800556 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
557 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams6cec03c2020-11-04 11:15:30 -0800558 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800559 appStartedCompleter: futureAppStart,
560 connectionInfoCompleter: futureConnectionInfo,
561 enableDevTools: true,
Jonah Williams6cec03c2020-11-04 11:15:30 -0800562 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800563 await futureAppStart.future;
Ian Hickson61a0add2021-10-08 09:25:14 -0700564 flutterDevice.report = UpdateFSReport(success: true);
Jonah Williams6cec03c2020-11-04 11:15:30 -0800565
Ian Hickson61a0add2021-10-08 09:25:14 -0700566 final OperationResult result = await residentRunner.restart();
Jonah Williams6cec03c2020-11-04 11:15:30 -0800567
568 expect(result.code, 0);
569 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700570 }));
Jonah Williams6cec03c2020-11-04 11:15:30 -0800571
Jonah Williams762d9f72020-08-05 15:11:15 -0700572 testUsingContext('ResidentRunner reports error with missing entrypoint file', () => testbed.run(() async {
573 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
574 listViews,
575 listViews,
576 listViews,
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700577 FakeVmServiceRequest(
578 method: 'getVM',
579 jsonResponse: vm_service.VM.parse(<String, Object>{
580 'isolates': <Object>[
581 fakeUnpausedIsolate.toJson(),
582 ],
583 }).toJson(),
584 ),
585 const FakeVmServiceRequest(
586 method: 'reloadSources',
587 args: <String, Object>{
588 'isolateId': '1',
589 'pause': false,
Jonah Williams0afddf32020-10-12 09:47:41 -0700590 'rootLibUri': 'main.dart.incremental.dill'
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700591 },
592 jsonResponse: <String, Object>{
593 'type': 'ReloadReport',
594 'success': true,
595 'details': <String, Object>{
596 'loadedLibraryCount': 1,
597 },
598 },
599 ),
Jonah Williams762d9f72020-08-05 15:11:15 -0700600 FakeVmServiceRequest(
601 method: 'getIsolate',
602 args: <String, Object>{
603 'isolateId': '1',
604 },
605 jsonResponse: fakeUnpausedIsolate.toJson(),
606 ),
607 FakeVmServiceRequest(
608 method: 'ext.flutter.reassemble',
609 args: <String, Object>{
610 'isolateId': fakeUnpausedIsolate.id,
611 },
612 ),
613 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800614 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
615 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams762d9f72020-08-05 15:11:15 -0700616 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800617 appStartedCompleter: futureAppStart,
618 connectionInfoCompleter: futureConnectionInfo,
619 enableDevTools: true,
Jonah Williams762d9f72020-08-05 15:11:15 -0700620 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800621 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700622 flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1);
Jonah Williams762d9f72020-08-05 15:11:15 -0700623
Ian Hickson61a0add2021-10-08 09:25:14 -0700624 final OperationResult result = await residentRunner.restart();
Jonah Williams762d9f72020-08-05 15:11:15 -0700625
626 expect(globals.fs.file(globals.fs.path.join('lib', 'main.dart')), isNot(exists));
627 expect(testLogger.errorText, contains('The entrypoint file (i.e. the file with main())'));
628 expect(result.fatal, false);
629 expect(result.code, 0);
Jonah Williams8beee472021-05-24 11:59:03 -0700630 }));
Jonah Williams762d9f72020-08-05 15:11:15 -0700631
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700632 testUsingContext('ResidentRunner resets compilation time on reload reject', () => testbed.run(() async {
633 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
634 listViews,
635 listViews,
636 listViews,
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700637 FakeVmServiceRequest(
638 method: 'getVM',
639 jsonResponse: vm_service.VM.parse(<String, Object>{
640 'isolates': <Object>[
641 fakeUnpausedIsolate.toJson(),
642 ],
643 }).toJson(),
644 ),
645 const FakeVmServiceRequest(
646 method: 'reloadSources',
647 args: <String, Object>{
648 'isolateId': '1',
649 'pause': false,
Jonah Williams0afddf32020-10-12 09:47:41 -0700650 'rootLibUri': 'main.dart.incremental.dill'
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700651 },
652 jsonResponse: <String, Object>{
653 'type': 'ReloadReport',
654 'success': false,
655 'notices': <Object>[
656 <String, Object>{
657 'message': 'Failed to hot reload'
658 }
659 ],
660 'details': <String, Object>{},
661 },
662 ),
663 listViews,
664 FakeVmServiceRequest(
665 method: 'getIsolate',
666 args: <String, Object>{
667 'isolateId': '1',
668 },
669 jsonResponse: fakeUnpausedIsolate.toJson(),
670 ),
671 FakeVmServiceRequest(
672 method: 'ext.flutter.reassemble',
673 args: <String, Object>{
674 'isolateId': fakeUnpausedIsolate.id,
675 },
676 ),
677 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800678 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
679 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700680 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800681 appStartedCompleter: futureAppStart,
682 connectionInfoCompleter: futureConnectionInfo,
683 enableDevTools: true,
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700684 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800685 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -0700686 flutterDevice.report = UpdateFSReport(success: true, invalidatedSourcesCount: 1);
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700687
Ian Hickson61a0add2021-10-08 09:25:14 -0700688 final OperationResult result = await residentRunner.restart();
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700689
690 expect(result.fatal, false);
691 expect(result.message, contains('Reload rejected: Failed to hot reload')); // contains error message from reload report.
692 expect(result.code, 1);
Jonah Williams73df0692021-06-14 16:29:02 -0700693 expect(devFS.lastCompiled, null);
Jonah Williams8beee472021-05-24 11:59:03 -0700694 }));
Jonah Williams55abbb62020-06-22 17:05:01 -0700695
Jenn Magder88631332020-06-08 11:28:02 -0700696 testUsingContext('ResidentRunner can send target platform to analytics from hot reload', () => testbed.run(() async {
Jonah Williams9202e542020-04-20 15:15:54 -0700697 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700698 listViews,
699 listViews,
Jonah Williams0f801162020-11-11 15:31:07 -0800700 listViews,
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700701 FakeVmServiceRequest(
702 method: 'getVM',
703 jsonResponse: vm_service.VM.parse(<String, Object>{
704 'isolates': <Object>[
705 fakeUnpausedIsolate.toJson(),
706 ],
707 }).toJson(),
708 ),
709 const FakeVmServiceRequest(
710 method: 'reloadSources',
711 args: <String, Object>{
712 'isolateId': '1',
713 'pause': false,
Jonah Williams0afddf32020-10-12 09:47:41 -0700714 'rootLibUri': 'main.dart.incremental.dill'
Jonah Williamsbdb830a2020-10-09 15:44:52 -0700715 },
716 jsonResponse: <String, Object>{
717 'type': 'ReloadReport',
718 'success': true,
719 'details': <String, Object>{
720 'loadedLibraryCount': 1,
721 },
722 },
723 ),
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700724 FakeVmServiceRequest(
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700725 method: 'getIsolate',
726 args: <String, Object>{
727 'isolateId': '1',
728 },
729 jsonResponse: fakeUnpausedIsolate.toJson(),
730 ),
731 FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -0700732 method: 'ext.flutter.reassemble',
733 args: <String, Object>{
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700734 'isolateId': fakeUnpausedIsolate.id,
Jonah Williams9202e542020-04-20 15:15:54 -0700735 },
736 ),
737 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800738 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
739 final Completer<void> futureAppStart = Completer<void>.sync();
Zachary Andersonef146f62019-07-29 07:24:02 -0700740 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800741 appStartedCompleter: futureAppStart,
742 connectionInfoCompleter: futureConnectionInfo,
743 enableDevTools: true,
Zachary Andersonef146f62019-07-29 07:24:02 -0700744 ));
Ian Hickson8acac062021-02-01 16:06:02 -0800745 await futureAppStart.future;
Zachary Andersonef146f62019-07-29 07:24:02 -0700746
Ian Hickson61a0add2021-10-08 09:25:14 -0700747 final OperationResult result = await residentRunner.restart();
Zachary Andersonef146f62019-07-29 07:24:02 -0700748 expect(result.fatal, false);
749 expect(result.code, 0);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800750
751 final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
752 expect(event.category, 'hot');
753 expect(event.parameter, 'reload');
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700754 expect(event.parameters.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
Zachary Andersonef146f62019-07-29 07:24:02 -0700755 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800756 Usage: () => TestUsage(),
Jonah Williams8beee472021-05-24 11:59:03 -0700757 }));
Zachary Andersonef146f62019-07-29 07:24:02 -0700758
Jonah Williams07caa0f2020-07-20 14:03:44 -0700759 testUsingContext('ResidentRunner can perform fast reassemble', () => testbed.run(() async {
760 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
761 listViews,
762 FakeVmServiceRequest(
763 method: 'getVM',
764 jsonResponse: fakeVM.toJson(),
765 ),
766 listViews,
767 listViews,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700768 FakeVmServiceRequest(
769 method: 'getVM',
770 jsonResponse: fakeVM.toJson(),
771 ),
772 const FakeVmServiceRequest(
773 method: 'reloadSources',
774 args: <String, Object>{
775 'isolateId': '1',
776 'pause': false,
Jonah Williams0afddf32020-10-12 09:47:41 -0700777 'rootLibUri': 'main.dart.incremental.dill',
Jonah Williams07caa0f2020-07-20 14:03:44 -0700778 },
779 jsonResponse: <String, Object>{
780 'type': 'ReloadReport',
781 'success': true,
782 'details': <String, Object>{
783 'loadedLibraryCount': 1,
784 },
785 },
786 ),
Jonah Williams07caa0f2020-07-20 14:03:44 -0700787 FakeVmServiceRequest(
788 method: 'getIsolate',
789 args: <String, Object>{
790 'isolateId': '1',
791 },
792 jsonResponse: fakeUnpausedIsolate.toJson(),
793 ),
794 FakeVmServiceRequest(
795 method: 'ext.flutter.fastReassemble',
796 args: <String, Object>{
797 'isolateId': fakeUnpausedIsolate.id,
Jonah Williamsa19f5ba2020-09-19 11:02:04 -0700798 'className': 'FOO',
Jonah Williams07caa0f2020-07-20 14:03:44 -0700799 },
800 ),
801 ]);
Christopher Fujino91dd3272021-10-02 10:18:03 -0700802 final FakeDelegateFlutterDevice flutterDevice = FakeDelegateFlutterDevice(
Jonah Williams73df0692021-06-14 16:29:02 -0700803 device,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700804 BuildInfo.debug,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700805 FakeResidentCompiler(),
Jonah Williams73df0692021-06-14 16:29:02 -0700806 devFS,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700807 )..vmService = fakeVmServiceHost.vmService;
808 residentRunner = HotRunner(
809 <FlutterDevice>[
810 flutterDevice,
811 ],
812 stayResident: false,
813 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -0800814 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -0800815 devtoolsHandler: createNoOpHandler,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700816 );
Jonah Williams73df0692021-06-14 16:29:02 -0700817 devFS.nextUpdateReport = UpdateFSReport(
Jonah Williams8beee472021-05-24 11:59:03 -0700818 success: true,
819 fastReassembleClassName: 'FOO',
820 invalidatedSourcesCount: 1,
821 );
Jonah Williams07caa0f2020-07-20 14:03:44 -0700822
Ian Hickson8acac062021-02-01 16:06:02 -0800823 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
824 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams07caa0f2020-07-20 14:03:44 -0700825 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800826 appStartedCompleter: futureAppStart,
827 connectionInfoCompleter: futureConnectionInfo,
828 enableDevTools: true,
Jonah Williams07caa0f2020-07-20 14:03:44 -0700829 ));
830
Ian Hickson8acac062021-02-01 16:06:02 -0800831 await futureAppStart.future;
Ian Hickson61a0add2021-10-08 09:25:14 -0700832 final OperationResult result = await residentRunner.restart();
Jonah Williamsa19f5ba2020-09-19 11:02:04 -0700833
Jonah Williams07caa0f2020-07-20 14:03:44 -0700834 expect(result.fatal, false);
835 expect(result.code, 0);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800836
837 final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
838 expect(event.category, 'hot');
839 expect(event.parameter, 'reload');
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700840 expect(event.parameters.fastReassemble, true);
Jonah Williams07caa0f2020-07-20 14:03:44 -0700841 }, overrides: <Type, Generator>{
842 FileSystem: () => MemoryFileSystem.test(),
Ian Hickson61a0add2021-10-08 09:25:14 -0700843 Platform: () => FakePlatform(),
Jonah Williams07caa0f2020-07-20 14:03:44 -0700844 ProjectFileInvalidator: () => FakeProjectFileInvalidator(),
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800845 Usage: () => TestUsage(),
Jonah Williamsa19f5ba2020-09-19 11:02:04 -0700846 FeatureFlags: () => TestFeatureFlags(isSingleWidgetReloadEnabled: true),
Jonah Williams8beee472021-05-24 11:59:03 -0700847 }));
Jonah Williams07caa0f2020-07-20 14:03:44 -0700848
Jenn Magder88631332020-06-08 11:28:02 -0700849 testUsingContext('ResidentRunner can send target platform to analytics from full restart', () => testbed.run(() async {
Jonah Williams9202e542020-04-20 15:15:54 -0700850 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700851 listViews,
852 listViews,
853 listViews,
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700854 FakeVmServiceRequest(
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700855 method: 'getIsolate',
856 args: <String, Object>{
857 'isolateId': fakeUnpausedIsolate.id,
858 },
859 jsonResponse: fakeUnpausedIsolate.toJson(),
860 ),
861 FakeVmServiceRequest(
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700862 method: 'getVM',
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700863 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
864 ),
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700865 listViews,
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700866 const FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -0700867 method: 'streamListen',
868 args: <String, Object>{
869 'streamId': 'Isolate',
870 },
871 ),
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700872 FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -0700873 method: kRunInViewMethod,
874 args: <String, Object>{
Jonah Williamsffcf1db2020-04-27 17:41:42 -0700875 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -0700876 'mainScript': 'main.dart.dill',
Jonah Williams9202e542020-04-20 15:15:54 -0700877 'assetDirectory': 'build/flutter_assets',
878 },
879 ),
880 FakeVmServiceStreamResponse(
881 streamId: 'Isolate',
882 event: vm_service.Event(
883 timestamp: 0,
884 kind: vm_service.EventKind.kIsolateRunnable,
885 )
886 )
887 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800888 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
889 final Completer<void> futureAppStart = Completer<void>.sync();
Zachary Andersond208ce22019-07-30 12:18:15 -0700890 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800891 appStartedCompleter: futureAppStart,
892 connectionInfoCompleter: futureConnectionInfo,
893 enableDevTools: true,
Zachary Andersond208ce22019-07-30 12:18:15 -0700894 ));
895
896 final OperationResult result = await residentRunner.restart(fullRestart: true);
897 expect(result.fatal, false);
898 expect(result.code, 0);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800899
900 final TestUsageEvent event = (globals.flutterUsage as TestUsage).events.first;
901 expect(event.category, 'hot');
902 expect(event.parameter, 'restart');
Lau Ching Jun2acd00072021-05-18 20:29:03 -0700903 expect(event.parameters.hotEventTargetPlatform, getNameForTargetPlatform(TargetPlatform.android_arm));
Jonah Williams9b7b9d72020-05-05 12:09:51 -0700904 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Zachary Andersond208ce22019-07-30 12:18:15 -0700905 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -0800906 Usage: () => TestUsage(),
Jonah Williams8beee472021-05-24 11:59:03 -0700907 }));
Zachary Andersond208ce22019-07-30 12:18:15 -0700908
Danny Tuppeny99e85b12021-11-19 06:23:09 +0000909 testUsingContext('ResidentRunner can remove breakpoints and exception-pause-mode from paused isolate during hot restart', () => testbed.run(() async {
Jonah Williamsc6dce232020-07-24 15:34:55 -0700910 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
911 listViews,
912 listViews,
913 listViews,
914 FakeVmServiceRequest(
915 method: 'getIsolate',
916 args: <String, Object>{
917 'isolateId': fakeUnpausedIsolate.id,
918 },
919 jsonResponse: fakePausedIsolate.toJson(),
920 ),
921 FakeVmServiceRequest(
922 method: 'getVM',
923 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
924 ),
925 const FakeVmServiceRequest(
Anna Gringauzed7466d82021-12-07 14:29:07 -0800926 method: 'setIsolatePauseMode',
Danny Tuppeny99e85b12021-11-19 06:23:09 +0000927 args: <String, String>{
928 'isolateId': '1',
Anna Gringauzed7466d82021-12-07 14:29:07 -0800929 'exceptionPauseMode': 'None',
Danny Tuppeny99e85b12021-11-19 06:23:09 +0000930 }
931 ),
932 const FakeVmServiceRequest(
Jonah Williamsc6dce232020-07-24 15:34:55 -0700933 method: 'removeBreakpoint',
934 args: <String, String>{
935 'isolateId': '1',
936 'breakpointId': 'test-breakpoint',
937 }
938 ),
939 const FakeVmServiceRequest(
940 method: 'resume',
941 args: <String, String>{
942 'isolateId': '1',
943 }
944 ),
945 listViews,
946 const FakeVmServiceRequest(
947 method: 'streamListen',
948 args: <String, Object>{
949 'streamId': 'Isolate',
950 },
951 ),
952 FakeVmServiceRequest(
953 method: kRunInViewMethod,
954 args: <String, Object>{
955 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -0700956 'mainScript': 'main.dart.dill',
Jonah Williamsc6dce232020-07-24 15:34:55 -0700957 'assetDirectory': 'build/flutter_assets',
958 },
959 ),
960 FakeVmServiceStreamResponse(
961 streamId: 'Isolate',
962 event: vm_service.Event(
963 timestamp: 0,
964 kind: vm_service.EventKind.kIsolateRunnable,
965 )
966 )
967 ]);
Ian Hickson8acac062021-02-01 16:06:02 -0800968 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
969 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williamsc6dce232020-07-24 15:34:55 -0700970 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -0800971 appStartedCompleter: futureAppStart,
972 connectionInfoCompleter: futureConnectionInfo,
973 enableDevTools: true,
Jonah Williamsc6dce232020-07-24 15:34:55 -0700974 ));
975
976 final OperationResult result = await residentRunner.restart(fullRestart: true);
977
978 expect(result.isOk, true);
979 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -0700980 }));
Jonah Williamsc6dce232020-07-24 15:34:55 -0700981
Jonah Williams6d360562020-09-09 15:56:25 -0700982 testUsingContext('ResidentRunner will alternative the name of the dill file uploaded for a hot restart', () => testbed.run(() async {
983 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
984 listViews,
985 listViews,
986 listViews,
987 FakeVmServiceRequest(
988 method: 'getIsolate',
989 args: <String, Object>{
990 'isolateId': fakeUnpausedIsolate.id,
991 },
992 jsonResponse: fakeUnpausedIsolate.toJson(),
993 ),
994 FakeVmServiceRequest(
995 method: 'getVM',
996 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
997 ),
998 listViews,
999 const FakeVmServiceRequest(
1000 method: 'streamListen',
1001 args: <String, Object>{
1002 'streamId': 'Isolate',
1003 },
1004 ),
1005 FakeVmServiceRequest(
1006 method: kRunInViewMethod,
1007 args: <String, Object>{
1008 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -07001009 'mainScript': 'main.dart.dill',
Jonah Williams6d360562020-09-09 15:56:25 -07001010 'assetDirectory': 'build/flutter_assets',
1011 },
1012 ),
1013 FakeVmServiceStreamResponse(
1014 streamId: 'Isolate',
1015 event: vm_service.Event(
1016 timestamp: 0,
1017 kind: vm_service.EventKind.kIsolateRunnable,
1018 ),
1019 ),
1020 listViews,
1021 FakeVmServiceRequest(
1022 method: 'getIsolate',
1023 args: <String, Object>{
1024 'isolateId': fakeUnpausedIsolate.id,
1025 },
1026 jsonResponse: fakeUnpausedIsolate.toJson(),
1027 ),
1028 FakeVmServiceRequest(
1029 method: 'getVM',
1030 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
1031 ),
1032 listViews,
1033 const FakeVmServiceRequest(
1034 method: 'streamListen',
1035 args: <String, Object>{
1036 'streamId': 'Isolate',
1037 },
1038 ),
1039 FakeVmServiceRequest(
1040 method: kRunInViewMethod,
1041 args: <String, Object>{
1042 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -07001043 'mainScript': 'main.dart.swap.dill',
Jonah Williams6d360562020-09-09 15:56:25 -07001044 'assetDirectory': 'build/flutter_assets',
1045 },
1046 ),
1047 FakeVmServiceStreamResponse(
1048 streamId: 'Isolate',
1049 event: vm_service.Event(
1050 timestamp: 0,
1051 kind: vm_service.EventKind.kIsolateRunnable,
1052 ),
1053 ),
1054 listViews,
1055 FakeVmServiceRequest(
1056 method: 'getIsolate',
1057 args: <String, Object>{
1058 'isolateId': fakeUnpausedIsolate.id,
1059 },
1060 jsonResponse: fakeUnpausedIsolate.toJson(),
1061 ),
1062 FakeVmServiceRequest(
1063 method: 'getVM',
1064 jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
1065 ),
1066 listViews,
1067 const FakeVmServiceRequest(
1068 method: 'streamListen',
1069 args: <String, Object>{
1070 'streamId': 'Isolate',
1071 },
1072 ),
1073 FakeVmServiceRequest(
1074 method: kRunInViewMethod,
1075 args: <String, Object>{
1076 'viewId': fakeFlutterView.id,
Jonah Williams0afddf32020-10-12 09:47:41 -07001077 'mainScript': 'main.dart.dill',
Jonah Williams6d360562020-09-09 15:56:25 -07001078 'assetDirectory': 'build/flutter_assets',
1079 },
1080 ),
1081 FakeVmServiceStreamResponse(
1082 streamId: 'Isolate',
1083 event: vm_service.Event(
1084 timestamp: 0,
1085 kind: vm_service.EventKind.kIsolateRunnable,
1086 ),
1087 )
1088 ]);
Ian Hickson8acac062021-02-01 16:06:02 -08001089 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
1090 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams6d360562020-09-09 15:56:25 -07001091 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -08001092 appStartedCompleter: futureAppStart,
1093 connectionInfoCompleter: futureConnectionInfo,
1094 enableDevTools: true,
Jonah Williams6d360562020-09-09 15:56:25 -07001095 ));
1096
1097 await residentRunner.restart(fullRestart: true);
1098 await residentRunner.restart(fullRestart: true);
1099 await residentRunner.restart(fullRestart: true);
1100
1101 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -07001102 }));
Jonah Williams6d360562020-09-09 15:56:25 -07001103
Jenn Magder88631332020-06-08 11:28:02 -07001104 testUsingContext('ResidentRunner Can handle an RPC exception from hot restart', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001105 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1106 listViews,
1107 listViews,
1108 ]);
Ian Hickson8acac062021-02-01 16:06:02 -08001109 final Completer<DebugConnectionInfo> futureConnectionInfo = Completer<DebugConnectionInfo>.sync();
1110 final Completer<void> futureAppStart = Completer<void>.sync();
Jonah Williams1957c662019-07-18 10:40:40 -07001111 unawaited(residentRunner.attach(
Ian Hickson8acac062021-02-01 16:06:02 -08001112 appStartedCompleter: futureAppStart,
1113 connectionInfoCompleter: futureConnectionInfo,
1114 enableDevTools: true,
Jonah Williams1957c662019-07-18 10:40:40 -07001115 ));
Ian Hickson8acac062021-02-01 16:06:02 -08001116 await futureAppStart.future;
Jonah Williams73df0692021-06-14 16:29:02 -07001117 flutterDevice.reportError = vm_service.RPCError('something bad happened', 666, '');
Jonah Williams1957c662019-07-18 10:40:40 -07001118
1119 final OperationResult result = await residentRunner.restart(fullRestart: true);
1120 expect(result.fatal, true);
1121 expect(result.code, 1);
Jenn Magder6ecb8cb2021-01-28 18:49:04 -08001122
1123 expect((globals.flutterUsage as TestUsage).events, contains(
Lau Ching Jun2acd00072021-05-18 20:29:03 -07001124 TestUsageEvent('hot', 'exception', parameters: CustomDimensions(
1125 hotEventTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
1126 hotEventSdkName: 'Android',
1127 hotEventEmulator: false,
1128 hotEventFullRestart: true,
Ian Hickson61a0add2021-10-08 09:25:14 -07001129 fastReassemble: false,
Lau Ching Jun2acd00072021-05-18 20:29:03 -07001130 )),
Jenn Magder6ecb8cb2021-01-28 18:49:04 -08001131 ));
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001132 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams1957c662019-07-18 10:40:40 -07001133 }, overrides: <Type, Generator>{
Jenn Magder6ecb8cb2021-01-28 18:49:04 -08001134 Usage: () => TestUsage(),
Jonah Williams8beee472021-05-24 11:59:03 -07001135 }));
Jonah Williams1957c662019-07-18 10:40:40 -07001136
Jenn Magder88631332020-06-08 11:28:02 -07001137 testUsingContext('ResidentRunner uses temp directory when there is no output dill path', () => testbed.run(() {
Jonah Williams9202e542020-04-20 15:15:54 -07001138 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Ian Hicksoncdc2d992019-10-07 16:43:04 -07001139 expect(residentRunner.artifactDirectory.path, contains('flutter_tool.'));
Jonah Williams6d378672019-09-11 12:57:43 -07001140
1141 final ResidentRunner otherRunner = HotRunner(
1142 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001143 flutterDevice,
Jonah Williams6d378672019-09-11 12:57:43 -07001144 ],
1145 stayResident: false,
1146 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001147 dillOutputPath: globals.fs.path.join('foobar', 'app.dill'),
Jonah Williams613a9592020-11-20 14:17:11 -08001148 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001149 devtoolsHandler: createNoOpHandler,
Jonah Williams6d378672019-09-11 12:57:43 -07001150 );
1151 expect(otherRunner.artifactDirectory.path, contains('foobar'));
1152 }));
1153
Jenn Magder88631332020-06-08 11:28:02 -07001154 testUsingContext('ResidentRunner deletes artifact directory on preExit', () => testbed.run(() async {
Jonah Williams6d8ec352020-05-29 15:43:03 -07001155 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001156 residentRunner.artifactDirectory.childFile('app.dill').createSync();
Jonah Williams6d8ec352020-05-29 15:43:03 -07001157 await residentRunner.preExit();
Jonah Williams6d8ec352020-05-29 15:43:03 -07001158
Jonah Williamse934c2f2020-06-04 10:17:43 -07001159 expect(residentRunner.artifactDirectory, isNot(exists));
Jonah Williams6d8ec352020-05-29 15:43:03 -07001160 }));
1161
Jenn Magder88631332020-06-08 11:28:02 -07001162 testUsingContext('ResidentRunner can run source generation', () => testbed.run(() async {
Shi-Hao Hongb80b4322020-09-04 00:26:58 +08001163 final File arbFile = globals.fs.file(globals.fs.path.join('lib', 'l10n', 'app_en.arb'))
1164 ..createSync(recursive: true);
Alexandre Ardhuin73301a32020-10-16 00:37:04 +02001165 arbFile.writeAsStringSync('''
1166{
Shi-Hao Hongb80b4322020-09-04 00:26:58 +08001167 "helloWorld": "Hello, World!",
1168 "@helloWorld": {
1169 "description": "Sample description"
1170 }
1171}''');
Jonah Williams70b889a2020-05-18 12:47:18 -07001172 globals.fs.file('l10n.yaml').createSync();
Shi-Hao Hongfd22fc32020-08-31 13:19:41 +08001173 globals.fs.file('pubspec.yaml').writeAsStringSync('flutter:\n generate: true\n');
Jonah Williams70b889a2020-05-18 12:47:18 -07001174
Emmanuel Garciab0a63c42021-04-23 15:34:04 -07001175 // Create necessary files for [DartPluginRegistrantTarget]
1176 final File packageConfig = globals.fs.directory('.dart_tool')
1177 .childFile('package_config.json');
1178 packageConfig.createSync(recursive: true);
1179 packageConfig.writeAsStringSync('''
1180{
1181 "configVersion": 2,
1182 "packages": [
1183 {
1184 "name": "path_provider_linux",
1185 "rootUri": "../../../path_provider_linux",
1186 "packageUri": "lib/",
1187 "languageVersion": "2.12"
1188 }
1189 ]
1190}
1191''');
1192 // Start from an empty generated_main.dart file.
1193 globals.fs.directory('.dart_tool').childDirectory('flutter_build').childFile('generated_main.dart').createSync(recursive: true);
1194
Jonah Williams70b889a2020-05-18 12:47:18 -07001195 await residentRunner.runSourceGenerators();
1196
1197 expect(testLogger.errorText, isEmpty);
Shi-Hao Honga1a096e2020-11-06 08:24:02 +08001198 expect(testLogger.statusText, isEmpty);
Jonah Williams70b889a2020-05-18 12:47:18 -07001199 }));
1200
stuartmorganed616082021-10-27 12:25:15 -04001201 testUsingContext('generated main uses correct target', () => testbed.run(() async {
1202 final File arbFile = globals.fs.file(globals.fs.path.join('lib', 'l10n', 'app_en.arb'))
1203 ..createSync(recursive: true);
1204 arbFile.writeAsStringSync('''
1205{
1206 "helloWorld": "Hello, World!",
1207 "@helloWorld": {
1208 "description": "Sample description"
1209 }
1210}''');
1211 globals.fs.file('l10n.yaml').createSync();
1212 globals.fs.file('pubspec.yaml').writeAsStringSync('''
1213flutter:
1214 generate: true
1215
1216dependencies:
1217 flutter:
1218 sdk: flutter
1219 path_provider_linux: 1.0.0
1220''');
1221
1222 // Create necessary files for [DartPluginRegistrantTarget], including a
1223 // plugin that will trigger generation.
1224 final File packageConfig = globals.fs.directory('.dart_tool')
1225 .childFile('package_config.json');
1226 packageConfig.createSync(recursive: true);
1227 packageConfig.writeAsStringSync('''
1228{
1229 "configVersion": 2,
1230 "packages": [
1231 {
1232 "name": "path_provider_linux",
1233 "rootUri": "../path_provider_linux",
1234 "packageUri": "lib/",
1235 "languageVersion": "2.12"
1236 }
1237 ]
1238}
1239''');
1240 globals.fs.file('.packages').writeAsStringSync('''
1241path_provider_linux:/path_provider_linux/lib/
1242''');
1243 final Directory fakePluginDir = globals.fs.directory('path_provider_linux');
1244 final File pluginPubspec = fakePluginDir.childFile('pubspec.yaml');
1245 pluginPubspec.createSync(recursive: true);
1246 pluginPubspec.writeAsStringSync('''
1247name: path_provider_linux
1248
1249flutter:
1250 plugin:
1251 implements: path_provider
1252 platforms:
1253 linux:
1254 dartPluginClass: PathProviderLinux
1255''');
1256
1257 residentRunner = HotRunner(
1258 <FlutterDevice>[
1259 flutterDevice,
1260 ],
1261 stayResident: false,
1262 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
1263 target: 'custom_main.dart',
1264 devtoolsHandler: createNoOpHandler,
1265 );
1266 await residentRunner.runSourceGenerators();
1267
1268 final File generatedMain = globals.fs.directory('.dart_tool')
1269 .childDirectory('flutter_build')
1270 .childFile('generated_main.dart');
1271
1272 expect(generatedMain.readAsStringSync(), contains('custom_main.dart'));
1273 expect(testLogger.errorText, isEmpty);
1274 expect(testLogger.statusText, isEmpty);
1275 }));
1276
Jenn Magder88631332020-06-08 11:28:02 -07001277 testUsingContext('ResidentRunner can run source generation - generation fails', () => testbed.run(() async {
Shi-Hao Hongb80b4322020-09-04 00:26:58 +08001278 // Intentionally define arb file with wrong name. generate_localizations defaults
1279 // to app_en.arb.
1280 final File arbFile = globals.fs.file(globals.fs.path.join('lib', 'l10n', 'foo.arb'))
1281 ..createSync(recursive: true);
Alexandre Ardhuin73301a32020-10-16 00:37:04 +02001282 arbFile.writeAsStringSync('''
1283{
Shi-Hao Hongb80b4322020-09-04 00:26:58 +08001284 "helloWorld": "Hello, World!",
1285 "@helloWorld": {
1286 "description": "Sample description"
1287 }
1288}''');
Jonah Williams70b889a2020-05-18 12:47:18 -07001289 globals.fs.file('l10n.yaml').createSync();
Shi-Hao Hongfd22fc32020-08-31 13:19:41 +08001290 globals.fs.file('pubspec.yaml').writeAsStringSync('flutter:\n generate: true\n');
Jonah Williams70b889a2020-05-18 12:47:18 -07001291
1292 await residentRunner.runSourceGenerators();
1293
Shi-Hao Hongb80b4322020-09-04 00:26:58 +08001294 expect(testLogger.errorText, allOf(contains('Exception')));
1295 expect(testLogger.statusText, isEmpty);
Jonah Williams70b889a2020-05-18 12:47:18 -07001296 }));
1297
Ian Hickson598737a2021-04-22 19:34:02 -07001298 testUsingContext('ResidentRunner printHelpDetails hot runner', () => testbed.run(() {
Jonah Williams9202e542020-04-20 15:15:54 -07001299 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams1957c662019-07-18 10:40:40 -07001300
1301 residentRunner.printHelp(details: true);
Jonah Williams1957c662019-07-18 10:40:40 -07001302
Zachary Anderson4d096c42020-01-10 16:53:01 -08001303 final CommandHelp commandHelp = residentRunner.commandHelp;
1304
Jonah Williams1957c662019-07-18 10:40:40 -07001305 // supports service protocol
1306 expect(residentRunner.supportsServiceProtocol, true);
Jonah Williams1957c662019-07-18 10:40:40 -07001307 // isRunningDebug
1308 expect(residentRunner.isRunningDebug, true);
Jonah Williams08fe78f2020-04-07 12:17:39 -07001309 // does support SkSL
1310 expect(residentRunner.supportsWriteSkSL, true);
Zachary Anderson23ce1922020-01-09 08:18:03 -08001311 // commands
1312 expect(testLogger.statusText, equals(
1313 <dynamic>[
1314 'Flutter run key commands.',
Zachary Anderson4d096c42020-01-10 16:53:01 -08001315 commandHelp.r,
1316 commandHelp.R,
Kenzie Schmoll766b4502021-05-13 09:54:10 -07001317 commandHelp.v,
Zachary Anderson4d096c42020-01-10 16:53:01 -08001318 commandHelp.s,
1319 commandHelp.w,
1320 commandHelp.t,
1321 commandHelp.L,
1322 commandHelp.S,
1323 commandHelp.U,
1324 commandHelp.i,
1325 commandHelp.p,
Ian Hickson598737a2021-04-22 19:34:02 -07001326 commandHelp.I,
Zachary Anderson4d096c42020-01-10 16:53:01 -08001327 commandHelp.o,
Ian Hickson598737a2021-04-22 19:34:02 -07001328 commandHelp.b,
Zachary Anderson4d096c42020-01-10 16:53:01 -08001329 commandHelp.P,
1330 commandHelp.a,
Ian Hickson598737a2021-04-22 19:34:02 -07001331 commandHelp.M,
1332 commandHelp.g,
1333 commandHelp.hWithDetails,
1334 commandHelp.c,
1335 commandHelp.q,
1336 '',
1337 '💪 Running with sound null safety 💪',
1338 '',
1339 'An Observatory debugger and profiler on FakeDevice is available at: null',
1340 '',
1341 ].join('\n')
1342 ));
1343 }));
1344
1345 testUsingContext('ResidentRunner printHelp hot runner', () => testbed.run(() {
1346 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
1347
1348 residentRunner.printHelp(details: false);
1349
1350 final CommandHelp commandHelp = residentRunner.commandHelp;
1351
1352 // supports service protocol
1353 expect(residentRunner.supportsServiceProtocol, true);
1354 // isRunningDebug
1355 expect(residentRunner.isRunningDebug, true);
1356 // does support SkSL
1357 expect(residentRunner.supportsWriteSkSL, true);
1358 // commands
1359 expect(testLogger.statusText, equals(
1360 <dynamic>[
1361 'Flutter run key commands.',
1362 commandHelp.r,
1363 commandHelp.R,
1364 commandHelp.hWithoutDetails,
1365 commandHelp.c,
1366 commandHelp.q,
Ian Hickson8acac062021-02-01 16:06:02 -08001367 '',
1368 '💪 Running with sound null safety 💪',
1369 '',
Jonah Williams6efe8e92021-01-29 14:27:42 -08001370 'An Observatory debugger and profiler on FakeDevice is available at: null',
Ian Hickson8acac062021-02-01 16:06:02 -08001371 '',
Zachary Anderson23ce1922020-01-09 08:18:03 -08001372 ].join('\n')
1373 ));
Jonah Williams1957c662019-07-18 10:40:40 -07001374 }));
1375
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001376 testUsingContext('ResidentRunner printHelpDetails cold runner', () => testbed.run(() {
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001377 fakeVmServiceHost = null;
1378 residentRunner = ColdRunner(
1379 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001380 flutterDevice,
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001381 ],
1382 stayResident: false,
1383 debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
Jonah Williams613a9592020-11-20 14:17:11 -08001384 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001385 devtoolsHandler: createNoOpHandler,
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001386 );
1387 residentRunner.printHelp(details: true);
1388
1389 final CommandHelp commandHelp = residentRunner.commandHelp;
1390
1391 // does not supports service protocol
1392 expect(residentRunner.supportsServiceProtocol, false);
1393 // isRunningDebug
1394 expect(residentRunner.isRunningDebug, false);
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001395 // does support SkSL
1396 expect(residentRunner.supportsWriteSkSL, false);
1397 // commands
1398 expect(testLogger.statusText, equals(
1399 <dynamic>[
1400 'Flutter run key commands.',
Kenzie Schmoll766b4502021-05-13 09:54:10 -07001401 commandHelp.v,
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001402 commandHelp.s,
Ian Hickson598737a2021-04-22 19:34:02 -07001403 commandHelp.hWithDetails,
1404 commandHelp.c,
1405 commandHelp.q,
1406 ''
1407 ].join('\n')
1408 ));
1409 }));
1410
1411 testUsingContext('ResidentRunner printHelp cold runner', () => testbed.run(() {
1412 fakeVmServiceHost = null;
1413 residentRunner = ColdRunner(
1414 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001415 flutterDevice,
Ian Hickson598737a2021-04-22 19:34:02 -07001416 ],
1417 stayResident: false,
1418 debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
1419 target: 'main.dart',
1420 devtoolsHandler: createNoOpHandler,
1421 );
1422 residentRunner.printHelp(details: false);
1423
1424 final CommandHelp commandHelp = residentRunner.commandHelp;
1425
1426 // does not supports service protocol
1427 expect(residentRunner.supportsServiceProtocol, false);
1428 // isRunningDebug
1429 expect(residentRunner.isRunningDebug, false);
1430 // does support SkSL
1431 expect(residentRunner.supportsWriteSkSL, false);
1432 // commands
1433 expect(testLogger.statusText, equals(
1434 <dynamic>[
1435 'Flutter run key commands.',
1436 commandHelp.hWithoutDetails,
Jonah Williamsc034f1a2020-09-02 17:33:41 -07001437 commandHelp.c,
1438 commandHelp.q,
1439 ''
1440 ].join('\n')
1441 ));
1442 }));
1443
Jenn Magder88631332020-06-08 11:28:02 -07001444 testUsingContext('ResidentRunner handles writeSkSL returning no data', () => testbed.run(() async {
Jonah Williams9202e542020-04-20 15:15:54 -07001445 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001446 listViews,
1447 FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -07001448 method: kGetSkSLsMethod,
1449 args: <String, Object>{
Jonah Williamsffcf1db2020-04-27 17:41:42 -07001450 'viewId': fakeFlutterView.id,
Jonah Williams9202e542020-04-20 15:15:54 -07001451 },
1452 jsonResponse: <String, Object>{
1453 'SkSLs': <String, Object>{}
1454 }
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001455 ),
Jonah Williams9202e542020-04-20 15:15:54 -07001456 ]);
Jonah Williams08fe78f2020-04-07 12:17:39 -07001457 await residentRunner.writeSkSL();
1458
Jonah Williams08576cb2020-10-12 09:31:02 -07001459 expect(testLogger.statusText, contains('No data was received'));
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001460 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams08fe78f2020-04-07 12:17:39 -07001461 }));
1462
Jenn Magder88631332020-06-08 11:28:02 -07001463 testUsingContext('ResidentRunner can write SkSL data to a unique file with engine revision, platform, and device name', () => testbed.run(() async {
Jonah Williams9202e542020-04-20 15:15:54 -07001464 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001465 listViews,
Jonah Williamsffcf1db2020-04-27 17:41:42 -07001466 FakeVmServiceRequest(
Jonah Williams9202e542020-04-20 15:15:54 -07001467 method: kGetSkSLsMethod,
1468 args: <String, Object>{
Jonah Williamsffcf1db2020-04-27 17:41:42 -07001469 'viewId': fakeFlutterView.id,
Jonah Williams9202e542020-04-20 15:15:54 -07001470 },
1471 jsonResponse: <String, Object>{
1472 'SkSLs': <String, Object>{
1473 'A': 'B',
1474 }
1475 }
1476 )
1477 ]);
Jonah Williams08fe78f2020-04-07 12:17:39 -07001478 await residentRunner.writeSkSL();
1479
Jonah Williamsc5709252020-05-08 09:44:03 -07001480 expect(testLogger.statusText, contains('flutter_01.sksl.json'));
1481 expect(globals.fs.file('flutter_01.sksl.json'), exists);
1482 expect(json.decode(globals.fs.file('flutter_01.sksl.json').readAsStringSync()), <String, Object>{
Jonah Williams368da5b2020-04-30 13:39:08 -07001483 'platform': 'android',
Jonah Williams6efe8e92021-01-29 14:27:42 -08001484 'name': 'FakeDevice',
Jonah Williams72170272021-03-05 14:04:03 -08001485 'engineRevision': 'abcdefg',
Jonah Williams08fe78f2020-04-07 12:17:39 -07001486 'data': <String, Object>{'A': 'B'}
1487 });
Jonah Williams9202e542020-04-20 15:15:54 -07001488 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams5d61bff2020-06-24 10:23:59 -07001489 }, overrides: <Type, Generator>{
1490 FileSystemUtils: () => FileSystemUtils(
1491 fileSystem: globals.fs,
1492 platform: globals.platform,
Jonah Williams72170272021-03-05 14:04:03 -08001493 ),
1494 FlutterVersion: () => FakeFlutterVersion(engineRevision: 'abcdefg')
Jonah Williams08fe78f2020-04-07 12:17:39 -07001495 }));
1496
Ian Hickson8acac062021-02-01 16:06:02 -08001497 testUsingContext('ResidentRunner ignores DevtoolsLauncher when attaching with enableDevTools: false - cold mode', () => testbed.run(() async {
1498 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1499 listViews,
1500 listViews,
Ian Hickson8acac062021-02-01 16:06:02 -08001501 ]);
1502 residentRunner = ColdRunner(
1503 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001504 flutterDevice,
Ian Hickson8acac062021-02-01 16:06:02 -08001505 ],
1506 stayResident: false,
1507 debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
1508 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001509 devtoolsHandler: createNoOpHandler,
Ian Hickson8acac062021-02-01 16:06:02 -08001510 );
Ian Hickson8acac062021-02-01 16:06:02 -08001511
Ian Hickson61a0add2021-10-08 09:25:14 -07001512 final Future<int> result = residentRunner.attach();
Ian Hickson8acac062021-02-01 16:06:02 -08001513 expect(await result, 0);
Jonah Williams8beee472021-05-24 11:59:03 -07001514 }));
Ian Hickson8acac062021-02-01 16:06:02 -08001515
Jenn Magder88631332020-06-08 11:28:02 -07001516 testUsingContext('FlutterDevice can exit from a release mode isolate with no VmService', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001517 final TestFlutterDevice flutterDevice = TestFlutterDevice(
Jonah Williams73df0692021-06-14 16:29:02 -07001518 device,
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001519 );
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001520
1521 await flutterDevice.exitApps();
1522
Jonah Williams73df0692021-06-14 16:29:02 -07001523 expect(device.appStopped, true);
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001524 }));
1525
Jonah Williamsf666f932021-06-02 17:34:02 -07001526 testUsingContext('FlutterDevice will exit an un-paused isolate using stopApp', () => testbed.run(() async {
1527 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams1957c662019-07-18 10:40:40 -07001528 final TestFlutterDevice flutterDevice = TestFlutterDevice(
Jonah Williams73df0692021-06-14 16:29:02 -07001529 device,
Jonah Williams1957c662019-07-18 10:40:40 -07001530 );
Jonah Williams9202e542020-04-20 15:15:54 -07001531 flutterDevice.vmService = fakeVmServiceHost.vmService;
Jonah Williams1957c662019-07-18 10:40:40 -07001532
Jonah Williamsffcf1db2020-04-27 17:41:42 -07001533 final Future<void> exitFuture = flutterDevice.exitApps();
1534
1535 await expectLater(exitFuture, completes);
Jonah Williams73df0692021-06-14 16:29:02 -07001536 expect(device.appStopped, true);
Jonah Williams9202e542020-04-20 15:15:54 -07001537 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams1957c662019-07-18 10:40:40 -07001538 }));
Jonah Williams3b4d9f62019-07-23 15:38:52 -07001539
Jenn Magder88631332020-06-08 11:28:02 -07001540 testUsingContext('HotRunner writes vm service file when providing debugging option', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001541 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1542 listViews,
1543 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001544 ], wsAddress: testUri);
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001545 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001546 residentRunner = HotRunner(
1547 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001548 flutterDevice,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001549 ],
1550 stayResident: false,
1551 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
Jonah Williams613a9592020-11-20 14:17:11 -08001552 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001553 devtoolsHandler: createNoOpHandler,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001554 );
Jonah Williams73df0692021-06-14 16:29:02 -07001555
Ian Hickson8acac062021-02-01 16:06:02 -08001556 await residentRunner.run(enableDevTools: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001557
Jonah Williams7ab85172021-02-10 17:04:47 -08001558 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001559 expect(await globals.fs.file('foo').readAsString(), testUri.toString());
Jonah Williams8beee472021-05-24 11:59:03 -07001560 }));
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001561
Jenn Magder88631332020-06-08 11:28:02 -07001562 testUsingContext('HotRunner copies compiled app.dill to cache during startup', () => testbed.run(() async {
Jonah Williamse934c2f2020-06-04 10:17:43 -07001563 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1564 listViews,
1565 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001566 ], wsAddress: testUri);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001567 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
1568 residentRunner = HotRunner(
1569 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001570 flutterDevice,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001571 ],
1572 stayResident: false,
1573 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -08001574 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001575 devtoolsHandler: createNoOpHandler,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001576 );
1577 residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
Jonah Williams73df0692021-06-14 16:29:02 -07001578
Ian Hickson8acac062021-02-01 16:06:02 -08001579 await residentRunner.run(enableDevTools: true);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001580
1581 expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill')).readAsString(), 'ABC');
Jonah Williams8beee472021-05-24 11:59:03 -07001582 }));
Jonah Williamse934c2f2020-06-04 10:17:43 -07001583
Jonah Williamse54f8f52020-06-09 12:03:28 -07001584 testUsingContext('HotRunner copies compiled app.dill to cache during startup with dart defines', () => testbed.run(() async {
1585 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1586 listViews,
1587 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001588 ], wsAddress: testUri);
Jonah Williamse54f8f52020-06-09 12:03:28 -07001589 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
1590 residentRunner = HotRunner(
1591 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001592 flutterDevice,
Jonah Williamse54f8f52020-06-09 12:03:28 -07001593 ],
1594 stayResident: false,
1595 debuggingOptions: DebuggingOptions.enabled(
1596 const BuildInfo(
1597 BuildMode.debug,
1598 '',
1599 treeShakeIcons: false,
1600 dartDefines: <String>['a', 'b'],
1601 )
1602 ),
Jonah Williams613a9592020-11-20 14:17:11 -08001603 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001604 devtoolsHandler: createNoOpHandler,
Jonah Williamse54f8f52020-06-09 12:03:28 -07001605 );
1606 residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
Jonah Williams73df0692021-06-14 16:29:02 -07001607
Ian Hickson8acac062021-02-01 16:06:02 -08001608 await residentRunner.run(enableDevTools: true);
Jonah Williamse54f8f52020-06-09 12:03:28 -07001609
1610 expect(await globals.fs.file(globals.fs.path.join(
1611 'build', '187ef4436122d1cc2f40dc2b92f0eba0.cache.dill')).readAsString(), 'ABC');
Jonah Williams8beee472021-05-24 11:59:03 -07001612 }));
Jonah Williamse54f8f52020-06-09 12:03:28 -07001613
Jonah Williamsc543db72020-06-30 15:49:31 -07001614 testUsingContext('HotRunner copies compiled app.dill to cache during startup with null safety', () => testbed.run(() async {
1615 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1616 listViews,
1617 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001618 ], wsAddress: testUri);
Jonah Williamsc543db72020-06-30 15:49:31 -07001619 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
1620 residentRunner = HotRunner(
1621 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001622 flutterDevice,
Jonah Williamsc543db72020-06-30 15:49:31 -07001623 ],
1624 stayResident: false,
1625 debuggingOptions: DebuggingOptions.enabled(
1626 const BuildInfo(
1627 BuildMode.debug,
1628 '',
1629 treeShakeIcons: false,
Jonah Williams1977ee72021-06-25 11:11:04 -07001630 extraFrontEndOptions: <String>['--enable-experiment=non-nullable']
Jonah Williamsc543db72020-06-30 15:49:31 -07001631 )
1632 ),
Jonah Williams613a9592020-11-20 14:17:11 -08001633 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001634 devtoolsHandler: createNoOpHandler,
Jonah Williamsc543db72020-06-30 15:49:31 -07001635 );
1636 residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
Jonah Williams73df0692021-06-14 16:29:02 -07001637
Ian Hickson8acac062021-02-01 16:06:02 -08001638 await residentRunner.run(enableDevTools: true);
Jonah Williamsc543db72020-06-30 15:49:31 -07001639
1640 expect(await globals.fs.file(globals.fs.path.join(
Jonah Williams1977ee72021-06-25 11:11:04 -07001641 'build', 'cache.dill')).readAsString(), 'ABC');
Jonah Williams8beee472021-05-24 11:59:03 -07001642 }));
Jonah Williamsc543db72020-06-30 15:49:31 -07001643
Jenn Magder88631332020-06-08 11:28:02 -07001644 testUsingContext('HotRunner does not copy app.dill if a dillOutputPath is given', () => testbed.run(() async {
Jonah Williamse934c2f2020-06-04 10:17:43 -07001645 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1646 listViews,
1647 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001648 ], wsAddress: testUri);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001649 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
1650 residentRunner = HotRunner(
1651 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001652 flutterDevice,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001653 ],
1654 stayResident: false,
1655 dillOutputPath: 'test',
1656 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -08001657 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001658 devtoolsHandler: createNoOpHandler,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001659 );
1660 residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
Jonah Williams73df0692021-06-14 16:29:02 -07001661
Ian Hickson8acac062021-02-01 16:06:02 -08001662 await residentRunner.run(enableDevTools: true);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001663
1664 expect(globals.fs.file(globals.fs.path.join('build', 'cache.dill')), isNot(exists));
Jonah Williams8beee472021-05-24 11:59:03 -07001665 }));
Jonah Williamse934c2f2020-06-04 10:17:43 -07001666
Jenn Magder88631332020-06-08 11:28:02 -07001667 testUsingContext('HotRunner copies compiled app.dill to cache during startup with --track-widget-creation', () => testbed.run(() async {
Jonah Williamse934c2f2020-06-04 10:17:43 -07001668 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1669 listViews,
1670 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001671 ], wsAddress: testUri);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001672 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
1673 residentRunner = HotRunner(
1674 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001675 flutterDevice,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001676 ],
1677 stayResident: false,
1678 debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
1679 BuildMode.debug,
1680 '',
1681 treeShakeIcons: false,
1682 trackWidgetCreation: true,
1683 )),
Jonah Williams613a9592020-11-20 14:17:11 -08001684 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001685 devtoolsHandler: createNoOpHandler,
Jonah Williamse934c2f2020-06-04 10:17:43 -07001686 );
1687 residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
Jonah Williams73df0692021-06-14 16:29:02 -07001688
Ian Hickson8acac062021-02-01 16:06:02 -08001689 await residentRunner.run(enableDevTools: true);
Jonah Williamse934c2f2020-06-04 10:17:43 -07001690
1691 expect(await globals.fs.file(globals.fs.path.join('build', 'cache.dill.track.dill')).readAsString(), 'ABC');
Jonah Williams8beee472021-05-24 11:59:03 -07001692 }));
Jonah Williamse934c2f2020-06-04 10:17:43 -07001693
Jonah Williams6efe8e92021-01-29 14:27:42 -08001694 testUsingContext('HotRunner calls device dispose', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001695 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1696 listViews,
1697 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001698 ], wsAddress: testUri);
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001699 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
Zachary Anderson99684ce2019-12-05 08:48:00 -08001700 residentRunner = HotRunner(
1701 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001702 flutterDevice,
Zachary Anderson99684ce2019-12-05 08:48:00 -08001703 ],
1704 stayResident: false,
1705 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
Jonah Williams613a9592020-11-20 14:17:11 -08001706 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001707 devtoolsHandler: createNoOpHandler,
Zachary Anderson99684ce2019-12-05 08:48:00 -08001708 );
Zachary Anderson99684ce2019-12-05 08:48:00 -08001709
Zachary Anderson99684ce2019-12-05 08:48:00 -08001710 await residentRunner.run();
Jonah Williams73df0692021-06-14 16:29:02 -07001711 expect(device.disposed, true);
Jonah Williams8beee472021-05-24 11:59:03 -07001712 }));
Zachary Anderson99684ce2019-12-05 08:48:00 -08001713
Jenn Magder88631332020-06-08 11:28:02 -07001714 testUsingContext('HotRunner handles failure to write vmservice file', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001715 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1716 listViews,
1717 listViews,
1718 ]);
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001719 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001720 residentRunner = HotRunner(
1721 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001722 flutterDevice,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001723 ],
1724 stayResident: false,
1725 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
Jonah Williams613a9592020-11-20 14:17:11 -08001726 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001727 devtoolsHandler: createNoOpHandler,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001728 );
Jonah Williams73df0692021-06-14 16:29:02 -07001729
Ian Hickson8acac062021-02-01 16:06:02 -08001730 await residentRunner.run(enableDevTools: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001731
Alexandre Ardhuin980f14e2019-11-24 06:54:43 +01001732 expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo'));
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001733 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001734 }, overrides: <Type, Generator>{
Jenn Magdere8fbb432020-09-29 17:50:33 -07001735 FileSystem: () => ThrowingForwardingFileSystem(MemoryFileSystem.test()),
Jonah Williams8beee472021-05-24 11:59:03 -07001736 }));
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001737
Jenn Magder88631332020-06-08 11:28:02 -07001738 testUsingContext('ColdRunner writes vm service file when providing debugging option', () => testbed.run(() async {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001739 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
1740 listViews,
Jonah Williamsa3b14c52021-02-24 15:40:33 -08001741 ], wsAddress: testUri);
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001742 globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001743 residentRunner = ColdRunner(
1744 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07001745 flutterDevice,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001746 ],
1747 stayResident: false,
1748 debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
Jonah Williams613a9592020-11-20 14:17:11 -08001749 target: 'main.dart',
Jonah Williams7ab85172021-02-10 17:04:47 -08001750 devtoolsHandler: createNoOpHandler,
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001751 );
Jonah Williams73df0692021-06-14 16:29:02 -07001752
Ian Hickson8acac062021-02-01 16:06:02 -08001753 await residentRunner.run(enableDevTools: true);
Jonah Williamse22d4aa2019-10-15 13:05:47 -07001754
Jonah Williamsee7a37f2020-01-06 11:04:20 -08001755 expect(await globals.fs.file('foo').readAsString(), testUri.toString());
Jonah Williams9b7b9d72020-05-05 12:09:51 -07001756 expect(fakeVmServiceHost.hasRemainingExpectations, false);
Jonah Williams8beee472021-05-24 11:59:03 -07001757 }));
Jonah Williams79a985f2019-10-22 20:35:05 -07001758
Jonah Williams7ca324a2020-06-30 12:29:42 -07001759 testUsingContext('FlutterDevice uses dartdevc configuration when targeting web', () async {
Jonah Williams9202e542020-04-20 15:15:54 -07001760 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams73df0692021-06-14 16:29:02 -07001761 final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
Jonah Williams79a985f2019-10-22 20:35:05 -07001762 final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
Jonah Williams73df0692021-06-14 16:29:02 -07001763 device,
Jonah Williams7ca324a2020-06-30 12:29:42 -07001764 buildInfo: const BuildInfo(
1765 BuildMode.debug,
1766 '',
1767 treeShakeIcons: false,
1768 nullSafetyMode: NullSafetyMode.unsound,
1769 ),
Jonah Williams79a985f2019-10-22 20:35:05 -07001770 target: null,
Ian Hickson61a0add2021-10-08 09:25:14 -07001771 platform: FakePlatform(),
Alexandre Ardhuin980f14e2019-11-24 06:54:43 +01001772 )).generator as DefaultResidentCompiler;
Jonah Williams79a985f2019-10-22 20:35:05 -07001773
Jonah Williams6d8ec352020-05-29 15:43:03 -07001774 expect(residentCompiler.initializeFromDill,
Jonah Williams0a73ecf2020-11-13 09:41:11 -08001775 globals.fs.path.join(getBuildDirectory(), 'fbbe6a61fb7a1de317d381f8df4814e5.cache.dill'));
Jonah Williams515027a2020-02-28 11:26:02 -08001776 expect(residentCompiler.librariesSpec,
Jonah Williamsb30d97a2021-04-22 19:29:02 -07001777 globals.fs.file(globals.artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson))
Jonah Williams515027a2020-02-28 11:26:02 -08001778 .uri.toString());
Jonah Williams79a985f2019-10-22 20:35:05 -07001779 expect(residentCompiler.targetModel, TargetModel.dartdevc);
1780 expect(residentCompiler.sdkRoot,
Alexandre Ardhuin34059ee2021-06-01 20:14:06 +02001781 '${globals.artifacts.getHostArtifact(HostArtifact.flutterWebSdk).path}/');
Jonah Williamsb30d97a2021-04-22 19:29:02 -07001782 expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformKernelDill');
Jonah Williams7ca324a2020-06-30 12:29:42 -07001783 }, overrides: <Type, Generator>{
1784 Artifacts: () => Artifacts.test(),
1785 FileSystem: () => MemoryFileSystem.test(),
1786 ProcessManager: () => FakeProcessManager.any(),
1787 });
1788
1789 testUsingContext('FlutterDevice uses dartdevc configuration when targeting web with null-safety autodetected', () async {
1790 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams73df0692021-06-14 16:29:02 -07001791 final FakeDevice device = FakeDevice(targetPlatform: TargetPlatform.web_javascript);
Jonah Williams7ca324a2020-06-30 12:29:42 -07001792
1793 final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
Jonah Williams73df0692021-06-14 16:29:02 -07001794 device,
Jonah Williams7ca324a2020-06-30 12:29:42 -07001795 buildInfo: const BuildInfo(
1796 BuildMode.debug,
1797 '',
1798 treeShakeIcons: false,
1799 extraFrontEndOptions: <String>['--enable-experiment=non-nullable'],
1800 ),
Jonah Williams7ca324a2020-06-30 12:29:42 -07001801 target: null,
Ian Hickson61a0add2021-10-08 09:25:14 -07001802 platform: FakePlatform(),
Jonah Williams7ca324a2020-06-30 12:29:42 -07001803 )).generator as DefaultResidentCompiler;
1804
1805 expect(residentCompiler.initializeFromDill,
Jonah Williams1977ee72021-06-25 11:11:04 -07001806 globals.fs.path.join(getBuildDirectory(), '80b1a4cf4e7b90e1ab5f72022a0bc624.cache.dill'));
Jonah Williams7ca324a2020-06-30 12:29:42 -07001807 expect(residentCompiler.librariesSpec,
Jonah Williamsb30d97a2021-04-22 19:29:02 -07001808 globals.fs.file(globals.artifacts.getHostArtifact(HostArtifact.flutterWebLibrariesJson))
Jonah Williams7ca324a2020-06-30 12:29:42 -07001809 .uri.toString());
1810 expect(residentCompiler.targetModel, TargetModel.dartdevc);
1811 expect(residentCompiler.sdkRoot,
Alexandre Ardhuin34059ee2021-06-01 20:14:06 +02001812 '${globals.artifacts.getHostArtifact(HostArtifact.flutterWebSdk).path}/');
Jonah Williamsb30d97a2021-04-22 19:29:02 -07001813 expect(residentCompiler.platformDill, 'file:///HostArtifact.webPlatformSoundKernelDill');
Jonah Williams7ca324a2020-06-30 12:29:42 -07001814 }, overrides: <Type, Generator>{
1815 Artifacts: () => Artifacts.test(),
1816 FileSystem: () => MemoryFileSystem.test(),
1817 ProcessManager: () => FakeProcessManager.any(),
Jonah Williams8beee472021-05-24 11:59:03 -07001818 });
Jenn Magder2e7d9132019-11-01 14:37:17 -07001819
Jonah Williamsa19f5ba2020-09-19 11:02:04 -07001820 testUsingContext('FlutterDevice passes flutter-widget-cache flag when feature is enabled', () async {
1821 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Ian Hickson61a0add2021-10-08 09:25:14 -07001822 final FakeDevice device = FakeDevice();
Jonah Williamsa19f5ba2020-09-19 11:02:04 -07001823
1824 final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
Jonah Williams73df0692021-06-14 16:29:02 -07001825 device,
Jonah Williamsa19f5ba2020-09-19 11:02:04 -07001826 buildInfo: const BuildInfo(
1827 BuildMode.debug,
1828 '',
1829 treeShakeIcons: false,
1830 extraFrontEndOptions: <String>[],
1831 ),
Jonah Williams51ededb2020-09-23 07:03:59 -07001832 target: null, platform: null,
Jonah Williamsa19f5ba2020-09-19 11:02:04 -07001833 )).generator as DefaultResidentCompiler;
1834
1835 expect(residentCompiler.extraFrontEndOptions,
1836 contains('--flutter-widget-cache'));
1837 }, overrides: <Type, Generator>{
1838 Artifacts: () => Artifacts.test(),
1839 FileSystem: () => MemoryFileSystem.test(),
1840 ProcessManager: () => FakeProcessManager.any(),
1841 FeatureFlags: () => TestFeatureFlags(isSingleWidgetReloadEnabled: true)
1842 });
1843
Jonah Williams67a57eb2021-06-10 11:59:04 -07001844 testUsingContext('FlutterDevice passes alternative-invalidation-strategy flag', () async {
Jonah Williams18167782020-12-01 09:54:23 -08001845 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Ian Hickson61a0add2021-10-08 09:25:14 -07001846 final FakeDevice device = FakeDevice();
Jonah Williams6efe8e92021-01-29 14:27:42 -08001847
Jonah Williams18167782020-12-01 09:54:23 -08001848
1849 final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
Jonah Williams73df0692021-06-14 16:29:02 -07001850 device,
Jonah Williams18167782020-12-01 09:54:23 -08001851 buildInfo: const BuildInfo(
1852 BuildMode.debug,
1853 '',
1854 treeShakeIcons: false,
1855 extraFrontEndOptions: <String>[],
1856 ),
1857 target: null, platform: null,
1858 )).generator as DefaultResidentCompiler;
1859
1860 expect(residentCompiler.extraFrontEndOptions,
1861 contains('--enable-experiment=alternative-invalidation-strategy'));
1862 }, overrides: <Type, Generator>{
1863 Artifacts: () => Artifacts.test(),
1864 FileSystem: () => MemoryFileSystem.test(),
1865 ProcessManager: () => FakeProcessManager.any(),
Jonah Williams18167782020-12-01 09:54:23 -08001866 });
1867
Lau Ching Juna9d61312021-05-26 23:06:38 -07001868 testUsingContext('FlutterDevice passes initializeFromDill parameter if specified', () async {
1869 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Ian Hickson61a0add2021-10-08 09:25:14 -07001870 final FakeDevice device = FakeDevice();
Lau Ching Juna9d61312021-05-26 23:06:38 -07001871
1872 final DefaultResidentCompiler residentCompiler = (await FlutterDevice.create(
Jonah Williams73df0692021-06-14 16:29:02 -07001873 device,
Lau Ching Juna9d61312021-05-26 23:06:38 -07001874 buildInfo: const BuildInfo(
1875 BuildMode.debug,
1876 '',
1877 treeShakeIcons: false,
1878 extraFrontEndOptions: <String>[],
1879 initializeFromDill: '/foo/bar.dill',
1880 ),
1881 target: null, platform: null,
1882 )).generator as DefaultResidentCompiler;
1883
1884 expect(residentCompiler.initializeFromDill, '/foo/bar.dill');
1885 }, overrides: <Type, Generator>{
1886 Artifacts: () => Artifacts.test(),
1887 FileSystem: () => MemoryFileSystem.test(),
1888 ProcessManager: () => FakeProcessManager.any(),
1889 });
1890
Ben Konyi92427f22021-01-25 12:29:05 -08001891 testUsingContext('Handle existing VM service clients DDS error', () => testbed.run(() async {
1892 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
Jonah Williams73df0692021-06-14 16:29:02 -07001893 final FakeDevice device = FakeDevice()
Jonah Williams6b3093b2021-03-31 12:59:00 -07001894 ..dds = DartDevelopmentService();
Ben Konyiac3c4432021-10-20 22:05:49 -07001895 ddsLauncherCallback = (Uri uri, {bool enableAuthCodes, bool ipv6, Uri serviceUri}) {
Jenn Magder2d550322021-08-17 21:12:03 -07001896 expect(uri, Uri(scheme: 'foo', host: 'bar'));
1897 expect(enableAuthCodes, isTrue);
1898 expect(ipv6, isFalse);
1899 expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0));
Ben Konyi92427f22021-01-25 12:29:05 -08001900 throw FakeDartDevelopmentServiceException(message:
1901 'Existing VM service clients prevent DDS from taking control.',
1902 );
1903 };
1904 final TestFlutterDevice flutterDevice = TestFlutterDevice(
Jonah Williams73df0692021-06-14 16:29:02 -07001905 device,
Ben Konyi92427f22021-01-25 12:29:05 -08001906 observatoryUris: Stream<Uri>.value(testUri),
1907 );
1908 bool caught = false;
1909 final Completer<void>done = Completer<void>();
1910 runZonedGuarded(() {
1911 flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete());
1912 }, (Object e, StackTrace st) {
1913 expect(e is ToolExit, true);
1914 expect((e as ToolExit).message,
1915 contains('Existing VM service clients prevent DDS from taking control.',
1916 ));
1917 done.complete();
1918 caught = true;
1919 });
1920 await done.future;
1921 if (!caught) {
1922 fail('Expected ToolExit to be thrown.');
1923 }
1924 }, overrides: <Type, Generator>{
1925 VMServiceConnector: () => (Uri httpUri, {
1926 ReloadSources reloadSources,
1927 Restart restart,
1928 CompileExpression compileExpression,
1929 GetSkSLMethod getSkSLMethod,
1930 PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
1931 io.CompressionOptions compression,
1932 Device device,
Jonah Williams4ae68a32021-04-01 13:23:40 -07001933 Logger logger,
Jonah Williams6728cf32021-06-10 12:00:38 -07001934 }) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
Ben Konyi92427f22021-01-25 12:29:05 -08001935 }));
1936
Jenn Magder2d550322021-08-17 21:12:03 -07001937 testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async {
1938 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
1939 final FakeDevice device = FakeDevice()
1940 ..dds = DartDevelopmentService();
1941 final Completer<void>done = Completer<void>();
Ben Konyiac3c4432021-10-20 22:05:49 -07001942 ddsLauncherCallback = (Uri uri, {bool enableAuthCodes, bool ipv6, Uri serviceUri}) async {
Jenn Magder2d550322021-08-17 21:12:03 -07001943 expect(uri, Uri(scheme: 'foo', host: 'bar'));
1944 expect(enableAuthCodes, isFalse);
1945 expect(ipv6, isTrue);
1946 expect(serviceUri, Uri(scheme: 'http', host: '::1', port: 0));
1947 done.complete();
1948 return null;
1949 };
1950 final TestFlutterDevice flutterDevice = TestFlutterDevice(
1951 device,
1952 observatoryUris: Stream<Uri>.value(testUri),
1953 );
1954 await flutterDevice.connect(allowExistingDdsInstance: true, ipv6: true, disableServiceAuthCodes: true);
1955 await done.future;
1956 }, overrides: <Type, Generator>{
1957 VMServiceConnector: () => (Uri httpUri, {
1958 ReloadSources reloadSources,
1959 Restart restart,
1960 CompileExpression compileExpression,
1961 GetSkSLMethod getSkSLMethod,
1962 PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
1963 io.CompressionOptions compression,
1964 Device device,
1965 Logger logger,
1966 }) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
1967 }));
1968
Ben Konyi620a8282020-12-22 10:24:04 -08001969 testUsingContext('Failed DDS start outputs error message', () => testbed.run(() async {
1970 // See https://github.com/flutter/flutter/issues/72385 for context.
Jonah Williams73df0692021-06-14 16:29:02 -07001971 final FakeDevice device = FakeDevice()
Jonah Williams6b3093b2021-03-31 12:59:00 -07001972 ..dds = DartDevelopmentService();
Ben Konyiac3c4432021-10-20 22:05:49 -07001973 ddsLauncherCallback = (Uri uri, {bool enableAuthCodes, bool ipv6, Uri serviceUri}) {
Jenn Magder2d550322021-08-17 21:12:03 -07001974 expect(uri, Uri(scheme: 'foo', host: 'bar'));
1975 expect(enableAuthCodes, isTrue);
1976 expect(ipv6, isFalse);
1977 expect(serviceUri, Uri(scheme: 'http', host: '127.0.0.1', port: 0));
Ben Konyi620a8282020-12-22 10:24:04 -08001978 throw FakeDartDevelopmentServiceException(message: 'No URI');
1979 };
1980 final TestFlutterDevice flutterDevice = TestFlutterDevice(
Jonah Williams73df0692021-06-14 16:29:02 -07001981 device,
Ben Konyi620a8282020-12-22 10:24:04 -08001982 observatoryUris: Stream<Uri>.value(testUri),
1983 );
1984 bool caught = false;
1985 final Completer<void>done = Completer<void>();
1986 runZonedGuarded(() {
1987 flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete());
1988 }, (Object e, StackTrace st) {
1989 expect(e is StateError, true);
1990 expect((e as StateError).message, contains('No URI'));
1991 expect(testLogger.errorText, contains(
1992 'DDS has failed to start and there is not an existing DDS instance',
1993 ));
1994 done.complete();
1995 caught = true;
1996 });
1997 await done.future;
1998 if (!caught) {
1999 fail('Expected a StateError to be thrown.');
2000 }
Ben Konyi913d5932021-01-19 22:34:03 -08002001 }, overrides: <Type, Generator>{
2002 VMServiceConnector: () => (Uri httpUri, {
2003 ReloadSources reloadSources,
2004 Restart restart,
2005 CompileExpression compileExpression,
2006 GetSkSLMethod getSkSLMethod,
2007 PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
2008 io.CompressionOptions compression,
2009 Device device,
Jonah Williams4ae68a32021-04-01 13:23:40 -07002010 Logger logger,
Jonah Williams6728cf32021-06-10 12:00:38 -07002011 }) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
Ben Konyi620a8282020-12-22 10:24:04 -08002012 }));
Ben Konyi89ef88c2020-12-04 17:16:30 -08002013
Jenn Magder88631332020-06-08 11:28:02 -07002014 testUsingContext('nextPlatform moves through expected platforms', () {
Jonah Williams9904a7f2021-04-16 17:27:35 -07002015 expect(nextPlatform('android'), 'iOS');
2016 expect(nextPlatform('iOS'), 'fuchsia');
2017 expect(nextPlatform('fuchsia'), 'macOS');
2018 expect(nextPlatform('macOS'), 'android');
2019 expect(() => nextPlatform('unknown'), throwsAssertionError);
Jonah Williams5ba28302019-12-12 15:20:52 -08002020 });
Jason Simmonsf94fa272021-04-18 09:34:03 -07002021
2022 testUsingContext('cleanupAtFinish shuts down resident devtools handler', () => testbed.run(() async {
2023 residentRunner = HotRunner(
2024 <FlutterDevice>[
Jonah Williams73df0692021-06-14 16:29:02 -07002025 flutterDevice,
Jason Simmonsf94fa272021-04-18 09:34:03 -07002026 ],
2027 stayResident: false,
2028 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
2029 target: 'main.dart',
2030 devtoolsHandler: createNoOpHandler,
2031 );
2032 await residentRunner.cleanupAtFinish();
2033
2034 expect((residentRunner.residentDevtoolsHandler as NoOpDevtoolsHandler).wasShutdown, true);
2035 }));
Lau Ching Junaf42e7d2021-06-28 13:16:04 -07002036
2037 testUsingContext('HotRunner sets asset directory when first evict assets', () => testbed.run(() async {
2038 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
2039 listViews,
2040 setAssetBundlePath,
2041 evict,
2042 ]);
2043 residentRunner = HotRunner(
2044 <FlutterDevice>[
2045 flutterDevice,
2046 ],
2047 stayResident: false,
2048 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
2049 target: 'main.dart',
2050 devtoolsHandler: createNoOpHandler,
2051 );
2052
2053 (flutterDevice.devFS as FakeDevFS).assetPathsToEvict = <String>{'asset'};
2054
2055 expect(flutterDevice.devFS.hasSetAssetDirectory, false);
2056 await (residentRunner as HotRunner).evictDirtyAssets();
2057 expect(flutterDevice.devFS.hasSetAssetDirectory, true);
2058 expect(fakeVmServiceHost.hasRemainingExpectations, false);
2059 }));
2060
2061 testUsingContext('HotRunner does not sets asset directory when no assets to evict', () => testbed.run(() async {
2062 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
2063 ]);
2064 residentRunner = HotRunner(
2065 <FlutterDevice>[
2066 flutterDevice,
2067 ],
2068 stayResident: false,
2069 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
2070 target: 'main.dart',
2071 devtoolsHandler: createNoOpHandler,
2072 );
2073
2074 expect(flutterDevice.devFS.hasSetAssetDirectory, false);
2075 await (residentRunner as HotRunner).evictDirtyAssets();
2076 expect(flutterDevice.devFS.hasSetAssetDirectory, false);
2077 expect(fakeVmServiceHost.hasRemainingExpectations, false);
2078 }));
2079
2080 testUsingContext('HotRunner does not set asset directory if it has been set before', () => testbed.run(() async {
2081 fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
2082 listViews,
2083 evict,
2084 ]);
2085 residentRunner = HotRunner(
2086 <FlutterDevice>[
2087 flutterDevice,
2088 ],
2089 stayResident: false,
2090 debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
2091 target: 'main.dart',
2092 devtoolsHandler: createNoOpHandler,
2093 );
2094
2095 (flutterDevice.devFS as FakeDevFS).assetPathsToEvict = <String>{'asset'};
2096 flutterDevice.devFS.hasSetAssetDirectory = true;
2097
2098 await (residentRunner as HotRunner).evictDirtyAssets();
2099 expect(flutterDevice.devFS.hasSetAssetDirectory, true);
2100 expect(fakeVmServiceHost.hasRemainingExpectations, false);
2101 }));
Alexander Aprelev5b1e9722017-05-21 15:15:44 -07002102}
2103
Ben Konyi89ef88c2020-12-04 17:16:30 -08002104class FakeDartDevelopmentServiceException implements dds.DartDevelopmentServiceException {
Ben Konyi620a8282020-12-22 10:24:04 -08002105 FakeDartDevelopmentServiceException({this.message = defaultMessage});
2106
Ben Konyi89ef88c2020-12-04 17:16:30 -08002107 @override
2108 final int errorCode = dds.DartDevelopmentServiceException.existingDdsInstanceError;
2109
2110 @override
Ben Konyi620a8282020-12-22 10:24:04 -08002111 final String message;
2112 static const String defaultMessage = 'A DDS instance is already connected at http://localhost:8181';
Ben Konyi89ef88c2020-12-04 17:16:30 -08002113}
2114
Jonah Williams6b178402019-07-15 15:44:58 -07002115class TestFlutterDevice extends FlutterDevice {
Jonah Williams9b7b9d72020-05-05 12:09:51 -07002116 TestFlutterDevice(Device device, { Stream<Uri> observatoryUris })
Jonah Williamsc1112d32020-03-06 14:53:36 -08002117 : super(device, buildInfo: BuildInfo.debug) {
Jenn Magder2e7d9132019-11-01 14:37:17 -07002118 _observatoryUris = observatoryUris;
2119 }
Jonah Williams6b178402019-07-15 15:44:58 -07002120
2121 @override
Emmanuel Garcia5df4b7d2019-11-20 18:51:25 -08002122 Stream<Uri> get observatoryUris => _observatoryUris;
2123 Stream<Uri> _observatoryUris;
Jonah Williams6b178402019-07-15 15:44:58 -07002124}
2125
Jonah Williamse22d4aa2019-10-15 13:05:47 -07002126class ThrowingForwardingFileSystem extends ForwardingFileSystem {
2127 ThrowingForwardingFileSystem(FileSystem delegate) : super(delegate);
2128
2129 @override
2130 File file(dynamic path) {
2131 if (path == 'foo') {
2132 throw const FileSystemException();
2133 }
2134 return delegate.file(path);
2135 }
2136}
Jonah Williams07caa0f2020-07-20 14:03:44 -07002137
Jonah Williams73df0692021-06-14 16:29:02 -07002138class FakeFlutterDevice extends Fake implements FlutterDevice {
2139 FakeVmServiceHost Function() vmServiceHost;
2140 Uri testUri;
2141 UpdateFSReport report = UpdateFSReport(
2142 success: true,
Jonah Williams73df0692021-06-14 16:29:02 -07002143 invalidatedSourcesCount: 1,
2144 );
2145 Object reportError;
2146 Object runColdError;
2147 int runHotCode = 0;
2148 int runColdCode = 0;
2149
2150 @override
2151 ResidentCompiler generator;
2152
2153 @override
2154 Stream<Uri> get observatoryUris => Stream<Uri>.value(testUri);
2155
2156 @override
2157 FlutterVmService get vmService => vmServiceHost?.call()?.vmService;
2158
2159 DevFS _devFS;
2160
2161 @override
2162 DevFS get devFS => _devFS;
2163
2164 @override
2165 set devFS(DevFS value) { }
2166
2167 @override
2168 Device device;
2169
2170 @override
2171 Future<void> stopEchoingDeviceLog() async { }
2172
2173 @override
2174 Future<void> initLogReader() async { }
2175
2176 @override
2177 Future<Uri> setupDevFS(String fsName, Directory rootDirectory) async {
2178 return testUri;
2179 }
2180
2181 @override
2182 Future<int> runHot({HotRunner hotRunner, String route}) async {
2183 return runHotCode;
2184 }
2185
2186 @override
2187 Future<int> runCold({ColdRunner coldRunner, String route}) async {
2188 if (runColdError != null) {
2189 throw runColdError;
2190 }
2191 return runColdCode;
2192 }
2193
2194 @override
2195 Future<void> connect({
2196 ReloadSources reloadSources,
2197 Restart restart,
2198 CompileExpression compileExpression,
2199 GetSkSLMethod getSkSLMethod,
2200 PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
2201 int hostVmServicePort,
2202 int ddsPort,
2203 bool disableServiceAuthCodes = false,
2204 bool enableDds = true,
2205 @required bool allowExistingDdsInstance,
2206 bool ipv6 = false,
2207 }) async { }
2208
2209 @override
2210 Future<UpdateFSReport> updateDevFS({
2211 Uri mainUri,
2212 String target,
2213 AssetBundle bundle,
2214 DateTime firstBuildTime,
2215 bool bundleFirstUpload = false,
2216 bool bundleDirty = false,
2217 bool fullRestart = false,
2218 String projectRootPath,
2219 String pathToReload,
2220 String dillOutputPath,
2221 List<Uri> invalidatedFiles,
2222 PackageConfig packageConfig,
2223 }) async {
2224 if (reportError != null) {
2225 throw reportError;
2226 }
2227 return report;
2228 }
2229
2230 @override
2231 Future<void> updateReloadStatus(bool wasReloadSuccessful) async { }
2232}
2233
2234class FakeDelegateFlutterDevice extends FlutterDevice {
2235 FakeDelegateFlutterDevice(
Jonah Williams07caa0f2020-07-20 14:03:44 -07002236 Device device,
2237 BuildInfo buildInfo,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002238 ResidentCompiler residentCompiler,
2239 this.fakeDevFS,
Jonah Williamsa19f5ba2020-09-19 11:02:04 -07002240 ) : super(device, buildInfo: buildInfo, generator: residentCompiler);
Jonah Williams07caa0f2020-07-20 14:03:44 -07002241
2242 @override
2243 Future<void> connect({
2244 ReloadSources reloadSources,
2245 Restart restart,
Ian Hicksone5414692021-04-23 16:29:38 -07002246 bool enableDds = true,
Ben Konyia17b3302020-09-16 16:27:42 -07002247 bool disableServiceAuthCodes = false,
Ben Konyi3a5a3ea2020-07-29 10:05:40 -07002248 bool ipv6 = false,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002249 CompileExpression compileExpression,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002250 GetSkSLMethod getSkSLMethod,
Ben Konyia17b3302020-09-16 16:27:42 -07002251 int hostVmServicePort,
2252 int ddsPort,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002253 PrintStructuredErrorLogMethod printStructuredErrorLogMethod,
Ben Konyi89ef88c2020-12-04 17:16:30 -08002254 bool allowExistingDdsInstance = false,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002255 }) async { }
2256
2257
2258 final DevFS fakeDevFS;
2259
2260 @override
2261 DevFS get devFS => fakeDevFS;
2262
2263 @override
2264 set devFS(DevFS value) {}
2265}
2266
2267class FakeResidentCompiler extends Fake implements ResidentCompiler {
Jonah Williams73df0692021-06-14 16:29:02 -07002268 CompilerOutput nextOutput;
2269 bool didSuppressErrors = false;
2270
Jonah Williams07caa0f2020-07-20 14:03:44 -07002271 @override
2272 Future<CompilerOutput> recompile(
2273 Uri mainUri,
2274 List<Uri> invalidatedFiles, {
2275 @required String outputPath,
2276 @required PackageConfig packageConfig,
Emmanuel Garciab0a63c42021-04-23 15:34:04 -07002277 @required String projectRootPath,
2278 @required FileSystem fs,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002279 bool suppressErrors = false,
stuartmorgan97fb8c02021-09-30 23:25:13 -04002280 bool checkDartPluginRegistry = false,
Jonah Williams07caa0f2020-07-20 14:03:44 -07002281 }) async {
Jonah Williams73df0692021-06-14 16:29:02 -07002282 didSuppressErrors = suppressErrors;
2283 return nextOutput ?? const CompilerOutput('foo.dill', 0, <Uri>[]);
Jonah Williams07caa0f2020-07-20 14:03:44 -07002284 }
2285
2286 @override
2287 void accept() { }
2288
2289 @override
2290 void reset() { }
2291}
2292
2293class FakeProjectFileInvalidator extends Fake implements ProjectFileInvalidator {
2294 @override
2295 Future<InvalidationResult> findInvalidated({
2296 @required DateTime lastCompiled,
2297 @required List<Uri> urisToMonitor,
2298 @required String packagesPath,
2299 @required PackageConfig packageConfig,
2300 bool asyncScanning = false,
2301 }) async {
2302 return InvalidationResult(
2303 packageConfig: packageConfig ?? PackageConfig.empty,
2304 uris: <Uri>[Uri.parse('file:///hello_world/main.dart'),
2305 ]);
2306 }
2307}
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002308
Ian Hickson2bab6512021-10-04 13:48:04 -07002309// Unfortunately Device, despite not being immutable, has an `operator ==`.
2310// Until we fix that, we have to also ignore related lints here.
2311// ignore: avoid_implementing_value_types
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002312class FakeDevice extends Fake implements Device {
2313 FakeDevice({
2314 String sdkNameAndVersion = 'Android',
2315 TargetPlatform targetPlatform = TargetPlatform.android_arm,
2316 bool isLocalEmulator = false,
2317 this.supportsHotRestart = true,
Jonah Williams6efe8e92021-01-29 14:27:42 -08002318 this.supportsScreenshot = true,
2319 this.supportsFlutterExit = true,
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002320 }) : _isLocalEmulator = isLocalEmulator,
2321 _targetPlatform = targetPlatform,
2322 _sdkNameAndVersion = sdkNameAndVersion;
2323
2324 final bool _isLocalEmulator;
2325 final TargetPlatform _targetPlatform;
2326 final String _sdkNameAndVersion;
2327
Jonah Williams6efe8e92021-01-29 14:27:42 -08002328 bool disposed = false;
2329 bool appStopped = false;
2330 bool failScreenshot = false;
2331
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002332 @override
Jonah Williams6efe8e92021-01-29 14:27:42 -08002333 bool supportsHotRestart;
2334
2335 @override
2336 bool supportsScreenshot;
2337
2338 @override
2339 bool supportsFlutterExit;
2340
2341 @override
2342 PlatformType get platformType => _targetPlatform == TargetPlatform.web_javascript
2343 ? PlatformType.web
2344 : PlatformType.android;
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002345
2346 @override
2347 Future<String> get sdkNameAndVersion async => _sdkNameAndVersion;
2348
2349 @override
2350 Future<TargetPlatform> get targetPlatform async => _targetPlatform;
2351
2352 @override
2353 Future<bool> get isLocalEmulator async => _isLocalEmulator;
2354
2355 @override
2356 String get name => 'FakeDevice';
2357
2358 @override
Jonah Williams6efe8e92021-01-29 14:27:42 -08002359 DartDevelopmentService dds;
2360
2361 @override
2362 Future<void> dispose() async {
2363 disposed = true;
2364 }
2365
2366 @override
2367 Future<bool> stopApp(covariant ApplicationPackage app, {String userIdentifier}) async {
2368 appStopped = true;
2369 return true;
2370 }
2371
2372 @override
2373 Future<void> takeScreenshot(File outputFile) async {
2374 if (failScreenshot) {
2375 throw Exception();
2376 }
2377 outputFile.writeAsBytesSync(List<int>.generate(1024, (int i) => i));
2378 }
2379
2380 @override
2381 FutureOr<DeviceLogReader> getLogReader({
2382 covariant ApplicationPackage app,
2383 bool includePastLogs = false,
2384 }) => NoOpDeviceLogReader(name);
2385
2386 @override
2387 DevicePortForwarder portForwarder = const NoOpDevicePortForwarder();
Jonah Williamsbdb830a2020-10-09 15:44:52 -07002388}
Jonah Williams8beee472021-05-24 11:59:03 -07002389
2390class FakeDevFS extends Fake implements DevFS {
2391 @override
2392 DateTime lastCompiled = DateTime(2000);
2393
2394 @override
2395 PackageConfig lastPackageConfig = PackageConfig.empty;
2396
2397 @override
2398 List<Uri> sources = <Uri>[];
2399
2400 @override
2401 Uri baseUri = Uri();
2402
2403 @override
2404 Future<void> destroy() async { }
2405
2406 @override
2407 Set<String> assetPathsToEvict = <String>{};
2408
2409 UpdateFSReport nextUpdateReport = UpdateFSReport(success: true);
2410
2411 @override
Lau Ching Junaf42e7d2021-06-28 13:16:04 -07002412 bool hasSetAssetDirectory = false;
2413
2414 @override
Jonah Williams8beee472021-05-24 11:59:03 -07002415 Future<Uri> create() async {
2416 return Uri();
2417 }
2418
2419 @override
2420 void resetLastCompiled() {
2421 lastCompiled = null;
2422 }
2423
2424 @override
2425 Future<UpdateFSReport> update({
2426 @required Uri mainUri,
2427 @required ResidentCompiler generator,
2428 @required bool trackWidgetCreation,
2429 @required String pathToReload,
2430 @required List<Uri> invalidatedFiles,
2431 @required PackageConfig packageConfig,
2432 @required String dillOutputPath,
2433 DevFSWriter devFSWriter,
2434 String target,
2435 AssetBundle bundle,
2436 DateTime firstBuildTime,
2437 bool bundleFirstUpload = false,
2438 bool fullRestart = false,
2439 String projectRootPath,
2440 }) async {
2441 return nextUpdateReport;
2442 }
2443}