diff options
Diffstat (limited to 'nxcomp/test/logging_test.h')
-rw-r--r-- | nxcomp/test/logging_test.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/nxcomp/test/logging_test.h b/nxcomp/test/logging_test.h new file mode 100644 index 000000000..239fbfe2b --- /dev/null +++ b/nxcomp/test/logging_test.h @@ -0,0 +1,121 @@ +#ifndef LOGGING_TEST_H +#define LOGGING_TEST_H + +#include <unistd.h> + +#define INTERNAL_LOGGING_TEST +#include "Log.h" + +class Faulty_Logger : public NXLog { + /* Copied from base class, inserted "fault" within critical section. */ + using NXLog::flush; + void flush(per_thread_data *pdt) + { + sigset_t orig_signal_mask, + tmp_signal_mask; + sigemptyset(&orig_signal_mask); + + sigfillset(&tmp_signal_mask); + + pthread_sigmask(SIG_BLOCK, &tmp_signal_mask, &orig_signal_mask); + + if (!pdt->buffer.empty ()) { + const std::string str = pdt->buffer.top()->str(); + + if (!str.empty()) + { + pthread_mutex_lock(&output_lock_); + usleep (3000000); + (*stream()) << str; + pthread_mutex_unlock(&output_lock_); + } + + pdt->buffer.pop(); + } + + pthread_sigmask(SIG_SETMASK, &orig_signal_mask, NULL); + } + + template<typename T> + friend Faulty_Logger& operator<<(Faulty_Logger& out, const T& value); + + friend Faulty_Logger& operator<< (Faulty_Logger& out, const NXLogStamp& value); +}; + +template <typename T> +Faulty_Logger& operator<<(Faulty_Logger& out, const T& value) { + if ( out.will_log() ) { + if ( out.synchronized() ) { + // In synchronized mode, we buffer data until a newline, std::flush, or the buffer + // gets full. Then we dump the whole thing at once to the output stream, synchronizing + // with a mutex. + Faulty_Logger::per_thread_data *pdt = out.get_data(); + assert (!pdt->buffer.empty ()); + usleep (1000000); + (*pdt->buffer.top()) << value; + + if ( ss_length(pdt->buffer.top()) >= out.thread_buffer_size_ || has_newline(value) ) + out.flush(); + } + else { + // In async mode we just dump data on the output stream as-is. + // Multithreaded code will have ugly output. + *(out.stream()) << value; + } + } + + return out; +} + +Faulty_Logger& operator<< (Faulty_Logger& out, const NXLogStamp& value) +{ + out.current_level( value.level() ); + out.current_file( value.file() ); + + // Writing an NXLogStamp to the stream indicates the start of a new entry. + // If there's any content in the buffer, create a new entry in the output + // queue. + if ( out.synchronized() ) + out.new_stack_entry(); + + out << out.stamp_to_string(value); + + return out; +} + +#undef nxdbg +#undef nxinfo +#undef nxwarn +#undef nxerr +#undef nxfatal + +#define nxdbg faulty_logger << nxstamp(NXDEBUG) +#define nxinfo faulty_logger << nxstamp(NXINFO) +#define nxwarn faulty_logger << nxstamp(NXWARNING) +#define nxerr faulty_logger << nxstamp(NXERROR) +#define nxfatal faulty_logger << nxstamp(NXFATAL) + +#define nxdbg_good good_logger << nxstamp(NXDEBUG) +#define nxinfo_good good_logger << nxstamp(NXINFO) +#define nxwarn_good good_logger << nxstamp(NXWARNING) +#define nxerr_good good_logger << nxstamp(NXERROR) +#define nxfatal_good good_logger << nxstamp(NXFATAL) + +/* Helper functions used by all component. */ +void print_sigmask (); +void setup_faulty_logger (); +void setup_good_logger (); + +/* Functions used by both main and auxiliary threads. */ +void* log_task (void* /* unused */); + +/* Functions used in main thread only. */ +pthread_t spawn_thread (); +void install_signal_handler (); +void sig_handler (int signo); + +/* Functions used by "killing" process. */ +void killing_process_init (int argc, char **argv); +void killing_process_work (pid_t parent_pid); + +#endif /* !defined (LOGGING_TEST_H) */ |