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 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 44 void Test::Stop() { 45 end_ns_ = NanoTime(); 46 } 47 48 void Test::CloseFd() { 49 fd_.reset(); 50 } 51 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 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 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 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 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