OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /// Integration test that runs the incremental compiler, runs the compiled | 5 /// Integration test that runs the incremental compiler, runs the compiled |
6 /// program, incrementally rebuild portions of the app, and triggers a hot | 6 /// program, incrementally rebuild portions of the app, and triggers a hot |
7 /// reload on the running program. | 7 /// reload on the running program. |
8 library front_end.incremental.hot_reload_e2e_test; | 8 library front_end.incremental.hot_reload_e2e_test; |
9 | 9 |
10 import 'dart:async'; | 10 import 'dart:async'; |
(...skipping 30 matching lines...) Expand all Loading... |
41 compiler = await createIncrementalCompiler( | 41 compiler = await createIncrementalCompiler( |
42 'file:///a.dart', new HybridFileSystem(fs)); | 42 'file:///a.dart', new HybridFileSystem(fs)); |
43 await rebuild(compiler, outputUri); // this is a full compile. | 43 await rebuild(compiler, outputUri); // this is a full compile. |
44 }); | 44 }); |
45 | 45 |
46 tearDown(() async { | 46 tearDown(() async { |
47 outDir.deleteSync(recursive: true); | 47 outDir.deleteSync(recursive: true); |
48 lines = null; | 48 lines = null; |
49 }); | 49 }); |
50 | 50 |
| 51 Future<int> computeVmPort() async { |
| 52 var portLine = await lines[0]; |
| 53 expect(observatoryPortRegExp.hasMatch(portLine), isTrue); |
| 54 var match = observatoryPortRegExp.firstMatch(portLine); |
| 55 return int.parse(match.group(1)); |
| 56 } |
| 57 |
| 58 /// Request vm to resume execution |
| 59 Future resume() async { |
| 60 var port = await computeVmPort(); |
| 61 var remoteVm = new RemoteVm(port); |
| 62 await remoteVm.resume(); |
| 63 } |
| 64 |
51 /// Start the VM with the first version of the program compiled by the | 65 /// Start the VM with the first version of the program compiled by the |
52 /// incremental compiler. | 66 /// incremental compiler. |
53 startProgram(int reloadCount) async { | 67 startProgram(int reloadCount) async { |
54 var vmArgs = [ | 68 var vmArgs = [ |
55 '--enable-vm-service=0', // Note: use 0 to avoid port collisions. | 69 '--enable-vm-service=0', // Note: use 0 to avoid port collisions. |
56 '--platform=${platformFile.toFilePath()}', | 70 '--pause_isolates_on_start', |
| 71 '--kernel-binaries=${sdkRoot.toFilePath()}', |
57 outputUri.toFilePath() | 72 outputUri.toFilePath() |
58 ]; | 73 ]; |
59 vmArgs.add('$reloadCount'); | 74 vmArgs.add('$reloadCount'); |
60 var vm = await Process.start(Platform.executable, vmArgs); | 75 var vm = await Process.start(Platform.executable, vmArgs); |
61 var splitter = new LineSplitter(); | 76 var splitter = new LineSplitter(); |
62 | 77 |
63 /// The program prints at most 2 + reloadCount lines: | 78 /// The program prints at most 2 + reloadCount lines: |
64 /// - a line displaying the observatory port | 79 /// - a line displaying the observatory port |
65 /// - a line before waiting for a reload | 80 /// - a line before waiting for a reload |
66 /// - a line after each hot-reload | 81 /// - a line after each hot-reload |
67 int i = 0; | 82 int i = 0; |
68 int expectedLines = 2 + reloadCount; | 83 int expectedLines = 2 + reloadCount; |
69 var completers = | 84 var completers = |
70 new List.generate(expectedLines, (_) => new Completer<String>()); | 85 new List.generate(expectedLines, (_) => new Completer<String>()); |
71 lines = completers.map((c) => c.future).toList(); | 86 lines = completers.map((c) => c.future).toList(); |
72 vm.stdout.transform(UTF8.decoder).transform(splitter).listen((line) { | 87 vm.stdout.transform(UTF8.decoder).transform(splitter).listen((line) { |
73 expect(i, lessThan(expectedLines)); | 88 expect(i, lessThan(expectedLines)); |
74 completers[i++].complete(line); | 89 completers[i++].complete(line); |
75 }, onDone: () { | 90 }, onDone: () { |
76 expect(i, expectedLines); | 91 expect(i, expectedLines); |
77 }); | 92 }); |
78 | 93 |
79 vm.stderr.transform(UTF8.decoder).transform(splitter).toList().then((err) { | 94 vm.stderr.transform(UTF8.decoder).transform(splitter).toList().then((err) { |
80 expect(err, isEmpty, reason: err.join('\n')); | 95 expect(err, isEmpty, reason: err.join('\n')); |
81 }); | 96 }); |
82 | 97 |
83 programIsDone = vm.exitCode; | 98 programIsDone = vm.exitCode; |
| 99 await resume(); |
84 } | 100 } |
85 | 101 |
86 /// Request a hot reload on the running program. | 102 /// Request a hot reload on the running program. |
87 Future hotReload() async { | 103 Future hotReload() async { |
88 var portLine = await lines[0]; | 104 var port = await computeVmPort(); |
89 expect(observatoryPortRegExp.hasMatch(portLine), isTrue); | 105 var remoteVm = new RemoteVm(port); |
90 var match = observatoryPortRegExp.firstMatch(portLine); | 106 var reloadResult = await remoteVm.reload(outputUri); |
91 var port = int.parse(match.group(1)); | |
92 var reloader = new VmReloader(port); | |
93 var reloadResult = await reloader.reload(outputUri); | |
94 expect(reloadResult['success'], isTrue); | 107 expect(reloadResult['success'], isTrue); |
95 await reloader.disconnect(); | 108 await remoteVm.disconnect(); |
96 } | 109 } |
97 | 110 |
98 test('initial program is valid', () async { | 111 test('initial program is valid', () async { |
99 await startProgram(0); | 112 await startProgram(0); |
100 await programIsDone; | 113 await programIsDone; |
101 expect(await lines.skip(1).first, "part1 part2"); | 114 expect(await lines[1], "part1 part2"); |
102 }); | 115 }); |
103 | 116 |
104 test('reload after leaf library modification', () async { | 117 test('reload after leaf library modification', () async { |
105 await startProgram(1); | 118 await startProgram(1); |
106 expect(await lines[1], "part1 part2"); | 119 expect(await lines[1], "part1 part2"); |
107 | 120 |
108 writeFile(fs, 'b.dart', sourceB.replaceAll("part1", "part3")); | 121 writeFile(fs, 'b.dart', sourceB.replaceAll("part1", "part3")); |
109 await rebuild(compiler, outputUri); | 122 await rebuild(compiler, outputUri); |
110 await hotReload(); | 123 await hotReload(); |
111 await programIsDone; | 124 await programIsDone; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 writeFile(fs, 'a.dart', sourceA.replaceAll("part2", "part8")); | 162 writeFile(fs, 'a.dart', sourceA.replaceAll("part2", "part8")); |
150 await rebuild(compiler, outputUri); | 163 await rebuild(compiler, outputUri); |
151 await hotReload(); | 164 await hotReload(); |
152 await programIsDone; | 165 await programIsDone; |
153 expect(await lines[3], "part7 part8"); | 166 expect(await lines[3], "part7 part8"); |
154 }); | 167 }); |
155 } | 168 } |
156 | 169 |
157 var dartVm = Uri.base.resolve(Platform.resolvedExecutable); | 170 var dartVm = Uri.base.resolve(Platform.resolvedExecutable); |
158 var sdkRoot = dartVm.resolve("patched_sdk/"); | 171 var sdkRoot = dartVm.resolve("patched_sdk/"); |
159 var platformFile = sdkRoot.resolve('platform.dill'); | |
160 | 172 |
161 Future<IncrementalKernelGenerator> createIncrementalCompiler( | 173 Future<IncrementalKernelGenerator> createIncrementalCompiler( |
162 String entry, FileSystem fs) { | 174 String entry, FileSystem fs) { |
163 var entryUri = Uri.base.resolve(entry); | 175 var entryUri = Uri.base.resolve(entry); |
164 var options = new CompilerOptions() | 176 var options = new CompilerOptions() |
165 ..sdkRoot = sdkRoot | 177 ..sdkRoot = sdkRoot |
166 ..sdkSummary = sdkRoot.resolve('outline.dill') | 178 ..sdkSummary = sdkRoot.resolve('outline.dill') |
167 ..packagesFileUri = Uri.parse('file:///.packages') | 179 ..packagesFileUri = Uri.parse('file:///.packages') |
168 ..strongMode = false | 180 ..strongMode = false |
169 ..dartLibraries = loadDartLibraries() | 181 ..dartLibraries = loadDartLibraries() |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 | 249 |
238 f() => "$line part2"; | 250 f() => "$line part2"; |
239 '''; | 251 '''; |
240 | 252 |
241 const sourceB = r''' | 253 const sourceB = r''' |
242 get line => "part1"; | 254 get line => "part1"; |
243 '''; | 255 '''; |
244 | 256 |
245 RegExp observatoryPortRegExp = | 257 RegExp observatoryPortRegExp = |
246 new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)/"); | 258 new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)/"); |
OLD | NEW |