blob: 99dd36f71cc7b30f01cc6aaaf4a073a8310418ab [file] [log] [blame]
Chris Bracken1438ae82017-06-30 16:09:48 -07001// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Bracken27d3e8a2017-08-29 10:55:14 -07005import 'dart:async';
Liam Appelbeb0563e12019-09-23 10:09:22 -07006import 'dart:convert';
Chris Brackenfd54bd42017-08-25 14:32:01 -07007
Chris Bracken1438ae82017-06-30 16:09:48 -07008import 'package:file/memory.dart';
Chris Bracken8b8d3682018-05-08 17:28:53 -07009import 'package:flutter_tools/src/android/android_sdk.dart';
Mikkel Nygaard Ravna1f03972017-09-12 08:35:02 +020010import 'package:flutter_tools/src/artifacts.dart';
Chris Brackenfd54bd42017-08-25 14:32:01 -070011import 'package:flutter_tools/src/build_info.dart';
Chris Bracken1438ae82017-06-30 16:09:48 -070012import 'package:flutter_tools/src/base/build.dart';
Chris Bracken27d3e8a2017-08-29 10:55:14 -070013import 'package:flutter_tools/src/base/context.dart';
Chris Bracken1438ae82017-06-30 16:09:48 -070014import 'package:flutter_tools/src/base/file_system.dart';
Chris Bracken802301e2018-05-01 15:14:20 -070015import 'package:flutter_tools/src/base/io.dart';
Vyacheslav Egorov01e34962019-04-03 12:12:18 +020016import 'package:flutter_tools/src/base/logger.dart';
Chris Bracken802301e2018-05-01 15:14:20 -070017import 'package:flutter_tools/src/base/process.dart';
stuartmorgan81c38b22019-05-24 22:51:02 -040018import 'package:flutter_tools/src/macos/xcode.dart';
Chris Brackenfd54bd42017-08-25 14:32:01 -070019import 'package:flutter_tools/src/version.dart';
20import 'package:mockito/mockito.dart';
Liam Appelbeb0563e12019-09-23 10:09:22 -070021import 'package:process/process.dart';
Chris Bracken1438ae82017-06-30 16:09:48 -070022
Ian Hicksond919e692019-07-13 11:51:44 -070023import '../../src/common.dart';
24import '../../src/context.dart';
Chris Bracken1438ae82017-06-30 16:09:48 -070025
Chris Brackenfd54bd42017-08-25 14:32:01 -070026class MockFlutterVersion extends Mock implements FlutterVersion {}
Chris Bracken8b8d3682018-05-08 17:28:53 -070027class MockAndroidSdk extends Mock implements AndroidSdk {}
Mikkel Nygaard Ravna1f03972017-09-12 08:35:02 +020028class MockArtifacts extends Mock implements Artifacts {}
Chris Bracken82f969f2018-04-26 14:37:39 -070029class MockXcode extends Mock implements Xcode {}
Liam Appelbeb0563e12019-09-23 10:09:22 -070030class MockProcessManager extends Mock implements ProcessManager {}
31class MockProcess extends Mock implements Process {}
Chris Brackenfd54bd42017-08-25 14:32:01 -070032
Chris Bracken27d3e8a2017-08-29 10:55:14 -070033class _FakeGenSnapshot implements GenSnapshot {
34 _FakeGenSnapshot({
Alexandre Ardhuin09276be2018-06-05 08:50:40 +020035 this.succeed = true,
Chris Bracken27d3e8a2017-08-29 10:55:14 -070036 });
37
38 final bool succeed;
Chris Brackenb45a2602018-04-25 20:50:33 -070039 Map<String, String> outputs = <String, String>{};
Chris Bracken27d3e8a2017-08-29 10:55:14 -070040 int _callCount = 0;
Chris Brackencf577882018-04-19 16:03:07 -070041 SnapshotType _snapshotType;
Chris Brackencf577882018-04-19 16:03:07 -070042 String _depfilePath;
43 List<String> _additionalArgs;
Chris Bracken27d3e8a2017-08-29 10:55:14 -070044
45 int get callCount => _callCount;
46
Chris Brackencf577882018-04-19 16:03:07 -070047 SnapshotType get snapshotType => _snapshotType;
48
Chris Brackencf577882018-04-19 16:03:07 -070049 String get depfilePath => _depfilePath;
50
51 List<String> get additionalArgs => _additionalArgs;
52
Chris Bracken27d3e8a2017-08-29 10:55:14 -070053 @override
54 Future<int> run({
55 SnapshotType snapshotType,
Chris Bracken27d3e8a2017-08-29 10:55:14 -070056 String depfilePath,
Jonah Williams1df165e2019-08-15 17:38:35 -070057 DarwinArch darwinArch,
Konstantin Scheglov4fe41ab2019-01-29 11:49:57 -080058 Iterable<String> additionalArgs = const <String>[],
Chris Bracken27d3e8a2017-08-29 10:55:14 -070059 }) async {
60 _callCount += 1;
Chris Brackencf577882018-04-19 16:03:07 -070061 _snapshotType = snapshotType;
Chris Brackencf577882018-04-19 16:03:07 -070062 _depfilePath = depfilePath;
63 _additionalArgs = additionalArgs.toList();
Chris Bracken27d3e8a2017-08-29 10:55:14 -070064
Zachary Andersone2340c62019-09-13 14:51:35 -070065 if (!succeed) {
Chris Bracken27d3e8a2017-08-29 10:55:14 -070066 return 1;
Zachary Andersone2340c62019-09-13 14:51:35 -070067 }
Chris Bracken993f3942018-04-24 15:51:10 -070068 outputs.forEach((String filePath, String fileContent) {
69 fs.file(filePath).writeAsString(fileContent);
70 });
Chris Bracken27d3e8a2017-08-29 10:55:14 -070071 return 0;
72 }
73}
74
Chris Bracken1438ae82017-06-30 16:09:48 -070075void main() {
Mikkel Nygaard Ravn14016522017-09-07 14:45:42 +020076 group('SnapshotType', () {
77 test('throws, if build mode is null', () {
78 expect(
Alexandre Ardhuind927c932018-09-12 08:29:29 +020079 () => SnapshotType(TargetPlatform.android_x64, null),
Mikkel Nygaard Ravn14016522017-09-07 14:45:42 +020080 throwsA(anything),
81 );
82 });
83 test('does not throw, if target platform is null', () {
Alexandre Ardhuind927c932018-09-12 08:29:29 +020084 expect(SnapshotType(null, BuildMode.release), isNotNull);
Mikkel Nygaard Ravn14016522017-09-07 14:45:42 +020085 });
86 });
Chris Bracken993f3942018-04-24 15:51:10 -070087
Liam Appelbeb0563e12019-09-23 10:09:22 -070088 group('GenSnapshot', () {
89 GenSnapshot genSnapshot;
90 MockArtifacts mockArtifacts;
91 MockProcessManager mockProcessManager;
92 MockProcess mockProc;
93
94 setUp(() async {
95 genSnapshot = const GenSnapshot();
96 mockArtifacts = MockArtifacts();
97 mockProcessManager = MockProcessManager();
98 mockProc = MockProcess();
99 });
100
101 final Map<Type, Generator> contextOverrides = <Type, Generator>{
102 Artifacts: () => mockArtifacts,
103 ProcessManager: () => mockProcessManager,
104 };
105
106 testUsingContext('android_x64', () async {
107 when(mockArtifacts.getArtifactPath(Artifact.genSnapshot,
108 platform: TargetPlatform.android_x64, mode: BuildMode.release))
109 .thenReturn('gen_snapshot');
110 when(mockProcessManager.start(any,
111 workingDirectory: anyNamed('workingDirectory'),
112 environment: anyNamed('environment')))
113 .thenAnswer((_) => Future<Process>.value(mockProc));
114 when(mockProc.stdout).thenAnswer((_) => const Stream<List<int>>.empty());
115 when(mockProc.stderr).thenAnswer((_) => const Stream<List<int>>.empty());
116 await genSnapshot.run(
117 snapshotType:
118 SnapshotType(TargetPlatform.android_x64, BuildMode.release),
119 darwinArch: null,
120 additionalArgs: <String>['--additional_arg']);
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200121 verify(mockProcessManager.start(
122 <String>[
123 'gen_snapshot',
124 '--causal_async_stacks',
125 '--additional_arg',
126 ],
127 workingDirectory: anyNamed('workingDirectory'),
128 environment: anyNamed('environment'),
129 )).called(1);
Liam Appelbeb0563e12019-09-23 10:09:22 -0700130 }, overrides: contextOverrides);
131
132 testUsingContext('iOS armv7', () async {
133 when(mockArtifacts.getArtifactPath(Artifact.genSnapshot,
134 platform: TargetPlatform.ios, mode: BuildMode.release))
135 .thenReturn('gen_snapshot');
136 when(mockProcessManager.start(any,
137 workingDirectory: anyNamed('workingDirectory'),
138 environment: anyNamed('environment')))
139 .thenAnswer((_) => Future<Process>.value(mockProc));
140 when(mockProc.stdout).thenAnswer((_) => const Stream<List<int>>.empty());
141 when(mockProc.stderr).thenAnswer((_) => const Stream<List<int>>.empty());
142 await genSnapshot.run(
143 snapshotType: SnapshotType(TargetPlatform.ios, BuildMode.release),
144 darwinArch: DarwinArch.armv7,
145 additionalArgs: <String>['--additional_arg']);
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200146 verify(mockProcessManager.start(
147 <String>[
148 'gen_snapshot_armv7',
149 '--causal_async_stacks',
150 '--additional_arg',
151 ],
152 workingDirectory: anyNamed('workingDirectory'),
153 environment: anyNamed('environment')),
154 ).called(1);
Liam Appelbeb0563e12019-09-23 10:09:22 -0700155 }, overrides: contextOverrides);
156
157 testUsingContext('iOS arm64', () async {
158 when(mockArtifacts.getArtifactPath(Artifact.genSnapshot,
159 platform: TargetPlatform.ios, mode: BuildMode.release))
160 .thenReturn('gen_snapshot');
161 when(mockProcessManager.start(any,
162 workingDirectory: anyNamed('workingDirectory'),
163 environment: anyNamed('environment')))
164 .thenAnswer((_) => Future<Process>.value(mockProc));
165 when(mockProc.stdout).thenAnswer((_) => const Stream<List<int>>.empty());
166 when(mockProc.stderr).thenAnswer((_) => const Stream<List<int>>.empty());
167 await genSnapshot.run(
168 snapshotType: SnapshotType(TargetPlatform.ios, BuildMode.release),
169 darwinArch: DarwinArch.arm64,
170 additionalArgs: <String>['--additional_arg']);
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200171 verify(mockProcessManager.start(
172 <String>[
173 'gen_snapshot_arm64',
174 '--causal_async_stacks',
175 '--additional_arg',
176 ],
177 workingDirectory: anyNamed('workingDirectory'),
178 environment: anyNamed('environment'),
179 )).called(1);
Liam Appelbeb0563e12019-09-23 10:09:22 -0700180 }, overrides: contextOverrides);
181
182 testUsingContext('--strip filters outputs', () async {
183 when(mockArtifacts.getArtifactPath(Artifact.genSnapshot,
184 platform: TargetPlatform.android_x64, mode: BuildMode.release))
185 .thenReturn('gen_snapshot');
186 when(mockProcessManager.start(
187 <String>['gen_snapshot', '--causal_async_stacks', '--strip'],
188 workingDirectory: anyNamed('workingDirectory'),
189 environment: anyNamed('environment')))
190 .thenAnswer((_) => Future<Process>.value(mockProc));
191 when(mockProc.stdout).thenAnswer((_) => const Stream<List<int>>.empty());
192 when(mockProc.stderr)
Alexandre Ardhuinf11c3412019-09-27 10:46:45 +0200193 .thenAnswer((_) => Stream<String>.fromIterable(<String>[
194 '--ABC\n',
195 'Warning: Generating ELF library without DWARF debugging information.\n',
196 '--XYZ\n',
197 ])
198 .transform<List<int>>(utf8.encoder));
Liam Appelbeb0563e12019-09-23 10:09:22 -0700199 await genSnapshot.run(
200 snapshotType:
201 SnapshotType(TargetPlatform.android_x64, BuildMode.release),
202 darwinArch: null,
203 additionalArgs: <String>['--strip']);
204 verify(mockProcessManager.start(
205 <String>['gen_snapshot', '--causal_async_stacks', '--strip'],
206 workingDirectory: anyNamed('workingDirectory'),
207 environment: anyNamed('environment')))
208 .called(1);
209 expect(testLogger.errorText, contains('ABC'));
210 expect(testLogger.errorText, isNot(contains('ELF library')));
211 expect(testLogger.errorText, contains('XYZ'));
212 }, overrides: contextOverrides);
213 });
214
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700215 group('Snapshotter - AOT', () {
Chris Bracken82f969f2018-04-26 14:37:39 -0700216 const String kSnapshotDart = 'snapshot.dart';
Chris Bracken82f969f2018-04-26 14:37:39 -0700217 String skyEnginePath;
218
219 _FakeGenSnapshot genSnapshot;
Chris Bracken82f969f2018-04-26 14:37:39 -0700220 MemoryFileSystem fs;
Chris Bracken42ed0152018-05-01 12:42:05 -0700221 AOTSnapshotter snapshotter;
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200222 AOTSnapshotter snapshotterWithTimings;
Chris Bracken8b8d3682018-05-08 17:28:53 -0700223 MockAndroidSdk mockAndroidSdk;
Chris Bracken82f969f2018-04-26 14:37:39 -0700224 MockArtifacts mockArtifacts;
225 MockXcode mockXcode;
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200226 BufferLogger bufferLogger;
Chris Bracken82f969f2018-04-26 14:37:39 -0700227
228 setUp(() async {
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200229 fs = MemoryFileSystem();
Chris Bracken82f969f2018-04-26 14:37:39 -0700230 fs.file(kSnapshotDart).createSync();
Chris Bracken82f969f2018-04-26 14:37:39 -0700231 fs.file('.packages').writeAsStringSync('sky_engine:file:///flutter/bin/cache/pkg/sky_engine/lib/');
232
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200233 skyEnginePath = fs.path.fromUri(Uri.file('/flutter/bin/cache/pkg/sky_engine'));
Chris Bracken82f969f2018-04-26 14:37:39 -0700234 fs.directory(fs.path.join(skyEnginePath, 'lib', 'ui')).createSync(recursive: true);
235 fs.directory(fs.path.join(skyEnginePath, 'sdk_ext')).createSync(recursive: true);
236 fs.file(fs.path.join(skyEnginePath, '.packages')).createSync();
237 fs.file(fs.path.join(skyEnginePath, 'lib', 'ui', 'ui.dart')).createSync();
238 fs.file(fs.path.join(skyEnginePath, 'sdk_ext', 'vmservice_io.dart')).createSync();
239
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200240 genSnapshot = _FakeGenSnapshot();
241 snapshotter = AOTSnapshotter();
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200242 snapshotterWithTimings = AOTSnapshotter(reportTimings: true);
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200243 mockAndroidSdk = MockAndroidSdk();
244 mockArtifacts = MockArtifacts();
245 mockXcode = MockXcode();
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200246 bufferLogger = BufferLogger();
Chris Bracken82f969f2018-04-26 14:37:39 -0700247 for (BuildMode mode in BuildMode.values) {
Alexander Aprelevd7759082019-04-15 21:02:20 -0700248 when(mockArtifacts.getArtifactPath(Artifact.snapshotDart,
249 platform: anyNamed('platform'), mode: mode)).thenReturn(kSnapshotDart);
Chris Bracken82f969f2018-04-26 14:37:39 -0700250 }
Chris Bracken82f969f2018-04-26 14:37:39 -0700251 });
252
253 final Map<Type, Generator> contextOverrides = <Type, Generator>{
Chris Bracken8b8d3682018-05-08 17:28:53 -0700254 AndroidSdk: () => mockAndroidSdk,
Chris Bracken82f969f2018-04-26 14:37:39 -0700255 Artifacts: () => mockArtifacts,
256 FileSystem: () => fs,
257 GenSnapshot: () => genSnapshot,
Chris Bracken82f969f2018-04-26 14:37:39 -0700258 Xcode: () => mockXcode,
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200259 Logger: () => bufferLogger,
Chris Bracken82f969f2018-04-26 14:37:39 -0700260 };
261
Chris Bracken68a1e2f2018-04-30 19:51:30 -0700262 testUsingContext('iOS debug AOT snapshot is invalid', () async {
Chris Bracken82f969f2018-04-26 14:37:39 -0700263 final String outputPath = fs.path.join('build', 'foo');
Chris Bracken42ed0152018-05-01 12:42:05 -0700264 expect(await snapshotter.build(
Chris Bracken82f969f2018-04-26 14:37:39 -0700265 platform: TargetPlatform.ios,
266 buildMode: BuildMode.debug,
Chris Brackencdbb2382018-04-29 10:47:34 -0700267 mainPath: 'main.dill',
Chris Bracken82f969f2018-04-26 14:37:39 -0700268 packagesPath: '.packages',
269 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700270 bitcode: false,
Chris Bracken68a1e2f2018-04-30 19:51:30 -0700271 ), isNot(equals(0)));
Chris Bracken82f969f2018-04-26 14:37:39 -0700272 }, overrides: contextOverrides);
273
Chris Bracken1605fbb2018-05-10 17:45:51 -0700274 testUsingContext('Android arm debug AOT snapshot is invalid', () async {
Chris Bracken231b9422018-05-08 11:06:58 -0700275 final String outputPath = fs.path.join('build', 'foo');
276 expect(await snapshotter.build(
277 platform: TargetPlatform.android_arm,
278 buildMode: BuildMode.debug,
279 mainPath: 'main.dill',
280 packagesPath: '.packages',
281 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700282 bitcode: false,
Chris Bracken231b9422018-05-08 11:06:58 -0700283 ), isNot(0));
284 }, overrides: contextOverrides);
285
Chris Bracken1605fbb2018-05-10 17:45:51 -0700286 testUsingContext('Android arm64 debug AOT snapshot is invalid', () async {
287 final String outputPath = fs.path.join('build', 'foo');
288 expect(await snapshotter.build(
289 platform: TargetPlatform.android_arm64,
290 buildMode: BuildMode.debug,
291 mainPath: 'main.dill',
292 packagesPath: '.packages',
293 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700294 bitcode: false,
Chris Bracken1605fbb2018-05-10 17:45:51 -0700295 ), isNot(0));
296 }, overrides: contextOverrides);
297
Dan Fieldeefe9d92019-08-29 20:54:30 -0700298 testUsingContext('iOS profile AOT with bitcode uses right flags', () async {
Chris Bracken1605fbb2018-05-10 17:45:51 -0700299 fs.file('main.dill').writeAsStringSync('binary magic');
300
301 final String outputPath = fs.path.join('build', 'foo');
302 fs.directory(outputPath).createSync(recursive: true);
303
Dan Fieldc953cd12019-07-18 22:42:47 -0700304 final String assembly = fs.path.join(outputPath, 'snapshot_assembly.S');
Chris Bracken1605fbb2018-05-10 17:45:51 -0700305 genSnapshot.outputs = <String, String>{
Dan Fieldc953cd12019-07-18 22:42:47 -0700306 assembly: 'blah blah\n.section __DWARF\nblah blah\n',
Chris Bracken1605fbb2018-05-10 17:45:51 -0700307 };
308
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200309 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
310 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
311 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
Chris Bracken1605fbb2018-05-10 17:45:51 -0700312
313 final int genSnapshotExitCode = await snapshotter.build(
314 platform: TargetPlatform.ios,
315 buildMode: BuildMode.profile,
316 mainPath: 'main.dill',
317 packagesPath: '.packages',
318 outputPath: outputPath,
Jonah Williams1df165e2019-08-15 17:38:35 -0700319 darwinArch: DarwinArch.armv7,
Dan Fieldc953cd12019-07-18 22:42:47 -0700320 bitcode: true,
Chris Bracken1605fbb2018-05-10 17:45:51 -0700321 );
322
323 expect(genSnapshotExitCode, 0);
324 expect(genSnapshot.callCount, 1);
325 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
326 expect(genSnapshot.snapshotType.mode, BuildMode.profile);
Chris Bracken1605fbb2018-05-10 17:45:51 -0700327 expect(genSnapshot.additionalArgs, <String>[
Ryan Macnakd92d1752018-11-07 11:06:46 -0800328 '--deterministic',
Chris Bracken1605fbb2018-05-10 17:45:51 -0700329 '--snapshot_kind=app-aot-assembly',
Dan Fieldc953cd12019-07-18 22:42:47 -0700330 '--assembly=$assembly',
Chris Bracken1605fbb2018-05-10 17:45:51 -0700331 '--no-sim-use-hardfp',
332 '--no-use-integer-division',
333 'main.dill',
334 ]);
Dan Fieldc953cd12019-07-18 22:42:47 -0700335
336 verify(xcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
337 verify(xcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
Dan Fieldc953cd12019-07-18 22:42:47 -0700338
339 final File assemblyFile = fs.file(assembly);
Dan Fieldeefe9d92019-08-29 20:54:30 -0700340 expect(assemblyFile.existsSync(), true);
341 expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
342 }, overrides: contextOverrides);
343
344 testUsingContext('iOS release AOT with bitcode uses right flags', () async {
345 fs.file('main.dill').writeAsStringSync('binary magic');
346
347 final String outputPath = fs.path.join('build', 'foo');
348 fs.directory(outputPath).createSync(recursive: true);
349
350 final String assembly = fs.path.join(outputPath, 'snapshot_assembly.S');
351 genSnapshot.outputs = <String, String>{
352 assembly: 'blah blah\n.section __DWARF\nblah blah\n',
353 };
354
355 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
356 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
357 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
358
359 final int genSnapshotExitCode = await snapshotter.build(
360 platform: TargetPlatform.ios,
361 buildMode: BuildMode.release,
362 mainPath: 'main.dill',
363 packagesPath: '.packages',
364 outputPath: outputPath,
365 darwinArch: DarwinArch.armv7,
366 bitcode: true,
367 );
368
369 expect(genSnapshotExitCode, 0);
370 expect(genSnapshot.callCount, 1);
371 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
372 expect(genSnapshot.snapshotType.mode, BuildMode.release);
373 expect(genSnapshot.additionalArgs, <String>[
374 '--deterministic',
375 '--snapshot_kind=app-aot-assembly',
376 '--assembly=$assembly',
377 '--no-sim-use-hardfp',
378 '--no-use-integer-division',
379 'main.dill',
380 ]);
381
382 verify(xcode.cc(argThat(contains('-fembed-bitcode')))).called(1);
383 verify(xcode.clang(argThat(contains('-fembed-bitcode')))).called(1);
384
385 final File assemblyFile = fs.file(assembly);
Dan Fieldcb965492019-08-28 15:19:04 -0700386 final File assemblyBitcodeFile = fs.file('$assembly.stripped.S');
Dan Fieldc953cd12019-07-18 22:42:47 -0700387 expect(assemblyFile.existsSync(), true);
388 expect(assemblyBitcodeFile.existsSync(), true);
389 expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
390 expect(assemblyBitcodeFile.readAsStringSync().contains('.section __DWARF'), false);
391 }, overrides: contextOverrides);
392
393 testUsingContext('builds iOS armv7 profile AOT snapshot', () async {
394 fs.file('main.dill').writeAsStringSync('binary magic');
395
396 final String outputPath = fs.path.join('build', 'foo');
397 fs.directory(outputPath).createSync(recursive: true);
398
399 final String assembly = fs.path.join(outputPath, 'snapshot_assembly.S');
400 genSnapshot.outputs = <String, String>{
401 assembly: 'blah blah\n.section __DWARF\nblah blah\n',
402 };
403
404 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
405 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
406 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
407
408 final int genSnapshotExitCode = await snapshotter.build(
409 platform: TargetPlatform.ios,
410 buildMode: BuildMode.profile,
411 mainPath: 'main.dill',
412 packagesPath: '.packages',
413 outputPath: outputPath,
Jonah Williams1df165e2019-08-15 17:38:35 -0700414 darwinArch: DarwinArch.armv7,
Dan Fieldc953cd12019-07-18 22:42:47 -0700415 bitcode: false,
416 );
417
418 expect(genSnapshotExitCode, 0);
419 expect(genSnapshot.callCount, 1);
420 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
421 expect(genSnapshot.snapshotType.mode, BuildMode.profile);
422 expect(genSnapshot.additionalArgs, <String>[
423 '--deterministic',
424 '--snapshot_kind=app-aot-assembly',
425 '--assembly=$assembly',
426 '--no-sim-use-hardfp',
427 '--no-use-integer-division',
428 'main.dill',
429 ]);
430 verifyNever(xcode.cc(argThat(contains('-fembed-bitcode'))));
431 verifyNever(xcode.clang(argThat(contains('-fembed-bitcode'))));
Dan Fieldc953cd12019-07-18 22:42:47 -0700432
433 final File assemblyFile = fs.file(assembly);
Dan Fieldc953cd12019-07-18 22:42:47 -0700434 expect(assemblyFile.existsSync(), true);
Dan Fieldc953cd12019-07-18 22:42:47 -0700435 expect(assemblyFile.readAsStringSync().contains('.section __DWARF'), true);
Chris Bracken1605fbb2018-05-10 17:45:51 -0700436 }, overrides: contextOverrides);
437
438 testUsingContext('builds iOS arm64 profile AOT snapshot', () async {
Chris Brackencdbb2382018-04-29 10:47:34 -0700439 fs.file('main.dill').writeAsStringSync('binary magic');
Chris Bracken82f969f2018-04-26 14:37:39 -0700440
441 final String outputPath = fs.path.join('build', 'foo');
442 fs.directory(outputPath).createSync(recursive: true);
443
Chris Bracken82f969f2018-04-26 14:37:39 -0700444 genSnapshot.outputs = <String, String>{
445 fs.path.join(outputPath, 'snapshot_assembly.S'): '',
Chris Bracken82f969f2018-04-26 14:37:39 -0700446 };
447
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200448 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
449 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
450 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
Chris Bracken802301e2018-05-01 15:14:20 -0700451
Chris Bracken42ed0152018-05-01 12:42:05 -0700452 final int genSnapshotExitCode = await snapshotter.build(
Chris Bracken82f969f2018-04-26 14:37:39 -0700453 platform: TargetPlatform.ios,
454 buildMode: BuildMode.profile,
Chris Brackencdbb2382018-04-29 10:47:34 -0700455 mainPath: 'main.dill',
Chris Bracken82f969f2018-04-26 14:37:39 -0700456 packagesPath: '.packages',
457 outputPath: outputPath,
Jonah Williams1df165e2019-08-15 17:38:35 -0700458 darwinArch: DarwinArch.arm64,
Dan Fieldc953cd12019-07-18 22:42:47 -0700459 bitcode: false,
Chris Bracken82f969f2018-04-26 14:37:39 -0700460 );
461
462 expect(genSnapshotExitCode, 0);
463 expect(genSnapshot.callCount, 1);
464 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
465 expect(genSnapshot.snapshotType.mode, BuildMode.profile);
Chris Bracken82f969f2018-04-26 14:37:39 -0700466 expect(genSnapshot.additionalArgs, <String>[
Ryan Macnakd92d1752018-11-07 11:06:46 -0800467 '--deterministic',
Chris Bracken82f969f2018-04-26 14:37:39 -0700468 '--snapshot_kind=app-aot-assembly',
469 '--assembly=${fs.path.join(outputPath, 'snapshot_assembly.S')}',
Chris Bracken82f969f2018-04-26 14:37:39 -0700470 'main.dill',
471 ]);
472 }, overrides: contextOverrides);
473
Chris Bracken1605fbb2018-05-10 17:45:51 -0700474 testUsingContext('builds iOS release armv7 AOT snapshot', () async {
475 fs.file('main.dill').writeAsStringSync('binary magic');
476
477 final String outputPath = fs.path.join('build', 'foo');
478 fs.directory(outputPath).createSync(recursive: true);
479
480 genSnapshot.outputs = <String, String>{
481 fs.path.join(outputPath, 'snapshot_assembly.S'): '',
Chris Bracken1605fbb2018-05-10 17:45:51 -0700482 };
483
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200484 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
485 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
486 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
Chris Bracken1605fbb2018-05-10 17:45:51 -0700487
488 final int genSnapshotExitCode = await snapshotter.build(
489 platform: TargetPlatform.ios,
490 buildMode: BuildMode.release,
491 mainPath: 'main.dill',
492 packagesPath: '.packages',
493 outputPath: outputPath,
Jonah Williams1df165e2019-08-15 17:38:35 -0700494 darwinArch: DarwinArch.armv7,
Dan Fieldc953cd12019-07-18 22:42:47 -0700495 bitcode: false,
Chris Bracken1605fbb2018-05-10 17:45:51 -0700496 );
497
498 expect(genSnapshotExitCode, 0);
499 expect(genSnapshot.callCount, 1);
500 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
501 expect(genSnapshot.snapshotType.mode, BuildMode.release);
Chris Bracken1605fbb2018-05-10 17:45:51 -0700502 expect(genSnapshot.additionalArgs, <String>[
Ryan Macnakd92d1752018-11-07 11:06:46 -0800503 '--deterministic',
Chris Bracken1605fbb2018-05-10 17:45:51 -0700504 '--snapshot_kind=app-aot-assembly',
505 '--assembly=${fs.path.join(outputPath, 'snapshot_assembly.S')}',
506 '--no-sim-use-hardfp',
507 '--no-use-integer-division',
508 'main.dill',
509 ]);
510 }, overrides: contextOverrides);
511
512 testUsingContext('builds iOS release arm64 AOT snapshot', () async {
Chris Brackencdbb2382018-04-29 10:47:34 -0700513 fs.file('main.dill').writeAsStringSync('binary magic');
Chris Bracken82f969f2018-04-26 14:37:39 -0700514
515 final String outputPath = fs.path.join('build', 'foo');
516 fs.directory(outputPath).createSync(recursive: true);
517
Chris Bracken82f969f2018-04-26 14:37:39 -0700518 genSnapshot.outputs = <String, String>{
519 fs.path.join(outputPath, 'snapshot_assembly.S'): '',
Chris Bracken82f969f2018-04-26 14:37:39 -0700520 };
521
Alexandre Ardhuind927c932018-09-12 08:29:29 +0200522 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
523 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
524 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
Chris Bracken802301e2018-05-01 15:14:20 -0700525
Chris Bracken42ed0152018-05-01 12:42:05 -0700526 final int genSnapshotExitCode = await snapshotter.build(
Chris Bracken82f969f2018-04-26 14:37:39 -0700527 platform: TargetPlatform.ios,
528 buildMode: BuildMode.release,
Chris Brackencdbb2382018-04-29 10:47:34 -0700529 mainPath: 'main.dill',
Chris Bracken82f969f2018-04-26 14:37:39 -0700530 packagesPath: '.packages',
531 outputPath: outputPath,
Jonah Williams1df165e2019-08-15 17:38:35 -0700532 darwinArch: DarwinArch.arm64,
Dan Fieldc953cd12019-07-18 22:42:47 -0700533 bitcode: false,
Chris Bracken82f969f2018-04-26 14:37:39 -0700534 );
535
536 expect(genSnapshotExitCode, 0);
537 expect(genSnapshot.callCount, 1);
538 expect(genSnapshot.snapshotType.platform, TargetPlatform.ios);
539 expect(genSnapshot.snapshotType.mode, BuildMode.release);
Chris Bracken82f969f2018-04-26 14:37:39 -0700540 expect(genSnapshot.additionalArgs, <String>[
Ryan Macnakd92d1752018-11-07 11:06:46 -0800541 '--deterministic',
Chris Bracken82f969f2018-04-26 14:37:39 -0700542 '--snapshot_kind=app-aot-assembly',
543 '--assembly=${fs.path.join(outputPath, 'snapshot_assembly.S')}',
Chris Bracken82f969f2018-04-26 14:37:39 -0700544 'main.dill',
545 ]);
546 }, overrides: contextOverrides);
Chris Bracken8b8d3682018-05-08 17:28:53 -0700547
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700548 testUsingContext('builds shared library for android-arm', () async {
549 fs.file('main.dill').writeAsStringSync('binary magic');
Jonah Williamsf8f7b892019-06-08 18:43:25 -0700550
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700551 final String outputPath = fs.path.join('build', 'foo');
552 fs.directory(outputPath).createSync(recursive: true);
Chris Bracken8b8d3682018-05-08 17:28:53 -0700553
554 final int genSnapshotExitCode = await snapshotter.build(
555 platform: TargetPlatform.android_arm,
556 buildMode: BuildMode.release,
557 mainPath: 'main.dill',
558 packagesPath: '.packages',
559 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700560 bitcode: false,
Chris Bracken8b8d3682018-05-08 17:28:53 -0700561 );
562
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700563 expect(genSnapshotExitCode, 0);
564 expect(genSnapshot.callCount, 1);
565 expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm);
566 expect(genSnapshot.snapshotType.mode, BuildMode.release);
567 expect(genSnapshot.additionalArgs, <String>[
568 '--deterministic',
569 '--snapshot_kind=app-aot-elf',
570 '--elf=build/foo/app.so',
Jason Simmons89d887f2019-06-11 13:34:24 -0700571 '--strip',
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700572 '--no-sim-use-hardfp',
573 '--no-use-integer-division',
574 'main.dill',
575 ]);
576 }, overrides: contextOverrides);
577
578 testUsingContext('builds shared library for android-arm64', () async {
579 fs.file('main.dill').writeAsStringSync('binary magic');
580
581 final String outputPath = fs.path.join('build', 'foo');
582 fs.directory(outputPath).createSync(recursive: true);
583
584 final int genSnapshotExitCode = await snapshotter.build(
585 platform: TargetPlatform.android_arm64,
586 buildMode: BuildMode.release,
587 mainPath: 'main.dill',
588 packagesPath: '.packages',
589 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700590 bitcode: false,
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700591 );
592
593 expect(genSnapshotExitCode, 0);
594 expect(genSnapshot.callCount, 1);
595 expect(genSnapshot.snapshotType.platform, TargetPlatform.android_arm64);
596 expect(genSnapshot.snapshotType.mode, BuildMode.release);
597 expect(genSnapshot.additionalArgs, <String>[
598 '--deterministic',
599 '--snapshot_kind=app-aot-elf',
600 '--elf=build/foo/app.so',
Jason Simmons89d887f2019-06-11 13:34:24 -0700601 '--strip',
Emmanuel Garcia8627ff42019-06-10 13:16:09 -0700602 'main.dill',
603 ]);
Chris Bracken8b8d3682018-05-08 17:28:53 -0700604 }, overrides: contextOverrides);
Chris Bracken1605fbb2018-05-10 17:45:51 -0700605
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200606 testUsingContext('reports timing', () async {
607 fs.file('main.dill').writeAsStringSync('binary magic');
608
609 final String outputPath = fs.path.join('build', 'foo');
610 fs.directory(outputPath).createSync(recursive: true);
611
612 genSnapshot.outputs = <String, String>{
Todd Volkertbb6c3f82019-06-22 19:30:24 -0700613 fs.path.join(outputPath, 'app.so'): '',
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200614 };
615
616 final RunResult successResult = RunResult(ProcessResult(1, 0, '', ''), <String>['command name', 'arguments...']);
617 when(xcode.cc(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
618 when(xcode.clang(any)).thenAnswer((_) => Future<RunResult>.value(successResult));
619
620 final int genSnapshotExitCode = await snapshotterWithTimings.build(
621 platform: TargetPlatform.android_arm,
622 buildMode: BuildMode.release,
623 mainPath: 'main.dill',
624 packagesPath: '.packages',
625 outputPath: outputPath,
Dan Fieldc953cd12019-07-18 22:42:47 -0700626 bitcode: false,
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200627 );
628
629 expect(genSnapshotExitCode, 0);
630 expect(genSnapshot.callCount, 1);
Jonas Termansen8b9eb3e2019-05-02 15:22:43 +0200631 expect(bufferLogger.statusText, matches(RegExp(r'snapshot\(CompileTime\): \d+ ms.')));
Vyacheslav Egorov01e34962019-04-03 12:12:18 +0200632 }, overrides: contextOverrides);
Chris Bracken82f969f2018-04-26 14:37:39 -0700633 });
Chris Bracken1438ae82017-06-30 16:09:48 -0700634}