1 /* 2 * Copyright 2016, 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 #ifndef RS2SPIRV_TEST_RUNNER 18 #define RS2SPIRV_TEST_RUNNER 19 20 #include "llvm/Support/Debug.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 #include <cassert> 24 #include <vector> 25 26 namespace rs2spirv { 27 28 struct TestCase { 29 void (*testPtr)(void); 30 const char *const description; 31 }; 32 33 class TestRunnerContext { 34 public: getInstance()35 static TestRunnerContext &getInstance() { 36 static TestRunnerContext ctx; 37 return ctx; 38 } 39 addTest(TestCase TC)40 static void addTest(TestCase TC) { getInstance().tests.push_back(TC); } getCheckSuccessNum()41 static size_t &getCheckSuccessNum() { return getInstance().checkSuccessNum; } getTotalCheckNum()42 static size_t &getTotalCheckNum() { return getInstance().totalCheckNum; } 43 runTests()44 static int runTests() { 45 bool Failed = false; 46 for (auto &TC : getInstance().tests) { 47 getCheckSuccessNum() = getTotalCheckNum() = 0; 48 llvm::outs() << "Test(" << TC.description << ") {\n"; 49 TC.testPtr(); 50 llvm::outs() << "\n} (" << TC.description << ") [" << getCheckSuccessNum() 51 << "/" << getTotalCheckNum() << "]\n\n"; 52 Failed |= getCheckSuccessNum() != getTotalCheckNum(); 53 } 54 55 return static_cast<int>(Failed); 56 } 57 58 private: 59 TestRunnerContext() = default; 60 std::vector<TestCase> tests; 61 size_t checkSuccessNum; 62 size_t totalCheckNum; 63 }; 64 65 struct TestAdder { TestAdderTestAdder66 TestAdder(TestCase TC) { TestRunnerContext::addTest(TC); } 67 }; 68 69 #define RS2SPIRV_CONCAT_IMPL(S1, S2) S1##S2 70 #define RS2SPIRV_CONCAT(S1, S2) RS2SPIRV_CONCAT_IMPL(S1, S2) 71 #define RS2SPIRV_ANONYMOUS(X) RS2SPIRV_CONCAT(X, __COUNTER__) 72 73 #if RS2SPIRV_DEBUG 74 #define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \ 75 static void FNAME(); \ 76 static rs2spirv::TestAdder VNAME({FNAME, DESCRIPTION}); \ 77 inline void FNAME() 78 #elif defined(__GNUC__) || defined(__clang__) 79 #define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \ 80 static inline void __attribute__((unused)) FNAME() 81 #else 82 #define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION) \ 83 static inline void FNAME() 84 #endif 85 86 #define RS2SPIRV_TEST_CASE_ADD(NAME, DESCRIPTION) \ 87 RS2SPIRV_TEST_CASE_ADD_IMPL(RS2SPIRV_ANONYMOUS(NAME), \ 88 RS2SPIRV_ANONYMOUS(NAME), DESCRIPTION) 89 90 #define TEST_CASE(DESCRIPTION) RS2SPIRV_TEST_CASE_ADD(TC, DESCRIPTION) 91 92 #define CHECK(CONDITION) \ 93 ++rs2spirv::TestRunnerContext::getTotalCheckNum(); \ 94 if (!(CONDITION)) \ 95 llvm::errs() << "\nCHECK <( " #CONDITION " )> failed!\n"; \ 96 else \ 97 ++rs2spirv::TestRunnerContext::getCheckSuccessNum(); \ 98 (void)0 99 100 } // namespace rs2spirv 101 102 #endif 103