summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2021-02-14 14:50:44 -0500
committerPeter Jones <pjones@redhat.com>2021-02-25 10:15:14 -0500
commit9ca8e9a633501c3ec3c95d2576b795eee8d9b1cc (patch)
tree00bb38ceba093b70cb1f54a85dac69c4e3de7532
parent73322ba087d10d06b0656816bf4b7ba80b02c751 (diff)
downloadefi-boot-shim-9ca8e9a633501c3ec3c95d2576b795eee8d9b1cc.tar.gz
efi-boot-shim-9ca8e9a633501c3ec3c95d2576b795eee8d9b1cc.zip
make 'make test' able to run unit test harnesses
This adds a couple of make targets to do unit tests that are linked to libc: test-FOO : builds and runs test-FOO for any test-FOO.c test : builds and runs all test-FOO tests Note that building and running this test does not quite work yet /on this branch/. In order to do that, we need some cleanups and reorganizing that I don't want to push just yet, which can be found on https://github.com/rhboot/shim/tree/test-reorg Signed-off-by: Peter Jones <pjones@redhat.com>
-rw-r--r--.gitignore2
-rw-r--r--Makefile13
-rw-r--r--include/test.h123
-rw-r--r--include/test.mk45
-rw-r--r--shim.h11
-rw-r--r--test.c63
6 files changed, 256 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 811ca69d..9f492510 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,4 +32,6 @@
/scan-results/
[Ss]creenlog*
shim_cert.h
+test-*
+!test-*.c
version.c
diff --git a/Makefile b/Makefile
index 5dc745b3..87115b6f 100644
--- a/Makefile
+++ b/Makefile
@@ -240,6 +240,17 @@ else
$(PESIGN) -n certdb -i $< -c "shim" -s -o $@ -f
endif
+test :
+ @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" all
+
+$(patsubst %.c,%,$(wildcard test-*.c)) :
+ @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" $@
+
+.PHONY : $(patsubst %.c,%,$(wildcard test-*.c)) test
+
+clean-test-objs:
+ @make -f include/test.mk EFI_INCLUDES="$(EFI_INCLUDES)" ARCH_DEFINES="$(ARCH_DEFINES)" clean
+
clean-shim-objs:
$(MAKE) -C lib -f $(TOPDIR)/lib/Makefile clean
@rm -rvf $(TARGET) *.o $(SHIM_OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb $(BOOTCSVNAME)
@@ -247,7 +258,7 @@ clean-shim-objs:
@rm -vf Cryptlib/*.[oa] Cryptlib/*/*.[oa]
@if [ -d .git ] ; then git clean -f -d -e 'Cryptlib/OpenSSL/*'; fi
-clean: clean-shim-objs
+clean: clean-shim-objs clean-test-objs
$(MAKE) -C Cryptlib -f $(TOPDIR)/Cryptlib/Makefile clean
$(MAKE) -C Cryptlib/OpenSSL -f $(TOPDIR)/Cryptlib/OpenSSL/Makefile clean
diff --git a/include/test.h b/include/test.h
new file mode 100644
index 00000000..6fc178ba
--- /dev/null
+++ b/include/test.h
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * test.h - fake a bunch of EFI types so we can build test harnesses with libc
+ * Copyright Peter Jones <pjones@redhat.com>
+ */
+
+#ifdef SHIM_UNIT_TEST
+#ifndef TEST_H_
+#define TEST_H_
+
+#include <stdarg.h>
+
+#if defined(__aarch64__)
+#include <aa64/efibind.h>
+#elif defined(__arm__)
+#include <arm/efibind.h>
+#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
+#include <ia32/efibind.h>
+#elif defined(__x86_64__)
+#include <x64/efibind.h>
+#else
+#error what arch is this
+#endif
+
+#include <efidef.h>
+
+#include <efidevp.h>
+#include <efiprot.h>
+#include <eficon.h>
+#include <efiapi.h>
+#include <efierr.h>
+
+#include <efipxebc.h>
+#include <efinet.h>
+#include <efiip.h>
+
+#include <stdlib.h>
+
+#define ZeroMem(buf, sz) memset(buf, 0, sz)
+#define SetMem(buf, sz, value) memset(buf, value, sz)
+#define CopyMem(dest, src, len) memcpy(dest, src, len)
+#define CompareMem(dest, src, len) memcmp(dest, src, len)
+
+#include <assert.h>
+
+#define AllocateZeroPool(x) calloc(1, (x))
+#define AllocatePool(x) malloc(x)
+#define FreePool(x) free(x)
+#define ReallocatePool(old, oldsz, newsz) realloc(old, newsz)
+
+extern int debug;
+#ifdef dprint
+#undef dprint
+#define dprint(fmt, ...) {( if (debug) printf("%s:%d:" fmt, __func__, __LINE__, ##__VA_ARGS__); })
+#endif
+
+#define eassert(cond, fmt, ...) \
+ ({ \
+ if (!(cond)) { \
+ printf("%s:%d:" fmt, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ } \
+ assert(cond); \
+ })
+
+#define assert_equal_return(a, b, status, fmt, ...) \
+ ({ \
+ if (!((a) == (b))) { \
+ printf("%s:%d:" fmt, __func__, __LINE__, (a), (b), \
+ ##__VA_ARGS__); \
+ printf("%s:%d:Assertion `%s' failed.\n", __func__, \
+ __LINE__, __stringify(a == b)); \
+ return status; \
+ } \
+ })
+
+#define assert_return(cond, status, fmt, ...) \
+ ({ \
+ if (!(cond)) { \
+ printf("%s:%d:" fmt, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ printf("%s:%d:Assertion `%s' failed.\n", __func__, \
+ __LINE__, __stringify(cond)); \
+ return status; \
+ } \
+ })
+
+#define assert_goto(cond, label, fmt, ...) \
+ ({ \
+ if (!(cond)) { \
+ printf("%s:%d:" fmt, __func__, __LINE__, \
+ ##__VA_ARGS__); \
+ printf("%s:%d:Assertion `%s' failed.\n", __func__, \
+ __LINE__, __stringify(cond)); \
+ goto label; \
+ } \
+ })
+
+#define assert_equal_goto(a, b, label, fmt, ...) \
+ ({ \
+ if (!((a) == (b))) { \
+ printf("%s:%d:" fmt, __func__, __LINE__, (a), (b), \
+ ##__VA_ARGS__); \
+ printf("%s:%d:Assertion `%s' failed.\n", __func__, \
+ __LINE__, __stringify(a == b)); \
+ goto label; \
+ } \
+ })
+
+#define test(x, ...) \
+ ({ \
+ int rc; \
+ printf("running %s\n", __stringify(x)); \
+ rc = x(__VA_ARGS__); \
+ if (rc < 0) \
+ status = 1; \
+ printf("%s: %s\n", __stringify(x), \
+ rc < 0 ? "failed" : "passed"); \
+ })
+
+#endif /* !TEST_H_ */
+#endif /* SHIM_UNIT_TEST */
+// vim:fenc=utf-8:tw=75:noet
diff --git a/include/test.mk b/include/test.mk
new file mode 100644
index 00000000..f70fdaa9
--- /dev/null
+++ b/include/test.mk
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# test.mk - makefile to make local test programs
+#
+
+.SUFFIXES:
+
+CC = gcc
+VALGRIND ?=
+DEBUG_PRINTS ?= 0
+CFLAGS = -O2 -ggdb -std=gnu11 \
+ -isystem $(TOPDIR)/include/system \
+ $(EFI_INCLUDES) \
+ -Iinclude -iquote . \
+ -fshort-wchar -flto -fno-builtin \
+ -Wall \
+ -Wextra \
+ -Wsign-compare \
+ -Wno-deprecated-declarations \
+ -Wno-pointer-sign \
+ -Wno-unused \
+ -Werror \
+ -Werror=nonnull \
+ -Werror=nonnull-compare \
+ $(ARCH_DEFINES) \
+ -DEFI_FUNCTION_WRAPPER \
+ -DGNU_EFI_USE_MS_ABI -DPAGE_SIZE=4096 \
+ -DSHIM_UNIT_TEST \
+ "-DDEFAULT_DEBUG_PRINT_STATE=$(DEBUG_PRINTS)"
+
+tests := $(patsubst %.c,%,$(wildcard test-*.c))
+
+$(tests) :: test-% : test.c test-%.c $(test-%_FILES)
+ $(CC) $(CFLAGS) -o $@ $^ $(wildcard $*.c) $(test-$*_FILES)
+ $(VALGRIND) ./$@
+
+test : $(tests)
+
+all : test
+
+clean :
+
+.PHONY: $(tests) all test clean
+
+# vim:ft=make
diff --git a/shim.h b/shim.h
index 55b0aa28..0a6c8cfa 100644
--- a/shim.h
+++ b/shim.h
@@ -26,15 +26,21 @@
#endif
#endif
+#ifndef SHIM_UNIT_TEST
#include <efi.h>
#include <efilib.h>
#undef uefi_call_wrapper
#include <efierr.h>
#include <efiip.h>
+#endif
#include <stddef.h>
#include <stdint.h>
+#ifdef SHIM_UNIT_TEST
+#include "include/test.h"
+#endif
+
#ifdef __x86_64__
#ifndef DEFAULT_LOADER
#define DEFAULT_LOADER L"\\grubx64.efi"
@@ -222,6 +228,7 @@ verify_buffer (char *data, int datasize,
PE_COFF_LOADER_IMAGE_CONTEXT *context,
UINT8 *sha256hash, UINT8 *sha1hash);
+#ifndef SHIM_UNIT_TEST
#define perror_(file, line, func, fmt, ...) ({ \
UINTN __perror_ret = 0; \
if (!in_protocol) \
@@ -233,5 +240,9 @@ verify_buffer (char *data, int datasize,
perror_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__)
#define LogError(fmt, ...) \
LogError_(__FILE__, __LINE__ - 1, __func__, fmt, ##__VA_ARGS__)
+#else
+#define perror(fmt, ...)
+#define LogError(fmt, ...)
+#endif
#endif /* SHIM_H_ */
diff --git a/test.c b/test.c
new file mode 100644
index 00000000..b21e2191
--- /dev/null
+++ b/test.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * test.c - stuff we need for test harnesses
+ * Copyright Peter Jones <pjones@redhat.com>
+ */
+
+#ifndef SHIM_UNIT_TEST
+#define SHIM_UNIT_TEST
+#endif
+#include "shim.h"
+
+UINT8 in_protocol = 0;
+int debug = DEFAULT_DEBUG_PRINT_STATE;
+
+EFI_STATUS LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...)
+{
+ assert(0);
+ return EFI_SUCCESS;
+}
+
+INTN
+StrCmp(CONST CHAR16 *s1, CONST CHAR16 *s2) {
+ assert(s1 != NULL);
+ assert(s2 != NULL);
+
+ int i;
+ for (i = 0; s1[i] && s2[i]; i++) {
+ if (s1[i] != s2[i])
+ return s2[i] - s1[i];
+ }
+ return 0;
+}
+
+INTN
+StrnCmp(CONST CHAR16 *s1, CONST CHAR16 *s2, UINTN len) {
+ assert(s1 != NULL);
+ assert(s2 != NULL);
+
+ UINTN i;
+ for (i = 0; i < len && s1[i] && s2[i]; i++) {
+ if (s1[i] != s2[i])
+ return s2[i] - s1[i];
+
+ }
+ return 0;
+}
+
+EFI_STATUS
+get_variable_attr(const CHAR16 * const var, UINT8 **data, UINTN *len,
+ EFI_GUID owner, UINT32 *attributes)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+get_variable(const CHAR16 * const var, UINT8 **data, UINTN *len, EFI_GUID owner)
+{
+ return get_variable_attr(var, data, len, owner, NULL);
+}
+
+EFI_GUID SHIM_LOCK_GUID = {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } };
+
+// vim:fenc=utf-8:tw=75:noet