From fe21cbb973f592f82353418a55d07e4d8638f3c5 Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Wed, 20 Sep 2017 00:19:58 +0100 Subject: [PATCH] Add unit tests for address cache. --- Makefile | 3 +- src/addrcache.h | 2 +- tests/07-addrcache.t | 29 ++++++ tests/addrcache.c | 215 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 247 insertions(+), 2 deletions(-) create mode 100644 tests/07-addrcache.t create mode 100644 tests/addrcache.c diff --git a/Makefile b/Makefile index 3bb528c..58abf76 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ BIN_FILES := $(shell cat manifest.bin.txt) SRC_FILES := $(shell cat manifest.src.txt) # Tests to compile before running the test suite. -TESTS := tests/addr.exe tests/ethernet.exe +TESTS := tests/addr.exe tests/addrcache.exe tests/ethernet.exe # Tools to compile before running the test suite. TOOLS := tools/socket.exe tools/list-interfaces.exe tools/bind.exe tools/ipx-send.exe \ @@ -168,6 +168,7 @@ test-prep: $(TESTS) $(TOOLS) $(TOOL_DLLS) .PHONY: tools test-prep tests/addr.exe: tests/addr.o tests/tap/basic.o src/addr.o +tests/addrcache.exe: tests/addrcache.o tests/tap/basic.o src/addrcache.o src/addr.o tests/ethernet.exe: tests/ethernet.o tests/tap/basic.o src/ethernet.o src/addr.o tests/%.exe: tests/%.o diff --git a/src/addrcache.h b/src/addrcache.h index 3462d1c..64a6686 100644 --- a/src/addrcache.h +++ b/src/addrcache.h @@ -18,8 +18,8 @@ #ifndef _ADDRCACHE_H #define _ADDRCACHE_H -#include #include +#include #include #include "common.h" diff --git a/tests/07-addrcache.t b/tests/07-addrcache.t new file mode 100644 index 0000000..d7ae61a --- /dev/null +++ b/tests/07-addrcache.t @@ -0,0 +1,29 @@ +# IPXWrapper test suite +# Copyright (C) 2017 Daniel Collins +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +use strict; +use warnings; + +use FindBin; + +require "$FindBin::Bin/config.pm"; +our $remote_ip_a; + +# Unit tests implemented by addrcache.exe, so run it on the test system and +# pass the (TAP) output/exit status to our parent. + +system("ssh", $remote_ip_a, "Z:\\tests\\addrcache.exe"); +exit($? >> 8); diff --git a/tests/addrcache.c b/tests/addrcache.c new file mode 100644 index 0000000..2783fdf --- /dev/null +++ b/tests/addrcache.c @@ -0,0 +1,215 @@ +/* IPXWrapper test suite + * Copyright (C) 2017 Daniel Collins + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include "src/addr.h" +#include "src/addrcache.h" +#include "src/common.h" +#include "tests/tap/basic.h" + +/* Mock time() so we can test timing out of address cache records */ + +static time_t now = 0; + +time_t __cdecl time(time_t *_Time) +{ + if(_Time != NULL) + { + *_Time = now; + } + + return now; +} + +/* Need to implement log_printf() and w32_error() for addrcache.c */ + +void log_printf(enum ipx_log_level level, const char *fmt, ...) +{ + va_list argv; + + va_start(argv, fmt); + vfprintf(stderr, fmt, argv); + va_end(argv); + + fprintf(stderr, "\n"); +} + +const char *w32_error(DWORD errnum) { + static char buf[1024] = {'\0'}; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errnum, 0, buf, 1023, NULL); + buf[strcspn(buf, "\r\n")] = '\0'; + return buf; +} + +int main() +{ + plan_lazy(); + + { + addr_cache_init(); + + SOCKADDR_STORAGE addr; + size_t addrlen; + + ok(!addr_cache_get(&addr, &addrlen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1), + "addr_cache_get() returns false when no addresses are known"); + + addr_cache_cleanup(); + } + + { + addr_cache_init(); + + struct sockaddr_in addr_in; + memset(&addr_in, 0xAB, sizeof(addr_in)); + + addr_cache_set((struct sockaddr*)(&addr_in), sizeof(addr_in), + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1); + + SOCKADDR_STORAGE addr_out; + size_t aolen; + + if(ok(addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1), + "addr_cache_get() returns true when address is known")) + { + is_int(sizeof(addr_in), aolen, "addr_cache_get() returns correct address length"); + is_blob(&addr_in, &addr_out, sizeof(addr_in), "addr_cache_get() returns correct address data"); + } + + addr_cache_cleanup(); + } + + { + addr_cache_init(); + + struct sockaddr_in addr_in; + memset(&addr_in, 0xAB, sizeof(addr_in)); + + addr_cache_set((struct sockaddr*)(&addr_in), sizeof(addr_in), + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1); + + SOCKADDR_STORAGE addr_out; + size_t aolen; + + now += 29; + + if(ok(addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1), + "addr_cache_get() returns true when address is about to expire")) + { + is_int(sizeof(addr_in), aolen, "addr_cache_get() returns correct address length"); + is_blob(&addr_in, &addr_out, sizeof(addr_in), "addr_cache_get() returns correct address data"); + } + + now += 1; + + ok(!addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1), + "addr_cache_get() returns false when address has expired"); + + addr_cache_cleanup(); + } + + { + addr_cache_init(); + + struct sockaddr_in addr_in; + memset(&addr_in, 0xAB, sizeof(addr_in)); + + addr_cache_set((struct sockaddr*)(&addr_in), sizeof(addr_in), + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1); + + SOCKADDR_STORAGE addr_out; + size_t aolen; + + ok(!addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x02}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1), + "addr_cache_get() returns false when network number differs"); + + addr_cache_cleanup(); + } + + { + addr_cache_init(); + + struct sockaddr_in addr_in; + memset(&addr_in, 0xAB, sizeof(addr_in)); + + addr_cache_set((struct sockaddr*)(&addr_in), sizeof(addr_in), + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1); + + SOCKADDR_STORAGE addr_out; + size_t aolen; + + ok(!addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x02}), + 1), + "addr_cache_get() returns false when node number differs"); + + addr_cache_cleanup(); + } + + { + addr_cache_init(); + + struct sockaddr_in addr_in; + memset(&addr_in, 0xAB, sizeof(addr_in)); + + addr_cache_set((struct sockaddr*)(&addr_in), sizeof(addr_in), + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 1); + + SOCKADDR_STORAGE addr_out; + size_t aolen; + + ok(!addr_cache_get(&addr_out, &aolen, + addr32_in((unsigned char[]){0x00, 0x00, 0x00, 0x01}), + addr48_in((unsigned char[]){0x00, 0x00, 0x00, 0x00, 0x00, 0x01}), + 2), + "addr_cache_get() returns false when socket number differs"); + + addr_cache_cleanup(); + } + + return 0; +}