DECLARE_TEST(foundation, environment) { lua_t* env = lua_allocate(); log_set_suppress(HASH_LUA, ERRORLEVEL_NONE); log_info(HASH_LUA, STRING_CONST("Running environment lua tests")); EXPECT_NE(env, 0); string_const_t testcode = string_const(STRING_CONST( "local ffi = require(\"ffi\")\n" "local foundation = require(\"foundation\")\n" "local C = ffi.C\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_DEBUG)\n" "C.log_enable_prefix(false)\n" "foundation.log.info(\"Executable name: \" .. tostring(C.environment_executable_name()))\n" "local cmdline = \"\"\n" "local cmdline_tab = C.environment_command_line()\n" "local num = C.array_size(cmdline_tab)" "for i = 0, num-1 do\n" " cmdline = cmdline .. \" \" .. tostring(cmdline_tab[i])\n" "end\n" "foundation.log.info(\"Command line:\" .. cmdline)\n" "C.log_enable_prefix(true)\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_INFO)\n" )); EXPECT_EQ(lua_eval_string(env, STRING_ARGS(testcode)), LUA_OK); log_info(HASH_LUA, STRING_CONST("Done running environment lua tests")); log_set_suppress(HASH_LUA, ERRORLEVEL_INFO); lua_deallocate(env); return 0; }
DECLARE_TEST( library, lookup ) { object_t lib = 0; object_t otherlib = 0; void* symbol = 0; #if FOUNDATION_PLATFORM_WINDOWS const char* libraryname = "kernel32"; const char* symbolname = "ExitProcess"; #elif FOUNDATION_PLATFORM_APPLE const char* libraryname = "dl"; const char* symbolname = "dlsym"; #elif FOUNDATION_PLATFORM_POSIX const char* libraryname = "dl"; const char* symbolname = "dlsym"; #else const char* libraryname = "somelib"; const char* symbolname = "somesym"; #endif lib = library_load( libraryname ); EXPECT_NE( lib, 0 ); otherlib = library_load( libraryname ); EXPECT_EQ( lib, otherlib ); library_unload( otherlib ); library_unload( 0 ); otherlib = 0; log_set_suppress( 0, ERRORLEVEL_WARNING ); EXPECT_EQ( library_load( "this_library_should_not_exist" ), 0 ); log_set_suppress( 0, ERRORLEVEL_DEBUG ); EXPECT_TRUE( library_valid( lib ) ); EXPECT_FALSE( library_valid( 0 ) ); symbol = library_symbol( lib, symbolname ); EXPECT_NE( symbol, 0 ); EXPECT_EQ( library_symbol( 0, symbolname ), 0 ); library_unload( lib ); EXPECT_EQ( library_symbol( lib, symbolname ), 0 ); EXPECT_FALSE( library_valid( lib ) ); return 0; }
int main_run( void* main_arg ) { FOUNDATION_UNUSED( main_arg ); log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG ); return test_run_all(); }
static int test_foundation_initialize(void) { lua_config_t lua_config; resource_config_t resource_config; log_set_suppress(HASH_RESOURCE, ERRORLEVEL_NONE); memset(&lua_config, 0, sizeof(lua_config)); memset(&resource_config, 0, sizeof(resource_config)); resource_config.enable_local_source = true; resource_config.enable_local_cache = true; resource_config.enable_remote_cache = true; if (resource_module_initialize(resource_config) < 0) return -1; if (lua_module_initialize(lua_config) < 0) return -1; test_set_suitable_working_directory(); test_load_config(test_parse_config); return 0; }
int main_initialize( void ) { application_t application; memset( &application, 0, sizeof( application ) ); application.name = "Foundation library test suite"; application.short_name = "test_all"; application.config_dir = "test_all"; application.version = foundation_version(); application.flags = APPLICATION_UTILITY; application.dump_callback = test_crash_handler; log_set_suppress( 0, ERRORLEVEL_INFO ); #if ( FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID ) && BUILD_ENABLE_LOG log_set_callback( test_log_callback ); #endif #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL _test_should_start = true; #endif return foundation_initialize( memory_system_malloc(), application ); }
DECLARE_TEST(foundation, log) { lua_t* env = lua_allocate(); log_set_suppress(HASH_LUA, ERRORLEVEL_NONE); EXPECT_NE(env, 0); string_const_t testcode = string_const(STRING_CONST( "local ffi = require(\"ffi\")\n" "local foundation = require(\"foundation\")\n" "local C = ffi.C\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_NONE)\n" "foundation.log.debug(\"Testing log debug output\")\n" "foundation.log.info(\"Testing log info output\")\n" "foundation.log.warn(\"Testing log warning output\")\n" "C.log_enable_prefix(false)\n" "foundation.log.error(\"Testing log error output without prefix\")\n" "C.log_enable_stdout(false)\n" "foundation.log.debug(\"Invisible on stdout\")\n" "C.log_enable_stdout(true)\n" "C.log_enable_prefix(true)\n" "C.log_set_suppress(foundation.HASH_LUA, foundation.ERRORLEVEL_INFO)\n" )); EXPECT_EQ(lua_eval_string(env, STRING_ARGS(testcode)), LUA_OK); EXPECT_EQ(error(), ERROR_SCRIPT); lua_deallocate(env); return 0; }
int test_udp_initialize(void) { network_config_t config; memset(&config, 0, sizeof(config)); log_set_suppress(HASH_NETWORK, ERRORLEVEL_INFO); return network_module_initialize(config); }
int main_initialize( void ) { log_set_suppress( 0, ERRORLEVEL_INFO ); test_suite = test_suite_define(); return foundation_initialize( test_suite.memory_system(), test_suite.application() ); }
static void hashify_print_usage(void) { const error_level_t saved_level = log_suppress(0); log_set_suppress(0, ERRORLEVEL_DEBUG); log_info(0, STRING_CONST( "hashify usage:\n" " hashify [--validate] [--generate-string <string>] [<filename> <filename> ...] [--debug] [--help] [--]\n" " Generated files have the same file name as the input file, with the extension replaced by .h\n" " Optional arguments:\n" " --validate Suppress output and only validate existing hashes\n" " --generate-string <string> Generate hash of the given string\n" " <filename> <filename> ... Any number of input files\n" " --debug Enable debug output\n" " --help Display this help message\n" " -- Stop processing command line arguments" )); log_set_suppress(0, saved_level); }
static void rendercompile_print_usage(void) { const error_level_t saved_level = log_suppress(0); log_set_suppress(0, ERRORLEVEL_DEBUG); log_info(0, STRING_CONST( "rendercompile usage:\n" " rendercompile [--source <path>] [--ascii] [--binary] [--debug] [--help] <file> <uuid> ... [--]\n" " Arguments:\n" " <file> <uuid> ... Any number of input files or UUIDs\n" " Optional arguments:\n" " --source <path> Operate on resource file source structure given by <path>\n" " --binary Write binary files\n" " --ascii Write ASCII files (default)\n" " --debug Enable debug output\n" " --help Display this help message\n" " -- Stop processing command line arguments" )); log_set_suppress(0, saved_level); }
int main_initialize(void) { int ret = 0; application_t application; foundation_config_t foundation_config; resource_config_t resource_config; window_config_t window_config; render_config_t render_config; memset(&foundation_config, 0, sizeof(foundation_config)); memset(&resource_config, 0, sizeof(resource_config)); memset(&window_config, 0, sizeof(window_config)); memset(&render_config, 0, sizeof(render_config)); memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("rendercompile")); application.short_name = string_const(STRING_CONST("rendercompile")); application.config_dir = string_const(STRING_CONST("rendercompile")); application.flags = APPLICATION_UTILITY; log_enable_prefix(false); log_set_suppress(0, ERRORLEVEL_WARNING); resource_config.enable_local_source = true; resource_config.enable_local_cache = true; resource_config.enable_remote_cache = true; if ((ret = foundation_initialize(memory_system_malloc(), application, foundation_config)) < 0) return ret; if ((ret = resource_module_initialize(resource_config)) < 0) return ret; if ((ret = window_module_initialize(window_config)) < 0) return ret; if ((ret = render_module_initialize(render_config)) < 0) return ret; log_set_suppress(HASH_RESOURCE, ERRORLEVEL_DEBUG); log_set_suppress(HASH_RENDER, ERRORLEVEL_INFO); return 0; }
int main_initialize( void ) { application_t application = {0}; application.name = "Foundation library test suite"; application.short_name = "test_all"; application.config_dir = "test_all"; application.flags = APPLICATION_UTILITY; log_set_suppress( 0, ERRORLEVEL_DEBUG ); return foundation_initialize( memory_system_malloc(), application ); }
int main_initialize(void) { foundation_config_t config; application_t application; int ret; size_t iarg, asize; const string_const_t* cmdline = environment_command_line(); _test_memory_tracker = true; for (iarg = 0, asize = array_size(cmdline); iarg < asize; ++iarg) { if (string_equal(STRING_ARGS(cmdline[iarg]), STRING_CONST("--no-memory-tracker"))) _test_memory_tracker = false; } if (_test_memory_tracker) memory_set_tracker(memory_tracker_local()); memset(&config, 0, sizeof(config)); memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("Task library test suite")); application.short_name = string_const(STRING_CONST("test_all")); application.company = string_const(STRING_CONST("Rampant Pixels")); application.version = task_module_version(); application.flags = APPLICATION_UTILITY; application.exception_handler = test_exception_handler; log_set_suppress(0, ERRORLEVEL_INFO); #if ( FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID ) && BUILD_ENABLE_LOG log_set_handler(test_log_handler); #endif #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL _test_should_start = true; #endif ret = foundation_initialize(memory_system_malloc(), application, config); #if BUILD_MONOLITHIC if (ret == 0) { task_config_t task_config; memset(&task_config, 0, sizeof(task_config)); ret = task_module_initialize(task_config); test_set_suitable_working_directory(); } #endif return ret; }
int main_run(void* main_arg) { const char element[4][2] = { "X", "Y", "Z", "W" }; FOUNDATION_UNUSED(main_arg); log_set_suppress(HASH_TOOL, ERRORLEVEL_DEBUG); log_info(HASH_TOOL, STRING_CONST( "/* mask.h - Vector library - Public Domain - 2013 Mattias Jansson / Rampant Pixels\n" " *\n" " * This library provides a cross-platform vector math library in C11 providing basic support data types and\n" " * functions to write applications and games in a platform-independent fashion. The latest source code is\n" " * always available at\n" " *\n" " * https://github.com/rampantpixels/vector_lib\n" " *\n" " * This library is built on top of the foundation library available at\n" " *\n" " * https://github.com/rampantpixels/foundation_lib\n" " *\n" " * This library is put in the public domain; you can redistribute it and/or modify it without any restrictions.\n" " *\n" "*/\n\n" "#pragma once\n\n" "/*! \\file math/mask.h\n" " Vector mask definitions */\n\n" "#include <vector/types.h>\n\n" "#define VECTOR_MASK(x, y, z, w) (((w) << 6) | ((z) << 4) | ((y) << 2) | ((x)))\n\n" "/* Vector shuffle masks where the operation performed by\n" " v1 = vector_shuffle(v0, VECTOR_MASK_abcd)\n" " will be equal to\n" " v1.x = v0[a]\n" " v1.y = v0[b]\n" " v1.z = v0[c]\n" " v1.w = v0[d] */\n")); for (int e0 = 0; e0 < 4; ++e0) for (int e1 = 0; e1 < 4; ++e1) for (int e2 = 0; e2 < 4; ++e2) for (int e3 = 0; e3 < 4; ++e3) log_infof(HASH_TOOL, STRING_CONST("#define VECTOR_MASK_%s%s%s%s VECTOR_MASK(%d, %d, %d, %d)"), element[e0], element[e1], element[e2], element[e3], e0, e1, e2, e3); return 0; }
hashify_input_t hashify_parse_command_line(const string_const_t* cmdline) { hashify_input_t input; size_t arg, asize; memset(&input, 0, sizeof(input)); input.check_only = false; error_context_push(STRING_CONST("parsing command line"), STRING_CONST("")); for (arg = 1, asize = array_size(cmdline); arg < asize; ++arg) { if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--help"))) { hashify_print_usage(); continue; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--validate"))) { input.check_only = true; continue; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--generate-string"))) { if (arg < asize - 1) { ++arg; array_push(input.strings, string_clone(STRING_ARGS(cmdline[arg]))); } continue; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--debug"))) { log_set_suppress(0, ERRORLEVEL_NONE); continue; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--"))) break; //Stop parsing cmdline options else if ((cmdline[arg].length > 2) && string_equal(cmdline[arg].str, 2, STRING_CONST("--"))) continue; //Cmdline argument not parsed here array_push(input.files, string_clone(STRING_ARGS(cmdline[arg]))); } error_context_pop(); if (array_size(cmdline) <= 1) hashify_print_usage(); return input; }
int main_initialize(void) { int ret = 0; application_t application; foundation_config_t config; memset(&config, 0, sizeof(config)); memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("hashify")); application.short_name = string_const(STRING_CONST("hashify")); application.flags = APPLICATION_UTILITY; log_enable_prefix(false); log_set_suppress(0, ERRORLEVEL_ERROR); if ((ret = foundation_initialize(memory_system_malloc(), application, config)) < 0) return ret; return 0; }
DECLARE_TEST(mutex, basic) { mutex_t* mutex; mutex = mutex_allocate(STRING_CONST("test")); EXPECT_CONSTSTRINGEQ(mutex_name(mutex), string_const(STRING_CONST("test"))); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_try_lock(mutex)); EXPECT_TRUE(mutex_lock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); EXPECT_TRUE(mutex_unlock(mutex)); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_wait(mutex)); EXPECT_TRUE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_signal(mutex); thread_yield(); EXPECT_TRUE(mutex_try_wait(mutex, 1)); log_set_suppress(0, ERRORLEVEL_WARNING); EXPECT_FALSE(mutex_try_wait(mutex, 100)); EXPECT_TRUE(mutex_unlock(mutex)); EXPECT_FALSE(mutex_unlock(mutex)); log_set_suppress(0, ERRORLEVEL_INFO); mutex_deallocate(mutex); return 0; }
int main_run( void* main_arg ) { #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID const char* pattern = 0; char** exe_paths = 0; unsigned int iexe, exesize; process_t* process = 0; char* process_path = 0; unsigned int* exe_flags = 0; #endif int process_result = 0; object_t thread = 0; log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG ); thread = thread_create( event_thread, "event_thread", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread, 0 ); while( !thread_is_running( thread ) ) thread_sleep( 10 ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID while( !_test_should_start ) thread_sleep( 10 ); test_run_fn tests[] = { //test_app_run test_array_run, test_atomic_run, test_base64_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_config_run, test_crash_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_profile_run, test_radixsort_run, test_random_run, test_ringbuffer_run, test_semaphore_run, test_stacktrace_run, test_string_run, test_uuid_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID object_t test_thread = thread_create( test_runner, "test_runner", THREAD_PRIORITY_NORMAL, 0 ); thread_start( test_thread, tests ); while( !thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } while( thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } process_result = (int)(intptr_t)thread_result( test_thread ); thread_destroy( test_thread ); while( thread_is_thread( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } #else process_result = (int)(intptr_t)test_runner( 0, tests ); #endif if( process_result != 0 ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); while( !_test_should_terminate ) { system_process_events(); thread_sleep( 100 ); } log_debug( HASH_TEST, "Exiting main loop" ); #else //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = "test-*.exe"; #elif FOUNDATION_PLATFORM_MACOSX pattern = "test-*"; #elif FOUNDATION_PLATFORM_POSIX pattern = "test-*"; #else # error Not implemented #endif exe_paths = fs_matching_files( environment_executable_directory(), pattern, false ); array_resize( exe_flags, array_size( exe_paths ) ); memset( exe_flags, 0, sizeof( unsigned int ) * array_size( exe_flags ) ); #if FOUNDATION_PLATFORM_MACOSX //Also search for test-*.app const char* app_pattern = "test-*.app"; char** subdirs = fs_subdirs( environment_executable_directory() ); for( int idir = 0, dirsize = array_size( subdirs ); idir < dirsize; ++idir ) { if( string_match_pattern( subdirs[idir], app_pattern ) ) { array_push( exe_paths, string_substr( subdirs[idir], 0, string_length( subdirs[idir] ) - 4 ) ); array_push( exe_flags, PROCESS_OSX_USE_OPENAPPLICATION ); } } string_array_deallocate( subdirs ); #endif for( iexe = 0, exesize = array_size( exe_paths ); iexe < exesize; ++iexe ) { bool is_self = false; char* exe_file_name = path_base_file_name( exe_paths[iexe] ); if( string_equal( exe_file_name, environment_executable_name() ) ) is_self = true; string_deallocate( exe_file_name ); if( is_self ) continue; //Don't run self process_path = path_merge( environment_executable_directory(), exe_paths[iexe] ); process = process_allocate(); process_set_executable_path( process, process_path ); process_set_working_directory( process, environment_executable_directory() ); process_set_flags( process, PROCESS_ATTACHED | exe_flags[iexe] ); log_infof( HASH_TEST, "Running test executable: %s", exe_paths[iexe] ); process_result = process_spawn( process ); while( process_result == PROCESS_WAIT_INTERRUPTED ) { thread_sleep( 10 ); process_result = process_wait( process ); } process_deallocate( process ); string_deallocate( process_path ); if( process_result != 0 ) { if( process_result >= PROCESS_INVALID_ARGS ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed, process terminated with error %x", process_result ); else log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); process_set_exit_code( -1 ); goto exit; } log_infof( HASH_TEST, "All tests from %s passed (%d)", exe_paths[iexe], process_result ); } log_info( HASH_TEST, "All tests passed" ); exit: if( exe_paths ) string_array_deallocate( exe_paths ); array_deallocate( exe_flags ); #endif thread_terminate( thread ); thread_destroy( thread ); while( thread_is_running( thread ) ) thread_sleep( 10 ); while( thread_is_thread( thread ) ) thread_sleep( 10 ); return process_result; }
int main_run(void* main_arg) { #if !BUILD_MONOLITHIC string_const_t pattern; string_t* exe_paths = 0; size_t iexe, exesize; process_t* process = 0; string_t process_path = { 0, 0 }; unsigned int* exe_flags = 0; #else void* test_result; #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL int remain_counter = 0; #endif #if BUILD_DEBUG const string_const_t build_name = string_const(STRING_CONST("debug")); #elif BUILD_RELEASE const string_const_t build_name = string_const(STRING_CONST("release")); #elif BUILD_PROFILE const string_const_t build_name = string_const(STRING_CONST("profile")); #elif BUILD_DEPLOY const string_const_t build_name = string_const(STRING_CONST("deploy")); #endif #if BUILD_MONOLITHIC const string_const_t build_type = string_const(STRING_CONST(" monolithic")); #else const string_const_t build_type = string_empty(); #endif char* pathbuf; int process_result = 0; thread_t event_thread; FOUNDATION_UNUSED(main_arg); FOUNDATION_UNUSED(build_name); log_set_suppress(HASH_TEST, ERRORLEVEL_DEBUG); log_infof(HASH_TEST, STRING_CONST("Task library v%s built for %s using %s (%.*s%.*s)"), string_from_version_static(task_module_version()).str, FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, STRING_FORMAT(build_name), STRING_FORMAT(build_type)); thread_initialize(&event_thread, event_loop, 0, STRING_CONST("event_thread"), THREAD_PRIORITY_NORMAL, 0); thread_start(&event_thread); pathbuf = memory_allocate(HASH_STRING, BUILD_MAX_PATHLEN, 0, MEMORY_PERSISTENT); while (!thread_is_running(&event_thread)) thread_sleep(10); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_start) { #if FOUNDATION_PLATFORM_ANDROID system_process_events(); #endif thread_sleep(100); } #endif fs_remove_directory(STRING_ARGS(environment_temporary_directory())); #if BUILD_MONOLITHIC test_run_fn tests[] = { test_task_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID thread_t test_thread; thread_initialize(&test_thread, test_runner, tests, STRING_CONST("test_runner"), THREAD_PRIORITY_NORMAL, 0); thread_start(&test_thread); log_debug(HASH_TEST, STRING_CONST("Starting test runner thread")); while (!thread_is_running(&test_thread)) { system_process_events(); thread_sleep(10); } while (thread_is_running(&test_thread)) { system_process_events(); thread_sleep(10); } test_result = thread_join(&test_thread); process_result = (int)(intptr_t)test_result; thread_finalize(&test_thread); #else test_result = test_runner(tests); process_result = (int)(intptr_t)test_result; #endif if (process_result != 0) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while (!_test_should_terminate && _test_have_focus && (remain_counter < 50)) { system_process_events(); thread_sleep(100); ++remain_counter; } #endif log_debug(HASH_TEST, STRING_CONST("Exiting main loop")); #else // !BUILD_MONOLITHIC //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = string_const(STRING_CONST("^test-.*\\.exe$")); #elif FOUNDATION_PLATFORM_MACOSX pattern = string_const(STRING_CONST("^test-.*$")); #elif FOUNDATION_PLATFORM_POSIX pattern = string_const(STRING_CONST("^test-.*$")); #else # error Not implemented #endif exe_paths = fs_matching_files(STRING_ARGS(environment_executable_directory()), STRING_ARGS(pattern), false); array_resize(exe_flags, array_size(exe_paths)); memset(exe_flags, 0, sizeof(unsigned int) * array_size(exe_flags)); #if FOUNDATION_PLATFORM_MACOSX //Also search for test applications string_const_t app_pattern = string_const(STRING_CONST("^test-.*\\.app$")); regex_t* app_regex = regex_compile(app_pattern.str, app_pattern.length); string_t* subdirs = fs_subdirs(STRING_ARGS(environment_executable_directory())); for (size_t idir = 0, dirsize = array_size(subdirs); idir < dirsize; ++idir) { if (regex_match(app_regex, subdirs[idir].str, subdirs[idir].length, 0, 0)) { string_t exe_path = { subdirs[idir].str, subdirs[idir].length - 4 }; array_push(exe_paths, exe_path); array_push(exe_flags, PROCESS_MACOSX_USE_OPENAPPLICATION); } } string_array_deallocate(subdirs); regex_deallocate(app_regex); #endif for (iexe = 0, exesize = array_size(exe_paths); iexe < exesize; ++iexe) { string_const_t* process_args = 0; string_const_t exe_file_name = path_base_file_name(STRING_ARGS(exe_paths[iexe])); if (string_equal(STRING_ARGS(exe_file_name), STRING_ARGS(environment_executable_name()))) continue; //Don't run self process_path = path_concat(pathbuf, BUILD_MAX_PATHLEN, STRING_ARGS(environment_executable_directory()), STRING_ARGS(exe_paths[iexe])); process = process_allocate(); process_set_executable_path(process, STRING_ARGS(process_path)); process_set_working_directory(process, STRING_ARGS(environment_executable_directory())); process_set_flags(process, PROCESS_ATTACHED | exe_flags[iexe]); if (!_test_memory_tracker) array_push(process_args, string_const(STRING_CONST("--no-memory-tracker"))); process_set_arguments(process, process_args, array_size(process_args)); log_infof(HASH_TEST, STRING_CONST("Running test executable: %.*s"), STRING_FORMAT(exe_paths[iexe])); process_result = process_spawn(process); while (process_result == PROCESS_WAIT_INTERRUPTED) { thread_sleep(10); process_result = process_wait(process); } process_deallocate(process); array_deallocate(process_args); if (process_result != 0) { if (process_result >= PROCESS_INVALID_ARGS) log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed, process terminated with error %x"), process_result); else log_warnf(HASH_TEST, WARNING_SUSPICIOUS, STRING_CONST("Tests failed with exit code %d"), process_result); process_set_exit_code(-1); goto exit; } log_infof(HASH_TEST, STRING_CONST("All tests from %.*s passed (%d)"), STRING_FORMAT(exe_paths[iexe]), process_result); } log_info(HASH_TEST, STRING_CONST("All tests passed")); exit: if (exe_paths) string_array_deallocate(exe_paths); array_deallocate(exe_flags); #endif _test_should_terminate = true; thread_signal(&event_thread); thread_finalize(&event_thread); memory_deallocate(pathbuf); log_infof(HASH_TEST, STRING_CONST("Tests exiting: %s (%d)"), process_result ? "FAILED" : "PASSED", process_result); if (process_result) memory_set_tracker(memory_tracker_none()); return process_result; }
int main_run( void* main_arg ) { #if !BUILD_MONOLITHIC const char* pattern = 0; char** exe_paths = 0; unsigned int iexe, exesize; process_t* process = 0; char* process_path = 0; unsigned int* exe_flags = 0; #endif #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL int remain_counter = 0; #endif #if BUILD_DEBUG const char* build_name = "debug"; #elif BUILD_RELEASE const char* build_name = "release"; #elif BUILD_PROFILE const char* build_name = "profile"; #elif BUILD_DEPLOY const char* build_name = "deploy"; #endif int process_result = 0; object_t thread = 0; FOUNDATION_UNUSED( main_arg ); FOUNDATION_UNUSED( build_name ); log_set_suppress( HASH_TEST, ERRORLEVEL_DEBUG ); log_infof( HASH_TEST, "Foundation library v%s built for %s using %s (%s)", string_from_version_static( foundation_version() ), FOUNDATION_PLATFORM_DESCRIPTION, FOUNDATION_COMPILER_DESCRIPTION, build_name ); thread = thread_create( event_thread, "event_thread", THREAD_PRIORITY_NORMAL, 0 ); thread_start( thread, 0 ); while( !thread_is_running( thread ) ) thread_sleep( 10 ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID while( !_test_should_start ) { #if FOUNDATION_PLATFORM_ANDROID system_process_events(); #endif thread_sleep( 100 ); } #endif fs_remove_directory( environment_temporary_directory() ); #if BUILD_MONOLITHIC test_run_fn tests[] = { test_app_run, test_array_run, test_atomic_run, test_base64_run, test_bitbuffer_run, test_blowfish_run, test_bufferstream_run, test_config_run, test_crash_run, test_environment_run, test_error_run, test_event_run, test_fs_run, test_hash_run, test_hashmap_run, test_hashtable_run, test_library_run, test_math_run, test_md5_run, test_mutex_run, test_objectmap_run, test_path_run, test_pipe_run, test_process_run, test_profile_run, test_radixsort_run, test_random_run, test_regex_run, test_ringbuffer_run, test_semaphore_run, test_stacktrace_run, test_stream_run, //stream test closes stdin test_string_run, test_system_run, test_time_run, test_uuid_run, 0 }; #if FOUNDATION_PLATFORM_ANDROID object_t test_thread = thread_create( test_runner, "test_runner", THREAD_PRIORITY_NORMAL, 0 ); thread_start( test_thread, tests ); log_debug( HASH_TEST, "Starting test runner thread" ); while( !thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } while( thread_is_running( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } process_result = (int)(intptr_t)thread_result( test_thread ); thread_destroy( test_thread ); while( thread_is_thread( test_thread ) ) { system_process_events(); thread_sleep( 10 ); } #else process_result = (int)(intptr_t)test_runner( 0, tests ); #endif if( process_result != 0 ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); #if FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID || FOUNDATION_PLATFORM_PNACL while( !_test_should_terminate && _test_have_focus && ( remain_counter < 50 ) ) { system_process_events(); thread_sleep( 100 ); ++remain_counter; } #endif log_debug( HASH_TEST, "Exiting main loop" ); #else // !BUILD_MONOLITHIC //Find all test executables in the current executable directory #if FOUNDATION_PLATFORM_WINDOWS pattern = "^test-.*\\.exe$"; #elif FOUNDATION_PLATFORM_MACOSX pattern = "^test-.*$"; #elif FOUNDATION_PLATFORM_POSIX pattern = "^test-.*$"; #else # error Not implemented #endif exe_paths = fs_matching_files( environment_executable_directory(), pattern, false ); array_resize( exe_flags, array_size( exe_paths ) ); memset( exe_flags, 0, sizeof( unsigned int ) * array_size( exe_flags ) ); #if FOUNDATION_PLATFORM_MACOSX //Also search for test applications const char* app_pattern = "^test-.*\\.app$"; regex_t* app_regex = regex_compile( app_pattern ); char** subdirs = fs_subdirs( environment_executable_directory() ); for( int idir = 0, dirsize = array_size( subdirs ); idir < dirsize; ++idir ) { if( regex_match( app_regex, subdirs[idir], string_length( subdirs[idir] ), 0, 0 ) ) { array_push( exe_paths, string_substr( subdirs[idir], 0, string_length( subdirs[idir] ) - 4 ) ); array_push( exe_flags, PROCESS_MACOSX_USE_OPENAPPLICATION ); } } string_array_deallocate( subdirs ); regex_deallocate( app_regex ); #endif for( iexe = 0, exesize = array_size( exe_paths ); iexe < exesize; ++iexe ) { bool is_self = false; char* exe_file_name = path_base_file_name( exe_paths[iexe] ); if( string_equal( exe_file_name, environment_executable_name() ) ) is_self = true; string_deallocate( exe_file_name ); if( is_self ) continue; //Don't run self process_path = path_merge( environment_executable_directory(), exe_paths[iexe] ); process = process_allocate(); process_set_executable_path( process, process_path ); process_set_working_directory( process, environment_executable_directory() ); process_set_flags( process, PROCESS_ATTACHED | exe_flags[iexe] ); log_infof( HASH_TEST, "Running test executable: %s", exe_paths[iexe] ); process_result = process_spawn( process ); while( process_result == PROCESS_WAIT_INTERRUPTED ) { thread_sleep( 10 ); process_result = process_wait( process ); } process_deallocate( process ); string_deallocate( process_path ); if( process_result != 0 ) { if( process_result >= PROCESS_INVALID_ARGS ) log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed, process terminated with error %x", process_result ); else log_warnf( HASH_TEST, WARNING_SUSPICIOUS, "Tests failed with exit code %d", process_result ); process_set_exit_code( -1 ); goto exit; } log_infof( HASH_TEST, "All tests from %s passed (%d)", exe_paths[iexe], process_result ); } log_info( HASH_TEST, "All tests passed" ); exit: if( exe_paths ) string_array_deallocate( exe_paths ); array_deallocate( exe_flags ); #endif thread_terminate( thread ); thread_destroy( thread ); while( thread_is_running( thread ) ) thread_sleep( 10 ); while( thread_is_thread( thread ) ) thread_sleep( 10 ); log_infof( HASH_TEST, "Tests exiting: %d", process_result ); return process_result; }
int foundation_initialize(const memory_system_t memory, const application_t application, const foundation_config_t config) { int ret = 0; if (_initialized) return 0; process_set_exit_code(PROCESS_EXIT_SUCCESS); foundation_initialize_config(config); /*lint -e774 */ SUBSYSTEM_INIT(atomic); SUBSYSTEM_INIT_ARGS(memory, memory); SUBSYSTEM_INIT(static_hash); SUBSYSTEM_INIT(log); SUBSYSTEM_INIT(time); SUBSYSTEM_INIT(thread); SUBSYSTEM_INIT(random); SUBSYSTEM_INIT(stream); SUBSYSTEM_INIT(fs); SUBSYSTEM_INIT(stacktrace); SUBSYSTEM_INIT(exception); SUBSYSTEM_INIT_ARGS(environment, application); SUBSYSTEM_INIT(library); SUBSYSTEM_INIT(system); if (ret) return ret; //Parse built-in command line options { /*lint --e{613} */ const string_const_t* cmdline = environment_command_line(); size_t iarg, argsize; for (iarg = 0, argsize = array_size(cmdline); iarg < argsize; ++iarg) { string_const_t arg = cmdline[iarg]; if (string_equal(arg.str, arg.length, STRING_CONST("--log-debug"))) log_set_suppress(0, ERRORLEVEL_NONE); else if (string_equal(arg.str, arg.length, STRING_CONST("--log-info"))) log_set_suppress(0, ERRORLEVEL_DEBUG); else if (string_equal(arg.str, arg.length, STRING_CONST("--log-warning"))) log_set_suppress(0, ERRORLEVEL_WARNING); else if (string_equal(arg.str, arg.length, STRING_CONST("--log-error"))) log_set_suppress(0, ERRORLEVEL_ERROR); } } #if !BUILD_DYNAMIC_LINK //Artificial references /*lint -e506 */ #if FOUNDATION_PLATFORM_ANDROID android_main(0); #elif FOUNDATION_PLATFORM_PNACL if (((uintptr_t)PPP_InitializeModule < 1) || ((uintptr_t)PPP_GetInterface < 1) || ((uintptr_t)PPP_ShutdownModule < 1)) return -1; #else if ((uintptr_t)main < 1) return -1; #endif #endif _initialized = true; return 0; }
rendercompile_input_t rendercompile_parse_command_line(const string_const_t* cmdline) { rendercompile_input_t input; size_t arg, asize; memset(&input, 0, sizeof(input)); for (arg = 1, asize = array_size(cmdline); arg < asize; ++arg) { if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--help"))) input.display_help = true; else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--source"))) { if (arg < asize - 1) input.source_path = cmdline[++arg]; } /*else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--uuid"))) { if (arg < asize - 1) { ++arg; input.uuid = string_to_uuid(STRING_ARGS(cmdline[arg])); if (uuid_is_null(input.uuid)) log_warnf(HASH_RESOURCE, WARNING_INVALID_VALUE, STRING_CONST("Invalid UUID: %.*s"), STRING_FORMAT(cmdline[arg])); } } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--set"))) { if (arg < asize - 2) { input.key = cmdline[++arg]; input.value = cmdline[++arg]; } }*/ else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--binary"))) { input.binary = 1; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--ascii"))) { input.binary = 0; } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--debug"))) { log_set_suppress(0, ERRORLEVEL_NONE); log_set_suppress(HASH_RESOURCE, ERRORLEVEL_NONE); log_set_suppress(HASH_RENDER, ERRORLEVEL_NONE); } else if (string_equal(STRING_ARGS(cmdline[arg]), STRING_CONST("--"))) break; //Stop parsing cmdline options else { array_push(input.input_files, cmdline[arg]); } } error_context_pop(); bool already_help = input.display_help; if (!input.source_path.length) input.source_path = resource_source_path(); if (!already_help && !input.source_path.length) { log_errorf(HASH_RESOURCE, ERROR_INVALID_VALUE, STRING_CONST("No source path given")); input.display_help = true; } if (!already_help && !array_size(input.input_files)) { log_errorf(HASH_RESOURCE, ERROR_INVALID_VALUE, STRING_CONST("No input files given")); input.display_help = true; } return input; }
int main_initialize(void) { foundation_config_t config; application_t application; int ret; size_t iarg, asize; const string_const_t* cmdline = environment_command_line(); _test_memory_tracker = true; for (iarg = 0, asize = array_size(cmdline); iarg < asize; ++iarg) { if (string_equal(STRING_ARGS(cmdline[iarg]), STRING_CONST("--no-memory-tracker"))) _test_memory_tracker = false; } if (_test_memory_tracker) memory_set_tracker(memory_tracker_local()); memset(&config, 0, sizeof(config)); #if BUILD_MONOLITHIC //For fs monitor test config.fs_monitor_max = 1; //For temporary allocator test, 256KiB config.temporary_memory = 256 * 1024; //For testing static hash store config.hash_store_size = 32 * 1024; //Test preallocation of random state buffers config.random_state_prealloc = 4; #endif memset(&application, 0, sizeof(application)); application.name = string_const(STRING_CONST("Foundation library test suite")); application.short_name = string_const(STRING_CONST("test_all")); application.company = string_const(STRING_CONST("Rampant Pixels")); application.version = foundation_version(); application.flags = APPLICATION_UTILITY; application.exception_handler = test_exception_handler; log_set_suppress(0, ERRORLEVEL_INFO); #if (FOUNDATION_PLATFORM_IOS || FOUNDATION_PLATFORM_ANDROID) && BUILD_ENABLE_LOG log_set_handler(test_log_handler); #endif #if !FOUNDATION_PLATFORM_IOS && !FOUNDATION_PLATFORM_ANDROID && !FOUNDATION_PLATFORM_PNACL _test_should_start = true; #endif ret = foundation_initialize(memory_system_malloc(), application, config); #if BUILD_MONOLITHIC //For monolithic process test if (string_array_find(cmdline, array_size(cmdline), STRING_CONST("wait for kill")) >= 0) { while (true) thread_sleep(100); } test_set_suitable_working_directory(); #endif return ret; }
DECLARE_TEST(exception, assert_handler) { EXPECT_EQ(assert_handler(), 0); assert_set_handler(handle_assert); EXPECT_EQ(assert_handler(), handle_assert); log_enable_stdout(false); EXPECT_EQ(assert_report(1, STRING_CONST("condition"), STRING_CONST("file"), 2, STRING_CONST("msg")), 1234); log_enable_stdout(true); EXPECT_EQ(assert_handler(), handle_assert); EXPECT_EQ(handled_context, 1); EXPECT_STRINGEQ(string(handled_condition, string_length(handled_condition)), string_const(STRING_CONST("condition"))); EXPECT_STRINGEQ(string(handled_file, string_length(handled_file)), string_const(STRING_CONST("file"))); EXPECT_EQ(handled_line, 2); EXPECT_STRINGEQ(string(handled_msg, string_length(handled_msg)), string_const(STRING_CONST("msg"))); assert_set_handler(0); EXPECT_EQ(assert_handler(), 0); #if BUILD_ENABLE_LOG _global_log_handler = log_handler(); log_set_handler(handle_log); #endif log_enable_stdout(false); EXPECT_EQ(assert_report_formatted(1, STRING_CONST("assert_report_formatted"), STRING_CONST("file"), 2, STRING_CONST("%.*s"), 3, "msg"), 1); log_enable_stdout(true); EXPECT_EQ(error(), ERROR_ASSERT); #if BUILD_ENABLE_LOG EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("assert_report_formatted"), 0) != STRING_NPOS); EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("msg"), 0) != STRING_NPOS); log_enable_stdout(false); log_set_suppress(HASH_TEST, ERRORLEVEL_NONE); #if BUILD_ENABLE_DEBUG_LOG log_debugf(HASH_TEST, STRING_CONST("%s"), #else log_infof(HASH_TEST, STRING_CONST("%s"), #endif "To test log handler and memory handling this test will print " "a really long log line with complete nonsense. Log handlers only occur for non-suppressed " "log levels, which is why this will be visible. However, it will not be printed to stdout. " "Lorem ipsum dolor sit amet, an quas vivendum sed, in est summo conclusionemque, an est nulla nonumy option. " "Malorum invidunt et mel, mei et hinc adolescens, eu velit deleniti urbanitas cum. Ei pericula omittantur duo, " "eam ei malis pertinacia, eum hinc dictas et. Duo et velit dolorem explicari, an tacimates abhorreant qui, " "esse possit intellegat ad vis. Eros populo numquam pro ea. Eius altera volumus duo ex, offendit comprehensam " "sit te. Ea facete nostrum fabellas sea. Vel ea rebum ridens quodsi, etiam urbanitas mea an. Ornatus commune et his, " "quo habeo denique an, id his amet diceret. Eam ei essent denique, cu quaestio perpetua vim. Mei utamur maluisset ex, " "iriure tritani eu per. Pro at rebum maluisset, nec ei eirmod scaevola consulatu, ius in meis patrioque. Vis at summo " "ancillae omnesque, inani moderatius delicatissimi qui an. Et illum vocibus eum, aliquando intellegat ex ius. Ius at " "tation veritus. Scripta reprehendunt at sed. Hinc idque mollis in cum, at elit habemus civibus eam, sea et modus " "eripuit. Alii ipsum electram id vel, mei alterum percipitur cu. Pro cu minim erant graecis, no vis tation nominavi " "imperdiet, mei affert probatus ut. Quo veri modus ad, solet nostrud atomorum ius ea. Everti aliquid ne usu, populo " "sapientem pro te. Persecuti definitionem qui ei, dicit dicunt ea quo. Sed minimum copiosae ei, pri dicat possit " "urbanitas eu. Tritani interesset theophrastus id sit, phaedrum facilisis his eu. Dictas accusam eu quo. Ea democritum " "consetetur vel. Iudicabit definitionem est eu, oportere temporibus at nec." ); log_set_suppress(HASH_TEST, ERRORLEVEL_DEBUG); log_enable_stdout(true); EXPECT_TRUE(string_find_string(handled_log, string_length(handled_log), STRING_CONST("Lorem ipsum"), 0) != STRING_NPOS); log_set_handler(_global_log_handler); #endif return 0; }