diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-07-24 10:41:11 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-07-24 13:44:42 +0100 |
commit | cc74ad91a55c681634227c26e27f5b10fbe05ded (patch) | |
tree | dcbf0a2b0258b3cce4b06167d92c0c68e4469bd0 | |
parent | a93ecd3a4ed47a8ec57f5100919323e752cb83ef (diff) | |
download | syslinux-cc74ad91a55c681634227c26e27f5b10fbe05ded.tar.gz syslinux-cc74ad91a55c681634227c26e27f5b10fbe05ded.tar.xz syslinux-cc74ad91a55c681634227c26e27f5b10fbe05ded.zip |
tests: unit tests for core/mem
We can exercise the memory subsystem through unit tests with a little
bit of coaxing. We need to create a number of fake data objects in order
to get it to build. This is less than ideal, but once we've got good
test coverage and confidence in our tests we can begin refactoring.
Had this unit test already been in place, commit 33c4ab1b ("mem: fix
regression in recent memscan changes") would have never been required
because buggy commit a1331f8d ("memscan: pass enum syslinux_memmap_types
around") would have broke the unit test. Ordinarily, this unit test
would have been part of the bugfix commit 33c4ab1b, but the bugfix needs
to be backported to 5.xx on its own.
test_mem_init_reserved() tests whether SMT_RESERVED regions are
incorrectly added to the memory subsystems's freelist.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | core/Makefile | 6 | ||||
-rw-r--r-- | core/mem/tests/Makefile | 17 | ||||
-rw-r--r-- | core/mem/tests/meminit.c | 115 | ||||
-rw-r--r-- | efi/Makefile | 4 | ||||
-rw-r--r-- | tests/unittest/include/thread.h | 0 |
6 files changed, 142 insertions, 1 deletions
@@ -103,6 +103,7 @@ $(filter-out $(private-targets), $(MAKECMDGOALS)): unittest: printf "Executing unit tests\n" + $(MAKE) -C core/mem/tests all $(MAKE) -C com32/lib/syslinux/tests all regression: diff --git a/core/Makefile b/core/Makefile index f795a5c8..a7503ef4 100644 --- a/core/Makefile +++ b/core/Makefile @@ -67,9 +67,13 @@ PXELINUX_CSRC = $(CORE_PXE_CSRC) \ LPXELINUX_OBJS = $(subst $(SRC)/,,$(LPXELINUX_CSRC:%.c=%.o)) PXELINUX_OBJS = $(subst $(SRC)/,,$(PXELINUX_CSRC:%.c=%.o)) -# Don't include console and network stack specific objects +UNITTEST_CSRC = $(shell find $(SRC) -path '*/tests/*.c' -print) +UNITTEST_OBJS = $(subst $(SRC)/,,$(UNITTEST_CSRC:%.c=%.o)) + +# Don't include console and network stack specific objects or unit tests FILTER_OBJS = %rawcon.o %plaincon.o %pxelinux-c.o %ldlinux-c.o \ %isolinux-c.o %localboot.o %pxeboot.o \ + $(subst $(OBJ)/,,$(UNITTEST_OBJS)) \ $(subst $(OBJ)/,,$(LPXELINUX_OBJS)) \ $(subst $(OBJ)/,,$(PXELINUX_OBJS)) diff --git a/core/mem/tests/Makefile b/core/mem/tests/Makefile new file mode 100644 index 00000000..d1fb7867 --- /dev/null +++ b/core/mem/tests/Makefile @@ -0,0 +1,17 @@ +CFLAGS = -g -I$(topdir)/tests/unittest/include + +tests = meminit +.INTERMEDIATE: $(tests) + +all: banner $(tests) + for t in $(tests); \ + do printf " [+] $$t passed\n" ; ./$$t ; done + +banner: + printf " Running memory subsystem unit tests...\n" + +meminit: meminit.c ../init.c + +%: %.c + $(CC) $(CFLAGS) -o $@ $< + diff --git a/core/mem/tests/meminit.c b/core/mem/tests/meminit.c new file mode 100644 index 00000000..e6c25c71 --- /dev/null +++ b/core/mem/tests/meminit.c @@ -0,0 +1,115 @@ +#include "unittest/unittest.h" +#include "unittest/memmap.h" + +/* + * Fake data objects. + * + * These are the dependencies required by mem_init(). + */ +struct com32_sys_args { + unsigned long cs_memsize; +} __com32 = { + .cs_memsize = 4 +}; +char __lowmem_heap[32]; +char free_high_memory[32]; + +#include "../init.c" + +void __inject_free_block(struct free_arena_header *ah) +{ +} + +static unsigned long free_start = (unsigned long)free_high_memory; + +static inline bool free_list_empty(void) +{ + if (__com32.cs_memsize != free_start) + return false; + + return true; +} + +static struct test_memmap_entry *__test_entries; +static size_t __test_nr_entries; + +int syslinux_scan_memory(scan_memory_callback_t callback, void *data) +{ + struct test_memmap_entry *e; + int i; + + for (i = 0; i < __test_nr_entries; i++) { + e = &__test_entries[i]; + callback(data, e->start, e->size, e->type); + } + + return 0; +} + +void __setup(struct test_memmap_entry *entries, size_t nr_entries) +{ + uint16_t __fake_free_mem = 64; + + bios_free_mem = &__fake_free_mem; + + __test_entries = entries; + __test_nr_entries = nr_entries; +} + +/* + * scan_highmem_area() will prepend a free arena header if the size of + * the region is larger than the following expression. Using this small + * size allows us to test the interface safely without worrying about + * scan_highmem_area() writing data to random parts of our address + * space. + */ +#define safe_entry_sz ((2 * sizeof(struct arena_header)) - 1) + +/* + * Can we add SMT_RESERVED regions to the free list? + */ +static int test_mem_init_reserved(void) +{ + struct test_memmap_entry entries[] = { + 0x2000, safe_entry_sz, SMT_RESERVED, + 0x100000, safe_entry_sz, SMT_RESERVED, + 0x2fffff, safe_entry_sz, SMT_RESERVED, + 0x400000, safe_entry_sz, SMT_RESERVED, + }; + + __setup(entries, array_sz(entries)); + + mem_init(); + syslinux_assert_str(free_list_empty(), + "Added SMT_RESERVED regions to free list"); + return 0; +} + +/* + * Can we add regions outside of the valid address range? + */ +static int test_mem_limits(void) +{ + struct test_memmap_entry entries[] = { + 0x00000000, safe_entry_sz, SMT_FREE, + 0x000fffff, safe_entry_sz, SMT_FREE, + E820_MEM_MAX + 1, safe_entry_sz, SMT_FREE, + }; + + __setup(entries, array_sz(entries)); + + mem_init(); + syslinux_assert_str(free_list_empty(), + "Added regions outside of valid range to free list"); + + return 0; +} + + +int main(int argc, char **argv) +{ + test_mem_init_reserved(); + test_mem_limits(); + + return 0; +} diff --git a/efi/Makefile b/efi/Makefile index d7b6cee8..a818abe0 100644 --- a/efi/Makefile +++ b/efi/Makefile @@ -27,6 +27,10 @@ FILTERED_OBJS:= $(subst $(core),$(OBJ)/../core/,$(patsubst %.c,%.o, \ $(wildcard $(core)/fs/pxe/*.c) \ $(wildcard $(core)/thread/*.c))) +# Don't include unit tests +FILTERED_OBJS += $(subst $(core),$(OBJ)/../core/, \ + $(patsubst %.c,%.o,$(shell find $(core) -path "*/tests/*.c" -print))) + # Don't include console objects CORE_OBJS = $(filter-out %hello.o %rawcon.o %plaincon.o %strcasecmp.o %bios.o \ %diskio_bios.o %ldlinux-c.o %isolinux-c.o %pxelinux-c.o \ diff --git a/tests/unittest/include/thread.h b/tests/unittest/include/thread.h new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/unittest/include/thread.h |