aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-07-24 10:41:11 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-07-24 13:44:42 +0100
commitcc74ad91a55c681634227c26e27f5b10fbe05ded (patch)
treedcbf0a2b0258b3cce4b06167d92c0c68e4469bd0
parenta93ecd3a4ed47a8ec57f5100919323e752cb83ef (diff)
downloadsyslinux-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--Makefile1
-rw-r--r--core/Makefile6
-rw-r--r--core/mem/tests/Makefile17
-rw-r--r--core/mem/tests/meminit.c115
-rw-r--r--efi/Makefile4
-rw-r--r--tests/unittest/include/thread.h0
6 files changed, 142 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index e9c16545..cceb66ef 100644
--- a/Makefile
+++ b/Makefile
@@ -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