1 #include <gtest/gtest.h>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <iostream>
5 #include <memory>
6 #include <stdexcept>
7 #include <string>
8 #include <array>
9 #include <unordered_map>
10 #include <algorithm>
11
12 #include "gtest_helper.h"
13
14 enum TestResult {
15 PASS,
16 FAIL,
17 SKIP,
18 UNKNOWN
19 };
20
21 /**
22 * @brief Run the command and returns the output.
23 *
24 * @param cmd
25 * @return std::string
26 */
exec(std::string cmd)27 std::string exec(std::string cmd) {
28 std::unique_ptr<FILE, decltype(&pclose) > pipe(popen(cmd.c_str(), "r"), pclose);
29 if (!pipe) {
30 return "popen() failed! Could not find or run the binary.";
31 }
32
33 std::array<char, 128> buffer;
34 std::string result;
35 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
36 result += buffer.data();
37 }
38 return result;
39 }
40
41 /**
42 * @brief Get the Subtest Result From Log object
43 *
44 * @param log
45 * @param subtestName
46 * @return TestResult
47 */
getSubtestTestResultFromLog(std::string log,std::string subtestName)48 TestResult getSubtestTestResultFromLog(std::string log, std::string subtestName) {
49 if (log.find("Subtest " + subtestName + ": FAIL") != std::string::npos) {
50 return FAIL;
51 }
52 else if (log.find("Subtest " + subtestName + ": SKIP") != std::string::npos) {
53 return SKIP;
54 }
55 else if (log.find("Subtest " + subtestName + ": SUCCESS") != std::string::npos) {
56 return PASS;
57 }
58 else {
59 return UNKNOWN;
60 }
61 }
62
63 /**
64 * @brief Get the Test Result From Log object
65 *
66 * @param log
67 * @param subtestName
68 * @return TestResult
69 */
getTestResultFromLog(std::string log)70 TestResult getTestResultFromLog(std::string log) {
71
72 std::for_each(log.begin(), log.end(), [](char & c) {
73 c = ::tolower(c);
74 });
75
76 if (log.find("fail") != std::string::npos) {
77 return FAIL;
78 }
79 else if (log.find("skip") != std::string::npos) {
80 return SKIP;
81 }
82 else if (log.find("success") != std::string::npos) {
83 return PASS;
84 }
85 else {
86 return UNKNOWN;
87 }
88 }
89
presentTestResult(TestResult result,std::string log)90 void presentTestResult(TestResult result, std::string log) {
91 switch (result)
92 {
93 case PASS:
94 SUCCEED();
95 break;
96 case FAIL:
97 ADD_FAILURE() << log;
98 break;
99 case SKIP:
100 GTEST_SKIP() << log;
101 break;
102 case UNKNOWN:
103 ADD_FAILURE() << "Could not determine test result.\n" << log;
104 break;
105 default:
106 ADD_FAILURE() << log;
107 break;
108 }
109 }
110
runSubTest(std::string testBinaryName,std::string subtestName)111 void runSubTest(std::string testBinaryName, std::string subtestName) {
112 std::string log = exec("./" + testBinaryName + " --run-subtest " + subtestName);
113
114 TestResult result = getSubtestTestResultFromLog(log, subtestName);
115
116 presentTestResult(result, log);
117 }
118
runTest(std::string testBinaryName)119 void runTest(std::string testBinaryName) {
120 std::string log = exec("./" + testBinaryName);
121
122 TestResult result = getTestResultFromLog(log);
123
124 presentTestResult(result, log);
125 }
126