- memory allocation tests removed
[strongswan.git] / Source / charon / testcases / ike_sa_manager_test.c
1 /**
2 * @file ike_sa_manager_test.c
3 *
4 * @brief Tests to test the IKE_SA-Manager type ike_sa_manager_t
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 #include <string.h>
24 #include <pthread.h>
25 #include <unistd.h>
26
27 #include "ike_sa_manager_test.h"
28
29 #include <types.h>
30 #include <sa/ike_sa_manager.h>
31
32
33 static struct ike_sa_manager_test_struct_s {
34 tester_t *tester;
35 ike_sa_manager_t *isam;
36 } td;
37
38 static void test1_thread(ike_sa_id_t *ike_sa_id)
39 {
40 ike_sa_t *ike_sa;
41 status_t status;
42
43 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
44 td.tester->assert_true(td.tester, (status == SUCCESS), "checkout of a blocked ike_sa");
45 usleep(10000);
46 status = td.isam->checkin(td.isam, ike_sa);
47 td.tester->assert_true(td.tester, (status == SUCCESS), "checkin of a requested ike_sa");
48 }
49
50
51 static void test2_thread(ike_sa_id_t *ike_sa_id)
52 {
53 ike_sa_t *ike_sa;
54 status_t status;
55
56 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
57 td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
58 }
59
60 static void test3_thread(ike_sa_id_t *ike_sa_id)
61 {
62 ike_sa_t *ike_sa;
63 status_t status;
64
65 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
66 td.tester->assert_true(td.tester, (status == NOT_FOUND), "IKE_SA already deleted");
67
68 ike_sa_id->destroy(ike_sa_id);
69 }
70
71
72
73
74 void test_ike_sa_manager(tester_t *tester)
75 {
76 status_t status;
77 u_int64_t initiator, responder;
78 ike_sa_id_t *ike_sa_id, *sa_id;
79 ike_sa_t *ike_sa;
80 int thread_count = 200;
81 int sa_count = 100;
82 int i;
83 pthread_t threads[thread_count];
84
85 td.tester = tester;
86 td.isam = ike_sa_manager_create();
87 tester->assert_true(tester, (td.isam != NULL), "ike_sa_manager creation");
88
89
90
91
92 /* First Test:
93 * we play initiator for IKE_SA_INIT first
94 * create an IKE_SA,
95 *
96 */
97
98 td.isam->create_and_checkout(td.isam, &ike_sa);
99 /* for testing purposes, we manipulate the responder spi.
100 * this is usually done be the response from the communication partner,
101 * but we don't have one...
102 */
103 responder = 123;
104
105 sa_id = ike_sa->get_id(ike_sa);
106 sa_id->set_responder_spi(sa_id, responder);
107
108 ike_sa_id = sa_id->clone(sa_id);
109
110 /* check in, so we should have a "completed" sa, specified by ike_sa_id */
111 status = td.isam->checkin(td.isam, ike_sa);
112 tester->assert_true(tester, (status == SUCCESS), "checkin modified IKE_SA");
113
114 /* now we check it out and start some other threads */
115 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
116 tester->assert_true(tester, (status == SUCCESS), "checkout existing IKE_SA 1");
117
118 for (i = 0; i < thread_count; i++)
119 {
120 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test1_thread, (void*)ike_sa_id))
121 {
122 /* failed, decrease list */
123 thread_count--;
124 i--;
125 }
126 }
127 sleep(1);
128
129
130 status = td.isam->checkin(td.isam, ike_sa);
131 tester->assert_true(tester, (status == SUCCESS), "checkin IKE_SA");
132
133
134 sleep(1);
135 /* we now delete the IKE_SA, while it is requested by the threads.
136 * this should block until the have done their work.*/
137 status = td.isam->delete(td.isam, ike_sa_id);
138 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by id");
139
140
141 for (i = 0; i < thread_count; i++)
142 {
143 pthread_join(threads[i], NULL);
144 }
145
146 ike_sa_id->destroy(ike_sa_id);
147
148
149 /* Second Test:
150 * now we simulate our partner initiates an IKE_SA_INIT,
151 * so we are the responder.
152 *
153 */
154 memset(&initiator, 0, sizeof(initiator));
155 memset(&responder, 0, sizeof(responder));
156
157 initiator = 123;
158 ike_sa_id = ike_sa_id_create(initiator, responder, TRUE);
159
160 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
161 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 2");
162 for (i = 0; i < thread_count; i++)
163 {
164 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test2_thread, (void*)ike_sa_id))
165 {
166 /* failed, decrease list */
167 thread_count--;
168 i--;
169 }
170 }
171 /* let them go acquiring */
172 sleep(1);
173
174 /* this time, we delete the ike_sa while its checked out */
175 td.isam->checkin_and_delete(td.isam, ike_sa);
176 tester->assert_true(tester, (status == SUCCESS), "delete IKE_SA by SA");
177
178 for (i = 0; i < thread_count; i++)
179 {
180 pthread_join(threads[i], NULL);
181 }
182
183 ike_sa_id->destroy(ike_sa_id);
184
185 /* Third Test:
186 * put in a lot of IKE_SAs, check it out, set a thread waiting
187 * and destroy the manager...
188 */
189
190 memset(&initiator, 0, sizeof(initiator));
191 memset(&responder, 0, sizeof(responder));
192
193 thread_count = sa_count;
194
195 for (i = 0; i < sa_count; i++)
196 {
197 initiator = i + 1;
198 ike_sa_id = ike_sa_id_create(initiator, responder, FALSE);
199
200 status = td.isam->checkout(td.isam, ike_sa_id, &ike_sa);
201 tester->assert_true(tester, (status == SUCCESS), "checkout unexisting IKE_SA 3");
202
203 if (pthread_create(&threads[i], NULL, (void*(*)(void*))test3_thread, (void*)ike_sa_id))
204 {
205 /* failed, decrease list */
206 thread_count--;
207 }
208 }
209
210 /* let them go acquiring */
211 sleep(1);
212
213 td.isam->destroy(td.isam);
214
215 for (i = 0; i < thread_count; i++)
216 {
217 pthread_join(threads[i], NULL);
218 }
219
220
221 }
222