/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include "Color.h" #include "NanoTime.h" #include "Test.h" namespace android { namespace gtest_extras { Test::Test(std::tuple& test, size_t index, size_t run_index, int fd) : suite_name_(std::get<0>(test)), test_name_(std::get<1>(test)), name_(suite_name_ + test_name_), test_index_(index), run_index_(run_index), fd_(fd), start_ns_(NanoTime()) {} void Test::Stop() { end_ns_ = NanoTime(); } void Test::CloseFd() { fd_.reset(); } void Test::PrintGtestFormat() { ColoredPrintf(COLOR_GREEN, "[ RUN ]"); printf(" %s\n", name_.c_str()); printf("%s", output_.c_str()); switch (result_) { case TEST_PASS: case TEST_XFAIL: ColoredPrintf(COLOR_GREEN, "[ OK ]"); break; case TEST_SKIPPED: ColoredPrintf(COLOR_GREEN, "[ SKIPPED ]"); break; default: ColoredPrintf(COLOR_RED, "[ FAILED ]"); break; } printf(" %s", name_.c_str()); if (::testing::GTEST_FLAG(print_time)) { printf(" (%" PRId64 " ms)", RunTimeNs() / kNsPerMs); } printf("\n"); fflush(stdout); } void Test::Print(bool gtest_format) { if (gtest_format) { PrintGtestFormat(); return; } switch (result_) { case TEST_XFAIL: case TEST_PASS: ColoredPrintf(COLOR_GREEN, "[ OK ]"); break; case TEST_XPASS: case TEST_FAIL: ColoredPrintf(COLOR_RED, "[ FAILED ]"); break; case TEST_TIMEOUT: ColoredPrintf(COLOR_RED, "[ TIMEOUT ]"); break; case TEST_SKIPPED: ColoredPrintf(COLOR_GREEN, "[ SKIPPED ]"); break; case TEST_NONE: LOG(FATAL) << "Test result is TEST_NONE, this should not be possible."; } printf(" %s", name_.c_str()); if (::testing::GTEST_FLAG(print_time)) { printf(" (%" PRId64 " ms)", (end_ns_ - start_ns_) / kNsPerMs); } printf("\n"); printf("%s", output_.c_str()); fflush(stdout); } bool Test::Read() { char buffer[2048]; ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer, sizeof(buffer) - 1)); if (bytes < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // Reading would block. Since this is not an error keep going. return true; } PLOG(FATAL) << "Unexpected failure from read"; return false; } if (bytes == 0) { return false; } buffer[bytes] = '\0'; output_ += buffer; return true; } void Test::ReadUntilClosed() { uint64_t start_ns = NanoTime(); while (fd_ != -1) { if (!Read()) { CloseFd(); break; } if (NanoTime() - start_ns > 2 * kNsPerS) { printf("Reading of done process did not finish after 2 seconds.\n"); CloseFd(); break; } } } void Test::SetResultFromOutput() { result_ = TEST_PASS; // Need to parse the output to determine if this test was skipped. // Format of a skipped test: // :() Failure in test // Skipped // size_t line_end = output_.find('\n'); if (line_end == std::string::npos) { return; } std::string second_line(output_.substr(line_end, 9)); if (output_.substr(line_end, 9) != "\nSkipped\n") { return; } size_t failure_index = output_.find(" Failure in test "); if (failure_index == std::string::npos || failure_index >= line_end) { return; } // Only leave the output from the skip message. output_ = output_.substr(line_end + 9); result_ = TEST_SKIPPED; } } // namespace gtest_extras } // namespace android