diff options
Diffstat (limited to 'tests/gtp/queue_test.c')
-rw-r--r-- | tests/gtp/queue_test.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/tests/gtp/queue_test.c b/tests/gtp/queue_test.c new file mode 100644 index 0000000..bcc6d15 --- /dev/null +++ b/tests/gtp/queue_test.c @@ -0,0 +1,232 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <arpa/inet.h> + +#include <osmocom/core/utils.h> +#include <osmocom/core/application.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/bits.h> + +#include "../../lib/syserr.h" +#include "../../gtp/queue.h" + +static const struct qmsg_t qmsg_zero; + +static void queue_print(struct queue_t *queue, char* str) +{ + int n; + printf("=== [Queue %s] Next: %d First: %d Last: %d\n", str, + queue->next, queue->first, queue->last); + printf("#\tseq\tnext\tprev\ttimeout\tretrans\ttype\tcbp\n"); + for (n = 0; n < QUEUE_SIZE; n++) { + if (queue->qmsga[n].state == 0) { + /* Nothing there, validate everything is zeroed */ + OSMO_ASSERT(memcmp(&qmsg_zero, &queue->qmsga[n], sizeof(qmsg_zero)) == 0); + continue; + } + printf("%d\t%d\t%d\t%d\t%d\t%d\t%u\t%ld\n", + n, + queue->qmsga[n].seq, + queue->qmsga[n].next, + queue->qmsga[n].prev, + (int)queue->qmsga[n].timeout, + queue->qmsga[n].retrans, + queue->qmsga[n].type, + ((uintptr_t)queue->qmsga[n].cbp & 0xFFFFFFFF) + ); + } + printf("======================================================\n"); +} + +static void test_queue_empty() +{ + printf("***** Testing %s()\n", __func__); + struct queue_t *queue = NULL; + struct qmsg_t *qmsg = NULL; + uint16_t seq = 23; + uint8_t type = 0; + void *cbp = NULL; + struct sockaddr_in peer; + int rc; + + rc = inet_pton(AF_INET, "127.0.0.1", &(peer.sin_addr)); + OSMO_ASSERT(rc == 1); + + rc = queue_new(&queue); + OSMO_ASSERT(rc == 0); + queue_print(queue, "created"); + + rc = queue_getfirst(queue, &qmsg); + OSMO_ASSERT(rc == EOF); + rc = queue_seqget(queue, &qmsg, &peer, seq); + OSMO_ASSERT(rc == EOF); + rc = queue_freemsg_seq(queue, &peer, seq, &type, &cbp); + OSMO_ASSERT(rc==EOF); + + queue_print(queue, "pre-delete"); + rc = queue_free(queue); + OSMO_ASSERT(rc == 0); +} + +static void test_queue_one() +{ + printf("***** Testing %s()\n", __func__); + struct queue_t *queue = NULL; + struct qmsg_t *qmsg = NULL, *qmsg2 = NULL;; + uint16_t seq = 23; + uint8_t type = 0; + void *cbp = NULL; + struct sockaddr_in peer, peer2; + int rc; + + rc = inet_pton(AF_INET, "127.0.0.1", &(peer.sin_addr)); + OSMO_ASSERT(rc == 1); + rc = inet_pton(AF_INET, "127.0.0.2", &(peer2.sin_addr)); + OSMO_ASSERT(rc == 1); + + rc = queue_new(&queue); + OSMO_ASSERT(rc == 0); + queue_print(queue, "created"); + + rc = queue_newmsg(queue, &qmsg, &peer, seq); + OSMO_ASSERT(rc == 0); + queue_print(queue, "first added"); + qmsg->type = GTP_ECHO_REQ; + qmsg->cbp = (void*) 0x13243546; + qmsg->seq = seq; + + rc = queue_getfirst(queue, &qmsg2); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(qmsg == qmsg2); + + rc = queue_seqget(queue, &qmsg2, &peer, seq); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(qmsg == qmsg2); + rc = queue_seqget(queue, &qmsg, &peer2, seq); + OSMO_ASSERT(rc == EOF); + rc = queue_seqget(queue, &qmsg, &peer, seq + 1); + OSMO_ASSERT(rc == EOF); + queue_print(queue, "after-get"); + + rc = queue_back(queue, qmsg); + OSMO_ASSERT(rc == 0); + queue_print(queue, "after-back"); + + rc = queue_freemsg_seq(queue, &peer2, seq, &type, &cbp); + OSMO_ASSERT(rc == EOF); + rc = queue_freemsg_seq(queue, &peer, seq + 1, &type, &cbp); + OSMO_ASSERT(rc == EOF); + queue_print(queue, "pree-freemsg"); + rc = queue_freemsg_seq(queue, &peer, seq, &type, &cbp); + OSMO_ASSERT(rc == 0); + OSMO_ASSERT(type == GTP_ECHO_REQ); + OSMO_ASSERT(cbp == (void*)0x13243546); + + queue_print(queue, "pre-delete"); + rc = queue_free(queue); + OSMO_ASSERT(rc == 0); +} + +#define newmsg_fill(queue, qmsg_ptr, peer_ptr, seq) \ + do { \ + int rc = queue_newmsg(queue, &(qmsg_ptr), peer_ptr, seq); \ + OSMO_ASSERT(rc == 0); \ + OSMO_ASSERT(qmsg_ptr); \ + qmsg_ptr->type = GTP_CREATE_PDP_REQ; \ + qmsg_ptr->cbp = (void*)(uintptr_t)seq; \ + } while (0); + +#define freemsg_verify(seq, type, cbp) \ + do { \ + OSMO_ASSERT(type == GTP_CREATE_PDP_REQ); \ + OSMO_ASSERT(cbp == (void*)(uintptr_t)seq); \ + } while (0); + +static void test_queue_full() +{ + /* queue_newmsg until we receive EOF. Try moving back then. */ + printf("***** Testing %s()\n", __func__); + struct queue_t *queue = NULL; + struct qmsg_t *qmsg = NULL; + uint8_t type = 0; + void *cbp = NULL; + struct sockaddr_in peer; + int rc; + int i; + + rc = inet_pton(AF_INET, "127.0.0.1", &(peer.sin_addr)); + OSMO_ASSERT(rc == 1); + + rc = queue_new(&queue); + OSMO_ASSERT(rc == 0); + queue_print(queue, "created"); + + for (i = 0; i < QUEUE_SIZE - 1; i++) { + newmsg_fill(queue, qmsg, &peer, i); + } + queue_print(queue, "after-fill"); + + /* There's one slot left at the end, let's use first()->back() */ + rc = queue_getfirst(queue, &qmsg); + OSMO_ASSERT(rc == 0); + rc = queue_back(queue, qmsg); + OSMO_ASSERT(rc == 0); + queue_print(queue, "after-back"); + + /* Now let's fill last empty slot */ + newmsg_fill(queue, qmsg, &peer, QUEUE_SIZE - 1); + queue_print(queue, "after-full"); + + /* queue is now full, it should fail */ + rc = queue_newmsg(queue, &qmsg, &peer, QUEUE_SIZE); + OSMO_ASSERT(rc == EOF); + queue_print(queue, "after-failing-full"); + + /* Remove 1before-last msg (the one moved back) and make sure we can + re-add it at the end of the list */ + rc = queue_seqget(queue, &qmsg, &peer, 0); + OSMO_ASSERT(rc == 0); + rc = queue_freemsg(queue, qmsg); + queue_print(queue, "after-freeing-0"); + OSMO_ASSERT(rc == 0); + /* Now let's fill last empty slot which should be at the end */ + newmsg_fill(queue, qmsg, &peer, 0); + queue_print(queue, "after-refilling-0"); + + /* Now free first half seq set in increasing order */ + for (i = 0; i < QUEUE_SIZE / 2; i++) { + rc = queue_freemsg_seq(queue, &peer, i, &type, &cbp); + OSMO_ASSERT(rc == 0); + freemsg_verify(i, type, cbp); + } + queue_print(queue, "after-first-half-free"); + + /* Now free second half seq set in decreasing order */ + for (i = QUEUE_SIZE - 1; i >= QUEUE_SIZE / 2; i--) { + rc = queue_freemsg_seq(queue, &peer, i, &type, &cbp); + OSMO_ASSERT(rc == 0); + freemsg_verify(i, type, cbp); + } + queue_print(queue, "after-second-half-free"); + + rc = queue_free(queue); + OSMO_ASSERT(rc == 0); +} + +int main(int argc, char **argv) +{ + void *tall_ctx = talloc_named_const(NULL, 1, "Root context"); + msgb_talloc_ctx_init(tall_ctx, 0); + osmo_init_logging2(tall_ctx, &log_info); + log_set_use_color(osmo_stderr_target, 0); + log_set_print_filename(osmo_stderr_target, 0); + + test_queue_empty(); + test_queue_one(); + test_queue_full(); + + return 0; +} |