Back to home page

Enduro/X

 
 

    


0001 #include <cgreen/reporter.h>
0002 #include <cgreen/messaging.h>
0003 #include <cgreen/breadcrumb.h>
0004 #include <stdio.h>
0005 #include <string.h>
0006 #include <stdarg.h>
0007 #ifndef __cplusplus
0008 #include <stdbool.h>
0009 #endif
0010 #include <stdio.h>
0011 #include <stdlib.h>
0012 
0013 #ifdef __cplusplus
0014 namespace cgreen {
0015 #endif
0016 
0017 enum { pass = 1, fail, completion, exception };
0018 enum { FINISH_NOTIFICATION_RECEIVED = 0, FINISH_NOTIFICATION_NOT_RECEIVED };
0019 
0020 static TestContext context;
0021 
0022 static void show_pass(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0023 static void show_fail(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0024 static void show_incomplete(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments);
0025 static void assert_true(TestReporter *reporter, const char *file, int line, int result, const char *message, ...);
0026 static int  read_reporter_results(TestReporter *reporter);
0027 
0028 TestReporter *get_test_reporter() {
0029     return context.reporter;
0030 }
0031 
0032 void setup_reporting(TestReporter *reporter) {
0033     reporter->ipc = start_cgreen_messaging(45);
0034     context.reporter = reporter;
0035 }
0036 
0037 void set_reporter_options(TestReporter *reporter, void *options) {
0038     if (reporter->options != NULL)
0039         free(reporter->options);
0040     reporter->options = options;
0041 }
0042 
0043 TestReporter *create_reporter() {
0044     CgreenBreadcrumb *breadcrumb;
0045     TestReporter *reporter = (TestReporter *) malloc(sizeof(TestReporter));
0046     if (reporter == NULL) {
0047         return NULL;
0048     }
0049 
0050     breadcrumb = create_breadcrumb();
0051     if (breadcrumb == NULL) {
0052         free(reporter);
0053         return NULL;
0054     }
0055 
0056     reporter->destroy = &destroy_reporter;
0057     reporter->start_suite = &reporter_start_suite;
0058     reporter->start_test = &reporter_start;
0059     reporter->show_pass = &show_pass;
0060     reporter->show_fail = &show_fail;
0061     reporter->show_incomplete = &show_incomplete;
0062     reporter->assert_true = &assert_true;
0063     reporter->finish_test = &reporter_finish;
0064     reporter->finish_suite = &reporter_finish_suite;
0065     reporter->passes = 0;
0066     reporter->failures = 0;
0067     reporter->exceptions = 0;
0068     reporter->breadcrumb = breadcrumb;
0069     reporter->memo = NULL;
0070     reporter->options = NULL;
0071     return reporter;
0072 }
0073 
0074 void destroy_reporter(TestReporter *reporter) {
0075     destroy_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0076     destroy_memo((TestReportMemo *)reporter->memo);
0077     free(reporter);
0078     /* hack to allow destroy_reporter to be called in cute_reporter_tests when
0079      * tests are running in same process
0080      */
0081     if (context.reporter == reporter)
0082     {
0083         context.reporter = NULL;
0084     }
0085 }
0086 
0087 void destroy_memo(TestReportMemo *memo) {
0088     if (NULL != memo) {
0089         free(memo);
0090     }
0091 }
0092 
0093 void reporter_start(TestReporter *reporter, const char *name) {
0094     push_breadcrumb((CgreenBreadcrumb *) reporter->breadcrumb, name);
0095 }
0096 
0097 void reporter_start_suite(TestReporter *reporter, const char *name, const int count) {
0098     (void) count;
0099     reporter_start(reporter, name);
0100 }
0101 
0102 void reporter_finish(TestReporter *reporter, const char *filename, int line, const char *message) {
0103     int status = read_reporter_results(reporter);
0104 
0105     if (status == FINISH_NOTIFICATION_NOT_RECEIVED) {
0106         va_list no_arguments;
0107         memset(&no_arguments, 0, sizeof(va_list));
0108         reporter->exceptions++;
0109         (*reporter->show_incomplete)(reporter, filename, line, message, no_arguments);
0110     }
0111 
0112     pop_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0113 }
0114 
0115 void reporter_finish_suite(TestReporter *reporter, const char *filename, int line) {
0116     (void) filename;
0117     (void) line;
0118     read_reporter_results(reporter);
0119     pop_breadcrumb((CgreenBreadcrumb *)reporter->breadcrumb);
0120 }
0121 
0122 void add_reporter_result(TestReporter *reporter, int result) {
0123     send_cgreen_message(reporter->ipc, result ? pass : fail);
0124 }
0125 
0126 void send_reporter_exception_notification(TestReporter *reporter) {
0127     send_cgreen_message(reporter->ipc, exception);
0128 }
0129 
0130 void send_reporter_completion_notification(TestReporter *reporter) {
0131     send_cgreen_message(reporter->ipc, completion);
0132 }
0133 
0134 static void show_pass(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0135     (void)reporter;
0136     (void)file;
0137     (void)line;
0138     (void)message;
0139     (void)arguments;
0140 }
0141 
0142 static void show_fail(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0143     (void)reporter;
0144     (void)file;
0145     (void)line;
0146     (void)message;
0147     (void)arguments;
0148 }
0149 
0150 static void show_incomplete(TestReporter *reporter, const char *file, int line, const char *message, va_list arguments) {
0151     (void)reporter;
0152     (void)file;
0153     (void)line;
0154     (void)message;
0155     (void)arguments;
0156 }
0157 
0158 static const unsigned int MAX_ASSERTIONS_PER_TEST = 8100;
0159 
0160 static void assert_true(TestReporter *reporter, const char *file, int line, int result, const char *message, ...) {
0161     va_list arguments;
0162     memset(&arguments, 0, sizeof(va_list));
0163 
0164     va_start(arguments, message);
0165     if (result) {
0166             (*reporter->show_pass)(reporter, file, line, message, arguments);
0167     } else {
0168             (*reporter->show_fail)(reporter, file, line, message, arguments);
0169     }
0170 
0171     add_reporter_result(reporter, result);
0172     va_end(arguments);
0173 }
0174 
0175 static int read_reporter_results(TestReporter *reporter) {
0176     int result;
0177     while ((result = receive_cgreen_message(reporter->ipc)) > 0) {
0178         if (result == pass) {
0179             reporter->passes++;
0180         } else if (result == fail) {
0181             reporter->failures++;
0182         } else if (result == exception) {
0183             reporter->exceptions++;
0184         } else if (result == completion) {
0185             /* TODO: this should always be the last message; if it's not, there's a bad race */
0186             return FINISH_NOTIFICATION_RECEIVED;
0187         }
0188     }
0189 
0190     return FINISH_NOTIFICATION_NOT_RECEIVED;
0191 }
0192 
0193 #ifdef __cplusplus
0194 } // namespace cgreen
0195 #endif
0196 
0197 /* vim: set ts=4 sw=4 et cindent: */