-
Notifications
You must be signed in to change notification settings - Fork 26.7k
/
batch_entrypoint_test.dart
172 lines (155 loc) · 5.77 KB
/
batch_entrypoint_test.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/io.dart';
import '../src/common.dart';
import 'test_utils.dart';
final String flutterRootPath = getFlutterRoot();
Future<void> main() async {
// Regression test for https://github.com/flutter/flutter/issues/132592
test('flutter/bin/dart updates the Dart SDK without hanging', () async {
// Copy the parts of the Flutter SDK that are needed by the body code of
// this test into a temp directory to avoid operating on files that are
// currently being accessed to run this test, i.e.
// dartaotruntime.exe and frontend_server_aot.dart.snapshot.
final Directory tempDir = createResolvedTempDirectorySync('batch_entrypoint_test.');
final Directory flutterRootInTempDir = tempDir.childDirectory('flutter');
flutterRootInTempDir.createSync();
final File xcopyExcludeFile = tempDir.childFile('exclude.txt');
xcopyExcludeFile.writeAsStringSync(r'''
bin\cache\dart-sdk
bin\cache\engine-dart-sdk.stamp
packages\flutter_tools\test
''');
await processManager.run(
<String>[
'xcopy',
'/s',
'/e',
'/h',
'.git',
'${flutterRootInTempDir.childDirectory('.git').path}\\',
],
workingDirectory: flutterRootPath,
);
await processManager.run(
<String>[
'xcopy',
'/s',
'/e',
'/h',
'/exclude:${xcopyExcludeFile.path}',
'bin',
'${flutterRootInTempDir.childDirectory('bin').path}\\',
],
workingDirectory: flutterRootPath,
);
await processManager.run(
<String>[
'xcopy',
'/s',
'/e',
'/h',
'/exclude:${xcopyExcludeFile.path}',
r'packages\flutter_tools',
'${flutterRootInTempDir.childDirectory('packages').childDirectory('flutter_tools').path}\\',
],
workingDirectory: flutterRootPath,
);
expect(flutterRootInTempDir.existsSync(), true);
expect(
flutterRootInTempDir
.childDirectory('packages')
.childDirectory('flutter_tools')
.childDirectory('lib')
.childFile('executable.dart')
.existsSync(),
true,
);
// Run the Dart entrypoint once to ensure the Dart SDK is downloaded.
await runDartBatch(flutterRootInTempDir);
expect(getDartSdkStamp(flutterRootInTempDir).existsSync(), true);
// Remove the Dart SDK stamp and run the Dart entrypoint again to trigger
// the Dart SDK update.
getDartSdkStamp(flutterRootInTempDir).deleteSync();
final Future<String> runFuture = runDartBatch(flutterRootInTempDir);
final Timer timer = Timer(const Duration(minutes: 5), () {
// This print is useful for people debugging this test. Normally we would
// avoid printing in a test but this is an exception because it's useful
// ambient information.
// ignore: avoid_print
print(
'The Dart batch entrypoint did not complete after 5 minutes. '
'Historically this is a sign that 7-Zip zip extraction is waiting for '
'the user to confirm they would like to overwrite files. '
"This likely means the test isn't a flake and will fail. "
'See: https://github.com/flutter/flutter/issues/132592'
);
});
final String output = await runFuture;
timer.cancel();
// Check the Dart SDK was re-downloaded and extracted.
// If 7-Zip is installed, unexpected overwrites causes this to hang.
// If 7-Zip is not installed, unexpected overwrites results in error messages.
// See: https://github.com/flutter/flutter/issues/132592
expect(getDartSdkStamp(flutterRootInTempDir).existsSync(), true);
expect(output, contains('Downloading Dart SDK from Flutter engine ...'));
// Do not assert on the exact unzipping method, as this could change on CI
expect(output, contains(RegExp(r'Expanding downloaded archive with (.*)...')));
expect(output, isNot(contains('Use the -Force parameter' /* Luke */)));
tempDir.deleteSync(recursive: true);
},
skip: !platform.isWindows); // [intended] Only Windows uses the batch entrypoint
}
Future<String> runDartBatch(Directory flutterRoot) async {
String output = '';
final Process process = await processManager.start(
<String>[
getDartBatch(flutterRoot).path
],
);
final Future<Object?> stdoutFuture = process.stdout
.transform<String>(utf8.decoder)
.forEach((String str) {
print(str);
output += str;
});
final Future<Object?> stderrFuture = process.stderr
.transform<String>(utf8.decoder)
.forEach((String str) {
print(str);
output += str;
});
// Wait for the output to complete
await Future.wait(<Future<Object?>>[stdoutFuture, stderrFuture]);
// Ensure child exited successfully
expect(
await process.exitCode,
0,
reason: 'child process exited with code ${await process.exitCode}, and '
'output:\n$output',
);
// Check the Dart tool prints the expected output.
expect(output, contains('A command-line utility for Dart development.'));
expect(output, contains('Usage: dart <command|dart-file> [arguments]'));
return output;
}
// The executable batch entrypoint for the Dart binary within the Flutter SDK
// located at [flutterRoot].
File getDartBatch(Directory flutterRoot) {
return flutterRoot
.childDirectory('bin')
.childFile('dart.bat')
.absolute;
}
// The Dart SDK's stamp file within the Flutter SDK located at [flutterRoot].
File getDartSdkStamp(Directory flutterRoot) {
return flutterRoot
.childDirectory('bin')
.childDirectory('cache')
.childFile('engine-dart-sdk.stamp')
.absolute;
}