]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/asynctest.c
Run the withlibctx.pl script
[thirdparty/openssl.git] / test / asynctest.c
CommitLineData
5705e050 1/*
e39e295e 2 * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
5705e050 3 *
909f1a2e 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
440e5d80
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
5705e050
MC
8 */
9
f1f5ee17
AP
10#ifdef _WIN32
11# include <windows.h>
12#endif
13
5705e050
MC
14#include <stdio.h>
15#include <string.h>
16#include <openssl/async.h>
17#include <openssl/crypto.h>
5705e050 18
5705e050
MC
19static int ctr = 0;
20static ASYNC_JOB *currjob = NULL;
21
22static int only_pause(void *args)
23{
24 ASYNC_pause_job();
25
26 return 1;
27}
28
29static int add_two(void *args)
30{
31 ctr++;
32 ASYNC_pause_job();
33 ctr++;
34
35 return 2;
36}
37
38static int save_current(void *args)
39{
40 currjob = ASYNC_get_current_job();
41 ASYNC_pause_job();
42
43 return 1;
44}
45
92db29e5
MC
46static int change_deflt_libctx(void *args)
47{
48 OPENSSL_CTX *libctx = OPENSSL_CTX_new();
49 OPENSSL_CTX *oldctx, *tmpctx;
50 int ret = 0;
51
52 if (libctx == NULL)
53 return 0;
54
55 oldctx = OPENSSL_CTX_set0_default(libctx);
56 ASYNC_pause_job();
57
58 /* Check the libctx is set up as we expect */
59 tmpctx = OPENSSL_CTX_set0_default(oldctx);
60 if (tmpctx != libctx)
61 goto err;
62
63 /* Set it back again to continue to use our own libctx */
64 oldctx = OPENSSL_CTX_set0_default(libctx);
65 ASYNC_pause_job();
66
67 /* Check the libctx is set up as we expect */
68 tmpctx = OPENSSL_CTX_set0_default(oldctx);
69 if (tmpctx != libctx)
70 goto err;
71
72 ret = 1;
73 err:
74 OPENSSL_CTX_free(libctx);
75 return ret;
76}
77
78
ff75a257
MC
79#define MAGIC_WAIT_FD ((OSSL_ASYNC_FD)99)
80static int waitfd(void *args)
5705e050 81{
ff75a257
MC
82 ASYNC_JOB *job;
83 ASYNC_WAIT_CTX *waitctx;
ff75a257
MC
84 job = ASYNC_get_current_job();
85 if (job == NULL)
86 return 0;
87 waitctx = ASYNC_get_wait_ctx(job);
88 if (waitctx == NULL)
89 return 0;
f44e6364
AG
90
91 /* First case: no fd added or removed */
92 ASYNC_pause_job();
93
94 /* Second case: one fd added */
e8aa8b6c 95 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
ff75a257 96 return 0;
5705e050 97 ASYNC_pause_job();
ff75a257 98
f44e6364
AG
99 /* Third case: all fd removed */
100 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
101 return 0;
102 ASYNC_pause_job();
103
104 /* Last case: fd added and immediately removed */
105 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
106 return 0;
ff75a257
MC
107 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
108 return 0;
5705e050
MC
109
110 return 1;
111}
112
e8dfb5bf
MC
113static int blockpause(void *args)
114{
115 ASYNC_block_pause();
116 ASYNC_pause_job();
117 ASYNC_unblock_pause();
118 ASYNC_pause_job();
119
120 return 1;
121}
122
3cb7c5cf 123static int test_ASYNC_init_thread(void)
5705e050
MC
124{
125 ASYNC_JOB *job1 = NULL, *job2 = NULL, *job3 = NULL;
126 int funcret1, funcret2, funcret3;
174a74ef 127 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050 128
7b9f8f7f 129 if ( !ASYNC_init_thread(2, 0)
ff75a257
MC
130 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
131 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
5705e050 132 != ASYNC_PAUSE
ff75a257 133 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
5705e050 134 != ASYNC_PAUSE
ff75a257 135 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050 136 != ASYNC_NO_JOBS
ff75a257 137 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
5705e050 138 != ASYNC_FINISH
ff75a257 139 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050 140 != ASYNC_PAUSE
ff75a257 141 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
5705e050 142 != ASYNC_FINISH
ff75a257 143 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050
MC
144 != ASYNC_FINISH
145 || funcret1 != 1
146 || funcret2 != 1
147 || funcret3 != 1) {
7b9f8f7f 148 fprintf(stderr, "test_ASYNC_init_thread() failed\n");
ff75a257 149 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 150 ASYNC_cleanup_thread();
5705e050
MC
151 return 0;
152 }
153
ff75a257 154 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 155 ASYNC_cleanup_thread();
5705e050
MC
156 return 1;
157}
158
9f5a87fd
PY
159static int test_callback(void *arg)
160{
161 printf("callback test pass\n");
162 return 1;
163}
164
165static int test_ASYNC_callback_status(void)
166{
167 ASYNC_WAIT_CTX *waitctx = NULL;
168 int set_arg = 100;
169 ASYNC_callback_fn get_callback;
170 void *get_arg;
171 int set_status = 1;
172
173 if ( !ASYNC_init_thread(1, 0)
174 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
175 || ASYNC_WAIT_CTX_set_callback(waitctx, test_callback, (void*)&set_arg)
176 != 1
177 || ASYNC_WAIT_CTX_get_callback(waitctx, &get_callback, &get_arg)
178 != 1
179 || test_callback != get_callback
180 || get_arg != (void*)&set_arg
181 || (*get_callback)(get_arg) != 1
182 || ASYNC_WAIT_CTX_set_status(waitctx, set_status) != 1
183 || set_status != ASYNC_WAIT_CTX_get_status(waitctx)) {
184 fprintf(stderr, "test_ASYNC_callback_status() failed\n");
185 ASYNC_WAIT_CTX_free(waitctx);
186 ASYNC_cleanup_thread();
187 return 0;
188 }
189
190 ASYNC_WAIT_CTX_free(waitctx);
191 ASYNC_cleanup_thread();
192 return 1;
193
194}
195
3cb7c5cf 196static int test_ASYNC_start_job(void)
5705e050
MC
197{
198 ASYNC_JOB *job = NULL;
199 int funcret;
174a74ef 200 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050
MC
201
202 ctr = 0;
203
7b9f8f7f 204 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
205 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
206 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
207 != ASYNC_PAUSE
5705e050 208 || ctr != 1
ff75a257
MC
209 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
210 != ASYNC_FINISH
5705e050
MC
211 || ctr != 2
212 || funcret != 2) {
213 fprintf(stderr, "test_ASYNC_start_job() failed\n");
ff75a257 214 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 215 ASYNC_cleanup_thread();
5705e050
MC
216 return 0;
217 }
218
ff75a257 219 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 220 ASYNC_cleanup_thread();
5705e050
MC
221 return 1;
222}
223
3cb7c5cf 224static int test_ASYNC_get_current_job(void)
5705e050
MC
225{
226 ASYNC_JOB *job = NULL;
227 int funcret;
174a74ef 228 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050
MC
229
230 currjob = NULL;
231
7b9f8f7f 232 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
233 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
234 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
5705e050
MC
235 != ASYNC_PAUSE
236 || currjob != job
ff75a257 237 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
5705e050
MC
238 != ASYNC_FINISH
239 || funcret != 1) {
240 fprintf(stderr, "test_ASYNC_get_current_job() failed\n");
ff75a257 241 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 242 ASYNC_cleanup_thread();
5705e050
MC
243 return 0;
244 }
245
ff75a257 246 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 247 ASYNC_cleanup_thread();
5705e050
MC
248 return 1;
249}
250
3cb7c5cf 251static int test_ASYNC_WAIT_CTX_get_all_fds(void)
5705e050
MC
252{
253 ASYNC_JOB *job = NULL;
2b2c78d4 254 int funcret;
174a74ef 255 ASYNC_WAIT_CTX *waitctx = NULL;
ff75a257
MC
256 OSSL_ASYNC_FD fd = OSSL_BAD_ASYNC_FD, delfd = OSSL_BAD_ASYNC_FD;
257 size_t numfds, numdelfds;
5705e050 258
7b9f8f7f 259 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
260 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
261 /* On first run we're not expecting any wait fds */
262 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
5705e050 263 != ASYNC_PAUSE
ff75a257
MC
264 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
265 || numfds != 0
266 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
267 &numdelfds)
268 || numfds != 0
269 || numdelfds != 0
270 /* On second run we're expecting one added fd */
271 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
5705e050 272 != ASYNC_PAUSE
ff75a257
MC
273 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
274 || numfds != 1
275 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, &fd, &numfds)
276 || fd != MAGIC_WAIT_FD
277 || (fd = OSSL_BAD_ASYNC_FD, 0) /* Assign to something else */
278 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
f44e6364 279 &numdelfds)
ff75a257
MC
280 || numfds != 1
281 || numdelfds != 0
282 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, &fd, &numfds, NULL,
283 &numdelfds)
284 || fd != MAGIC_WAIT_FD
f44e6364 285 /* On third run we expect one deleted fd */
ff75a257 286 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
f44e6364 287 != ASYNC_PAUSE
ff75a257
MC
288 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
289 || numfds != 0
290 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
291 &numdelfds)
292 || numfds != 0
293 || numdelfds != 1
294 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, &delfd,
295 &numdelfds)
296 || delfd != MAGIC_WAIT_FD
f44e6364
AG
297 /* On last run we are not expecting any wait fd */
298 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
299 != ASYNC_FINISH
300 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
301 || numfds != 0
302 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
303 &numdelfds)
304 || numfds != 0
305 || numdelfds != 0
5705e050
MC
306 || funcret != 1) {
307 fprintf(stderr, "test_ASYNC_get_wait_fd() failed\n");
ff75a257 308 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 309 ASYNC_cleanup_thread();
5705e050
MC
310 return 0;
311 }
312
ff75a257 313 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 314 ASYNC_cleanup_thread();
5705e050
MC
315 return 1;
316}
e8dfb5bf 317
3cb7c5cf 318static int test_ASYNC_block_pause(void)
e8dfb5bf
MC
319{
320 ASYNC_JOB *job = NULL;
321 int funcret;
174a74ef 322 ASYNC_WAIT_CTX *waitctx = NULL;
e8dfb5bf 323
7b9f8f7f 324 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
325 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
326 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
e8dfb5bf 327 != ASYNC_PAUSE
ff75a257 328 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
e8dfb5bf
MC
329 != ASYNC_FINISH
330 || funcret != 1) {
331 fprintf(stderr, "test_ASYNC_block_pause() failed\n");
ff75a257 332 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 333 ASYNC_cleanup_thread();
e8dfb5bf
MC
334 return 0;
335 }
336
ff75a257 337 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 338 ASYNC_cleanup_thread();
e8dfb5bf
MC
339 return 1;
340}
341
d8652be0 342static int test_ASYNC_start_job_ex(void)
92db29e5
MC
343{
344 ASYNC_JOB *job = NULL;
345 int funcret;
346 ASYNC_WAIT_CTX *waitctx = NULL;
347 OPENSSL_CTX *libctx = OPENSSL_CTX_new();
348 OPENSSL_CTX *oldctx, *tmpctx, *globalctx;
349 int ret = 0;
350
351 if (libctx == NULL) {
352 fprintf(stderr,
d8652be0 353 "test_ASYNC_start_job_ex() failed to create libctx\n");
92db29e5
MC
354 goto err;
355 }
356
357 globalctx = oldctx = OPENSSL_CTX_set0_default(libctx);
358
359 if ((waitctx = ASYNC_WAIT_CTX_new()) == NULL
360 || ASYNC_start_job(&job, waitctx, &funcret, change_deflt_libctx,
361 NULL, 0)
362 != ASYNC_PAUSE) {
363 fprintf(stderr,
d8652be0 364 "test_ASYNC_start_job_ex() failed to start job\n");
92db29e5
MC
365 goto err;
366 }
367
368 /* Reset the libctx temporarily to find out what it is*/
369 tmpctx = OPENSSL_CTX_set0_default(oldctx);
370 oldctx = OPENSSL_CTX_set0_default(tmpctx);
371 if (tmpctx != libctx) {
372 fprintf(stderr,
d8652be0 373 "test_ASYNC_start_job_ex() failed - unexpected libctx\n");
92db29e5
MC
374 goto err;
375 }
376
377 if (ASYNC_start_job(&job, waitctx, &funcret, change_deflt_libctx, NULL, 0)
378 != ASYNC_PAUSE) {
379 fprintf(stderr,
d8652be0 380 "test_ASYNC_start_job_ex() - restarting job failed\n");
92db29e5
MC
381 goto err;
382 }
383
384 /* Reset the libctx and continue with the global default libctx */
385 tmpctx = OPENSSL_CTX_set0_default(oldctx);
386 if (tmpctx != libctx) {
387 fprintf(stderr,
d8652be0 388 "test_ASYNC_start_job_ex() failed - unexpected libctx\n");
92db29e5
MC
389 goto err;
390 }
391
392 if (ASYNC_start_job(&job, waitctx, &funcret, change_deflt_libctx, NULL, 0)
393 != ASYNC_FINISH
394 || funcret != 1) {
395 fprintf(stderr,
d8652be0 396 "test_ASYNC_start_job_ex() - finishing job failed\n");
92db29e5
MC
397 goto err;
398 }
399
400 /* Reset the libctx temporarily to find out what it is*/
401 tmpctx = OPENSSL_CTX_set0_default(libctx);
402 OPENSSL_CTX_set0_default(tmpctx);
403 if (tmpctx != globalctx) {
404 fprintf(stderr,
d8652be0 405 "test_ASYNC_start_job_ex() failed - global libctx check failed\n");
92db29e5
MC
406 goto err;
407 }
408
409 ret = 1;
410 err:
411 ASYNC_WAIT_CTX_free(waitctx);
412 OPENSSL_CTX_free(libctx);
413 return ret;
414}
415
5705e050
MC
416int main(int argc, char **argv)
417{
c521edc3
MC
418 if (!ASYNC_is_capable()) {
419 fprintf(stderr,
420 "OpenSSL build is not ASYNC capable - skipping async tests\n");
421 } else {
742ccab3 422 if (!test_ASYNC_init_thread()
9f5a87fd 423 || !test_ASYNC_callback_status()
c521edc3
MC
424 || !test_ASYNC_start_job()
425 || !test_ASYNC_get_current_job()
426 || !test_ASYNC_WAIT_CTX_get_all_fds()
92db29e5 427 || !test_ASYNC_block_pause()
d8652be0 428 || !test_ASYNC_start_job_ex()) {
c521edc3
MC
429 return 1;
430 }
5705e050 431 }
5705e050
MC
432 printf("PASS\n");
433 return 0;
434}