Merge branch 'features/new-logging' into bleeding

This commit is contained in:
Snaipe 2016-02-18 00:25:45 +01:00
commit e53f3892d5
23 changed files with 431 additions and 79 deletions

View file

@ -9,6 +9,7 @@ Criterion
starter
assert
hooks
logging
env
output
parameterized

61
doc/logging.rst Normal file
View file

@ -0,0 +1,61 @@
Logging messages
================
Sometimes, it might be useful to print some output from within a test
or fixture -- and while this can be done trivially with a ``printf``,
it doesn't integrate well with the current output, nor does it work
*at all* when the process is testing a redirected stdout.
For these cases, Criterion exposes a logging facility:
.. code-block:: c
#include <criterion/criterion.h>
#include <criterion/logging.h>
Test(suite_name, test_name) {
cr_log_info("This is an informational message. They are not displayed "
"by default.");
cr_log_warn("This is a warning. They indicate some possible malfunction "
"or misconfiguration in the test.");
cr_log_error("This is an error. They indicate serious problems and "
"are usually shown before the test is aborted.");
}
``cr_log_info``, ``cr_log_warn`` and ``cr_log_error`` are all macros expanding
to a call to the ``cr_log`` function. All of them take a mandatory format string,
followed by optional parameters; for instance:
.. code-block:: c
cr_log_info("%d + %d = %d", 1, 2, 3);
If using C++, the output stream objects ``info``, ``warn`` and ``error`` are
defined within the ``criterion::logging`` namespace, and can be used in
conjunction with ``operator<<``:
.. code-block:: c++
#include <criterion/criterion.h>
#include <criterion/logging.h>
using criterion::logging::info;
using criterion::logging::warn;
using criterion::logging::error;
Test(suite_name, test_name) {
info << "This is an informational message. "
<< "They are not displayed by default."
<< std::flush;
warn << "This is a warning. "
<< "They indicate some possible malfunction "
<< "or misconfiguration in the test."
<< std::flush;
error << "This is an error. "
<< "They indicate serious problems and "
<< "are usually shown before the test is aborted."
<< std::flush;
}
Note that empty messages are ignored, and newlines in the log message splits
the passed string into as many messages are there are lines.

View file

@ -0,0 +1,35 @@
/*
* The MIT License (MIT)
*
* Copyright © 2015-2016 Franklin "Snaipe" Mathieu <http://snai.pe/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_DEPRECATION_H_
# define CRITERION_INTERNAL_DEPRECATION_H_
# define CR_DEPRECATED(Msg) CR_DEPRECATED_(message (Msg))
# ifdef _MSC_VER
# define CR_DEPRECATED_(Msg) __pragma(Msg)
# else
# define CR_DEPRECATED_(Msg) _Pragma(#Msg)
# endif
#endif /* !CRITERION_INTERNAL_DEPRECATION_H_ */

View file

@ -24,17 +24,13 @@
#ifndef CRITERION_LOGGING_H_
# define CRITERION_LOGGING_H_
# ifdef __cplusplus
# include <cstdarg>
using std::va_list;
# else
# include <stdbool.h>
# include <stdarg.h>
# endif
# include "internal/common.h"
# include "internal/ordered-set.h"
# include "internal/deprecation.h"
# include "stats.h"
CR_BEGIN_C_API
enum criterion_logging_level {
CRITERION_INFO = 1,
CRITERION_IMPORTANT,
@ -42,66 +38,18 @@ enum criterion_logging_level {
CRITERION_LOG_LEVEL_QUIET = 1 << 30,
};
enum criterion_logging_prefix {
CRITERION_LOGGING_PREFIX_DASHES,
CRITERION_LOGGING_PREFIX_EQUALS,
CRITERION_LOGGING_PREFIX_RUN,
CRITERION_LOGGING_PREFIX_SKIP,
CRITERION_LOGGING_PREFIX_PASS,
CRITERION_LOGGING_PREFIX_FAIL,
CRITERION_LOGGING_PREFIX_ERR,
enum criterion_severity {
CR_LOG_INFO,
CR_LOG_WARNING,
CR_LOG_ERROR,
};
struct criterion_prefix_data {
const char *prefix;
const char *color;
};
# ifdef CRITERION_LOGGING_COLORS
# define CRIT_COLOR_NORMALIZE(Str) (criterion_options.use_ascii ? "" : Str)
# define CRIT_FG_BOLD "\33[0;1m"
# define CRIT_FG_RED "\33[0;31m"
# define CRIT_FG_GREEN "\33[0;32m"
# define CRIT_FG_GOLD "\33[0;33m"
# define CRIT_FG_BLUE "\33[0;34m"
# define CRIT_RESET "\33[0m"
# define CR_FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD)
# define CR_FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED)
# define CR_FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN)
# define CR_FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD)
# define CR_FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE)
# define CR_RESET CRIT_COLOR_NORMALIZE(CRIT_RESET)
# endif
CR_BEGIN_C_API
extern const struct criterion_prefix_data g_criterion_logging_prefixes[];
# define CRITERION_PREFIX_DASHES (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_DASHES])
# define CRITERION_PREFIX_EQUALS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_EQUALS])
# define CRITERION_PREFIX_RUN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_RUN ])
# define CRITERION_PREFIX_SKIP (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_SKIP ])
# define CRITERION_PREFIX_PASS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_PASS ])
# define CRITERION_PREFIX_FAIL (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_FAIL ])
# define CRITERION_PREFIX_ERR (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_ERR ])
CR_API void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args);
CR_FORMAT(printf, 3, 4)
CR_API void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...);
CR_FORMAT(printf, 2, 3)
CR_API void criterion_log(enum criterion_logging_level level, const char *msg, ...);
CR_API void cr_log(enum criterion_severity severity, const char *msg, ...);
# define criterion_info(...) criterion_log(CRITERION_INFO, __VA_ARGS__)
# define criterion_important(...) criterion_log(CRITERION_IMPORTANT, __VA_ARGS__)
# define criterion_pinfo(...) criterion_plog(CRITERION_INFO, __VA_ARGS__)
# define criterion_pimportant(...) criterion_plog(CRITERION_IMPORTANT, __VA_ARGS__)
# define criterion_perror(...) criterion_plog(CRITERION_IMPORTANT, CRITERION_PREFIX_ERR, __VA_ARGS__)
# define cr_log_info(...) cr_log(CR_LOG_INFO, __VA_ARGS__)
# define cr_log_warn(...) cr_log(CR_LOG_WARNING, __VA_ARGS__)
# define cr_log_error(...) cr_log(CR_LOG_ERROR, __VA_ARGS__)
struct criterion_logger {
void (*log_pre_all )(struct criterion_test_set *set);
@ -119,12 +67,63 @@ struct criterion_logger {
void (*log_post_fini )(struct criterion_test_stats *stats);
void (*log_post_suite )(struct criterion_suite_stats *stats);
void (*log_post_all )(struct criterion_global_stats *stats);
void (*log_message )(enum criterion_severity, const char *msg);
};
extern struct criterion_logger normal_logging;
CR_END_C_API
#define CR_NORMAL_LOGGING (&normal_logging)
# define CR_NORMAL_LOGGING (&normal_logging)
# ifdef __cplusplus
# include <sstream>
namespace criterion { namespace logging {
static void (*const log)(enum criterion_severity, const char *, ...) = cr_log;
class streambuf : public std::stringbuf {
public:
streambuf(enum criterion_severity severity__)
: std::stringbuf(), severity__(severity__)
{}
virtual int sync() override {
criterion::logging::log(severity__, "%s", str().c_str());
str(std::string());
return 0;
}
private:
enum criterion_severity severity__;
};
class stream : public std::ostream {
public:
stream(enum criterion_severity severity__)
: std::ostream(&buf), buf(severity__)
{}
private:
streambuf buf;
};
stream info { CR_LOG_INFO };
stream warn { CR_LOG_WARNING };
stream error { CR_LOG_ERROR };
}}
# endif
// Deprecated old logging system, schedule removal for 3.0
# ifndef CRITERION_NO_COMPAT
# define criterion_log(_, ...) CR_DEPRECATED("criterion_log is deprecated, please use cr_log instead.") cr_log_info(__VA_ARGS__)
# define criterion_info(...) CR_DEPRECATED("criterion_info is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pinfo(_, ...) CR_DEPRECATED("criterion_pinfo is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_important(...) CR_DEPRECATED("criterion_important is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pimportant(_, ...) CR_DEPRECATED("criterion_pimportant is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_perror(...) CR_DEPRECATED("criterion_perror is deprecated, please use cr_log_error instead.") cr_log_error(__VA_ARGS__)
# endif /* !CRITERION_NO_COMPAT */
#endif /* !CRITERION_LOGGING_H_ */

View file

@ -22,7 +22,7 @@ set(SAMPLES
timeout.c
redirect.c
parameterized.c
log.c
)
if (CMAKE_CXX_COMPILER_WORKS)
@ -37,6 +37,7 @@ if (CMAKE_CXX_COMPILER_WORKS)
simple.cc
redirect.cc
parameterized.cc
log.cc
)
endif ()

15
samples/log.c Normal file
View file

@ -0,0 +1,15 @@
#include <criterion/criterion.h>
#include <criterion/logging.h>
Test(logging, simple) {
cr_log_info("This is an informational message. They are not displayed "
"by default.");
cr_log_warn("This is a warning. They indicate some possible malfunction "
"or misconfiguration in the test.");
cr_log_error("This is an error. They indicate serious problems and "
"are usually shown before the test is aborted.");
}
Test(logging, format) {
cr_log_info("Log messages are %s.", "printf-formatted strings");
}

18
samples/log.cc Normal file
View file

@ -0,0 +1,18 @@
#include <criterion/criterion.h>
#include <criterion/logging.h>
using criterion::logging::info;
using criterion::logging::warn;
using criterion::logging::error;
Test(logging, stream) {
info << "This is an informational message. They are not displayed "
"by default."
<< std::endl;
warn << "This is a warning. They indicate some possible malfunction "
"or misconfiguration in the test."
<< std::endl;
error << "This is an error. They indicate serious problems and "
"are usually shown before the test is aborted."
<< std::endl;
}

View file

@ -53,6 +53,7 @@ set(SOURCE_FILES
src/io/xml.c
src/io/json.c
src/log/logging.c
src/log/logging.h
src/log/normal.c
src/string/i18n.c
src/string/i18n.h
@ -117,6 +118,7 @@ set(INTERFACE_FILES
include/criterion/internal/hooks.h
include/criterion/internal/redirect.h
include/criterion/internal/stdio_filebuf.hxx
include/criterion/internal/deprecation.h
)
if (THEORIES)

View file

@ -23,7 +23,7 @@
*/
#include "alloc.h"
#include "internal.h"
#include "criterion/logging.h"
#include "log/logging.h"
#include <stdlib.h>
#ifdef VANILLA_WIN32

View file

@ -23,7 +23,7 @@
*/
#include "kill.h"
#include "internal.h"
#include "criterion/logging.h"
#include "log/logging.h"
#include "core/report.h"
#include "core/stats.h"
#include "io/event.h"

View file

@ -27,7 +27,7 @@
# include <stdio.h>
# include <stdlib.h>
# include "common.h"
# include "criterion/logging.h"
# include "log/logging.h"
struct pipe_handle;
typedef struct pipe_handle s_pipe_handle;

View file

@ -27,8 +27,8 @@
#include "compat/strtok.h"
#include "protocol/protocol.h"
#include "protocol/messages.h"
#include "criterion/logging.h"
#include "criterion/options.h"
#include "log/logging.h"
#include "io/event.h"
#include "report.h"
#include "stats.h"
@ -483,6 +483,8 @@ bool handle_assert(struct server_ctx *sctx, struct client_ctx *ctx, const criter
bool handle_message(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
(void) sctx;
(void) ctx;
(void) msg;
const criterion_protocol_log *lg = &msg->data.value.message;
log(message, (enum criterion_severity) lg->severity, lg->message);
return false;
}

View file

@ -26,9 +26,9 @@
#include <stdlib.h>
#include "criterion/types.h"
#include "criterion/stats.h"
#include "criterion/logging.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
#include "log/logging.h"
#include "report.h"
#include "config.h"
#include "compat/posix.h"

View file

@ -31,7 +31,6 @@
#include "criterion/internal/test.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
#include "criterion/logging.h"
#include "criterion/internal/preprocess.h"
#include "criterion/redirect.h"
#include "protocol/protocol.h"
@ -44,6 +43,7 @@
#include "string/i18n.h"
#include "io/event.h"
#include "io/output.h"
#include "log/logging.h"
#include "runner_coroutine.h"
#include "stats.h"
#include "runner.h"

View file

@ -24,8 +24,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <csptr/smalloc.h>
#include "criterion/logging.h"
#include "criterion/internal/parameterized.h"
#include "log/logging.h"
#include "runner_coroutine.h"
#include "worker.h"
#include "stats.h"

View file

@ -26,9 +26,9 @@
#include <stdlib.h>
#include <string.h>
#include "criterion/stats.h"
#include "criterion/logging.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
#include "log/logging.h"
#include "compat/posix.h"
#include "compat/strtok.h"
#include "compat/time.h"

View file

@ -4,7 +4,7 @@
#include <kvec.h>
#include <errno.h>
#include "criterion/output.h"
#include "criterion/logging.h"
#include "log/logging.h"
#include "string/i18n.h"
typedef const char *const msg_t;

View file

@ -26,9 +26,9 @@
#include <stdlib.h>
#include <string.h>
#include "criterion/stats.h"
#include "criterion/logging.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
#include "log/logging.h"
#include "compat/posix.h"
#include "compat/strtok.h"
#include "compat/time.h"

View file

@ -25,8 +25,13 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "criterion/logging.h"
#include "criterion/criterion.h"
#include "criterion/options.h"
#include "compat/process.h"
#include "log/logging.h"
#include "io/asprintf.h"
#include "protocol/protocol.h"
#include "protocol/messages.h"
#include "string/i18n.h"
#ifdef ENABLE_NLS
@ -45,9 +50,46 @@ const struct criterion_prefix_data g_criterion_logging_prefixes[] = {
[CRITERION_LOGGING_PREFIX_PASS] = { "PASS", CRIT_FG_GREEN },
[CRITERION_LOGGING_PREFIX_FAIL] = { "FAIL", CRIT_FG_RED },
[CRITERION_LOGGING_PREFIX_ERR] = { "ERR ", CRIT_FG_RED },
[CRITERION_LOGGING_PREFIX_WARN] = { "WARN", CRIT_FG_GOLD },
{ NULL, NULL }
};
void criterion_log_noformat(enum criterion_severity severity, const char *msg) {
static const struct criterion_prefix_data *prefixes[] = {
[CR_LOG_INFO] = CRITERION_PREFIX_DASHES,
[CR_LOG_WARNING] = CRITERION_PREFIX_WARN,
[CR_LOG_ERROR] = CRITERION_PREFIX_ERR,
};
static enum criterion_logging_level severity_to_level[] = {
[CR_LOG_INFO] = CRITERION_INFO,
[CR_LOG_WARNING] = CRITERION_IMPORTANT,
[CR_LOG_ERROR] = CRITERION_IMPORTANT,
};
if (severity_to_level[severity] < criterion_options.logging_threshold)
return;
const struct criterion_prefix_data *prefix = prefixes[severity];
if (severity == CR_LOG_ERROR) {
fprintf(stderr, _(ERROR_FORMAT),
CRIT_COLOR_NORMALIZE(prefix->color),
prefix->prefix,
CR_RESET,
CR_FG_RED,
CR_FG_BOLD,
msg,
CR_RESET);
} else {
fprintf(stderr, _(LOG_FORMAT),
CRIT_COLOR_NORMALIZE(prefix->color),
prefix->prefix,
CR_RESET,
msg);
}
fprintf(stderr, "\n");
}
void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...) {
va_list args;
@ -91,3 +133,28 @@ void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list
vfprintf(stderr, msg, args);
}
void cr_log_noformat(enum criterion_severity severity, const char *out) {
criterion_protocol_msg msg = criterion_message(message,
.severity = (criterion_protocol_log_level) severity,
.message = (char *) out);
criterion_message_set_id(msg);
cr_send_to_runner(&msg);
}
void cr_log(enum criterion_severity severity, const char *msg, ...) {
va_list args;
char *out = NULL;
va_start(args, msg);
int res = cr_vasprintf(&out, msg, args);
va_end(args);
if (res == -1) {
cr_log_noformat(CR_LOG_ERROR, "Could not format log message");
abort();
}
cr_log_noformat(severity, out);
free(out);
}

107
src/log/logging.h Normal file
View file

@ -0,0 +1,107 @@
/*
* The MIT License (MIT)
*
* Copyright © 2015-2016 Franklin "Snaipe" Mathieu <http://snai.pe/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef LOGGING_H_
# define LOGGING_H_
# ifdef __cplusplus
# include <cstdarg>
using std::va_list;
# else
# include <stdbool.h>
# include <stdarg.h>
# endif
# include "criterion/logging.h"
enum criterion_logging_prefix {
CRITERION_LOGGING_PREFIX_DASHES,
CRITERION_LOGGING_PREFIX_EQUALS,
CRITERION_LOGGING_PREFIX_RUN,
CRITERION_LOGGING_PREFIX_SKIP,
CRITERION_LOGGING_PREFIX_PASS,
CRITERION_LOGGING_PREFIX_FAIL,
CRITERION_LOGGING_PREFIX_ERR,
CRITERION_LOGGING_PREFIX_WARN,
};
struct criterion_prefix_data {
const char *prefix;
const char *color;
};
# ifdef CRITERION_LOGGING_COLORS
# define CRIT_COLOR_NORMALIZE(Str) (criterion_options.use_ascii ? "" : Str)
# define CRIT_FG_BOLD "\33[0;1m"
# define CRIT_FG_RED "\33[0;31m"
# define CRIT_FG_GREEN "\33[0;32m"
# define CRIT_FG_GOLD "\33[0;33m"
# define CRIT_FG_BLUE "\33[0;34m"
# define CRIT_RESET "\33[0m"
# define CR_FG_BOLD CRIT_COLOR_NORMALIZE(CRIT_FG_BOLD)
# define CR_FG_RED CRIT_COLOR_NORMALIZE(CRIT_FG_RED)
# define CR_FG_GREEN CRIT_COLOR_NORMALIZE(CRIT_FG_GREEN)
# define CR_FG_GOLD CRIT_COLOR_NORMALIZE(CRIT_FG_GOLD)
# define CR_FG_BLUE CRIT_COLOR_NORMALIZE(CRIT_FG_BLUE)
# define CR_RESET CRIT_COLOR_NORMALIZE(CRIT_RESET)
# endif
extern const struct criterion_prefix_data g_criterion_logging_prefixes[];
# define CRITERION_PREFIX_DASHES (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_DASHES])
# define CRITERION_PREFIX_EQUALS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_EQUALS])
# define CRITERION_PREFIX_RUN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_RUN ])
# define CRITERION_PREFIX_SKIP (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_SKIP ])
# define CRITERION_PREFIX_PASS (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_PASS ])
# define CRITERION_PREFIX_FAIL (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_FAIL ])
# define CRITERION_PREFIX_ERR (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_ERR ])
# define CRITERION_PREFIX_WARN (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_WARN ])
# undef criterion_log
# undef criterion_info
# undef criterion_pinfo
# undef criterion_important
# undef criterion_pimportant
# undef criterion_perror
CR_API void criterion_vlog(enum criterion_logging_level level, const char *msg, va_list args);
CR_FORMAT(printf, 3, 4)
CR_API void criterion_plog(enum criterion_logging_level level, const struct criterion_prefix_data *prefix, const char *msg, ...);
CR_FORMAT(printf, 2, 3)
CR_API void criterion_log(enum criterion_logging_level level, const char *msg, ...);
# define criterion_info(...) criterion_log(CRITERION_INFO, __VA_ARGS__)
# define criterion_important(...) criterion_log(CRITERION_IMPORTANT, __VA_ARGS__)
# define criterion_pinfo(...) criterion_plog(CRITERION_INFO, __VA_ARGS__)
# define criterion_pimportant(...) criterion_plog(CRITERION_IMPORTANT, __VA_ARGS__)
# define criterion_perror(...) criterion_plog(CRITERION_IMPORTANT, CRITERION_PREFIX_ERR, __VA_ARGS__)
void cr_log_noformat(enum criterion_severity severity, const char *out);
void criterion_log_noformat(enum criterion_severity severity, const char *msg);
#endif /* !LOGGING_H_ */

View file

@ -27,9 +27,9 @@
#include <stdlib.h>
#include <string.h>
#include "criterion/stats.h"
#include "criterion/logging.h"
#include "criterion/options.h"
#include "criterion/internal/ordered-set.h"
#include "log/logging.h"
#include "compat/posix.h"
#include "compat/strtok.h"
#include "compat/time.h"
@ -233,6 +233,18 @@ void normal_log_test_abort(CR_UNUSED struct criterion_test_stats *stats, const c
free(dup);
}
void normal_log_message(enum criterion_severity severity, const char *msg) {
char *dup = strdup(msg);
char *saveptr = NULL;
char *line = strtok_r(dup, "\n", &saveptr);
do {
if (*line != '\0')
criterion_log_noformat(severity, line);
} while ((line = strtok_r(NULL, "\n", &saveptr)));
free (dup);
}
struct criterion_logger normal_logging = {
.log_pre_all = normal_log_pre_all,
.log_pre_init = normal_log_pre_init,
@ -247,4 +259,5 @@ struct criterion_logger normal_logging = {
.log_post_test = normal_log_post_test,
.log_post_suite = normal_log_post_suite,
.log_post_all = normal_log_post_all,
.log_message = normal_log_message,
};

View file

@ -24,7 +24,7 @@
#include <nanomsg/nn.h>
#include <stdlib.h>
#include "protocol/protocol.h"
#include "criterion/logging.h"
#include "log/logging.h"
#include "io/event.h"
#include "io/asprintf.h"

31
test/cram/log.t Normal file
View file

@ -0,0 +1,31 @@
Testing log messages
$ log.c.bin --verbose
[\x1b[0;34m----\x1b[0m] Criterion v2.2.0 (esc)
[\x1b[0;34m====\x1b[0m] Running \x1b[0;34m2\x1b[0m tests from \x1b[0;33mlogging\x1b[0m: (esc)
[\x1b[0;34mRUN \x1b[0m] logging::format (esc)
[\x1b[0;34m----\x1b[0m] Log messages are printf-formatted strings. (esc)
[\x1b[0;32mPASS\x1b[0m] logging::format (esc)
[\x1b[0;34mRUN \x1b[0m] logging::simple (esc)
[\x1b[0;34m----\x1b[0m] This is an informational message. They are not displayed by default. (esc)
[\x1b[0;33mWARN\x1b[0m] This is a warning. They indicate some possible malfunction or misconfiguration in the test. (esc)
[\x1b[0;31mERR \x1b[0m] \x1b[0;31m\x1b[0;1mThis is an error. They indicate serious problems and are usually shown before the test is aborted.\x1b[0m (esc)
[\x1b[0;32mPASS\x1b[0m] logging::simple (esc)
[\x1b[0;34m====\x1b[0m] \x1b[0;1mSynthesis: Tested: \x1b[0;34m2\x1b[0;1m | Passing: \x1b[0;32m2\x1b[0;1m | Failing: \x1b[0;31m0\x1b[0;1m | Crashing: \x1b[0;31m0\x1b[0;1m \x1b[0m (esc)
$ log.cc.bin --verbose
[\x1b[0;34m----\x1b[0m] Criterion v2.2.0 (esc)
[\x1b[0;34m====\x1b[0m] Running \x1b[0;34m1\x1b[0m test from \x1b[0;33mlogging\x1b[0m: (esc)
[\x1b[0;34mRUN \x1b[0m] logging::stream (esc)
[\x1b[0;34m----\x1b[0m] This is an informational message. They are not displayed by default. (esc)
[\x1b[0;33mWARN\x1b[0m] This is a warning. They indicate some possible malfunction or misconfiguration in the test. (esc)
[\x1b[0;31mERR \x1b[0m] \x1b[0;31m\x1b[0;1mThis is an error. They indicate serious problems and are usually shown before the test is aborted.\x1b[0m (esc)
[\x1b[0;32mPASS\x1b[0m] logging::stream (esc)
[\x1b[0;34m====\x1b[0m] \x1b[0;1mSynthesis: Tested: \x1b[0;34m1\x1b[0;1m | Passing: \x1b[0;32m1\x1b[0;1m | Failing: \x1b[0;31m0\x1b[0;1m | Crashing: \x1b[0;31m0\x1b[0;1m \x1b[0m (esc)
Testing log severity
$ log.c.bin
[\x1b[0;33mWARN\x1b[0m] This is a warning. They indicate some possible malfunction or misconfiguration in the test. (esc)
[\x1b[0;31mERR \x1b[0m] \x1b[0;31m\x1b[0;1mThis is an error. They indicate serious problems and are usually shown before the test is aborted.\x1b[0m (esc)
[\x1b[0;34m====\x1b[0m] \x1b[0;1mSynthesis: Tested: \x1b[0;34m2\x1b[0;1m | Passing: \x1b[0;32m2\x1b[0;1m | Failing: \x1b[0;31m0\x1b[0;1m | Crashing: \x1b[0;31m0\x1b[0;1m \x1b[0m (esc)