• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "util/Timer.h"
12 #include "util/test_utils.h"
13 #include "util/test_utils_unittest_helper.h"
14 
15 using namespace angle;
16 
17 namespace
18 {
19 #if defined(ANGLE_PLATFORM_WINDOWS)
20 constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper.exe";
21 #elif (ANGLE_PLATFORM_IOS)
22 constexpr char kRunAppHelperExecutable[] =
23     "../test_utils_unittest_helper.app/test_utils_unittest_helper";
24 #else
25 constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper";
26 #endif
27 
28 // Transforms various line endings into C/Unix line endings:
29 //
30 // - A\nB -> A\nB
31 // - A\rB -> A\nB
32 // - A\r\nB -> A\nB
NormalizeNewLines(const std::string & str)33 std::string NormalizeNewLines(const std::string &str)
34 {
35     std::string result;
36 
37     for (size_t i = 0; i < str.size(); ++i)
38     {
39         if (str[i] == '\r')
40         {
41             if (i + 1 < str.size() && str[i + 1] == '\n')
42             {
43                 ++i;
44             }
45             result += '\n';
46         }
47         else
48         {
49             result += str[i];
50         }
51     }
52 
53     return result;
54 }
55 
56 // Tests that Sleep() actually waits some time.
TEST(TestUtils,Sleep)57 TEST(TestUtils, Sleep)
58 {
59     Timer timer;
60     timer.start();
61     angle::Sleep(500);
62     timer.stop();
63 
64     // Use a slightly fuzzy range
65     EXPECT_GT(timer.getElapsedTime(), 0.48);
66 }
67 
68 constexpr uint32_t kMaxPath = 1000;
69 
70 // Temporary file creation is not supported on Android right now.
71 #if defined(ANGLE_PLATFORM_ANDROID)
72 #    define MAYBE_CreateAndDeleteTemporaryFile DISABLED_CreateAndDeleteTemporaryFile
73 #    define MAYBE_CreateAndDeleteFileInTempDir DISABLED_CreateAndDeleteFileInTempDir
74 #else
75 #    define MAYBE_CreateAndDeleteTemporaryFile CreateAndDeleteTemporaryFile
76 #    define MAYBE_CreateAndDeleteFileInTempDir CreateAndDeleteFileInTempDir
77 #endif  // defined(ANGLE_PLATFORM_ANDROID)
78 
79 // Test creating and deleting temporary file.
TEST(TestUtils,MAYBE_CreateAndDeleteTemporaryFile)80 TEST(TestUtils, MAYBE_CreateAndDeleteTemporaryFile)
81 {
82     char path[kMaxPath] = {};
83     ASSERT_TRUE(CreateTemporaryFile(path, kMaxPath));
84     ASSERT_TRUE(strlen(path) > 0);
85 
86     const char kOutputString[] = "test output";
87 
88     FILE *fp = fopen(path, "wt");
89     ASSERT_NE(fp, nullptr);
90     int retval = fputs(kOutputString, fp);
91     fclose(fp);
92 
93     EXPECT_GE(retval, 0);
94 
95     // Test ReadEntireFileToString
96     char actualString[kMaxPath];
97     EXPECT_TRUE(ReadEntireFileToString(path, actualString, kMaxPath));
98     EXPECT_EQ(strcmp(actualString, kOutputString), 0);
99 
100     // Delete the temporary file.
101     EXPECT_TRUE(angle::DeleteFile(path));
102 }
103 
104 // Tests creating and deleting a file in the system temp dir.
TEST(TestUtils,MAYBE_CreateAndDeleteFileInTempDir)105 TEST(TestUtils, MAYBE_CreateAndDeleteFileInTempDir)
106 {
107     char tempDir[kMaxPath];
108     ASSERT_TRUE(GetTempDir(tempDir, kMaxPath));
109 
110     char path[kMaxPath] = {};
111     ASSERT_TRUE(CreateTemporaryFileInDir(tempDir, path, kMaxPath));
112     ASSERT_TRUE(strlen(path) > 0);
113 
114     const char kOutputString[] = "test output";
115 
116     FILE *fp = fopen(path, "wt");
117     ASSERT_NE(fp, nullptr);
118     int retval = fputs(kOutputString, fp);
119     fclose(fp);
120 
121     EXPECT_GE(retval, 0);
122 
123     // Test ReadEntireFileToString
124     char actualString[kMaxPath];
125     EXPECT_TRUE(ReadEntireFileToString(path, actualString, kMaxPath));
126     EXPECT_EQ(strcmp(actualString, kOutputString), 0);
127 
128     // Delete the temporary file.
129     EXPECT_TRUE(angle::DeleteFile(path));
130 }
131 
132 // TODO: android support. http://anglebug.com/3125
133 #if defined(ANGLE_PLATFORM_ANDROID)
134 #    define MAYBE_RunApp DISABLED_RunApp
135 #    define MAYBE_RunAppAsync DISABLED_RunAppAsync
136 #    define MAYBE_RunAppAsyncRedirectStderrToStdout DISABLED_RunAppAsyncRedirectStderrToStdout
137 // TODO: fuchsia support. http://anglebug.com/3161
138 #elif defined(ANGLE_PLATFORM_FUCHSIA)
139 #    define MAYBE_RunApp DISABLED_RunApp
140 #    define MAYBE_RunAppAsync DISABLED_RunAppAsync
141 #    define MAYBE_RunAppAsyncRedirectStderrToStdout DISABLED_RunAppAsyncRedirectStderrToStdout
142 #else
143 #    define MAYBE_RunApp RunApp
144 #    define MAYBE_RunAppAsync RunAppAsync
145 #    define MAYBE_RunAppAsyncRedirectStderrToStdout RunAppAsyncRedirectStderrToStdout
146 #endif  // defined(ANGLE_PLATFORM_ANDROID)
147 
148 // Test running an external application and receiving its output
TEST(TestUtils,MAYBE_RunApp)149 TEST(TestUtils, MAYBE_RunApp)
150 {
151     std::string executablePath = GetExecutableDirectory();
152     EXPECT_NE(executablePath, "");
153     executablePath += "/";
154     executablePath += kRunAppHelperExecutable;
155 
156     std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
157 
158     // Test that the application can be executed.
159     {
160         ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrSeparately);
161         EXPECT_TRUE(process->started());
162         EXPECT_TRUE(process->finish());
163         EXPECT_TRUE(process->finished());
164 
165         EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
166         EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(process->getStdout()));
167         EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(process->getStderr()));
168         EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
169     }
170 
171     // Test that environment variables reach the child.
172     {
173         bool setEnvDone = SetEnvironmentVar(kRunAppTestEnvVarName, kRunAppTestEnvVarValue);
174         EXPECT_TRUE(setEnvDone);
175 
176         ProcessHandle process(LaunchProcess(args, ProcessOutputCapture::StdoutAndStderrSeparately));
177         EXPECT_TRUE(process->started());
178         EXPECT_TRUE(process->finish());
179 
180         EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
181         EXPECT_EQ("", process->getStdout());
182         EXPECT_EQ(kRunAppTestEnvVarValue, NormalizeNewLines(process->getStderr()));
183         EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
184 
185         // Unset environment var.
186         SetEnvironmentVar(kRunAppTestEnvVarName, "");
187     }
188 }
189 
190 // Test running an external application and receiving its output asynchronously.
TEST(TestUtils,MAYBE_RunAppAsync)191 TEST(TestUtils, MAYBE_RunAppAsync)
192 {
193     std::string executablePath = GetExecutableDirectory();
194     EXPECT_NE(executablePath, "");
195     executablePath += "/";
196     executablePath += kRunAppHelperExecutable;
197 
198     std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
199 
200     // Test that the application can be executed and the output is captured correctly.
201     {
202         ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrSeparately);
203         EXPECT_TRUE(process->started());
204 
205         constexpr double kTimeout = 3.0;
206 
207         Timer timer;
208         timer.start();
209         while (!process->finished() && timer.getElapsedTime() < kTimeout)
210         {
211             angle::Sleep(1);
212         }
213 
214         EXPECT_TRUE(process->finished());
215         EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
216         EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(process->getStdout()));
217         EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(process->getStderr()));
218         EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
219     }
220 }
221 
222 // Test running an external application and receiving its stdout and stderr output interleaved.
TEST(TestUtils,MAYBE_RunAppAsyncRedirectStderrToStdout)223 TEST(TestUtils, MAYBE_RunAppAsyncRedirectStderrToStdout)
224 {
225     std::string executablePath = GetExecutableDirectory();
226     EXPECT_NE(executablePath, "");
227     executablePath += "/";
228     executablePath += kRunAppHelperExecutable;
229 
230     std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2};
231 
232     // Test that the application can be executed and the output is captured correctly.
233     {
234         ProcessHandle process(args, ProcessOutputCapture::StdoutAndStderrInterleaved);
235         EXPECT_TRUE(process->started());
236 
237         constexpr double kTimeout = 3.0;
238 
239         Timer timer;
240         timer.start();
241         while (!process->finished() && timer.getElapsedTime() < kTimeout)
242         {
243             angle::Sleep(1);
244         }
245 
246         EXPECT_TRUE(process->finished());
247         EXPECT_GT(process->getElapsedTimeSeconds(), 0.0);
248         EXPECT_EQ(std::string(kRunAppTestStdout) + kRunAppTestStderr,
249                   NormalizeNewLines(process->getStdout()));
250         EXPECT_EQ("", process->getStderr());
251         EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
252     }
253 }
254 
255 // Verify that NumberOfProcessors returns something reasonable.
TEST(TestUtils,NumberOfProcessors)256 TEST(TestUtils, NumberOfProcessors)
257 {
258     int numProcs = angle::NumberOfProcessors();
259     EXPECT_GT(numProcs, 0);
260     EXPECT_LT(numProcs, 1000);
261 }
262 }  // namespace
263