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