TEST(LogFileOutput, startup_truncation) { const char* filename = "start-truncate-test"; const char* archived_filename = "start-truncate-test.0"; delete_file(filename); delete_file(archived_filename); // Use the same log file twice and expect it to be overwritten/truncated init_log_file(filename, "filecount=0"); ASSERT_TRUE(file_exists(filename)) << "configured logging to file '" << filename << "' but file was not found"; init_log_file(filename, "filecount=0"); ASSERT_TRUE(file_exists(filename)) << "configured logging to file '" << filename << "' but file was not found"; EXPECT_FALSE(file_exists(archived_filename)) << "existing log file was not properly truncated when filecount was 0"; // Verify that the file was really truncated and not just appended EXPECT_TRUE(file_contains_substring(filename, LOG_TEST_STRING_LITERAL)); const char* repeated[] = { LOG_TEST_STRING_LITERAL, LOG_TEST_STRING_LITERAL }; EXPECT_FALSE(file_contains_substrings_in_order(filename, repeated)) << "log file " << filename << " appended rather than truncated"; delete_file(filename); delete_file(archived_filename); }
TEST(LogTagSetDescriptions, command_line_help) { const char* filename = "logtagset_descriptions"; FILE* fp = fopen(filename, "w+"); ASSERT_NE((void*)NULL, fp); LogConfiguration::print_command_line_help(fp); fclose(fp); for (LogTagSetDescription* d = tagset_descriptions; d->tagset != NULL; d++) { char expected[1 * K]; d->tagset->label(expected, sizeof(expected), "+"); jio_snprintf(expected + strlen(expected), sizeof(expected) - strlen(expected), ": %s", d->descr); EXPECT_TRUE(file_contains_substring(filename, expected)) << "missing log tag set descriptions in -Xlog:help output"; } delete_file(filename); }
std::string unity_global::load_toolkit(std::string soname, std::string module_subpath) { // rewrite "local" protocol std::string protocol = fileio::get_protocol(soname); if (protocol == "local") { soname = fileio::remove_protocol(soname); } so_registration_list regentry; regentry.original_soname = soname; logstream(LOG_INFO) << "Attempt loading of " << sanitize_url(soname) << std::endl; // see if the file exists and whether we need to donwnload it if (fileio::try_to_open_file(soname) == false) { return "Unable to open file " + sanitize_url(soname); } if (protocol != "") { // there is a protocol associated. We need to copy this file to local // issue a copy to copy it to the local temp directory std::string tempname = get_temp_name(); fileio::copy(soname, tempname); soname = tempname; } if (!file_contains_substring(soname, "get_toolkit_function_registration") && !file_contains_substring(soname, "get_toolkit_class_registration")) { return soname + " is not a valid extension"; } // get the base name of the shared library (without the .so) std::string modulename = fileio::get_filename(regentry.original_soname); std::vector<std::string> split_names; boost::algorithm::split(split_names, modulename, boost::is_any_of(".")); if (split_names.size() == 0) return "Invalid filename"; if (module_subpath.empty()) { regentry.modulename = split_names[0]; } else if (module_subpath == "..") { regentry.modulename = ""; } else { regentry.modulename = module_subpath + "." + split_names[0]; } // goody. now for the dl loading #ifndef _WIN32 void* dl = dlopen(soname.c_str(), RTLD_NOW | RTLD_LOCAL); #else void *dl = (void *)LoadLibrary(soname.c_str()); #endif logstream(LOG_INFO) << "Library load of " << sanitize_url(soname) << std::endl; regentry.effective_soname = soname; regentry.dl = dl; // check for failure if (dl == NULL) { #ifndef _WIN32 char* err = dlerror(); // I think we need to copy this out early std::string ret = err; logstream(LOG_ERROR) << "Unable to load " << sanitize_url(soname) << ": " << ret << std::endl; if (err) return ret; else return "dlopen failed due to an unknown error"; #else std::string ret = get_last_err_str(GetLastError()); logstream(LOG_ERROR) << "Unable to load " << sanitize_url(soname) << ": " << ret << std::endl; if (!ret.empty()) return ret; else return "LoadLibrary failed due to an unknown error"; #endif } /**************************************************************************/ /* */ /* Function Registration */ /* */ /**************************************************************************/ // get the registration symbols std::vector<std::string> toolkit_function_reg_names {"get_toolkit_function_registration", "_Z33get_toolkit_function_registrationv", "__Z33get_toolkit_function_registrationv"}; get_toolkit_function_registration_type get_toolkit_function_registration = nullptr; for (auto reg_name : toolkit_function_reg_names) { get_toolkit_function_registration = reinterpret_cast<get_toolkit_function_registration_type> ( #ifndef _WIN32 dlsym(dl, reg_name.c_str()) #else (void *)GetProcAddress((HMODULE)dl, reg_name.c_str()) #endif ); if (get_toolkit_function_registration != nullptr) break; } // register functions if (get_toolkit_function_registration) { auto functions = (*get_toolkit_function_registration)(); for (auto& fn: functions) { if (!regentry.modulename.empty()) { fn.name = regentry.modulename + "." + fn.name; } fn.description["file"] = regentry.original_soname; logstream(LOG_INFO) << "Adding function: " << fn.name << std::endl; regentry.functions.push_back(fn.name); } toolkit_functions->register_toolkit_function(functions); } /**************************************************************************/ /* */ /* Class Registration */ /* */ /**************************************************************************/ std::vector<std::string> toolkit_class_reg_names {"get_toolkit_class_registration", "_Z30get_toolkit_class_registrationv", "__Z30get_toolkit_class_registrationv"}; get_toolkit_class_registration_type get_toolkit_class_registration = nullptr; for (auto reg_name : toolkit_class_reg_names) { get_toolkit_class_registration = reinterpret_cast<get_toolkit_class_registration_type> ( #ifndef _WIN32 dlsym(dl, reg_name.c_str()) #else (void *)GetProcAddress((HMODULE)dl, reg_name.c_str()) #endif ); if (get_toolkit_class_registration != nullptr) break; } // register classes if (get_toolkit_class_registration) { auto class_reg = (*get_toolkit_class_registration)(); for (auto& cl: class_reg) { if (!regentry.modulename.empty()) { cl.name = regentry.modulename + "." + cl.name; } cl.description["file"] = regentry.original_soname; logstream(LOG_INFO) << "Adding class : " << cl.name << std::endl; regentry.functions.push_back(cl.name); } classes->register_toolkit_class(class_reg); } if (regentry.functions.empty() && regentry.classes.empty()) { // nothing has been registered! unload the dl #ifndef _WIN32 dlclose(dl); #else FreeLibrary((HMODULE)dl); #endif return "No functions or classes registered by " + sanitize_url(soname); } // note that it is possible to load a toolkit multiple times. // It is not safe to unload previously loaded toolkits since I may have // a reference to it (for instance a class). We just keep loading over // and hope for the best. // store and remember the dlhandle and what was registered; dynamic_loaded_toolkits[regentry.original_soname] = regentry; return std::string(); }