- iterator for linked list implemented
[strongswan.git] / Source / charon / tester.c
1 /**
2 * @file tester.c
3 *
4 * @brief Test module for automatic testing
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23
24 #include <stdlib.h>
25 #include <freeswan.h>
26 #include <pluto/constants.h>
27 #include <pluto/defs.h>
28 #include <string.h>
29 #include <pthread.h>
30 #include <sys/time.h>
31
32 #include "tester.h"
33 #include "linked_list.h"
34 #include "thread_pool.h"
35 #include "job_queue.h"
36
37 /**
38 * @brief Private Variables and Functions of tester class
39 *
40 */
41 typedef struct private_tester_s private_tester_t;
42
43 struct private_tester_s {
44 tester_t public;
45
46 /* Private values */
47 FILE* output;
48 int tests_count;
49 int failed_tests_count;
50 int failed_asserts_count;
51 bool display_succeeded_asserts;
52 pthread_mutex_t mutex;
53 };
54
55 /*
56 * Implementation of function test_all
57 */
58 static status_t test_all(tester_t *tester,test_t **tests)
59 {
60 private_tester_t *this =(private_tester_t*) tester;
61 int current_test = 0;
62 fprintf(this->output,"Start testing\n");
63
64 while (tests[current_test] != NULL)
65 {
66 tester->run_test(tester,tests[current_test]->test_function,tests[current_test]->test_name);
67 current_test++;
68 }
69
70 fprintf(this->output,"End testing. %d of %d tests succeeded\n",this->tests_count - this->failed_tests_count,this->tests_count);
71
72 return SUCCESS;
73 }
74
75 /**
76 * Returns the difference of to timeval structs in microseconds
77 *
78 * @param end_time end time
79 * @param start_time start time
80 *
81 * @warning this function is also defined in the event queue
82 * in later improvements, this function can be added to a general
83 * class type!
84 *
85 * @return difference in microseconds
86 */
87 static long time_difference(struct timeval *end_time, struct timeval *start_time)
88 {
89 long seconds, microseconds;
90
91 seconds = (end_time->tv_sec - start_time->tv_sec);
92 microseconds = (end_time->tv_usec - start_time->tv_usec);
93 return ((seconds * 1000000) + microseconds);
94 }
95
96
97 /**
98 * Implementation of function run_test
99 */
100 static void run_test(tester_t *tester, void (*test_function) (tester_t * tester), char * test_name)
101 {
102 struct timeval start_time, end_time;
103 long timediff;
104 private_tester_t *this = (private_tester_t *) tester;
105 this->tests_count++;
106 this->failed_asserts_count = 0;
107 fprintf(this->output,"Start Test '%s'\n", test_name);
108 gettimeofday(&start_time,NULL);
109 test_function(tester);
110 gettimeofday(&end_time,NULL);
111 timediff = time_difference(&end_time, &start_time);
112
113 fprintf(this->output,"End Test '%s' in %ld microseconds\n", test_name,timediff);
114 if (this->failed_asserts_count > 0)
115 {
116 this->failed_tests_count++;
117 }
118 }
119
120 /**
121 * Implementation of function assert_true
122 */
123 static void assert_true(tester_t *tester, bool to_be_true,char * assert_name)
124 {
125 private_tester_t *this = (private_tester_t *) tester;
126
127 if (assert_name == NULL)
128 {
129 assert_name = "unknown";
130 }
131
132 pthread_mutex_lock(&(this->mutex));
133 if (!to_be_true)
134 {
135 this->failed_asserts_count++;
136 fprintf(this->output," Assert '%s' failed!\n", assert_name);
137 }else
138 {
139 if (this->display_succeeded_asserts)
140 {
141 fprintf(this->output," Assert '%s' succeeded\n", assert_name);
142 }
143 }
144 pthread_mutex_unlock(&(this->mutex));
145 }
146
147 /**
148 * Implementation of function assert_false
149 */
150 static void assert_false(tester_t *tester, bool to_be_false,char * assert_name)
151 {
152 tester->assert_true(tester,(!to_be_false),assert_name);
153 }
154
155 /**
156 * Implements the destroy function
157 */
158 static status_t destroy(tester_t *tester)
159 {
160 private_tester_t *this = (private_tester_t*) tester;
161 pthread_mutex_destroy(&(this->mutex));
162 pfree(this);
163 return SUCCESS;
164 }
165
166 tester_t *tester_create(FILE *output, bool display_succeeded_asserts)
167 {
168 private_tester_t *this = alloc_thing(private_tester_t, "private_tester_t");
169
170 this->public.destroy = destroy;
171 this->public.test_all = test_all;
172 this->public.run_test = run_test;
173 this->public.assert_true = assert_true;
174 this->public.assert_false = assert_false;
175
176 this->display_succeeded_asserts = display_succeeded_asserts;
177 this->failed_tests_count = 0;
178 this->tests_count = 0;
179 this->output = output;
180 pthread_mutex_init(&(this->mutex),NULL);
181
182 return &(this->public);
183 }