#include <vector>
#include <string>
#include <iostream>
+#include <sys/ioctl.h>
+#include <unistd.h>
#include <cstring>
+#define MAX_SUM_LINE 256
+
using namespace std;
vector<UTest> *UTest::utestList = NULL;
+// Initialize and declare statistics struct
+RStatistics UTest::retStatistics;
+
void releaseUTestList(void) { delete UTest::utestList; }
+void runAllNoIssueAtExit(void) {
+ // If case crashes, count it as fail, and accumulate finishrun
+ if(UTest::retStatistics.finishrun != UTest::utestList->size()) {
+ UTest::retStatistics.finishrun++;
+ UTest::retStatistics.failCount++;
+ }
+ printf("\nsummary:\n----------\n");
+ printf(" total: %zu\n",UTest::utestList->size());
+ printf(" run: %zu\n",UTest::retStatistics.finishrun);
+ printf(" pass: %zu\n",UTest::retStatistics.passCount);
+ printf(" fail: %zu\n",UTest::retStatistics.failCount);
+ printf(" pass rate: %f\n",1-(float)UTest::retStatistics.failCount/(float)UTest::utestList->size());
+ }
UTest::UTest(Function fn, const char *name, bool haveIssue, bool needDestroyProgram)
: fn(fn), name(name), haveIssue(haveIssue), needDestroyProgram(needDestroyProgram) {
+
if (utestList == NULL) {
utestList = new vector<UTest>;
atexit(releaseUTestList);
return false;
}
+void UTest::do_run(struct UTest utest){
+ // winsize is a struct in ioctl.h, contains terminal column number
+ struct winsize size;
+ char spaceList[MAX_SUM_LINE] = {0};
+
+ //Obtain terminal column size
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
+
+ //A string contain MAX_SUM_LINE spaces, to hide the statistic line in stdout
+ for (size_t j = 0; j < size.ws_col; j++){
+ if ( j >= MAX_SUM_LINE - 1 ) break;
+ spaceList[j] = ' ';
+ spaceList[j+1] = '\0';
+ }
+ printf("\r%s\r%s()", spaceList, utest.name);
+
+ // Run one case in utestList
+ (utest.fn)();
+
+ // Print dynamic statistics line
+ sprintf(spaceList, "\n [run/total: %zu/%zu]\
+ pass: %zu; fail: %zu; pass rate: %f\r",
+ retStatistics.finishrun+1, utestList->size(),
+ retStatistics.passCount,
+ retStatistics.failCount,
+ 1-(float)retStatistics.failCount/(float)utestList->size());
+
+ // If terminal column size lower than length of statistic line, print nothing, If not, print the statistics line
+ if (size.ws_col > strlen(spaceList))
+ printf("%s", spaceList);
+ else
+ printf("\n");
+
+ // Refresh console
+ fflush(stdout);
+}
+
void UTest::run(const char *name) {
if (name == NULL) return;
if (utestList == NULL) return;
- for (size_t i = 0; i < utestList->size(); ++i) {
- const UTest &utest = (*utestList)[i];
+ atexit(runAllNoIssueAtExit);
+
+ for (; retStatistics.finishrun < utestList->size(); ++retStatistics.finishrun) {
+ const UTest &utest = (*utestList)[retStatistics.finishrun];
if (utest.name == NULL || utest.fn == NULL ) continue;
if (strequal(utest.name, name)) {
- std::cout << utest.name << ":" << std::endl;
- (utest.fn)();
- std::cout << std::endl;
+ do_run(utest);
cl_kernel_destroy(true);
cl_buffer_destroy();
}
void UTest::runAll(void) {
if (utestList == NULL) return;
- for (size_t i = 0; i < utestList->size(); ++i) {
- const UTest &utest = (*utestList)[i];
+ atexit(runAllNoIssueAtExit);
+
+ for (; retStatistics.finishrun < utestList->size(); ++retStatistics.finishrun) {
+ const UTest &utest = (*utestList)[retStatistics.finishrun];
if (utest.fn == NULL) continue;
- std::cout << utest.name << ":" << std::endl;
- (utest.fn)();
- std::cout << std::endl;
+ do_run(utest);
cl_kernel_destroy(utest.needDestroyProgram);
cl_buffer_destroy();
}
void UTest::runAllNoIssue(void) {
if (utestList == NULL) return;
- for (size_t i = 0; i < utestList->size(); ++i) {
- const UTest &utest = (*utestList)[i];
+ atexit(runAllNoIssueAtExit);
+
+ for (; retStatistics.finishrun < utestList->size(); ++retStatistics.finishrun) {
+ const UTest &utest = (*utestList)[retStatistics.finishrun];
if (utest.fn == NULL || utest.haveIssue) continue;
- std::cout << utest.name << ":" << std::endl;
- (utest.fn)();
- std::cout << std::endl;
+ do_run(utest);
cl_kernel_destroy(utest.needDestroyProgram);
cl_buffer_destroy();
}
#include <vector>
#include <iostream>
+/*! struct for statistics */
+struct RStatistics
+{
+ size_t passCount;
+ size_t failCount;
+ size_t finishrun;
+};
+
/*! Quick and dirty unit test system with registration */
struct UTest
{
static void runAll(void);
/*! List all test cases */
static void listAllCases(void);
+ /*! Statistics struct */
+ static RStatistics retStatistics;
+ /*! Do run a test case actually */
+ static void do_run(struct UTest utest);
};
/*! Register a new unit test */
do { \
try { \
EXPR; \
- std::cout << " " << #EXPR << " [SUCCESS]" << std::endl; \
+ std::cout << " [SUCCESS]"; \
+ UTest::retStatistics.passCount += 1; \
} \
catch (Exception e) { \
- std::cout << " " << #EXPR << " [FAILED]" << std::endl; \
- std::cout << " " << e.what() << std::endl; \
+ std::cout << " [FAILED]"; \
+ std::cout << "\n " << e.what(); \
+ UTest::retStatistics.failCount++; \
} \
} while (0)
do { \
try { \
EXPR; \
- std::cout << " " << #EXPR << " [FAILED]" << std::endl; \
+ std::cout << " [FAILED]"; \
+ retStatistics.failCount++; \
} \
catch (gbe::Exception e) { \
- std::cout << " " << #EXPR << " [SUCCESS]" << std::endl; \
+ std::cout << " [SUCCESS]"; \
+ retStatistics.passCount++; \
} \
} while (0)