Flutter Engine
The Flutter Engine
run_vm_tests.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5#include "bin/console.h"
6#include "bin/crashpad.h"
7#include "bin/dartutils.h"
8#include "bin/dfe.h"
9#include "bin/eventhandler.h"
10#include "bin/exe_utils.h"
11#include "bin/file.h"
12#include "bin/loader.h"
13#include "bin/platform.h"
14#include "bin/process.h"
15#include "bin/snapshot_utils.h"
16#include "bin/thread.h"
17#include "bin/utils.h"
18#include "bin/vmservice_impl.h"
19#include "platform/assert.h"
20#include "vm/benchmark_test.h"
21#include "vm/dart.h"
22#include "vm/unit_test.h"
23
24extern "C" {
25extern const uint8_t kDartVmSnapshotData[];
26extern const uint8_t kDartVmSnapshotInstructions[];
27extern const uint8_t kDartCoreIsolateSnapshotData[];
28extern const uint8_t kDartCoreIsolateSnapshotInstructions[];
29}
30
31// TODO(iposva, asiva): This is a placeholder for the real unittest framework.
32namespace dart {
33
34// Snapshot pieces when we link in a snapshot.
40
41// Only run tests that match the filter string. The default does not match any
42// tests.
43static constexpr const char* kNone = "No Test or Benchmarks";
44static constexpr const char* kList = "List all Tests and Benchmarks";
45static constexpr const char* kAllBenchmarks = "All Benchmarks";
46static const char* run_filter = kNone;
47static const char* kernel_snapshot = nullptr;
48
49static int run_matches = 0;
50
52 Syslog::Print("Running test: %s\n", name());
53 (*run_)();
54 Syslog::Print("Done: %s\n", name());
55}
56
58 Syslog::Print("Running raw test: %s\n", name());
59 (*run_)();
60 Syslog::Print("Done: %s\n", name());
61}
62
64 if (strcmp(run_filter, this->name()) == 0) {
65 this->Run();
66 run_matches++;
67 } else if (run_filter == kList) {
68 Syslog::Print("%s %s\n", this->name(), this->expectation());
69 run_matches++;
70 }
71}
72
74 if ((run_filter == kAllBenchmarks) ||
75 (strcmp(run_filter, this->name()) == 0)) {
76 this->Run();
77 Syslog::Print("%s(%s): %" Pd64 "\n", this->name(), this->score_kind(),
78 this->score());
79 run_matches++;
80 } else if (run_filter == kList) {
81 Syslog::Print("%s Pass\n", this->name());
82 run_matches++;
83 }
84}
85
86static void PrintUsage() {
88 "Usage: one of the following\n"
89 " run_vm_tests --list\n"
90 " run_vm_tests [--dfe=<snapshot file name>] --benchmarks\n"
91 " run_vm_tests [--dfe=<snapshot file name>] [vm-flags ...] <test name>\n"
92 " run_vm_tests [--dfe=<snapshot file name>] [vm-flags ...] <benchmark "
93 "name>\n");
94}
95
96#define CHECK_RESULT(result) \
97 if (Dart_IsError(result)) { \
98 *error = Utils::StrDup(Dart_GetError(result)); \
99 Dart_ExitScope(); \
100 Dart_ShutdownIsolate(); \
101 return nullptr; \
102 }
103
104static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
105 const char* packages_config,
107 char** error) {
108 // We only enable the vm-service for this particular test.
109 // The vm-service seems to have some shutdown race which would cause other
110 // vm/cc tests to randomly time out due to inability to shut service-isolate
111 // down.
112 // Issue(https://dartbug.com/37741):
113 if ((strcmp(run_filter, "DartAPI_InvokeVMServiceMethod") != 0) &&
114 (strcmp(run_filter, "DartAPI_InvokeVMServiceMethod_Loop") != 0)) {
115 return nullptr;
116 }
117
118 ASSERT(script_uri != nullptr);
119 Dart_Isolate isolate = nullptr;
120 auto isolate_group_data = new bin::IsolateGroupData(
121 script_uri, packages_config, /*app_snapshot=*/nullptr,
122 /*isolate_run_app_snapshot=*/false);
123
124 const uint8_t* kernel_buffer = nullptr;
125 intptr_t kernel_buffer_size = 0;
126
127 bin::dfe.Init();
128 bin::dfe.LoadPlatform(&kernel_buffer, &kernel_buffer_size);
129 RELEASE_ASSERT(kernel_buffer != nullptr);
130
131 flags->load_vmservice_library = true;
132 flags->is_service_isolate = true;
133 isolate_group_data->SetKernelBufferUnowned(
134 const_cast<uint8_t*>(kernel_buffer), kernel_buffer_size);
136 script_uri, DART_VM_SERVICE_ISOLATE_NAME, kernel_buffer,
137 kernel_buffer_size, flags, isolate_group_data, /*isolate_data=*/nullptr,
138 error);
139 if (isolate == nullptr) {
140 delete isolate_group_data;
141 return nullptr;
142 }
143
145
149
150 // Load embedder specific bits and return.
151 if (!bin::VmService::Setup("127.0.0.1", 0,
152 /*dev_mode=*/false, /*auth_disabled=*/true,
153 /*write_service_info_filename=*/"",
154 /*trace_loading=*/false, /*deterministic=*/true,
155 /*enable_service_port_fallback=*/false,
156 /*wait_for_dds_to_advertise_service=*/false,
157 /*serve_devtools=*/false,
158 /*serve_observatory=*/true,
159 /*print_dtd=*/false)) {
161 return nullptr;
162 }
167 return isolate;
168}
169
170static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
171 const char* main,
172 const char* package_root,
173 const char* packages_config,
175 void* data,
176 char** error) {
177 ASSERT(script_uri != nullptr);
178 ASSERT(package_root == nullptr);
179 if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
180 return CreateAndSetupServiceIsolate(script_uri, packages_config, flags,
181 error);
182 }
183 const bool is_kernel_isolate =
184 strcmp(script_uri, DART_KERNEL_ISOLATE_NAME) == 0;
185 if (!is_kernel_isolate) {
187 "Spawning of only Kernel isolate is supported in run_vm_tests.");
188 return nullptr;
189 }
190 Dart_Isolate isolate = nullptr;
191 bin::IsolateGroupData* isolate_group_data = nullptr;
192 const uint8_t* kernel_service_buffer = nullptr;
193 intptr_t kernel_service_buffer_size = 0;
194
195 // Kernel isolate uses an app snapshot or the kernel service dill file.
196 if (kernel_snapshot != nullptr &&
199 script_uri = kernel_snapshot;
200 bin::AppSnapshot* app_snapshot =
202 ASSERT(app_snapshot != nullptr);
203 const uint8_t* ignore_vm_snapshot_data;
204 const uint8_t* ignore_vm_snapshot_instructions;
205 const uint8_t* isolate_snapshot_data;
206 const uint8_t* isolate_snapshot_instructions;
207 app_snapshot->SetBuffers(
208 &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
210 isolate_group_data = new bin::IsolateGroupData(
211 script_uri, packages_config, app_snapshot, app_snapshot != nullptr);
212 isolate = Dart_CreateIsolateGroup(
215 isolate_group_data, /*isolate_data=*/nullptr, error);
216 if (*error != nullptr) {
217 OS::PrintErr("Error creating isolate group: %s\n", *error);
218 free(*error);
219 *error = nullptr;
220 }
221 // If a test does not actually require the kernel isolate the main thead can
222 // start calling Dart::Cleanup() while the kernel isolate is booting up.
223 // This can cause the isolate to be killed early which will return `nullptr`
224 // here.
225 if (isolate == nullptr) {
226 delete isolate_group_data;
227 return nullptr;
228 }
229 }
230 if (isolate == nullptr) {
231 delete isolate_group_data;
232 isolate_group_data = nullptr;
233
234 bin::dfe.Init();
235 bin::dfe.LoadKernelService(&kernel_service_buffer,
236 &kernel_service_buffer_size);
237 ASSERT(kernel_service_buffer != nullptr);
238 isolate_group_data =
239 new bin::IsolateGroupData(script_uri, packages_config, nullptr, false);
240 isolate_group_data->SetKernelBufferUnowned(
241 const_cast<uint8_t*>(kernel_service_buffer),
242 kernel_service_buffer_size);
244 script_uri, main, kernel_service_buffer, kernel_service_buffer_size,
245 flags, isolate_group_data, /*isolate_data=*/nullptr, error);
246 }
247 if (isolate == nullptr) {
248 delete isolate_group_data;
249 return nullptr;
250 }
251
253
256 /*is_service_isolate=*/false, /*trace_loading=*/false);
258
259 // Setup kernel service as the main script for this isolate.
260 if (kernel_service_buffer != nullptr) {
261 result = Dart_LoadScriptFromKernel(kernel_service_buffer,
262 kernel_service_buffer_size);
264 }
265
269 if (*error != nullptr) {
270 Dart_EnterIsolate(isolate);
272 return nullptr;
273 }
274
275 return isolate;
276}
277
278static void CleanupIsolateGroup(void* callback_data) {
279 bin::IsolateGroupData* isolate_data =
280 reinterpret_cast<bin::IsolateGroupData*>(callback_data);
281 delete isolate_data;
282}
283
286 info->name = "Run VM Tests";
287 bin::Process::GetRSSInformation(&(info->max_rss), &(info->current_rss));
288}
289
290void ShiftArgs(int* argc, const char** argv) {
291 // Remove the first flag from the list by shifting all arguments down.
292 for (intptr_t i = 1; i < *argc - 1; i++) {
293 argv[i] = argv[i + 1];
294 }
295 argv[*argc - 1] = nullptr;
296 (*argc)--;
297}
298
299static int Main(int argc, const char** argv) {
300#if !defined(DART_HOST_OS_WINDOWS)
301 // Very early so any crashes during startup can also be symbolized.
303#endif
304
305 // Flags being passed to the Dart VM.
306 int dart_argc = 0;
307 const char** dart_argv = nullptr;
308
309 // Perform platform specific initialization.
311 Syslog::PrintErr("Initialization failed\n");
312 return 1;
313 }
314
315 // Save the console state so we can restore it later.
317
318 // Store the executable name.
320
321 if (argc < 2) {
322 // Bad parameter count.
323 PrintUsage();
324 return 1;
325 }
326
327 if (argc == 2 && strcmp(argv[1], "--list") == 0) {
329 // List all tests and benchmarks and exit without initializing the VM.
333 fflush(stdout);
334 return 0;
335 }
336
337 int arg_pos = 1;
338 bool start_kernel_isolate = false;
339 bool suppress_core_dump = false;
340 if (strcmp(argv[arg_pos], "--suppress-core-dump") == 0) {
341 suppress_core_dump = true;
342 ShiftArgs(&argc, argv);
343 }
344
345 if (suppress_core_dump) {
347 } else {
349 }
350
351 if (strncmp(argv[arg_pos], "--dfe", strlen("--dfe")) == 0) {
352 const char* delim = strstr(argv[arg_pos], "=");
353 if (delim == nullptr || strlen(delim + 1) == 0) {
354 Syslog::PrintErr("Invalid value for the option: %s\n", argv[arg_pos]);
355 PrintUsage();
356 return 1;
357 }
358 kernel_snapshot = Utils::StrDup(delim + 1);
359 start_kernel_isolate = true;
360 ShiftArgs(&argc, argv);
361 }
362
363 if (arg_pos == argc - 1 && strcmp(argv[arg_pos], "--benchmarks") == 0) {
364 // "--benchmarks" is the last argument.
366 } else {
367 // Last argument is the test name, the rest are vm flags.
368 run_filter = argv[argc - 1];
369 // Remove the first value (executable) from the arguments and
370 // exclude the last argument which is the test name.
371 dart_argc = argc - 2;
372 dart_argv = &argv[1];
373 }
374
378
379 char* error = Flags::ProcessCommandLineFlags(dart_argc, dart_argv);
380 if (error != nullptr) {
381 Syslog::PrintErr("Failed to parse flags: %s\n", error);
382 free(error);
383 return 1;
384 }
385
389 TesterState::argv = dart_argv;
390 TesterState::argc = dart_argc;
391
392 Dart_InitializeParams init_params;
393 memset(&init_params, 0, sizeof(init_params));
403 init_params.start_kernel_isolate = start_kernel_isolate;
404#if defined(DART_HOST_OS_FUCHSIA)
405 init_params.vmex_resource = dart::bin::Platform::GetVMEXResource();
406#endif
407 error = Dart::Init(&init_params);
408 if (error != nullptr) {
409 Syslog::PrintErr("Failed to initialize VM: %s\n", error);
410 free(error);
411 return 1;
412 }
413
415
416 // Apply the filter to all registered tests.
418 // Apply the filter to all registered benchmarks.
420
423 if (error != nullptr) {
424 Syslog::PrintErr("Failed shutdown VM: %s\n", error);
425 free(error);
426 return 1;
427 }
428
430
433
434 // Print a warning message if no tests or benchmarks were matched.
435 if (run_matches == 0) {
436 Syslog::PrintErr("No tests matched: %s\n", run_filter);
437 return 1;
438 }
439 if (Expect::failed()) {
440 return 255;
441 }
442 return 0;
443}
444
445} // namespace dart
446
447int main(int argc, const char** argv) {
449}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
const char * name() const
int64_t score() const
const char * score_kind() const
static void RunAll(const char *executable)
static char * Cleanup()
Definition: dart.cc:629
static char * Init(const Dart_InitializeParams *params)
Definition: dart.cc:526
void static bool failed()
Definition: assert.h:94
static char * ProcessCommandLineFlags(int argc, const char **argv)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
virtual void Run()
Definition: run_vm_tests.cc:57
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void Print(const char *format,...) PRINTF_ATTRIBUTE(1
virtual void Run()=0
const char * expectation() const
Definition: unit_test.h:291
static void RunAllRaw()
Definition: unit_test.cc:72
const char * name() const
Definition: unit_test.h:290
static void RunAll()
Definition: unit_test.cc:83
virtual void Run()
Definition: run_vm_tests.cc:51
static Dart_IsolateGroupCreateCallback create_callback
Definition: unit_test.h:256
static const char ** argv
Definition: unit_test.h:259
static Dart_IsolateGroupCleanupCallback group_cleanup_callback
Definition: unit_test.h:258
static int argc
Definition: unit_test.h:260
static const uint8_t * vm_snapshot_data
Definition: unit_test.h:255
static char * StrDup(const char *s)
virtual void SetBuffers(const uint8_t **vm_data_buffer, const uint8_t **vm_instructions_buffer, const uint8_t **isolate_data_buffer, const uint8_t **isolate_instructions_buffer)=0
static void SaveConfig()
void LoadPlatform(const uint8_t **kernel_buffer, intptr_t *kernel_buffer_size)
Definition: dfe.cc:137
void Init()
Definition: dfe.cc:88
void LoadKernelService(const uint8_t **kernel_service_buffer, intptr_t *kernel_service_buffer_size)
Definition: dfe.cc:131
static void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
Definition: dartutils.cc:273
static bool SetOriginalWorkingDirectory()
Definition: dartutils.cc:821
static Dart_Handle EnvironmentCallback(Dart_Handle name)
Definition: dartutils.cc:835
static Dart_Handle PrepareForScriptLoading(bool is_service_isolate, bool trace_loading)
Definition: dartutils.cc:570
static void CloseFile(void *stream)
Definition: dartutils.cc:303
static MagicNumber SniffForMagicNumber(const char *filename)
Definition: dartutils.cc:403
static void * OpenFile(const char *name, bool write)
Definition: dartutils.cc:261
static void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
Definition: dartutils.cc:294
static void LoadDartProfilerSymbols(const char *exepath)
Definition: exe_utils.cc:129
void SetKernelBufferUnowned(uint8_t *buffer, intptr_t size)
Definition: isolate_data.h:54
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
Definition: loader.cc:69
static void SetExecutableName(const char *executable_name)
Definition: platform.h:71
static DART_NORETURN void Exit(int exit_code)
static bool Initialize()
static void SetCoreDumpResourceLimit(int value)
static void Cleanup()
static void GetRSSInformation(int64_t *max_rss, int64_t *current_rss)
Definition: process.cc:393
static void TerminateExitCodeHandler()
static void Init()
static AppSnapshot * TryReadAppSnapshot(const char *script_uri, bool force_load_elf_from_memory=false, bool decode_uri=true)
static void InitOnce()
static const char * GetErrorMessage()
static bool Setup(const char *server_ip, intptr_t server_port, bool dev_mode_server, bool auth_codes_disabled, const char *write_service_info_filename, bool trace_loading, bool deterministic, bool enable_service_port_fallback, bool wait_for_dds_to_advertise_service, bool serve_devtools, bool serve_observatory, bool print_dtd)
#define DART_INITIALIZE_PARAMS_CURRENT_VERSION
Definition: dart_api.h:840
#define DART_KERNEL_ISOLATE_NAME
Definition: dart_api.h:3880
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
struct _Dart_Isolate * Dart_Isolate
Definition: dart_api.h:88
#define DART_VM_SERVICE_ISOLATE_NAME
Definition: dart_api.h:3888
#define DART_EMBEDDER_INFORMATION_CURRENT_VERSION
#define ASSERT(E)
FlutterSemanticsFlag flags
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
char ** argv
Definition: library.h:9
const uint8_t * isolate_snapshot_data
Definition: gen_snapshot.cc:69
const uint8_t * vm_snapshot_data
Definition: main_impl.cc:52
DFE dfe
Definition: dfe.cc:59
const uint8_t * vm_snapshot_instructions
Definition: main_impl.cc:53
const uint8_t * core_isolate_snapshot_data
Definition: main_impl.cc:54
const uint8_t * core_isolate_snapshot_instructions
Definition: main_impl.cc:55
void InitializeCrashpadClient()
Definition: crashpad.cc:77
const uint8_t * isolate_snapshot_instructions
Definition: gen_snapshot.cc:70
Definition: dart_vm.cc:33
static Dart_Isolate CreateIsolateAndSetup(const char *script_uri, const char *main, const char *package_root, const char *packages_config, Dart_IsolateFlags *flags, void *data, char **error)
DART_EXPORT void Dart_EnterScope()
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
static constexpr const char * kNone
Definition: run_vm_tests.cc:43
static int run_matches
Definition: run_vm_tests.cc:49
static void CleanupIsolateGroup(void *callback_data)
DART_EXPORT void Dart_SetEmbedderInformationCallback(Dart_EmbedderInformationCallback callback)
static const char * kernel_snapshot
Definition: run_vm_tests.cc:47
static void EmbedderInformationCallback(Dart_EmbedderInformation *info)
static const char * run_filter
Definition: run_vm_tests.cc:46
static constexpr const char * kAllBenchmarks
Definition: run_vm_tests.cc:45
static int Main(int argc, const char **argv)
void ShiftArgs(int *argc, const char **argv)
DART_EXPORT void Dart_ExitIsolate()
DART_EXPORT char * Dart_IsolateMakeRunnable(Dart_Isolate isolate)
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroup(const char *script_uri, const char *name, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Isolate Dart_CreateIsolateGroupFromKernel(const char *script_uri, const char *name, const uint8_t *kernel_buffer, intptr_t kernel_buffer_size, Dart_IsolateFlags *flags, void *isolate_group_data, void *isolate_data, char **error)
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler)
DART_EXPORT void Dart_ExitScope()
DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t *buffer, intptr_t buffer_size)
DART_EXPORT Dart_Handle Dart_SetEnvironmentCallback(Dart_EnvironmentCallback callback)
static int8_t data[kExtLength]
static Dart_Isolate CreateAndSetupServiceIsolate(const char *script_uri, const char *packages_config, Dart_IsolateFlags *flags, char **error)
DART_EXPORT void Dart_ShutdownIsolate()
static void PrintUsage()
Definition: run_vm_tests.cc:86
static constexpr const char * kList
Definition: run_vm_tests.cc:44
Definition: main.py:1
#define Pd64
Definition: globals.h:416
#define CHECK_RESULT(result)
Definition: run_vm_tests.cc:96
const uint8_t kDartVmSnapshotData[]
const uint8_t kDartVmSnapshotInstructions[]
int main(int argc, const char **argv)
const uint8_t kDartCoreIsolateSnapshotInstructions[]
const uint8_t kDartCoreIsolateSnapshotData[]
Dart_IsolateGroupCreateCallback create_group
Definition: dart_api.h:925
Dart_IsolateGroupCleanupCallback cleanup_group
Definition: dart_api.h:950
Dart_FileReadCallback file_read
Definition: dart_api.h:955
const uint8_t * vm_snapshot_data
Definition: dart_api.h:911
Dart_FileOpenCallback file_open
Definition: dart_api.h:954
Dart_FileWriteCallback file_write
Definition: dart_api.h:956
const uint8_t * vm_snapshot_instructions
Definition: dart_api.h:919
Dart_FileCloseCallback file_close
Definition: dart_api.h:957