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