loaders: JPG: Fix bussy loop on corrupted file.
[gfxprim.git] / tests / framework / tst_suite.c
blob6088db304235b619287d71ebf5a7119486f39626
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <errno.h>
27 #include <string.h>
28 #include <stdarg.h>
30 #include "tst_log.h"
31 #include "tst_job.h"
32 #include "tst_test.h"
33 #include "tst_preload.h"
34 #include "tst_timespec.h"
36 #define NAME_PADD 35
38 int tst_suite_verbose = 0;
39 const char *tst_log_dir = NULL;
41 static void test_job_report(const struct tst_job *job)
43 const char *name = job->test->name;
44 int sec, nsec;
45 const char *result = "";
47 if ((job->result == TST_SUCCESS || job->result == TST_SKIPPED)
48 && !tst_suite_verbose)
49 return;
51 timespec_diff(&sec, &nsec, &job->start_time, &job->stop_time);
53 switch (job->result) {
54 case TST_SUCCESS:
55 result = "[ \e[1;32mSUCCESS\e[0m ]";
56 break;
57 case TST_SKIPPED:
58 result = "[ \e[1;30mSKIPPED\e[0m ]";
59 break;
60 case TST_UNTESTED:
61 result = "[ \e[1;34mUNTESTED\e[0m ]";
62 break;
63 case TST_INTERR:
64 result = "[ \e[1;31mINTERNAL ERROR\e[0m ]";
65 break;
66 case TST_SIGSEGV:
67 result = "[ \e[1;31mSEGFAULT\e[0m ]";
68 break;
69 case TST_TIMEOUT:
70 result = "[ \e[1;35mTIMEOUT\e[0m ]";
71 break;
72 case TST_ABORTED:
73 result = "[ \e[1;31mABORTED\e[0m ]";
74 break;
75 case TST_FPE:
76 result = "[ \e[1;31mFP EXCEPTION\e[0m ]";
77 break;
78 case TST_MEMLEAK:
79 result = "[ \e[1;33mMEMLEAK\e[0m ]";
80 break;
81 case TST_FAILED:
82 result = "[ \e[1;31mFAILURE\e[0m ]";
83 break;
84 case TST_MAX:
85 break;
88 fprintf(stderr, "\e[1;37m%s\e[0m", name);
90 int i;
92 for (i = strlen(name); i < NAME_PADD; i++)
93 fprintf(stderr, " ");
95 fprintf(stderr, " finished (Time %3i.%03is) %s\n",
96 sec, nsec/1000000, result);
98 if (job->bench_iter) {
99 for (i = 0; i < NAME_PADD; i++)
100 fprintf(stderr, " ");
102 fprintf(stderr, " bench CPU time %i.%06is +/- %i.%06is\n",
103 (int)job->bench_mean.tv_sec,
104 (int)job->bench_mean.tv_nsec/1000,
105 (int)job->bench_var.tv_sec,
106 (int)job->bench_var.tv_nsec/1000);
109 if (job->result == TST_MEMLEAK)
110 tst_malloc_print(&job->malloc_stats);
112 /* Now print test message store */
113 tst_msg_print(&job->store);
115 fprintf(stderr, "------------------------------------------------------"
116 "------------------------- \n");
119 static int run_test(const struct tst_test *test, FILE *json)
121 struct tst_job job;
123 job.test = test;
126 * Flush the file before forking, otherwise
127 * there would be a copy of its buffers in both
128 * child and parent and the lines in the resulting
129 * file would be repeated several times.
131 if (json)
132 fflush(json);
134 tst_job_run(&job);
135 tst_job_wait(&job);
137 /* report result into stdout */
138 test_job_report(&job);
140 if (json)
141 tst_log_append(&job, json);
143 /* Free the test message store */
144 tst_msg_clear(&job.store);
146 return job.result;
149 void tst_run_suite(const struct tst_suite *suite, const char *tst_name)
151 unsigned int i;
152 unsigned int counters[TST_MAX] = {};
153 unsigned int counter = 0;
154 int ret;
156 fprintf(stderr, "Running \e[1;37m%s\e[0m\n\n", suite->suite_name);
158 FILE *json = NULL;
160 if (tst_log_dir) {
161 char buf[512];
162 snprintf(buf, sizeof(buf), "%s/%s.json",
163 tst_log_dir, suite->suite_name);
164 json = tst_log_open(suite, buf);
167 for (i = 0; suite->tests[i].name != NULL; i++) {
168 if (tst_name == NULL || !strcmp(tst_name, suite->tests[i].name)) {
169 ret = run_test(&suite->tests[i], json);
170 counters[ret]++;
172 if (ret != TST_SKIPPED)
173 counter++;
177 if (json)
178 tst_log_close(json);
180 float percents;
182 if (counter == 0)
183 percents = 100;
184 else
185 percents = 100.00 * counters[0] / counter;
187 fprintf(stderr, "\nSummary: succedded %u out of "
188 "%u %.2f%% (skipped %u)\n",
189 counters[0], counter, percents,
190 counters[TST_SKIPPED]);
193 void tst_list_suite(const struct tst_suite *suite)
195 int i;
197 fprintf(stderr, "Testsuite: \e[1;37m%s\e[0m\n\n", suite->suite_name);
199 for (i = 0; suite->tests[i].name != NULL; i++)
200 fprintf(stderr, "Test: \e[1;37m%s\e[0m\n", suite->tests[i].name);