| /* |
| * 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 <inttypes.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| #include <regex> |
| #include <string> |
| #include <tuple> |
| #include <vector> |
| |
| #include <android/log.h> |
| #include <gtest/gtest.h> |
| |
| #include "Color.h" |
| #include "Log.h" |
| #include "NanoTime.h" |
| #include "Test.h" |
| |
| namespace android { |
| namespace gtest_extras { |
| |
| std::regex Test::skipped_regex_("(^|\\n)[^\\n]+:\\(\\d+\\) Skipped\\n"); |
| |
| Test::Test(std::tuple<std::string, std::string>& 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() { |
| if (fd_ != -1) { |
| close(fd_); |
| fd_ = -1; |
| } |
| } |
| |
| void Test::Print() { |
| 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); |
| } |
| |
| 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; |
| } |
| FATAL_PLOG("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: |
| // <filename>:(<line_number>) Skipped |
| // <Skip Message> |
| |
| // If there are multiple skip messages, it doesn't matter, seeing |
| // even one indicates this is a skipped test. |
| if (std::regex_search(output_, skipped_regex_)) { |
| result_ = TEST_SKIPPED; |
| } |
| } |
| |
| } // namespace gtest_extras |
| } // namespace android |