Exemplo n.º 1
0
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);
}
Exemplo n.º 3
0
  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();
  }