16749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni/*
26749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Copyright 2016, The Android Open Source Project
36749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
46749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
56749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * you may not use this file except in compliance with the License.
66749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * You may obtain a copy of the License at
76749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
86749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *     http://www.apache.org/licenses/LICENSE-2.0
96749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni *
106749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * Unless required by applicable law or agreed to in writing, software
116749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
126749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * See the License for the specific language governing permissions and
146749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni * limitations under the License.
156749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni */
166749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
176749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#ifndef RS2SPIRV_TEST_RUNNER
186749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_TEST_RUNNER
196749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
206749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/Support/Debug.h"
216749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include "llvm/Support/raw_ostream.h"
226749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
236749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include <cassert>
246749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#include <vector>
256749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
266749f541c20e86f5deb6fd421ed5849ef43c275cYang Ninamespace rs2spirv {
276749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
286749f541c20e86f5deb6fd421ed5849ef43c275cYang Nistruct TestCase {
296749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  void (*testPtr)(void);
306749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  const char *const description;
316749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni};
326749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
336749f541c20e86f5deb6fd421ed5849ef43c275cYang Niclass TestRunnerContext {
346749f541c20e86f5deb6fd421ed5849ef43c275cYang Nipublic:
356749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static TestRunnerContext &getInstance() {
366749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    static TestRunnerContext ctx;
376749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    return ctx;
386749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  }
396749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
406749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static void addTest(TestCase TC) { getInstance().tests.push_back(TC); }
416749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static size_t &getCheckSuccessNum() { return getInstance().checkSuccessNum; }
426749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static size_t &getTotalCheckNum() { return getInstance().totalCheckNum; }
436749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
446749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static int runTests() {
456749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    bool Failed = false;
466749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    for (auto &TC : getInstance().tests) {
476749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      getCheckSuccessNum() = getTotalCheckNum() = 0;
486749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      llvm::outs() << "Test(" << TC.description << ") {\n";
496749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      TC.testPtr();
506749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      llvm::outs() << "\n} (" << TC.description << ") [" << getCheckSuccessNum()
516749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                   << "/" << getTotalCheckNum() << "]\n\n";
526749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni      Failed |= getCheckSuccessNum() != getTotalCheckNum();
536749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    }
546749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
556749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    return static_cast<int>(Failed);
566749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  }
576749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
586749f541c20e86f5deb6fd421ed5849ef43c275cYang Niprivate:
596749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  TestRunnerContext() = default;
606749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  std::vector<TestCase> tests;
616749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  size_t checkSuccessNum;
626749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  size_t totalCheckNum;
636749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni};
646749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
656749f541c20e86f5deb6fd421ed5849ef43c275cYang Nistruct TestAdder {
666749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  TestAdder(TestCase TC) { TestRunnerContext::addTest(TC); }
676749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni};
686749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
696749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_CONCAT_IMPL(S1, S2) S1##S2
706749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_CONCAT(S1, S2) RS2SPIRV_CONCAT_IMPL(S1, S2)
716749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_ANONYMOUS(X) RS2SPIRV_CONCAT(X, __COUNTER__)
726749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
736749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#if RS2SPIRV_DEBUG
746749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION)                 \
756749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static void FNAME();                                                         \
766749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static rs2spirv::TestAdder VNAME({FNAME, DESCRIPTION});                      \
776749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  inline void FNAME()
786749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#elif defined(__GNUC__) || defined(__clang__)
796749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION)                 \
806749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static inline void __attribute__((unused)) FNAME()
816749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#else
826749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_TEST_CASE_ADD_IMPL(FNAME, VNAME, DESCRIPTION)                 \
836749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  static inline void FNAME()
846749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#endif
856749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
866749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define RS2SPIRV_TEST_CASE_ADD(NAME, DESCRIPTION)                              \
876749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  RS2SPIRV_TEST_CASE_ADD_IMPL(RS2SPIRV_ANONYMOUS(NAME),                        \
886749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni                              RS2SPIRV_ANONYMOUS(NAME), DESCRIPTION)
896749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
906749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define TEST_CASE(DESCRIPTION) RS2SPIRV_TEST_CASE_ADD(TC, DESCRIPTION)
916749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
926749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#define CHECK(CONDITION)                                                       \
936749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  ++rs2spirv::TestRunnerContext::getTotalCheckNum();                           \
946749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  if (!(CONDITION))                                                            \
956749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    llvm::errs() << "\nCHECK <(  " #CONDITION "  )> failed!\n";                \
966749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  else                                                                         \
976749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni    ++rs2spirv::TestRunnerContext::getCheckSuccessNum();                       \
986749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni  (void)0
996749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1006749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni} // namespace rs2spirv
1016749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni
1026749f541c20e86f5deb6fd421ed5849ef43c275cYang Ni#endif
103