diff options
Diffstat (limited to 'extras/dispatch/tests/server_test.c')
-rw-r--r-- | extras/dispatch/tests/server_test.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/extras/dispatch/tests/server_test.c b/extras/dispatch/tests/server_test.c new file mode 100644 index 0000000000..adeab62af9 --- /dev/null +++ b/extras/dispatch/tests/server_test.c @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <qpid/dispatch/timer.h> +#include "test_case.h" +#include <qpid/dispatch/server.h> +#include <qpid/dispatch/user_fd.h> +#include <qpid/dispatch/threading.h> +#include <qpid/dispatch/log.h> + +#define THREAD_COUNT 4 +#define OCTET_COUNT 100 + +static sys_mutex_t *test_lock; + +static void *expected_context; +static int call_count; +static int threads_seen[THREAD_COUNT]; +static char stored_error[512]; + +static int write_count; +static int read_count; +static int fd[2]; +static dx_user_fd_t *ufd_write; +static dx_user_fd_t *ufd_read; + + +static void thread_start(void *context, int thread_id) +{ + sys_mutex_lock(test_lock); + if (context != expected_context && !stored_error[0]) + sprintf(stored_error, "Unexpected Context Value: %lx", (long) context); + if (thread_id >= THREAD_COUNT && !stored_error[0]) + sprintf(stored_error, "Thread_ID too large: %d", thread_id); + if (thread_id < 0 && !stored_error[0]) + sprintf(stored_error, "Thread_ID negative: %d", thread_id); + + call_count++; + if (thread_id >= 0 && thread_id < THREAD_COUNT) + threads_seen[thread_id]++; + + if (call_count == THREAD_COUNT) + dx_server_stop(); + sys_mutex_unlock(test_lock); +} + + +static int conn_handler(void *context, dx_conn_event_t event, dx_connection_t *conn) +{ + return 0; +} + + +static void ufd_handler(void *context, dx_user_fd_t *ufd) +{ + long dir = (long) context; + char buffer; + ssize_t len; + static int in_read = 0; + static int in_write = 0; + + if (dir == 0) { // READ + in_read++; + assert(in_read == 1); + if (!dx_user_fd_is_readable(ufd_read)) { + sprintf(stored_error, "Expected Readable"); + dx_server_stop(); + } else { + len = read(fd[0], &buffer, 1); + if (len == 1) { + read_count++; + if (read_count == OCTET_COUNT) + dx_server_stop(); + } + dx_user_fd_activate_read(ufd_read); + } + in_read--; + } else { // WRITE + in_write++; + assert(in_write == 1); + if (!dx_user_fd_is_writeable(ufd_write)) { + sprintf(stored_error, "Expected Writable"); + dx_server_stop(); + } else { + write(fd[1], "X", 1); + + write_count++; + if (write_count < OCTET_COUNT) + dx_user_fd_activate_write(ufd_write); + } + in_write--; + } +} + + +static void fd_test_start(void *context) +{ + dx_user_fd_activate_read(ufd_read); +} + + +static char* test_start_handler(void *context) +{ + int i; + + dx_server_initialize(THREAD_COUNT); + + expected_context = (void*) 0x00112233; + stored_error[0] = 0x0; + call_count = 0; + for (i = 0; i < THREAD_COUNT; i++) + threads_seen[i] = 0; + + dx_server_set_conn_handler(conn_handler); + dx_server_set_start_handler(thread_start, expected_context); + dx_server_run(); + dx_server_finalize(); + + if (stored_error[0]) return stored_error; + if (call_count != THREAD_COUNT) return "Incorrect number of thread-start callbacks"; + for (i = 0; i < THREAD_COUNT; i++) + if (threads_seen[i] != 1) return "Incorrect count on one thread ID"; + + return 0; +} + + +static char* test_user_fd(void *context) +{ + int res; + dx_timer_t *timer; + + dx_server_initialize(THREAD_COUNT); + dx_server_set_conn_handler(conn_handler); + dx_server_set_user_fd_handler(ufd_handler); + timer = dx_timer(fd_test_start, 0); + dx_timer_schedule(timer, 0); + + stored_error[0] = 0x0; + res = pipe2(fd, O_NONBLOCK); + if (res != 0) return "Error creating pipe2"; + + ufd_write = dx_user_fd(fd[1], (void*) 1); + ufd_read = dx_user_fd(fd[0], (void*) 0); + + dx_server_run(); + dx_timer_free(timer); + dx_server_finalize(); + close(fd[0]); + close(fd[1]); + + if (stored_error[0]) return stored_error; + if (write_count - OCTET_COUNT > 2) sprintf(stored_error, "Excessively high Write Count: %d", write_count); + if (read_count != OCTET_COUNT) sprintf(stored_error, "Incorrect Read Count: %d", read_count);; + + if (stored_error[0]) return stored_error; + return 0; +} + + +int server_tests(void) +{ + int result = 0; + test_lock = sys_mutex(); + dx_log_set_mask(LOG_NONE); + + TEST_CASE(test_start_handler, 0); + TEST_CASE(test_user_fd, 0); + + sys_mutex_free(test_lock); + return result; +} + |