]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/asynctest.c
Following the license change, modify the boilerplates in test/
[thirdparty/openssl.git] / test / asynctest.c
CommitLineData
5705e050 1/*
83cf7abf 2 * Copyright 2015-2018 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
ff75a257
MC
46#define MAGIC_WAIT_FD ((OSSL_ASYNC_FD)99)
47static int waitfd(void *args)
5705e050 48{
ff75a257
MC
49 ASYNC_JOB *job;
50 ASYNC_WAIT_CTX *waitctx;
ff75a257
MC
51 job = ASYNC_get_current_job();
52 if (job == NULL)
53 return 0;
54 waitctx = ASYNC_get_wait_ctx(job);
55 if (waitctx == NULL)
56 return 0;
f44e6364
AG
57
58 /* First case: no fd added or removed */
59 ASYNC_pause_job();
60
61 /* Second case: one fd added */
e8aa8b6c 62 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
ff75a257 63 return 0;
5705e050 64 ASYNC_pause_job();
ff75a257 65
f44e6364
AG
66 /* Third case: all fd removed */
67 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
68 return 0;
69 ASYNC_pause_job();
70
71 /* Last case: fd added and immediately removed */
72 if (!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
73 return 0;
ff75a257
MC
74 if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
75 return 0;
5705e050
MC
76
77 return 1;
78}
79
e8dfb5bf
MC
80static int blockpause(void *args)
81{
82 ASYNC_block_pause();
83 ASYNC_pause_job();
84 ASYNC_unblock_pause();
85 ASYNC_pause_job();
86
87 return 1;
88}
89
3cb7c5cf 90static int test_ASYNC_init_thread(void)
5705e050
MC
91{
92 ASYNC_JOB *job1 = NULL, *job2 = NULL, *job3 = NULL;
93 int funcret1, funcret2, funcret3;
174a74ef 94 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050 95
7b9f8f7f 96 if ( !ASYNC_init_thread(2, 0)
ff75a257
MC
97 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
98 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
5705e050 99 != ASYNC_PAUSE
ff75a257 100 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
5705e050 101 != ASYNC_PAUSE
ff75a257 102 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050 103 != ASYNC_NO_JOBS
ff75a257 104 || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
5705e050 105 != ASYNC_FINISH
ff75a257 106 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050 107 != ASYNC_PAUSE
ff75a257 108 || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
5705e050 109 != ASYNC_FINISH
ff75a257 110 || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
5705e050
MC
111 != ASYNC_FINISH
112 || funcret1 != 1
113 || funcret2 != 1
114 || funcret3 != 1) {
7b9f8f7f 115 fprintf(stderr, "test_ASYNC_init_thread() failed\n");
ff75a257 116 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 117 ASYNC_cleanup_thread();
5705e050
MC
118 return 0;
119 }
120
ff75a257 121 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 122 ASYNC_cleanup_thread();
5705e050
MC
123 return 1;
124}
125
3cb7c5cf 126static int test_ASYNC_start_job(void)
5705e050
MC
127{
128 ASYNC_JOB *job = NULL;
129 int funcret;
174a74ef 130 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050
MC
131
132 ctr = 0;
133
7b9f8f7f 134 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
135 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
136 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
137 != ASYNC_PAUSE
5705e050 138 || ctr != 1
ff75a257
MC
139 || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
140 != ASYNC_FINISH
5705e050
MC
141 || ctr != 2
142 || funcret != 2) {
143 fprintf(stderr, "test_ASYNC_start_job() failed\n");
ff75a257 144 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 145 ASYNC_cleanup_thread();
5705e050
MC
146 return 0;
147 }
148
ff75a257 149 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 150 ASYNC_cleanup_thread();
5705e050
MC
151 return 1;
152}
153
3cb7c5cf 154static int test_ASYNC_get_current_job(void)
5705e050
MC
155{
156 ASYNC_JOB *job = NULL;
157 int funcret;
174a74ef 158 ASYNC_WAIT_CTX *waitctx = NULL;
5705e050
MC
159
160 currjob = NULL;
161
7b9f8f7f 162 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
163 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
164 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
5705e050
MC
165 != ASYNC_PAUSE
166 || currjob != job
ff75a257 167 || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
5705e050
MC
168 != ASYNC_FINISH
169 || funcret != 1) {
170 fprintf(stderr, "test_ASYNC_get_current_job() failed\n");
ff75a257 171 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 172 ASYNC_cleanup_thread();
5705e050
MC
173 return 0;
174 }
175
ff75a257 176 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 177 ASYNC_cleanup_thread();
5705e050
MC
178 return 1;
179}
180
3cb7c5cf 181static int test_ASYNC_WAIT_CTX_get_all_fds(void)
5705e050
MC
182{
183 ASYNC_JOB *job = NULL;
2b2c78d4 184 int funcret;
174a74ef 185 ASYNC_WAIT_CTX *waitctx = NULL;
ff75a257
MC
186 OSSL_ASYNC_FD fd = OSSL_BAD_ASYNC_FD, delfd = OSSL_BAD_ASYNC_FD;
187 size_t numfds, numdelfds;
5705e050 188
7b9f8f7f 189 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
190 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
191 /* On first run we're not expecting any wait fds */
192 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
5705e050 193 != ASYNC_PAUSE
ff75a257
MC
194 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
195 || numfds != 0
196 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
197 &numdelfds)
198 || numfds != 0
199 || numdelfds != 0
200 /* On second run we're expecting one added fd */
201 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
5705e050 202 != ASYNC_PAUSE
ff75a257
MC
203 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
204 || numfds != 1
205 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, &fd, &numfds)
206 || fd != MAGIC_WAIT_FD
207 || (fd = OSSL_BAD_ASYNC_FD, 0) /* Assign to something else */
208 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
f44e6364 209 &numdelfds)
ff75a257
MC
210 || numfds != 1
211 || numdelfds != 0
212 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, &fd, &numfds, NULL,
213 &numdelfds)
214 || fd != MAGIC_WAIT_FD
f44e6364 215 /* On third run we expect one deleted fd */
ff75a257 216 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
f44e6364 217 != ASYNC_PAUSE
ff75a257
MC
218 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
219 || numfds != 0
220 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
221 &numdelfds)
222 || numfds != 0
223 || numdelfds != 1
224 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, &delfd,
225 &numdelfds)
226 || delfd != MAGIC_WAIT_FD
f44e6364
AG
227 /* On last run we are not expecting any wait fd */
228 || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
229 != ASYNC_FINISH
230 || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
231 || numfds != 0
232 || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
233 &numdelfds)
234 || numfds != 0
235 || numdelfds != 0
5705e050
MC
236 || funcret != 1) {
237 fprintf(stderr, "test_ASYNC_get_wait_fd() failed\n");
ff75a257 238 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 239 ASYNC_cleanup_thread();
5705e050
MC
240 return 0;
241 }
242
ff75a257 243 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 244 ASYNC_cleanup_thread();
5705e050
MC
245 return 1;
246}
e8dfb5bf 247
3cb7c5cf 248static int test_ASYNC_block_pause(void)
e8dfb5bf
MC
249{
250 ASYNC_JOB *job = NULL;
251 int funcret;
174a74ef 252 ASYNC_WAIT_CTX *waitctx = NULL;
e8dfb5bf 253
7b9f8f7f 254 if ( !ASYNC_init_thread(1, 0)
ff75a257
MC
255 || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
256 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
e8dfb5bf 257 != ASYNC_PAUSE
ff75a257 258 || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
e8dfb5bf
MC
259 != ASYNC_FINISH
260 || funcret != 1) {
261 fprintf(stderr, "test_ASYNC_block_pause() failed\n");
ff75a257 262 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 263 ASYNC_cleanup_thread();
e8dfb5bf
MC
264 return 0;
265 }
266
ff75a257 267 ASYNC_WAIT_CTX_free(waitctx);
7b9f8f7f 268 ASYNC_cleanup_thread();
e8dfb5bf
MC
269 return 1;
270}
271
5705e050
MC
272int main(int argc, char **argv)
273{
c521edc3
MC
274 if (!ASYNC_is_capable()) {
275 fprintf(stderr,
276 "OpenSSL build is not ASYNC capable - skipping async tests\n");
277 } else {
278 CRYPTO_set_mem_debug(1);
279 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
280
281 if ( !test_ASYNC_init_thread()
282 || !test_ASYNC_start_job()
283 || !test_ASYNC_get_current_job()
284 || !test_ASYNC_WAIT_CTX_get_all_fds()
285 || !test_ASYNC_block_pause()) {
286 return 1;
287 }
5705e050 288 }
5705e050
MC
289 printf("PASS\n");
290 return 0;
291}