-
Notifications
You must be signed in to change notification settings - Fork 171
/
run_flutter_tests.dart
181 lines (150 loc) · 5.16 KB
/
run_flutter_tests.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
173
174
175
176
177
178
179
180
181
/*
This file is part of KDDockWidgets.
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Sérgio Martins <[email protected]>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
Contact KDAB at <[email protected]> for commercial licensing options.
*/
// A script that runs the tests but first ensures the bundle is built
import 'dart:io';
import 'src/flutter/utils.dart';
bool isAOT = false;
bool isASAN = false;
bool isLSAN = false;
bool useGDB = false;
bool ubsanPrintStacks = false;
String kddwSourceDir() {
return Platform.script.path.replaceAll("run_flutter_tests.dart", "");
}
Future<int> runTests(String? singleTestName, List<String> singleTestArgs,
String buildDir) async {
if (!await Directory(buildDir).exists()) {
final presetName = buildDir
.replaceAll(kddwSourceDir(), "")
.replaceAll("build-", "")
.replaceAll("/", "");
print("ERROR: Could not find $buildDir.\n"
"Be sure to build the preset: $presetName");
return -1;
}
if (singleTestName != null &&
!await File("$buildDir/bin/$singleTestName").exists()) {
print("ERROR: Could not find executable $buildDir/bin/$singleTestName\n");
return -1;
}
/// Make sure the C++ is built:
int result = await runCommand("ninja", [], workingDirectory: buildDir);
if (result != 0) {
print("Failed to build C++");
return result;
}
/// Make sure the flutter bundle is built:
final flutterEmbedderDir = "${kddwSourceDir()}/tests/flutter_tests_embedder/";
result = await runCommand(
"flutter", ["build", "bundle", "--suppress-analytics"],
workingDirectory: flutterEmbedderDir);
if (result != 0) {
print("Failed to build bundle");
return result;
}
if (isAOT) {
result = await runCommand(
"flutter", ["build", "linux", "--release", "--suppress-analytics"],
workingDirectory: flutterEmbedderDir);
if (result != 0) {
print("Failed to build AOT snapshot (libapp.so)");
return result;
}
}
final String aotValue = isAOT ? "1" : "0";
final String lsanValue = isLSAN ? "1" : "0";
final String asanOptions = "detect_leaks=$lsanValue";
final String ubsanOptions = ubsanPrintStacks ? "print_stacktrace=1" : "";
final String gensnapshotOptions = "--no-strip";
final String libraryPath = "$buildDir/lib/";
print("export KDDW_FLUTTER_TESTS_USE_AOT=$aotValue");
print("export ASAN_OPTIONS=$asanOptions");
if (ubsanPrintStacks) print("export UBSAN_OPTIONS=$ubsanOptions");
print("export DARTAGNAN_BINDINGSLIB_PATH=$libraryPath");
print("\n");
final env = {
"KDDW_FLUTTER_TESTS_USE_AOT": aotValue,
"ASAN_OPTIONS": asanOptions,
"EXTRA_GEN_SNAPSHOT_OPTIONS": gensnapshotOptions,
if (ubsanPrintStacks) "UBSAN_OPTIONS": ubsanOptions,
"DARTAGNAN_BINDINGSLIB_PATH": libraryPath
};
/// Now we can run the tests:
if (singleTestName == null) {
// Run everything:
return await runCommand("ctest", ["-j1", "--output-on-failure"],
workingDirectory: buildDir, env: env);
} else {
// Run a single test:
final String executableName = useGDB ? "gdb" : "bin/$singleTestName";
List<String> args = [
// "--disable-service-auth-codes",
// "--verbose-logging",
// "--start-paused"
if (useGDB) ...[
"-ex=run",
"--args",
"bin/$singleTestName",
...singleTestArgs
] else
...singleTestArgs
];
return await runCommand(executableName, args,
workingDirectory: buildDir, env: env);
}
}
void printUsage() {
print(
"Usage: dart run_flutter_tests.dart [--aot] [--asan] [--lsan] [--ubsan-stacktraces]");
print("Or specify a single test to run:");
print(
"dart run_flutter_tests.dart [--aot] [--asan] [--lsan] [--ubsan-stacktraces] [--gdb] <test_name> [args]");
print("Use asan_symbolize.py if --lsan isn't symbolizing libapp.so");
}
String calculateBuildDir() {
String result;
if (isAOT) {
result = "build-dev-flutter-aot";
} else {
result = "build-dev-flutter";
}
if (isASAN) result += "-asan";
print("Using $result");
return "${kddwSourceDir()}${result}/";
}
Future<void> main(List<String> args) async {
final _args = List<String>.from(args);
isLSAN = _args.remove("--lsan");
isASAN = _args.remove("--asan") || isLSAN;
isAOT =
_args.remove("--aot") || isLSAN; // LSAN requires AOT for simbolization
useGDB = _args.remove("--gdb");
ubsanPrintStacks = _args.remove("--ubsan-stacktraces");
final bool isHelp = _args.remove("--help") || _args.remove("-h");
if (isHelp) {
printUsage();
exit(0);
}
if (ubsanPrintStacks && !isASAN) {
print("ERROR: --ubsan-stacktraces requires --asan");
exit(1);
}
final String? singleTestName = _args.isEmpty ? null : _args.first;
List<String> singleTestArgs = _args.isEmpty ? [] : _args.sublist(1);
final result =
await runTests(singleTestName, singleTestArgs, calculateBuildDir());
final bool isSuccess = result == 0;
if (isSuccess)
print("SUCCESS!");
else
print("ERROR!");
if (isLSAN && !isAOT && !isSuccess) {
print("\nConsider using LSAN with AOT so you can get symbolized traces");
}
exit(result);
}