source: mainline/uspace/lib/pcut/src/report/report.c

Last change on this file was 4b54bd9, checked in by Vojtech Horky <vojtech.horky@…>, 7 years ago

Update PCUT to latest revision

  • Property mode set to 100644
File size: 6.9 KB
RevLine 
[01579ad]1/*
2 * Copyright (c) 2013 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file
30 *
31 * Common functions for test results reporting.
32 */
33
34#include "../internal.h"
[4b54bd9]35
[1d6dd2a]36#ifdef __helenos__
[4b54bd9]37#include <mem.h>
[1d6dd2a]38#else
[4b54bd9]39#pragma warning(push, 0)
[01579ad]40#include <string.h>
[4b54bd9]41#pragma warning(pop)
[01579ad]42#endif
[4b54bd9]43
44#pragma warning(push, 0)
[01579ad]45#include <stdio.h>
[4b54bd9]46#pragma warning(pop)
47
[01579ad]48
49/** Currently used report ops. */
50static pcut_report_ops_t *report_ops = NULL;
51
52/** Call a report function if it is available.
53 *
54 * @param op Operation to be called on the pcut_report_ops_t.
[9b20126]55 * @param ... Arguments to the operation.
[01579ad]56 */
57#define REPORT_CALL(op, ...) \
58 if ((report_ops != NULL) && (report_ops->op != NULL)) report_ops->op(__VA_ARGS__)
59
[9b20126]60/** Call a report function if it is available.
61 *
62 * @param op Operation to be called on the pcut_report_ops_t.
63 */
64#define REPORT_CALL_NO_ARGS(op) \
65 if ((report_ops != NULL) && (report_ops->op != NULL)) report_ops->op()
66
[01579ad]67/** Print error message.
68 *
69 * NULL or empty message is silently ignored.
70 *
71 * The message is printed with a special 3-zero-byte prefix to be later
72 * parsed when reporting the results from a different process.
73 *
74 * @param msg The message to be printed.
75 */
[4b54bd9]76void pcut_print_fail_message(const char *msg) {
[01579ad]77 if (msg == NULL) {
78 return;
79 }
80 if (pcut_str_size(msg) == 0) {
81 return;
82 }
83
84 printf("%c%c%c%s\n%c", 0, 0, 0, msg, 0);
85}
86
87/** Size of buffer for storing error messages or extra test output. */
88#define BUFFER_SIZE 4096
89
90/** Buffer for stdout from the test. */
91static char buffer_for_extra_output[BUFFER_SIZE];
92
93/** Buffer for assertion and other error messages. */
94static char buffer_for_error_messages[BUFFER_SIZE];
95
96/** Parse output of a single test.
97 *
98 * @param full_output Full unparsed output.
99 * @param full_output_size Size of @p full_output in bytes.
100 * @param stdio_buffer Where to store normal output from the test.
101 * @param stdio_buffer_size Size of @p stdio_buffer in bytes.
102 * @param error_buffer Where to store error messages from the test.
103 * @param error_buffer_size Size of @p error_buffer in bytes.
104 */
105static void parse_command_output(const char *full_output, size_t full_output_size,
[4b54bd9]106 char *stdio_buffer, size_t stdio_buffer_size,
107 char *error_buffer, size_t error_buffer_size) {
[01579ad]108 memset(stdio_buffer, 0, stdio_buffer_size);
109 memset(error_buffer, 0, error_buffer_size);
110
111 /* Ensure that we do not read past the full_output. */
112 if (full_output[full_output_size - 1] != 0) {
[9b20126]113 /* FIXME: can this happen? */
[01579ad]114 return;
115 }
116
[4b54bd9]117 while (1) {
[9b20126]118 size_t message_length;
119
[01579ad]120 /* First of all, count number of zero bytes before the text. */
121 size_t cont_zeros_count = 0;
122 while (full_output[0] == 0) {
123 cont_zeros_count++;
124 full_output++;
125 full_output_size--;
126 if (full_output_size == 0) {
127 return;
128 }
129 }
130
131 /* Determine the length of the text after the zeros. */
[9b20126]132 message_length = pcut_str_size(full_output);
[01579ad]133
134 if (cont_zeros_count < 2) {
135 /* Okay, standard I/O. */
136 if (message_length > stdio_buffer_size) {
[9b20126]137 /* TODO: handle gracefully */
[01579ad]138 return;
139 }
140 memcpy(stdio_buffer, full_output, message_length);
141 stdio_buffer += message_length;
142 stdio_buffer_size -= message_length;
143 } else {
144 /* Error message. */
145 if (message_length > error_buffer_size) {
[9b20126]146 /* TODO: handle gracefully */
[01579ad]147 return;
148 }
149 memcpy(error_buffer, full_output, message_length);
150 error_buffer += message_length;
151 error_buffer_size -= message_length;
152 }
153
154 full_output += message_length + 1;
155 full_output_size -= message_length + 1;
156 }
157}
158
159/** Use given set of functions for error reporting.
160 *
161 * @param ops Functions to use.
162 */
[4b54bd9]163void pcut_report_register_handler(pcut_report_ops_t *ops) {
[01579ad]164 report_ops = ops;
165}
166
167/** Initialize the report.
168 *
169 * @param all_items List of all tests that could be run.
170 */
[4b54bd9]171void pcut_report_init(pcut_item_t *all_items) {
[01579ad]172 REPORT_CALL(init, all_items);
173}
174
175/** Report that a test suite was started.
176 *
177 * @param suite Suite that was just started.
178 */
[4b54bd9]179void pcut_report_suite_start(pcut_item_t *suite) {
[01579ad]180 REPORT_CALL(suite_start, suite);
181}
182
183/** Report that a test suite was completed.
184 *
185 * @param suite Suite that just completed.
186 */
[4b54bd9]187void pcut_report_suite_done(pcut_item_t *suite) {
[01579ad]188 REPORT_CALL(suite_done, suite);
189}
190
191/** Report that a test is about to start.
192 *
193 * @param test Test to be run just about now.
194 */
[4b54bd9]195void pcut_report_test_start(pcut_item_t *test) {
[01579ad]196 REPORT_CALL(test_start, test);
197}
198
199/** Report that a test was completed.
200 *
201 * @param test Test that just finished.
202 * @param outcome Outcome of the test.
203 * @param error_message Buffer with error message.
204 * @param teardown_error_message Buffer with error message from a tear-down function.
205 * @param extra_output Extra output from the test (stdout).
206 */
207void pcut_report_test_done(pcut_item_t *test, int outcome,
[4b54bd9]208 const char *error_message, const char *teardown_error_message,
209 const char *extra_output) {
[01579ad]210 REPORT_CALL(test_done, test, outcome, error_message, teardown_error_message,
[4b54bd9]211 extra_output);
[01579ad]212}
213
214/** Report that a test was completed with unparsed test output.
215 *
216 * @param test Test that just finished
217 * @param outcome Outcome of the test.
218 * @param unparsed_output Buffer with all the output from the test.
219 * @param unparsed_output_size Size of @p unparsed_output in bytes.
220 */
221void pcut_report_test_done_unparsed(pcut_item_t *test, int outcome,
[4b54bd9]222 const char *unparsed_output, size_t unparsed_output_size) {
[01579ad]223
224 parse_command_output(unparsed_output, unparsed_output_size,
[4b54bd9]225 buffer_for_extra_output, BUFFER_SIZE,
226 buffer_for_error_messages, BUFFER_SIZE);
[01579ad]227
228 pcut_report_test_done(test, outcome, buffer_for_error_messages, NULL, buffer_for_extra_output);
229}
230
231/** Close the report.
232 *
233 */
[4b54bd9]234void pcut_report_done(void) {
[9b20126]235 REPORT_CALL_NO_ARGS(done);
[01579ad]236}
237
Note: See TracBrowser for help on using the repository browser.