#include <stdio.h> #include <string.h> #include <sc_assert.h> #include <sc_mmgr.h> #include <sc_error.h> #include <unittest.h> /* -------------------------------------------------------------------- * 定数定義 * -------------------------------------------------------------------- */ /* assert エラー時に呼び出す最大関数登録数 */ #define UT_UNITTEST_FUNC_MAX (4096) #define UT_OUTPUT stderr /** * テスト用関数リスト. */ typedef struct TestFuncEntry_ { const char* funcName; void (*testFunc)(void); } TestFuncEntry; /* プロトタイプ宣言 */ static void UT_cleanup(void); static void UT_checkMemoryLeak(SC_MMgr* mmgr); static void UT_checkMemoryError(SC_MMgr* mmgr); /* テスト関数のリスト */ static TestFuncEntry testFuncs[UT_UNITTEST_FUNC_MAX]; static int testRunIndex = 0; static int testRunSize = 0; static int otherFuncSize = 0; extern void UT_run_kscript_main(void); /** * 単体テスト実行。 * * @param argc 引数の数 * @param argv コマンド引数 */ int main(int argc, char* argv[]) { UT_run_kscript_main(); UT_run(); return 0; } /** * テスト用関数を追加します. * * @param testfunc テスト用関数 */ void UT_add(const char* funcName, void (*testFunc)(void)) { testFuncs[testRunSize + otherFuncSize].funcName = funcName; testFuncs[testRunSize + otherFuncSize].testFunc = testFunc; if (strcmp("OTHER", funcName) == 0) { otherFuncSize++; } else { testRunSize++; } } /** * 単体テストを実行します. */ void UT_run(void) { int i; SC_setAssertOutput(UT_OUTPUT); SC_assertAtExit(UT_cleanup); testRunIndex = 0; for (i = 0; i < (testRunSize + otherFuncSize); i++) { SC_MMgr_setHandler(NULL, NULL, UT_checkMemoryError); if (strcmp("OTHER", testFuncs[i].funcName) != 0) { fprintf(UT_OUTPUT, "[No.%05d] %-50s\n", (testRunIndex + 1), testFuncs[i].funcName); testRunIndex++; } testFuncs[i].testFunc(); } UT_cleanup(); } /** * 単体試験終了時に実行します. */ static void UT_cleanup(void) { SC_MMgr_entries(UT_checkMemoryLeak); fprintf(UT_OUTPUT, "run test case [ %d / %d ]\n", testRunIndex, testRunSize); } /** * メモリリークが発生していないかチェックします。 */ static void UT_checkMemoryLeak(SC_MMgr* mmgr) { fprintf(UT_OUTPUT, "%s:%08d (size = %08d byte) memory Leak\n", mmgr->file, mmgr->line, mmgr->size); } static void UT_checkMemoryError(SC_MMgr* mmgr) { const char* errorType; int nowError = SC_getError(); int ret; switch (nowError) { case SC_EINVAL: errorType = "memory duplicate free"; break; case SC_ENOMEM: errorType = "memory allocate error"; break; default: errorType = "other error"; } /* メモリ管理部分 (tests/ut_scmmgr.c) のテストでは * エラーの試験しているため、エラー出力対象外とする */ ret = strcmp("tests/ut_sc_mmgr.c", mmgr->file); if (ret != 0) { fprintf(UT_OUTPUT, "%s:%08d (size = %08d byte) %s\n", mmgr->file, mmgr->line, mmgr->size, errorType); } }