.tests |-- suites | |-- CMakeLists.txt | |-- suite1.c | |-- suite2.c | |-- suite3.c |-- main.c |-- utils.c |-- utils.h |-- CMakeLists.txt
/* - */ static void test_foo(void) { /* - */ } /* - */ static void test_foo2(void) { /* - */ } void runSuite(void) { /* - */ }
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <dlfcn.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <CUnit/Basic.h> #include "utils.h" int modules_alphasort(const char **a, const char **b) { return strcoll(*a, *b); } void (*runSuite)( void); /* */ size_t searchModulesInDir( char ***m_list, char *dir ) { DIR *modules_dir = NULL; struct dirent *ent = NULL; size_t count = 0; char **modules_list = NULL; char *error = NULL; void *mem_module = NULL; void *module_handle = NULL; unsigned int allocated_mem = 0; errno = 0; if( !dir ) { return -1; } modules_dir = opendir( dir ); if( !modules_dir ) { fprintf( stderr, "%s: %s\n", dir, strerror(errno)); return -1; } while( ( ent = readdir( modules_dir ) ) ) { if( strncmp( ent->d_name, ".", 1 ) == 0 || strstr( ent->d_name, ".so" ) == NULL ) { continue; } size_t mem_len = ( strlen( ent->d_name ) + strlen( dir ) ) * sizeof( char ) + 2; char *module_path = malloc( mem_len ); memset(module_path, 0, mem_len); if( !module_path ) { fprintf( stderr, "%s\n", strerror(errno) ); return -1; } strncat( module_path, dir, strlen( dir ) * sizeof( char ) ); strncat( module_path, "/", 1 ); strncat( module_path, ent->d_name, strlen( ent->d_name ) * sizeof( char ) ); module_handle = dlopen ( module_path, RTLD_LAZY ); if( !module_handle ) { fprintf( stderr, "Could not load module: '%s'\n", dlerror()); free( module_path ); continue; } dlerror(); runSuite= dlsym( module_handle, "runSuite" ); error = dlerror(); if( error ) { fprintf( stderr, "Could not load module: %s\n", error); dlclose( module_handle ); free( module_path ); continue; } mem_module = realloc( modules_list, allocated_mem + strlen(module_path)); allocated_mem += strlen(module_path); if( !mem_module ) { fprintf( stderr, "%s\n", strerror(errno)); free( module_path ); dlclose( module_handle ); return -1; } modules_list = mem_module; modules_list[ count ] = module_path; count++; dlclose( module_handle ); } closedir( modules_dir ); qsort(modules_list, count, sizeof(char *), (int (*)(const void *, const void *))modules_alphasort); *m_list = modules_list; return count; } int main() { char *modules_dir = NULL; char *env_modules_dir = NULL; struct stat dir_info; size_t modules_total = 0; char **modules = NULL; size_t i = 0; void *module_handle = NULL; env_modules_dir = getenv( "TEST_SUITES_DIR" ); modules_dir = ( env_modules_dir ) ? env_modules_dir : "./suites"; if( stat( modules_dir, &dir_info ) < 0 ) { fprintf( stderr, "%s: %s\n", modules_dir, strerror(errno)); return 1; } if( !S_ISDIR( dir_info.st_mode ) ) { fprintf( stderr, "'%s' is not a directory\n", modules_dir); return 1; } if( access( modules_dir, R_OK | X_OK ) != 0 ) { fprintf( stderr, "Directory '%s' is not accessible\n", modules_dir ); return 1; } modules_total = searchModulesInDir( &modules, modules_dir); if(modules_total <= 0) { fprintf( stderr, "No test suites\n"); return 0; } CUnitInitialize(); for( i = 0; i < modules_total; i++ ) { module_handle = dlopen ( modules[i], RTLD_LAZY ); if( !module_handle ) { fprintf( stderr, "Module '%s'\n", dlerror()); continue; } runSuite = dlsym( module_handle, "runSuite" ); runSuite(); } CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CUnitUInitialize(); return CU_get_error(); }
#define TEST_FUNCT(name) \ static void test_##name()
static void test_foo() { /* Some code */ }
TEST_FUNCT(foo) { /* Some code */ }
#define ADD_SUITE_TEST(suite, name) \ if ((NULL == CU_add_test(suite, #name, (CU_TestFunc)test_##name))) {\ CU_cleanup_registry();\ return;\ }\
#ifndef __UTILS_H__ #define __UTILS_H__ #include <stdio.h> #include <stdlib.h> #include <CUnit/Basic.h> #define TEST_FUNCT(name) \ static void test_##name() #define ADD_SUITE_TEST(suite, name) \ if ((NULL == CU_add_test(suite, #name, (CU_TestFunc)test_##name))) {\ CU_cleanup_registry();\ return;\ }\ CU_pSuite CUnitCreateSuite(const char* title); void CUnitInitialize(void); void CUnitUInitialize(void); #endif
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <CUnit/Basic.h> #include "utils.h" void CUnitUInitialize(void) { CU_cleanup_registry(); } void CUnitInitialize(void) { if (CU_initialize_registry() != CUE_SUCCESS) { fprintf(stderr, "Failed to initialize the CUnit registry: %d\n", CU_get_error()); exit(1); } } static int initSuite(void) { return 0; } static int cleanSuite(void) { return 0; } CU_pSuite CUnitCreateSuite(const char* title) { CU_pSuite suite = NULL; suite = CU_add_suite(title, initSuite, cleanSuite); if (suite == NULL) { CU_cleanup_registry(); return NULL; } return suite; }
#include <stdio.h> #include <stdlib.h> #include <CUnit/Basic.h> #include "utils.h" TEST_FUNCT(foo) { /* */ CU_ASSERT_EQUAL(0, 1); } TEST_FUNCT(foo2) { /* */ CU_ASSERT_EQUAL(1, 1); } void runSuite(void) { CU_pSuite suite = CUnitCreateSuite("Suite1"); if (suite) { ADD_SUITE_TEST(suite, foo) ADD_SUITE_TEST(suite, foo2) } }
MACRO(ADD_MODULE file) ADD_LIBRARY( ${file} MODULE ${file}.c ../utils.c ) TARGET_LINK_LIBRARIES( ${file} cunit ) SET_TARGET_PROPERTIES( ${file} PROPERTIES PREFIX "" LIBRARY_OUTPUT_DIRECTORY "." ) ENDMACRO(ADD_MODULE file) FILE(GLOB C_FILES RELATIVE "${CMAKE_SOURCE_DIR}/suites" "${CMAKE_SOURCE_DIR}/suites/*.c") INCLUDE_DIRECTORIES ( "${CMAKE_SOURCE_DIR}" ) FOREACH ( module ${C_FILES} ) STRING( REGEX REPLACE ".c$" "" module "${module}" ) MESSAGE(STATUS "Found test suite: ${module}") ADD_MODULE(${module}) ENDFOREACH ( module ${MODULES} )
CMAKE_MINIMUM_REQUIRED (VERSION 2.6) SET(CMAKE_VERBOSE_MAKEFILE ON) PROJECT("runtest") SET(CMAKE_C_FLAGS " -std=c99 -O3 -Wall -Wextra -Wimplicit") INCLUDE_DIRECTORIES ( "/usr/include" ) ADD_EXECUTABLE(runtests main.c utils.c) TARGET_LINK_LIBRARIES(runtests cunit dl) ADD_CUSTOM_TARGET(test "./runtests" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" VERBATIM) ADD_SUBDIRECTORY(suites)
antonio: tests antonio $ cmake. antonio: tests antonio $ make antonio: tests antonio $ ./runtests
Source: https://habr.com/ru/post/123344/
All Articles