1 /*
2  * Copyright (C) 2019 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 #pragma once
18 
19 #include <gtest/gtest.h>
20 #include <lib/unittest/unittest.h>
21 #include <lk/compiler.h>
22 #include <trusty_unittest.h>
23 
24 class TrustyLogTestResultPrinter : public testing::EmptyTestEventListener {
25 public:
OnTestPartResult(const testing::TestPartResult & result)26     void OnTestPartResult(const testing::TestPartResult& result) override {
27         const char* type_string = nullptr;
28         switch (result.type()) {
29         case testing::TestPartResult::kSuccess:
30             return;
31         case testing::TestPartResult::kNonFatalFailure:
32         case testing::TestPartResult::kFatalFailure:
33             type_string = "Error";
34             break;
35         case testing::TestPartResult::kSkip:
36             type_string = "Skipped";
37             break;
38         }
39 
40         trusty_unittest_printf("  %s: %s:%d\n  %s\n", type_string,
41                                result.file_name(), result.line_number(),
42                                result.message());
43     }
44 
OnTestStart(const testing::TestInfo & test_info)45     void OnTestStart(const testing::TestInfo& test_info) override {
46         if (!test_info.should_run()) {
47             PrintTestName(test_info, "DISABLED");
48             return;
49         }
50 
51         PrintTestName(test_info, "RUN     ");
52     }
53 
OnTestEnd(const testing::TestInfo & test_info)54     void OnTestEnd(const testing::TestInfo& test_info) override {
55         if (!test_info.should_run()) {
56             return;
57         }
58 
59         const testing::TestResult* result = test_info.result();
60         if (result->Passed()) {
61             PrintTestName(test_info, "      OK");
62         } else if (result->Failed()) {
63             PrintTestName(test_info, " FAILED ");
64         } else {
65             assert(result->Skipped());
66             PrintTestName(test_info, " SKIPPED");
67         }
68     }
69 
OnTestProgramEnd(const testing::UnitTest & unit_test)70     void OnTestProgramEnd(const testing::UnitTest& unit_test) override {
71         trusty_unittest_printf("[==========] %d tests ran.\n",
72                                unit_test.test_to_run_count());
73         if (unit_test.successful_test_count() !=
74             unit_test.test_to_run_count()) {
75             trusty_unittest_printf("[  PASSED  ] %d tests.\n",
76                                    unit_test.successful_test_count());
77         }
78         if (unit_test.disabled_test_count()) {
79             trusty_unittest_printf("[ DISABLED ] %d tests.\n",
80                                    unit_test.disabled_test_count());
81         }
82         if (unit_test.failed_test_count()) {
83             trusty_unittest_printf("[  FAILED  ] %d tests.\n",
84                                    unit_test.failed_test_count());
85         }
86     }
87 
88 private:
PrintTestName(const testing::TestInfo & test_info,const char * state)89     static void PrintTestName(const testing::TestInfo& test_info,
90                               const char* state) {
91         trusty_unittest_printf("[ %s ] %s.%s", state,
92                                test_info.test_suite_name(), test_info.name());
93         if (test_info.type_param() != nullptr) {
94             trusty_unittest_printf("/%s", test_info.type_param());
95         }
96         trusty_unittest_printf("\n");
97     }
98 };
99 
100 #define PORT_GTEST(suite_name, port_name_string)              \
101     __BEGIN_CDECLS                                            \
102     static bool run_##suite_name(struct unittest* test) {     \
103         return RUN_ALL_TESTS() == 0;                          \
104     }                                                         \
105                                                               \
106     int main(int argc, char** argv) {                         \
107         static struct unittest test = {                       \
108                 .port_name = port_name_string,                \
109                 .run_test = run_##suite_name,                 \
110         };                                                    \
111         struct unittest* tests = &test;                       \
112         /* gtest requires argc > 1 */                         \
113         int fake_argc = 1;                                    \
114         char* fake_argv[] = {(char*)"test", NULL};            \
115         testing::InitGoogleTest(&fake_argc, fake_argv);       \
116         testing::UnitTest::GetInstance()->listeners().Append( \
117                 new TrustyLogTestResultPrinter);              \
118         return unittest_main(&tests, 1);                      \
119     }                                                         \
120     __END_CDECLS
121