• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
22 #include <tuple>
23 #include <vector>
24 
25 #include <android-base/logging.h>
26 #include <gtest/gtest.h>
27 
28 #include "Color.h"
29 #include "NanoTime.h"
30 #include "Test.h"
31 
32 namespace android {
33 namespace gtest_extras {
34 
Test(std::tuple<std::string,std::string> & test,size_t index,size_t run_index,int fd)35 Test::Test(std::tuple<std::string, std::string>& test, size_t index, size_t run_index, int fd)
36     : suite_name_(std::get<0>(test)),
37       test_name_(std::get<1>(test)),
38       name_(suite_name_ + test_name_),
39       test_index_(index),
40       run_index_(run_index),
41       fd_(fd),
42       start_ns_(NanoTime()) {}
43 
Stop()44 void Test::Stop() {
45   end_ns_ = NanoTime();
46 }
47 
CloseFd()48 void Test::CloseFd() {
49   fd_.reset();
50 }
51 
PrintGtestFormat()52 void Test::PrintGtestFormat() {
53   ColoredPrintf(COLOR_GREEN, "[ RUN      ]");
54   printf(" %s\n", name_.c_str());
55   printf("%s", output_.c_str());
56 
57   switch (result_) {
58     case TEST_PASS:
59     case TEST_XFAIL:
60       ColoredPrintf(COLOR_GREEN, "[       OK ]");
61       break;
62     case TEST_SKIPPED:
63       ColoredPrintf(COLOR_GREEN, "[  SKIPPED ]");
64       break;
65     default:
66       ColoredPrintf(COLOR_RED, "[  FAILED  ]");
67       break;
68   }
69   printf(" %s", name_.c_str());
70   if (::testing::GTEST_FLAG(print_time)) {
71     printf(" (%" PRId64 " ms)", RunTimeNs() / kNsPerMs);
72   }
73   printf("\n");
74   fflush(stdout);
75 }
76 
Print(bool gtest_format)77 void Test::Print(bool gtest_format) {
78   if (gtest_format) {
79     PrintGtestFormat();
80     return;
81   }
82 
83   switch (result_) {
84     case TEST_XFAIL:
85     case TEST_PASS:
86       ColoredPrintf(COLOR_GREEN, "[    OK    ]");
87       break;
88     case TEST_XPASS:
89     case TEST_FAIL:
90       ColoredPrintf(COLOR_RED, "[  FAILED  ]");
91       break;
92     case TEST_TIMEOUT:
93       ColoredPrintf(COLOR_RED, "[  TIMEOUT ]");
94       break;
95     case TEST_SKIPPED:
96       ColoredPrintf(COLOR_GREEN, "[  SKIPPED ]");
97       break;
98     case TEST_NONE:
99       LOG(FATAL) << "Test result is TEST_NONE, this should not be possible.";
100   }
101 
102   printf(" %s", name_.c_str());
103   if (::testing::GTEST_FLAG(print_time)) {
104     printf(" (%" PRId64 " ms)", (end_ns_ - start_ns_) / kNsPerMs);
105   }
106   printf("\n");
107 
108   printf("%s", output_.c_str());
109   fflush(stdout);
110 }
111 
Read()112 bool Test::Read() {
113   char buffer[2048];
114   ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer, sizeof(buffer) - 1));
115   if (bytes < 0) {
116     if (errno == EAGAIN || errno == EWOULDBLOCK) {
117       // Reading would block. Since this is not an error keep going.
118       return true;
119     }
120     PLOG(FATAL) << "Unexpected failure from read";
121     return false;
122   }
123 
124   if (bytes == 0) {
125     return false;
126   }
127   buffer[bytes] = '\0';
128   output_ += buffer;
129   return true;
130 }
131 
ReadUntilClosed()132 void Test::ReadUntilClosed() {
133   uint64_t start_ns = NanoTime();
134   while (fd_ != -1) {
135     if (!Read()) {
136       CloseFd();
137       break;
138     }
139     if (NanoTime() - start_ns > 2 * kNsPerS) {
140       printf("Reading of done process did not finish after 2 seconds.\n");
141       CloseFd();
142       break;
143     }
144   }
145 }
146 
SetResultFromOutput()147 void Test::SetResultFromOutput() {
148   result_ = TEST_PASS;
149 
150   // Need to parse the output to determine if this test was skipped.
151   // Format of a skipped test:
152   //   <filename>:(<line_number>) Failure in test <testname>
153   //   Skipped
154   //   <Skip Message>
155   size_t line_end = output_.find('\n');
156   if (line_end == std::string::npos) {
157     return;
158   }
159   std::string second_line(output_.substr(line_end, 9));
160   if (output_.substr(line_end, 9) != "\nSkipped\n") {
161     return;
162   }
163   size_t failure_index = output_.find(" Failure in test ");
164   if (failure_index == std::string::npos || failure_index >= line_end) {
165     return;
166   }
167 
168   // Only leave the output from the skip message.
169   output_ = output_.substr(line_end + 9);
170 
171   result_ = TEST_SKIPPED;
172 }
173 
174 }  // namespace gtest_extras
175 }  // namespace android
176