1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#include <cstdio>
#include <cstring>
#include "HCheckConfig.h"
#include "Highs.h"
#include "catch.hpp"
const bool dev_run = false;
const HighsInt kLogBufferSize = kIoBufferSize;
const HighsInt kLogUserCallbackNoData = -1;
const HighsInt kLogUserCallbackData = 99;
char alt_printed_log[kLogBufferSize];
using std::memset;
using std::strcmp;
using std::strcpy;
using std::strlen;
using std::strncmp;
using std::strstr;
// Callback that saves message for comparison
static void myLogCallback(HighsLogType type, const char* message,
void* user_log_callback_data) {
strcpy(alt_printed_log, message);
}
// Callback that provides user logging
static void userLogCallback(HighsLogType type, const char* message,
void* user_log_callback_data) {
// Extract local_callback_data from user_log_callback_data unless it
// is nullptr
const int local_callback_data =
user_log_callback_data
? static_cast<int>(reinterpret_cast<intptr_t>(user_log_callback_data))
: kLogUserCallbackNoData;
if (user_log_callback_data) {
REQUIRE(local_callback_data == kLogUserCallbackData);
} else {
REQUIRE(local_callback_data == kLogUserCallbackNoData);
}
if (dev_run) printf("userLogCallback(%2d): %s", local_callback_data, message);
}
TEST_CASE("run-callback", "[highs_io]") {
// Uses userLogCallback to start logging lines with
// "userLogCallback(kLogUserCallbackNoData): " since
// Highs::setLogCallback has no second argument so
// user_log_callback_data will be nullptr
std::string filename = std::string(HIGHS_DIR) + "/check/instances/avgas.mps";
Highs highs;
if (!dev_run) highs.setOptionValue("output_flag", false);
// highs.setLogCallback(userLogCallback);
highs.readModel(filename);
highs.run();
}
TEST_CASE("run-callback-data", "[highs_io]") {
// Uses userLogCallback to start logging lines with
// "userLogCallback(kLogUserCallbackData): " since
// Highs::setLogCallback has second argument
// p_user_log_callback_data
std::string filename = std::string(HIGHS_DIR) + "/check/instances/avgas.mps";
int user_log_callback_data = kLogUserCallbackData;
void* p_user_log_callback_data =
reinterpret_cast<void*>(static_cast<intptr_t>(user_log_callback_data));
Highs highs;
if (!dev_run) highs.setOptionValue("output_flag", false);
// deprecated
// highs.setLogCallback(userLogCallback, p_user_log_callback_data);
highs.readModel(filename);
highs.run();
}
TEST_CASE("log-callback", "[highs_io]") {
bool output_flag = true;
bool log_to_console = false;
HighsInt log_dev_level = kHighsLogDevLevelInfo;
HighsLogOptions log_options;
log_options.log_stream = stdout;
log_options.output_flag = &output_flag;
log_options.log_to_console = &log_to_console;
log_options.log_dev_level = &log_dev_level;
log_options.user_log_callback = myLogCallback;
highsLogDev(log_options, HighsLogType::kInfo, "Hi %s!", "HiGHS");
if (dev_run) printf("Log callback yields \"%s\"\n", alt_printed_log);
REQUIRE(strcmp(alt_printed_log, "Hi HiGHS!") == 0);
// Check that nothing is printed if the type is VERBOSE when
// log_dev_level is kHighsLogDevLevelInfo;
*alt_printed_log = '\0';
highsLogDev(log_options, HighsLogType::kVerbose, "Hi %s!", "HiGHS");
REQUIRE(*alt_printed_log == '\0');
{
char long_message[sizeof(alt_printed_log)];
memset(long_message, 'H', sizeof(long_message));
long_message[sizeof(long_message) - 2] = '\0';
long_message[sizeof(long_message) - 1] = '\n';
highsLogDev(log_options, HighsLogType::kInfo, long_message);
if (dev_run) printf("Log callback yields \"%s\"\n", alt_printed_log);
REQUIRE(strncmp(alt_printed_log, "HHHH", 4) == 0);
REQUIRE(strlen(alt_printed_log) <= sizeof(alt_printed_log));
}
highsLogUser(log_options, HighsLogType::kInfo, "Hello %s!\n", "HiGHS");
REQUIRE(strlen(alt_printed_log) > 9);
REQUIRE(strcmp(alt_printed_log, "Hello HiGHS!\n") == 0);
{
char long_message[sizeof(alt_printed_log)];
memset(long_message, 'H', sizeof(long_message));
long_message[sizeof(long_message) - 2] = '\0';
long_message[sizeof(long_message) - 1] = '\n';
highsLogUser(log_options, HighsLogType::kWarning, long_message);
if (dev_run) printf("Log callback yields \"%s\"\n", alt_printed_log);
REQUIRE(strstr(alt_printed_log, "HHHH") != nullptr);
REQUIRE(strlen(alt_printed_log) <= sizeof(alt_printed_log));
}
}
|