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 <inttypes.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include <regex>
22 #include <string>
23 #include <tuple>
24 #include <vector>
25 
26 #include <android/log.h>
27 #include <gtest/gtest.h>
28 
29 #include "Color.h"
30 #include "Log.h"
31 #include "NanoTime.h"
32 #include "Test.h"
33 
34 namespace android {
35 namespace gtest_extras {
36 
37 std::regex Test::skipped_regex_("(^|\\n)[^\\n]+:\\(\\d+\\) Skipped\\n");
38 
39 Test::Test(std::tuple<std::string, std::string>& test, size_t index, size_t run_index, int fd)
40     : suite_name_(std::get<0>(test)),
41       test_name_(std::get<1>(test)),
42       name_(suite_name_ + test_name_),
43       test_index_(index),
44       run_index_(run_index),
45       fd_(fd),
46       start_ns_(NanoTime()) {}
47 
48 void Test::Stop() {
49   end_ns_ = NanoTime();
50 }
51 
52 void Test::CloseFd() {
53   if (fd_ != -1) {
54     close(fd_);
55     fd_ = -1;
56   }
57 }
58 
59 void Test::Print() {
60   ColoredPrintf(COLOR_GREEN, "[ RUN      ]");
61   printf(" %s\n", name_.c_str());
62   printf("%s", output_.c_str());
63 
64   switch (result_) {
65     case TEST_PASS:
66     case TEST_XFAIL:
67       ColoredPrintf(COLOR_GREEN, "[       OK ]");
68       break;
69     case TEST_SKIPPED:
70       ColoredPrintf(COLOR_GREEN, "[  SKIPPED ]");
71       break;
72     default:
73       ColoredPrintf(COLOR_RED, "[  FAILED  ]");
74       break;
75   }
76   printf(" %s", name_.c_str());
77   if (::testing::GTEST_FLAG(print_time)) {
78     printf(" (%" PRId64 " ms)", RunTimeNs() / kNsPerMs);
79   }
80   printf("\n");
81   fflush(stdout);
82 }
83 
84 bool Test::Read() {
85   char buffer[2048];
86   ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer, sizeof(buffer) - 1));
87   if (bytes < 0) {
88     if (errno == EAGAIN || errno == EWOULDBLOCK) {
89       // Reading would block. Since this is not an error keep going.
90       return true;
91     }
92     FATAL_PLOG("Unexpected failure from read");
93     return false;
94   }
95 
96   if (bytes == 0) {
97     return false;
98   }
99   buffer[bytes] = '\0';
100   output_ += buffer;
101   return true;
102 }
103 
104 void Test::ReadUntilClosed() {
105   uint64_t start_ns = NanoTime();
106   while (fd_ != -1) {
107     if (!Read()) {
108       CloseFd();
109       break;
110     }
111     if (NanoTime() - start_ns > 2 * kNsPerS) {
112       printf("Reading of done process did not finish after 2 seconds.\n");
113       CloseFd();
114       break;
115     }
116   }
117 }
118 
119 void Test::SetResultFromOutput() {
120   result_ = TEST_PASS;
121 
122   // Need to parse the output to determine if this test was skipped.
123   // Format of a skipped test:
124   //   <filename>:(<line_number>) Skipped
125   //   <Skip Message>
126 
127   // If there are multiple skip messages, it doesn't matter, seeing
128   // even one indicates this is a skipped test.
129   if (std::regex_search(output_, skipped_regex_)) {
130     result_ = TEST_SKIPPED;
131   }
132 }
133 
134 }  // namespace gtest_extras
135 }  // namespace android
136