DECLARE_TEST(profile, thread) { thread_t thread[32]; int ith; uint64_t frame; error_t err = error(); _test_profile_offset = 0; atomic_store32(&_test_profile_output_counter, 0); profile_initialize(STRING_CONST("test_profile"), _test_profile_buffer, 30000); profile_enable(true); profile_set_output_wait(1); log_enable_stdout(false); for (ith = 0; ith < 32; ++ith) thread_initialize(&thread[ith], _profile_fail_thread, 0, STRING_CONST("profile_thread"), THREAD_PRIORITY_NORMAL, 0); for (ith = 0; ith < 32; ++ith) thread_start(&thread[ith]); test_wait_for_threads_startup(thread, 32); for (frame = 0; frame < 1000; ++frame) { thread_sleep(16); profile_end_frame(frame); } for (ith = 0; ith < 32; ++ith) thread_signal(&thread[ith]); test_wait_for_threads_finish(thread, 32); for (ith = 0; ith < 32; ++ith) thread_finalize(&thread[ith]); log_enable_stdout(true); err = error(); thread_sleep(1000); profile_enable(false); profile_finalize(); #if BUILD_ENABLE_PROFILE EXPECT_INTGT(atomic_load32(&_test_profile_output_counter), 0); //TODO: Implement parsing output results #else EXPECT_INTEQ(atomic_load32(&_test_profile_output_counter), 0); #endif EXPECT_INTEQ(err, ERROR_NONE); return 0; }
DECLARE_TEST(exception, exception_handler) { int result; if (system_debugger_attached() || (system_platform() == PLATFORM_PNACL)) return 0; //Don't do exception tests with debugger attached _exception_handler_called = false; log_enable_stdout(false); result = exception_try(raise_abort, 0, test_local_exception_handler, STRING_CONST("raise_abort")); log_enable_stdout(true); EXPECT_EQ(result, FOUNDATION_EXCEPTION_CAUGHT); EXPECT_TRUE(_exception_handler_called); return 0; }
DECLARE_TEST(environment, workingdir) { char buffer[BUILD_MAX_PATHLEN]; string_const_t working_dir = environment_current_working_directory(); string_const_t new_working_dir = path_directory_name(STRING_ARGS(working_dir)); string_t working_dir_copy = string_clone(STRING_ARGS(working_dir)); string_t new_working_dir_copy; if (string_equal(STRING_ARGS(working_dir), STRING_CONST("/"))) { string_t tmpwork = path_make_temporary(buffer, sizeof(buffer)); new_working_dir = path_directory_name(STRING_ARGS(tmpwork)); } new_working_dir_copy = string_clone(STRING_ARGS(new_working_dir)); new_working_dir = string_to_const(new_working_dir_copy); EXPECT_CONSTSTRINGNE(working_dir, new_working_dir); #if FOUNDATION_PLATFORM_PNACL EXPECT_FALSE(environment_set_current_working_directory(STRING_ARGS(new_working_dir))); EXPECT_CONSTSTRINGEQ(environment_current_working_directory(), string_const(STRING_ARGS(working_dir_copy))); #else EXPECT_TRUE(environment_set_current_working_directory(STRING_ARGS(new_working_dir))); EXPECT_CONSTSTRINGEQ(environment_current_working_directory(), new_working_dir); environment_set_current_working_directory(STRING_ARGS(working_dir_copy)); EXPECT_CONSTSTRINGEQ(environment_current_working_directory(), string_const(STRING_ARGS(working_dir_copy))); { log_enable_stdout(false); bool ret = environment_set_current_working_directory(STRING_CONST("/invalid/path/which/does/not/exist")); log_enable_stdout(true); EXPECT_FALSE(ret); } EXPECT_CONSTSTRINGEQ(environment_current_working_directory(), string_const(STRING_ARGS(working_dir_copy))); #endif string_deallocate(new_working_dir_copy.str); string_deallocate(working_dir_copy.str); return 0; }
DECLARE_TEST(exception, exception_thread) { thread_t thread; if (system_debugger_attached() || (system_platform() == PLATFORM_PNACL)) return 0; //Don't do exception tests with debugger attached _exception_handler_called = false; exception_set_handler(test_local_exception_handler, STRING_CONST("thread_raise_abort")); log_enable_stdout(false); thread_initialize(&thread, thread_raise_abort, 0, STRING_CONST("raise_abort"), THREAD_PRIORITY_NORMAL, 0); thread_start(&thread); while (!thread_is_started(&thread)) thread_sleep(100); thread_finalize(&thread); log_enable_stdout(true); EXPECT_TRUE(_exception_handler_called); return 0; }
DECLARE_TEST(error, output) { #if BUILD_ENABLE_LOG error_handler_fn handler_error = error_handler(); log_handler_fn handler_log = log_handler(); string_const_t shortmsg = string_const(STRING_CONST("Short message with prefix")); string_const_t longmsg = string_const(STRING_CONST("Longer message which should be output without a prefix")); error_set_handler(ignore_error_handler); log_set_handler(log_verify_handler); log_enable_stdout(false); EXPECT_EQ(log_stdout(), false); log_warn(HASH_TEST, WARNING_SUSPICIOUS, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(log_stdout(), true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("WARNING [suspicious]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_warn(HASH_TEST, (warning_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("WARNING [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_warn(HASH_TEST, WARNING_SYSTEM_CALL_FAIL, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_WARNING); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error(HASH_TEST, ERROR_DEPRECATED, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("ERROR [deprecated]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error(HASH_TEST, (error_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("ERROR [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_error(HASH_TEST, ERROR_INVALID_VALUE, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_ERROR); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_panic(HASH_TEST, ERROR_DEPRECATED, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("PANIC [deprecated]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_panic(HASH_TEST, (error_t)0x1000, STRING_ARGS(shortmsg)); log_enable_stdout(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_GE(_last_log_length, shortmsg.length); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(shortmsg), 0), 0); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("PANIC [4096]"), 0), STRING_NPOS); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_prefix(false); log_enable_stdout(false); log_panic(HASH_TEST, ERROR_INVALID_VALUE, STRING_ARGS(longmsg)); log_enable_stdout(true); log_enable_prefix(true); EXPECT_EQ(_last_log_context, HASH_TEST); EXPECT_EQ(_last_log_severity, ERRORLEVEL_PANIC); EXPECT_NE(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), STRING_NPOS); EXPECT_GT(string_find_string(_last_log_msg, _last_log_length, STRING_ARGS(longmsg), 0), 0); # if BUILD_ENABLE_ERROR_CONTEXT error_context_push(STRING_CONST("one"), STRING_CONST("dataone")); error_context_push(STRING_CONST("two"), STRING_CONST("datatwo")); error_context_push(STRING_CONST("three"), STRING_CONST("datathree")); _last_log_context = 0; _last_log_severity = ERRORLEVEL_NONE; _last_log_msg = nullptr; _last_log_length = 0; log_enable_stdout(false); log_error_context(HASH_TEST, ERRORLEVEL_INFO); log_enable_stdout(true); error_context_pop(); error_context_pop(); error_context_pop(); EXPECT_SIZEEQ(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When one: dataone"), 0), STRING_NPOS); EXPECT_SIZEEQ(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When two: datatwo"), 0), STRING_NPOS); EXPECT_SIZENE(string_find_string(_last_log_msg, _last_log_length, STRING_CONST("When three: datathree"), 0), STRING_NPOS); # endif log_set_handler(handler_log); error_set_handler(handler_error); #endif return 0; }
DECLARE_TEST(objectmap, store) { objectmap_t* map; object_base_t first; object_base_t second; object_base_t third; map = objectmap_allocate(129); memset(&first, 0, sizeof(first)); memset(&second, 0, sizeof(first)); memset(&third, 0, sizeof(first)); atomic_store32(&first.ref, 1); atomic_store32(&second.ref, 1); atomic_store32(&third.ref, 1); first.id = 1; second.id = 2; third.id = 3; EXPECT_EQ(objectmap_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, 1), 0); first.id = objectmap_reserve(map); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); second.id = objectmap_reserve(map); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); objectmap_set(map, first.id, &first); EXPECT_EQ(objectmap_lookup(map, first.id), &first); EXPECT_EQ(objectmap_raw_lookup(map, 0), &first); EXPECT_EQ(objectmap_lookup(map, second.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); objectmap_set(map, second.id, &second); EXPECT_EQ(objectmap_lookup(map, first.id), &first); EXPECT_EQ(objectmap_raw_lookup(map, 0), &first); EXPECT_EQ(objectmap_lookup(map, second.id), &second); EXPECT_EQ(objectmap_raw_lookup(map, 1), &second); objectmap_free(map, first.id); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), &second); EXPECT_EQ(objectmap_raw_lookup(map, 1), &second); objectmap_free(map, first.id); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), &second); EXPECT_EQ(objectmap_raw_lookup(map, 1), &second); objectmap_free(map, second.id); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); objectmap_deallocate(map); //Size should be clamped to three map = objectmap_allocate(1); EXPECT_EQ(objectmap_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, 1), 0); first.id = objectmap_reserve(map); EXPECT_TYPENE(first.id, 0, object_t, PRIx64); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); second.id = objectmap_reserve(map); EXPECT_TYPENE(second.id, 0, object_t, PRIx64); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); third.id = objectmap_reserve(map); EXPECT_TYPENE(third.id, 0, object_t, PRIx64); EXPECT_EQ(objectmap_lookup(map, first.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup(map, second.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); EXPECT_EQ(objectmap_lookup(map, third.id), 0); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); objectmap_set(map, first.id, &first); objectmap_set(map, second.id, &second); objectmap_set(map, third.id, &third); log_enable_stdout(false); EXPECT_TYPEEQ(objectmap_reserve(map), 0, object_t, PRIx64); EXPECT_TYPEEQ(objectmap_reserve(map), 0, object_t, PRIx64); log_enable_stdout(true); objectmap_free(map, first.id); objectmap_free(map, second.id); //Leak one object //objectmap_free(map, third.id); EXPECT_EQ(objectmap_lookup_ref(map, first.id), nullptr); EXPECT_EQ(objectmap_raw_lookup(map, 0), 0); EXPECT_EQ(objectmap_lookup_ref(map, second.id), nullptr); EXPECT_EQ(objectmap_raw_lookup(map, 1), 0); EXPECT_NE(objectmap_lookup_ref(map, third.id), nullptr); EXPECT_NE(objectmap_raw_lookup(map, 2), 0); log_enable_stdout(false); objectmap_deallocate(map); log_enable_stdout(true); return 0; }
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; }