summaryrefslogtreecommitdiff
path: root/extras/dispatch/tests/server_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'extras/dispatch/tests/server_test.c')
-rw-r--r--extras/dispatch/tests/server_test.c195
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;
+}
+