1 /*
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 <gtest/gtest.h>
26 #include <gtest_extras/IsolateMain.h>
27
28 #include "Color.h"
29 #include "Isolate.h"
30
31 namespace android {
32 namespace gtest_extras {
33
PrintHelpInfo()34 static void PrintHelpInfo() {
35 printf("Unit Test Options:\n");
36 ColoredPrintf(COLOR_GREEN, " -j ");
37 ColoredPrintf(COLOR_YELLOW, "[JOB_COUNT]");
38 printf(" or ");
39 ColoredPrintf(COLOR_GREEN, "-j");
40 ColoredPrintf(COLOR_YELLOW, "[JOB_COUNT]\n");
41 printf(
42 " Run up to JOB_COUNT tests in parallel.\n"
43 " Use isolation mode, Run each test in a separate process.\n"
44 " If JOB_COUNT is not given, it is set to the count of available processors.\n");
45 ColoredPrintf(COLOR_GREEN, " --no_isolate\n");
46 printf(" Don't use isolation mode, run all tests in a single process.\n");
47 ColoredPrintf(COLOR_GREEN, " --deadline_threshold_ms=");
48 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]\n");
49 printf(" Run each test in no longer than ");
50 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]");
51 printf(
52 " time.\n"
53 " Only valid in isolation mode. Default deadline is 90000 ms.\n");
54 ColoredPrintf(COLOR_GREEN, " --slow_threshold_ms=");
55 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]\n");
56 printf(" Test running longer than ");
57 ColoredPrintf(COLOR_YELLOW, "[TIME_IN_MS]");
58 printf(
59 " will be called slow.\n"
60 " Only valid in isolation mode. Default slow threshold is 2000 ms.\n");
61 ColoredPrintf(COLOR_GREEN, "-j");
62 printf(
63 ".\n"
64 "In isolation mode, you can send SIGQUIT to the parent process to show the\n"
65 "current running tests, or send SIGINT to the parent process to stop all\n"
66 "running tests.\n"
67 "\n");
68 }
69
GtestRun(std::vector<const char * > * args)70 static int GtestRun(std::vector<const char*>* args) {
71 int argc = args->size();
72 args->push_back(nullptr);
73 ::testing::InitGoogleTest(&argc, const_cast<char**>(args->data()));
74 return RUN_ALL_TESTS();
75 }
76
RunInIsolationMode(std::vector<const char * > & args)77 static bool RunInIsolationMode(std::vector<const char*>& args) {
78 // Parse arguments that can't be used in isolation mode.
79 for (size_t i = 1; i < args.size(); ++i) {
80 if (strcmp(args[i], "--no_isolate") == 0) {
81 return false;
82 } else if (strcmp(args[i], "--gtest_list_tests") == 0) {
83 return false;
84 }
85 }
86 return true;
87 }
88
89 } // namespace gtest_extras
90 } // namespace android
91
92 // Tests that override this weak function can add default arguments.
93 extern "C" bool __attribute__((weak)) GetInitialArgs(const char***, size_t*);
94
IsolateMain(int argc,char ** argv,char **)95 int IsolateMain(int argc, char** argv, char**) {
96 std::vector<const char*> args{argv[0]};
97
98 bool print_help = false;
99 size_t gtest_color_index = 0;
100 for (int i = 1; i < argc; ++i) {
101 args.push_back(argv[i]);
102 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
103 print_help = true;
104 } else if (strncmp(argv[i], "--gtest_color=", 14) == 0) {
105 gtest_color_index = args.size() - 1;
106 }
107 }
108
109 if (print_help) {
110 std::vector<const char*> help_args{args[0], "--help"};
111 if (gtest_color_index != 0) {
112 // This is the only option that changes the way the help is printed.
113 help_args.push_back(args[gtest_color_index]);
114 ::testing::GTEST_FLAG(color) = args[gtest_color_index] + 14;
115 }
116 android::gtest_extras::PrintHelpInfo();
117 return android::gtest_extras::GtestRun(&help_args);
118 }
119
120 if (!android::gtest_extras::RunInIsolationMode(args)) {
121 return android::gtest_extras::GtestRun(&args);
122 }
123
124 const char** start_args;
125 size_t num_args;
126 if (GetInitialArgs != nullptr && GetInitialArgs(&start_args, &num_args)) {
127 std::vector<const char*> initial_args;
128 for (size_t i = 0; i < num_args; i++) {
129 initial_args.push_back(start_args[i]);
130 }
131 args.insert(args.begin() + 1, initial_args.begin(), initial_args.end());
132 }
133
134 std::vector<char*> child_args;
135 android::gtest_extras::Options options;
136 if (!options.Process(args, &child_args)) {
137 return 1;
138 }
139
140 // Add the --no_isolate option to force child processes not to rerun
141 // in isolation mode.
142 child_args.push_back(strdup("--no_isolate"));
143
144 // Set the flag values.
145 ::testing::GTEST_FLAG(color) = options.color();
146 ::testing::GTEST_FLAG(print_time) = options.print_time();
147
148 android::gtest_extras::Isolate isolate(options, child_args);
149 int return_val = isolate.Run();
150 for (auto child_arg : child_args) {
151 free(child_arg);
152 }
153 return return_val;
154 }
155