1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 // test_utils_unittest.cpp: Unit tests for ANGLE's test utility functions
7
8 #include "gtest/gtest.h"
9
10 #include "common/system_utils.h"
11 #include "tests/test_utils/runner/TestSuite.h"
12 #include "util/Timer.h"
13 #include "util/test_utils.h"
14 #include "util/test_utils_unittest_helper.h"
15
16 using namespace angle;
17
18 namespace
19 {
20 #if defined(ANGLE_PLATFORM_WINDOWS)
21 constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper.exe";
22 #elif ANGLE_PLATFORM_IOS_FAMILY
23 constexpr char kRunAppHelperExecutable[] =
24 "../test_utils_unittest_helper.app/test_utils_unittest_helper";
25 #else
26 constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper";
27 #endif
28
29 // Transforms various line endings into C/Unix line endings:
30 //
31 // - A\nB -> A\nB
32 // - A\rB -> A\nB
33 // - A\r\nB -> A\nB
NormalizeNewLines(const std::string & str)34 std::string NormalizeNewLines(const std::string &str)
35 {
36 std::string result;
37
38 for (size_t i = 0; i < str.size(); ++i)
39 {
40 if (str[i] == '\r')
41 {
42 if (i + 1 < str.size() && str[i + 1] == '\n')
43 {
44 ++i;
45 }
46 result += '\n';
47 }
48 else
49 {
50 result += str[i];
51 }
52 }
53
54 return result;
55 }
56
57 // Tests that Sleep() actually waits some time.
TEST(TestUtils,Sleep)58 TEST(TestUtils, Sleep)
59 {
60 Timer timer;
61 timer.start();
62 angle::Sleep(500);
63 timer.stop();
64
65 // Use a slightly fuzzy range
66 EXPECT_GT(timer.getElapsedWallClockTime(), 0.48);
67 }
68
69 // TODO: android support. http://anglebug.com/40096559
70 #if defined(ANGLE_PLATFORM_ANDROID)
71 # define MAYBE_RunApp DISABLED_RunApp
72 # define MAYBE_RunAppAsync DISABLED_RunAppAsync
73 # define MAYBE_RunAppAsyncRedirectStderrToStdout DISABLED_RunAppAsyncRedirectStderrToStdout
74 // TODO: fuchsia support. http://anglebug.com/42265786
75 #elif defined(ANGLE_PLATFORM_FUCHSIA)
76 # define MAYBE_RunApp DISABLED_RunApp
77 # define MAYBE_RunAppAsync DISABLED_RunAppAsync
78 # define MAYBE_RunAppAsyncRedirectStderrToStdout DISABLED_RunAppAsyncRedirectStderrToStdout
79 // TODO: iOS simulator support. http://anglebug.com/42266562
80 #elif ANGLE_PLATFORM_IOS_FAMILY_SIMULATOR
81 # define MAYBE_RunApp DISABLED_RunApp
82 # define MAYBE_RunAppAsync DISABLED_RunAppAsync
83 # define MAYBE_RunAppAsyncRedirectStderrToStdout DISABLED_RunAppAsyncRedirectStderrToStdout
84 #else
85 # define MAYBE_RunApp RunApp
86 # define MAYBE_RunAppAsync RunAppAsync
87 # define MAYBE_RunAppAsyncRedirectStderrToStdout RunAppAsyncRedirectStderrToStdout
88 #endif // defined(ANGLE_PLATFORM_ANDROID)
89
GetTestAppExecutablePath()90 std::string GetTestAppExecutablePath()
91 {
92 std::string testExecutableName = angle::TestSuite::GetInstance()->getTestExecutableName();
93 std::string executablePath = angle::StripFilenameFromPath(testExecutableName);
94
95 EXPECT_NE(executablePath, "");
96 executablePath += "/";
97 executablePath += kRunAppHelperExecutable;
98
99 return executablePath;
100 }
101
102 // Test running an external application and receiving its output
TEST(TestUtils,MAYBE_RunApp)103 TEST(TestUtils, MAYBE_RunApp)
104 {
105 std::string executablePath = GetTestAppExecutablePath();
106
107 std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
108
109 // Test that the application can be executed.
110 {
111 ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrSeparately);
112 EXPECT_TRUE(process->started());
113 EXPECT_TRUE(process->finish());
114 EXPECT_TRUE(process->finished());
115
116 EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
117 EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(process->getStdout()));
118 EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(process->getStderr()));
119 EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
120 }
121
122 // Test that environment variables reach the child.
123 {
124 bool setEnvDone = SetEnvironmentVar(kRunAppTestEnvVarName, kRunAppTestEnvVarValue);
125 EXPECT_TRUE(setEnvDone);
126
127 ProcessHandle process(LaunchProcess(args, ProcessOutputCapture::StdoutAndStderrSeparately));
128 EXPECT_TRUE(process->started());
129 EXPECT_TRUE(process->finish());
130
131 EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
132 EXPECT_EQ("", process->getStdout());
133 EXPECT_EQ(kRunAppTestEnvVarValue, NormalizeNewLines(process->getStderr()));
134 EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
135
136 // Unset environment var.
137 SetEnvironmentVar(kRunAppTestEnvVarName, "");
138 }
139 }
140
141 // Test running an external application and receiving its output asynchronously.
TEST(TestUtils,MAYBE_RunAppAsync)142 TEST(TestUtils, MAYBE_RunAppAsync)
143 {
144 std::string executablePath = GetTestAppExecutablePath();
145
146 std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
147
148 // Test that the application can be executed and the output is captured correctly.
149 {
150 ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrSeparately);
151 EXPECT_TRUE(process->started());
152
153 constexpr double kTimeout = 3.0;
154
155 Timer timer;
156 timer.start();
157 while (!process->finished() && timer.getElapsedWallClockTime() < kTimeout)
158 {
159 angle::Sleep(1);
160 }
161
162 EXPECT_TRUE(process->finished());
163 EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
164 EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(process->getStdout()));
165 EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(process->getStderr()));
166 EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
167 }
168 }
169
170 // Test running an external application and receiving its stdout and stderr output interleaved.
TEST(TestUtils,MAYBE_RunAppAsyncRedirectStderrToStdout)171 TEST(TestUtils, MAYBE_RunAppAsyncRedirectStderrToStdout)
172 {
173 std::string executablePath = GetTestAppExecutablePath();
174
175 std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
176
177 // Test that the application can be executed and the output is captured correctly.
178 {
179 ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrInterleaved);
180 EXPECT_TRUE(process->started());
181
182 constexpr double kTimeout = 3.0;
183
184 Timer timer;
185 timer.start();
186 while (!process->finished() && timer.getElapsedWallClockTime() < kTimeout)
187 {
188 angle::Sleep(1);
189 }
190
191 EXPECT_TRUE(process->finished());
192 EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
193 EXPECT_EQ(std::string(kRunAppTestStdout) + kRunAppTestStderr,
194 NormalizeNewLines(process->getStdout()));
195 EXPECT_EQ("", process->getStderr());
196 EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
197 }
198 }
199
200 // Verify that NumberOfProcessors returns something reasonable.
TEST(TestUtils,NumberOfProcessors)201 TEST(TestUtils, NumberOfProcessors)
202 {
203 int numProcs = angle::NumberOfProcessors();
204 EXPECT_GT(numProcs, 0);
205 EXPECT_LT(numProcs, 1000);
206 }
207 } // namespace
208