blob: 23d139c1cbfa158808730bc4459877135030a797 [file] [log] [blame]
Christopher Ferris1a993562018-08-21 12:43:50 -07001/*
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
Christopher Ferris7cfd24e2019-11-14 19:27:19 -080021#include <regex>
Christopher Ferris1a993562018-08-21 12:43:50 -070022#include <string>
23#include <tuple>
24#include <vector>
25
Christopher Ferris4ba40d82020-05-11 13:31:11 -070026#include <android/log.h>
Christopher Ferris1a993562018-08-21 12:43:50 -070027#include <gtest/gtest.h>
28
29#include "Color.h"
Christopher Ferris4ba40d82020-05-11 13:31:11 -070030#include "Log.h"
Christopher Ferris1a993562018-08-21 12:43:50 -070031#include "NanoTime.h"
32#include "Test.h"
33
34namespace android {
35namespace gtest_extras {
36
Christopher Ferris7cfd24e2019-11-14 19:27:19 -080037std::regex Test::skipped_regex_("(^|\\n)[^\\n]+:\\(\\d+\\) Skipped\\n");
38
Christopher Ferris1a993562018-08-21 12:43:50 -070039Test::Test(std::tuple<std::string, std::string>& test, size_t index, size_t run_index, int fd)
Christopher Ferrisc2f85d62019-03-10 13:40:40 -070040 : suite_name_(std::get<0>(test)),
Christopher Ferris1a993562018-08-21 12:43:50 -070041 test_name_(std::get<1>(test)),
Christopher Ferrisc2f85d62019-03-10 13:40:40 -070042 name_(suite_name_ + test_name_),
Christopher Ferris1a993562018-08-21 12:43:50 -070043 test_index_(index),
44 run_index_(run_index),
45 fd_(fd),
46 start_ns_(NanoTime()) {}
47
48void Test::Stop() {
49 end_ns_ = NanoTime();
50}
51
52void Test::CloseFd() {
Christopher Ferris4ba40d82020-05-11 13:31:11 -070053 if (fd_ != -1) {
54 close(fd_);
55 fd_ = -1;
56 }
Christopher Ferris1a993562018-08-21 12:43:50 -070057}
58
Christopher Ferrisa3827162019-06-12 19:01:56 -070059void Test::Print() {
Christopher Ferris1a993562018-08-21 12:43:50 -070060 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;
Christopher Ferris849d24e2019-03-09 16:47:04 -080069 case TEST_SKIPPED:
70 ColoredPrintf(COLOR_GREEN, "[ SKIPPED ]");
71 break;
Christopher Ferris1a993562018-08-21 12:43:50 -070072 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
Christopher Ferris1a993562018-08-21 12:43:50 -070084bool 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 }
Christopher Ferris4ba40d82020-05-11 13:31:11 -070092 FATAL_PLOG("Unexpected failure from read");
Christopher Ferris1a993562018-08-21 12:43:50 -070093 return false;
94 }
95
96 if (bytes == 0) {
97 return false;
98 }
99 buffer[bytes] = '\0';
100 output_ += buffer;
101 return true;
102}
103
104void 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
Christopher Ferris849d24e2019-03-09 16:47:04 -0800119void 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:
Christopher Ferris7cfd24e2019-11-14 19:27:19 -0800124 // <filename>:(<line_number>) Skipped
Christopher Ferris849d24e2019-03-09 16:47:04 -0800125 // <Skip Message>
Christopher Ferris849d24e2019-03-09 16:47:04 -0800126
Christopher Ferris7cfd24e2019-11-14 19:27:19 -0800127 // 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_)) {
Christopher Ferris1d602252019-09-23 14:15:55 -0700130 result_ = TEST_SKIPPED;
Christopher Ferris1d602252019-09-23 14:15:55 -0700131 }
Christopher Ferris849d24e2019-03-09 16:47:04 -0800132}
133
Christopher Ferris1a993562018-08-21 12:43:50 -0700134} // namespace gtest_extras
135} // namespace android