blob: b25fc9c742f7fb116c4fd837dc54593fd8255fb5 [file] [log] [blame]
Christopher Ferris1a993562018-08-21 12:43:50 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22
23#include <vector>
24
25#include <android-base/file.h>
26#include <gtest/gtest.h>
27#include <gtest_extras/IsolateMain.h>
28
29#include "Color.h"
30#include "Isolate.h"
31
32namespace android {
33namespace gtest_extras {
34
35static void PrintHelpInfo() {
36 printf("Unit Test Options:\n");
37 ColoredPrintf(COLOR_GREEN, " -j ");
38 ColoredPrintf(COLOR_YELLOW, "[JOB_COUNT]");
39 printf(" or ");
40 ColoredPrintf(COLOR_GREEN, "-j");
41 ColoredPrintf(COLOR_YELLOW, "[JOB_COUNT]\n");
42 printf(
43 " Run up to JOB_COUNT tests in parallel.\n"
44 " Use isolation mode, Run each test in a separate process.\n"
45 " If JOB_COUNT is not given, it is set to the count of available processors.\n");
46 ColoredPrintf(COLOR_GREEN, " --no_isolate\n");
47 printf(" Don't use isolation mode, run all tests in a single process.\n");
48 ColoredPrintf(COLOR_GREEN, " --deadline_threshold_ms=");
49 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]\n");
50 printf(" Run each test in no longer than ");
51 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]");
52 printf(
53 " time.\n"
54 " Only valid in isolation mode. Default deadline is 90000 ms.\n");
55 ColoredPrintf(COLOR_GREEN, " --slow_threshold_ms=");
56 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]\n");
57 printf(" Test running longer than ");
58 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]");
59 printf(
60 " will be called slow.\n"
61 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n");
62 ColoredPrintf(COLOR_GREEN, " --gtest_format\n");
63 printf(
64 " Use the default gtest format, not the enhanced format.\n"
65 "\n"
66 "Default test option is ");
67 ColoredPrintf(COLOR_GREEN, "-j");
68 printf(
69 ".\n"
70 "In isolation mode, you can send SIGQUIT to the parent process to show the\n"
71 "current running tests, or send SIGINT to the parent process to stop all\n"
72 "running tests.\n"
73 "\n");
74}
75
76static int GtestRun(std::vector<const char*>* args) {
77 int argc = args->size();
78 args->push_back(nullptr);
79 ::testing::InitGoogleTest(&argc, const_cast<char**>(args->data()));
80 return RUN_ALL_TESTS();
81}
82
83static bool RunInIsolationMode(std::vector<const char*>& args) {
84 // Parse arguments that can't be used in isolation mode.
85 for (size_t i = 1; i < args.size(); ++i) {
86 if (strcmp(args[i], "--no_isolate") == 0) {
87 return false;
88 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
89 return false;
90 }
91 }
92 return true;
93}
94
95} // namespace gtest_extras
96} // namespace android
97
98// Tests that override this weak function can add default arguments.
99extern "C" bool __attribute__((weak)) GetInitialArgs(const char***, size_t*) {
100 return false;
101}
102
103int IsolateMain(int argc, char** argv, char**) {
104 std::vector<const char*> args{argv[0]};
105
106 bool print_help = false;
107 size_t gtest_color_index = 0;
108 for (int i = 1; i < argc; ++i) {
109 args.push_back(argv[i]);
110 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
111 print_help = true;
112 } else if (strncmp(argv[i], "--gtest_color=", 14) == 0) {
113 gtest_color_index = args.size() - 1;
114 }
115 }
116
117 if (print_help) {
118 std::vector<const char*> help_args{args[0], "--help"};
119 if (gtest_color_index != 0) {
120 // This is the only option that changes the way the help is printed.
121 help_args.push_back(args[gtest_color_index]);
122 ::testing::GTEST_FLAG(color) = args[gtest_color_index] + 14;
123 }
124 android::gtest_extras::PrintHelpInfo();
125 return android::gtest_extras::GtestRun(&help_args);
126 }
127
128 if (!android::gtest_extras::RunInIsolationMode(args)) {
129 return android::gtest_extras::GtestRun(&args);
130 }
131
132 const char** start_args;
133 size_t num_args;
134 if (GetInitialArgs(&start_args, &num_args)) {
135 std::vector<const char*> initial_args;
136 for (size_t i = 0; i < num_args; i++) {
137 initial_args.push_back(start_args[i]);
138 }
139 args.insert(args.begin() + 1, initial_args.begin(), initial_args.end());
140 }
141
142 // To run a DeathTest in threadsafe mode, gtest requires that the user must
143 // invoke the test program directly, not by running it from the path.
144 // This is because gtest uses clone() + execve() to run a DeathTest() and
145 // execve() doesn't search the path to execute.
146 std::vector<const char*> child_args;
147 std::string exec_path; // Need to be scoped through the entire function.
148 if (strchr(args[0], '/') == nullptr) {
149 exec_path = android::base::GetExecutablePath();
150 child_args.push_back(exec_path.c_str());
151 } else {
152 child_args.push_back(args[0]);
153 }
154
155 android::gtest_extras::Options options;
156 if (!options.Process(args, &child_args)) {
157 return 1;
158 }
159
160 // Add the --no_isolate option to force child processes not to rerun
161 // in isolation mode.
162 child_args.push_back("--no_isolate");
163
164 // Set the flag values.
165 ::testing::GTEST_FLAG(color) = options.color();
166 ::testing::GTEST_FLAG(print_time) = options.print_time();
167
Christopher Ferris1a993562018-08-21 12:43:50 -0700168 android::gtest_extras::Isolate isolate(options, child_args);
169 return isolate.Run();
170}