asynctest.c 10.4 KB
Newer Older
M
Matt Caswell 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/*
 * Written by Matt Caswell for the OpenSSL project.
 */
/* ====================================================================
 * Copyright (c) 2015 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#include <stdio.h>
#include <string.h>
#include <openssl/async.h>
#include <openssl/crypto.h>
#include <../apps/apps.h>

64
#if (defined(OPENSSL_SYS_UNIX) || defined(OPENSSL_SYS_CYGWIN)) && defined(OPENSSL_THREADS)
M
Matt Caswell 已提交
65 66 67 68
# include <unistd.h>
# if _POSIX_VERSION >= 200112L
#  define ASYNC_POSIX
# endif
69
#elif defined(_WIN32)
M
Matt Caswell 已提交
70 71 72 73 74 75 76
# define ASYNC_WIN
#endif

#if !defined(ASYNC_POSIX) && !defined(ASYNC_WIN)
# define ASYNC_NULL
#endif

M
Matt Caswell 已提交
77 78
#ifndef ASYNC_NULL

M
Matt Caswell 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
static int ctr = 0;
static ASYNC_JOB *currjob = NULL;

static int only_pause(void *args)
{
    ASYNC_pause_job();

    return 1;
}

static int add_two(void *args)
{
    ctr++;
    ASYNC_pause_job();
    ctr++;

    return 2;
}

static int save_current(void *args)
{
    currjob = ASYNC_get_current_job();
    ASYNC_pause_job();

    return 1;
}

M
Matt Caswell 已提交
106 107
#define MAGIC_WAIT_FD   ((OSSL_ASYNC_FD)99)
static int waitfd(void *args)
M
Matt Caswell 已提交
108
{
M
Matt Caswell 已提交
109 110
    ASYNC_JOB *job;
    ASYNC_WAIT_CTX *waitctx;
M
Matt Caswell 已提交
111
    ASYNC_pause_job();
M
Matt Caswell 已提交
112 113 114 115 116 117 118 119
    job = ASYNC_get_current_job();
    if (job == NULL)
        return 0;
    waitctx = ASYNC_get_wait_ctx(job);
    if (waitctx == NULL)
        return 0;
    if(!ASYNC_WAIT_CTX_set_wait_fd(waitctx, waitctx, MAGIC_WAIT_FD, NULL, NULL))
        return 0;
M
Matt Caswell 已提交
120
    ASYNC_pause_job();
M
Matt Caswell 已提交
121 122 123

    if (!ASYNC_WAIT_CTX_clear_fd(waitctx, waitctx))
        return 0;
M
Matt Caswell 已提交
124 125 126 127

    return 1;
}

128 129 130 131 132 133 134 135 136 137
static int blockpause(void *args)
{
    ASYNC_block_pause();
    ASYNC_pause_job();
    ASYNC_unblock_pause();
    ASYNC_pause_job();

    return 1;
}

M
Matt Caswell 已提交
138
static int test_ASYNC_init_thread()
M
Matt Caswell 已提交
139 140 141
{
    ASYNC_JOB *job1 = NULL, *job2 = NULL, *job3 = NULL;
    int funcret1, funcret2, funcret3;
142
    ASYNC_WAIT_CTX *waitctx = NULL;
M
Matt Caswell 已提交
143

M
Matt Caswell 已提交
144
    if (       !ASYNC_init_thread(2, 0)
M
Matt Caswell 已提交
145 146
            || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
            || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
M
Matt Caswell 已提交
147
                != ASYNC_PAUSE
M
Matt Caswell 已提交
148
            || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
M
Matt Caswell 已提交
149
                != ASYNC_PAUSE
M
Matt Caswell 已提交
150
            || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
M
Matt Caswell 已提交
151
                != ASYNC_NO_JOBS
M
Matt Caswell 已提交
152
            || ASYNC_start_job(&job1, waitctx, &funcret1, only_pause, NULL, 0)
M
Matt Caswell 已提交
153
                != ASYNC_FINISH
M
Matt Caswell 已提交
154
            || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
M
Matt Caswell 已提交
155
                != ASYNC_PAUSE
M
Matt Caswell 已提交
156
            || ASYNC_start_job(&job2, waitctx, &funcret2, only_pause, NULL, 0)
M
Matt Caswell 已提交
157
                != ASYNC_FINISH
M
Matt Caswell 已提交
158
            || ASYNC_start_job(&job3, waitctx, &funcret3, only_pause, NULL, 0)
M
Matt Caswell 已提交
159 160 161 162
                != ASYNC_FINISH
            || funcret1 != 1
            || funcret2 != 1
            || funcret3 != 1) {
M
Matt Caswell 已提交
163
        fprintf(stderr, "test_ASYNC_init_thread() failed\n");
M
Matt Caswell 已提交
164
        ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
165
        ASYNC_cleanup_thread();
M
Matt Caswell 已提交
166 167 168
        return 0;
    }

M
Matt Caswell 已提交
169
    ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
170
    ASYNC_cleanup_thread();
M
Matt Caswell 已提交
171 172 173 174 175 176 177
    return 1;
}

static int test_ASYNC_start_job()
{
    ASYNC_JOB *job = NULL;
    int funcret;
178
    ASYNC_WAIT_CTX *waitctx = NULL;
M
Matt Caswell 已提交
179 180 181

    ctr = 0;

M
Matt Caswell 已提交
182
    if (       !ASYNC_init_thread(1, 0)
M
Matt Caswell 已提交
183 184 185
            || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
            || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
               != ASYNC_PAUSE
M
Matt Caswell 已提交
186
            || ctr != 1
M
Matt Caswell 已提交
187 188
            || ASYNC_start_job(&job, waitctx, &funcret, add_two, NULL, 0)
               != ASYNC_FINISH
M
Matt Caswell 已提交
189 190 191
            || ctr != 2
            || funcret != 2) {
        fprintf(stderr, "test_ASYNC_start_job() failed\n");
M
Matt Caswell 已提交
192
        ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
193
        ASYNC_cleanup_thread();
M
Matt Caswell 已提交
194 195 196
        return 0;
    }

M
Matt Caswell 已提交
197
    ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
198
    ASYNC_cleanup_thread();
M
Matt Caswell 已提交
199 200 201 202 203 204 205
    return 1;
}

static int test_ASYNC_get_current_job()
{
    ASYNC_JOB *job = NULL;
    int funcret;
206
    ASYNC_WAIT_CTX *waitctx = NULL;
M
Matt Caswell 已提交
207 208 209

    currjob = NULL;

M
Matt Caswell 已提交
210
    if (       !ASYNC_init_thread(1, 0)
M
Matt Caswell 已提交
211 212
            || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
            || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
M
Matt Caswell 已提交
213 214
                != ASYNC_PAUSE
            || currjob != job
M
Matt Caswell 已提交
215
            || ASYNC_start_job(&job, waitctx, &funcret, save_current, NULL, 0)
M
Matt Caswell 已提交
216 217 218
                != ASYNC_FINISH
            || funcret != 1) {
        fprintf(stderr, "test_ASYNC_get_current_job() failed\n");
M
Matt Caswell 已提交
219
        ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
220
        ASYNC_cleanup_thread();
M
Matt Caswell 已提交
221 222 223
        return 0;
    }

M
Matt Caswell 已提交
224
    ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
225
    ASYNC_cleanup_thread();
M
Matt Caswell 已提交
226 227 228
    return 1;
}

M
Matt Caswell 已提交
229
static int test_ASYNC_WAIT_CTX_get_all_fds()
M
Matt Caswell 已提交
230 231
{
    ASYNC_JOB *job = NULL;
M
Matt Caswell 已提交
232
    int funcret;
233
    ASYNC_WAIT_CTX *waitctx = NULL;
M
Matt Caswell 已提交
234 235
    OSSL_ASYNC_FD fd = OSSL_BAD_ASYNC_FD, delfd = OSSL_BAD_ASYNC_FD;
    size_t numfds, numdelfds;
M
Matt Caswell 已提交
236

M
Matt Caswell 已提交
237
    if (       !ASYNC_init_thread(1, 0)
M
Matt Caswell 已提交
238 239 240
            || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
               /* On first run we're not expecting any wait fds */
            || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
M
Matt Caswell 已提交
241
                != ASYNC_PAUSE
M
Matt Caswell 已提交
242 243 244 245 246 247 248 249
            || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
            || numfds != 0
            || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
                                               &numdelfds)
            || numfds != 0
            || numdelfds != 0
               /* On second run we're expecting one added fd */
            || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
M
Matt Caswell 已提交
250
                != ASYNC_PAUSE
M
Matt Caswell 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264
            || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
            || numfds != 1
            || !ASYNC_WAIT_CTX_get_all_fds(waitctx, &fd, &numfds)
            || fd != MAGIC_WAIT_FD
            || (fd = OSSL_BAD_ASYNC_FD, 0) /* Assign to something else */
            || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
                                              &numdelfds)
            || numfds != 1
            || numdelfds != 0
            || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, &fd, &numfds, NULL,
                                               &numdelfds)
            || fd != MAGIC_WAIT_FD
               /* On final run we expect one deleted fd */
            || ASYNC_start_job(&job, waitctx, &funcret, waitfd, NULL, 0)
M
Matt Caswell 已提交
265
                != ASYNC_FINISH
M
Matt Caswell 已提交
266 267 268 269 270 271 272 273 274
            || !ASYNC_WAIT_CTX_get_all_fds(waitctx, NULL, &numfds)
            || numfds != 0
            || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, NULL,
                                               &numdelfds)
            || numfds != 0
            || numdelfds != 1
            || !ASYNC_WAIT_CTX_get_changed_fds(waitctx, NULL, &numfds, &delfd,
                                               &numdelfds)
            || delfd != MAGIC_WAIT_FD
M
Matt Caswell 已提交
275 276
            || funcret != 1) {
        fprintf(stderr, "test_ASYNC_get_wait_fd() failed\n");
M
Matt Caswell 已提交
277
        ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
278
        ASYNC_cleanup_thread();
M
Matt Caswell 已提交
279 280 281
        return 0;
    }

M
Matt Caswell 已提交
282
    ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
283
    ASYNC_cleanup_thread();
M
Matt Caswell 已提交
284 285
    return 1;
}
286 287 288 289 290

static int test_ASYNC_block_pause()
{
    ASYNC_JOB *job = NULL;
    int funcret;
291
    ASYNC_WAIT_CTX *waitctx = NULL;
292

M
Matt Caswell 已提交
293
    if (       !ASYNC_init_thread(1, 0)
M
Matt Caswell 已提交
294 295
            || (waitctx = ASYNC_WAIT_CTX_new()) == NULL
            || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
296
                != ASYNC_PAUSE
M
Matt Caswell 已提交
297
            || ASYNC_start_job(&job, waitctx, &funcret, blockpause, NULL, 0)
298 299 300
                != ASYNC_FINISH
            || funcret != 1) {
        fprintf(stderr, "test_ASYNC_block_pause() failed\n");
M
Matt Caswell 已提交
301
        ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
302
        ASYNC_cleanup_thread();
303 304 305
        return 0;
    }

M
Matt Caswell 已提交
306
    ASYNC_WAIT_CTX_free(waitctx);
M
Matt Caswell 已提交
307
    ASYNC_cleanup_thread();
308 309 310
    return 1;
}

M
Matt Caswell 已提交
311
#endif
M
Matt Caswell 已提交
312 313 314 315 316 317 318

int main(int argc, char **argv)
{

#ifdef ASYNC_NULL
    fprintf(stderr, "NULL implementation - skipping async tests\n");
#else
R
Rich Salz 已提交
319
    CRYPTO_set_mem_debug(1);
M
Matt Caswell 已提交
320 321
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

M
Matt Caswell 已提交
322
    if (       !test_ASYNC_init_thread()
M
Matt Caswell 已提交
323 324
            || !test_ASYNC_start_job()
            || !test_ASYNC_get_current_job()
M
Matt Caswell 已提交
325
            || !test_ASYNC_WAIT_CTX_get_all_fds()
326
            || !test_ASYNC_block_pause()) {
M
Matt Caswell 已提交
327 328 329 330 331 332
        return 1;
    }
#endif
    printf("PASS\n");
    return 0;
}