Run some tests under qemu when cross-compiling
BUG=chromium-os:26317
BRANCH=none
TEST=manual
sudo FEATURES=test emerge vboot_reference
FEATURES=test emerge-link vboot_reference chromeos-u-boot chromeos-installer
FEATURES=test emerge-daisy vboot_reference chromeos-u-boot chromeos-installer
make && make runtests (both inside and outside chroot)
Change-Id: Ie829e375736ce0df46ddd5a3345efb0ca7e33aba
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/41317
diff --git a/Makefile b/Makefile
index 93a612b..6752f55 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@
#
# to put the output somewhere else
BUILD ?= $(shell pwd)/build
+export BUILD
# Target for 'make install'
DESTDIR ?= /usr/bin
@@ -39,8 +40,7 @@
-fno-common -ffixed-r8 \
-mfloat-abi=hard -marm -mabi=aapcs-linux -mno-thumb-interwork \
$(COMMON_FLAGS)
-endif
-ifeq ($(FIRMWARE_ARCH), i386)
+else ifeq ($(FIRMWARE_ARCH), i386)
CC ?= i686-pc-linux-gnu-gcc
# Drop -march=i386 to permit use of SSE instructions
CFLAGS ?= \
@@ -48,15 +48,69 @@
-fomit-frame-pointer -fno-toplevel-reorder -fno-dwarf2-cfi-asm \
-mpreferred-stack-boundary=2 -mregparm=3 \
$(COMMON_FLAGS)
-endif
-ifeq ($(FIRMWARE_ARCH), x86_64)
+else ifeq ($(FIRMWARE_ARCH), x86_64)
CFLAGS ?= $(COMMON_FLAGS) \
-fvisibility=hidden -fno-strict-aliasing -fomit-frame-pointer
+else
+$(info FIRMWARE_ARCH not defined; assuming local compile.)
endif
-# Fix compiling directly on host (outside of emake)
+# Architecture detection
+HOST_ARCH ?= $(shell uname -m)
+
+# Pick a sane target architecture if none defined (building outside emake)
ifeq ($(ARCH),)
-ARCH = amd64
+ ARCH := $(HOST_ARCH)
+ ifeq ($(ARCH), x86_64)
+ ARCH := amd64
+ endif
+endif
+
+# Determine QEMU architecture needed, if any
+ifeq ($(ARCH),$(HOST_ARCH))
+ # Same architecture; no need for QEMU
+ QEMU_ARCH :=
+else ifeq ($(HOST_ARCH)-$(ARCH),x86_64-i386)
+ # 64-bit host can run 32-bit targets directly
+ QEMU_ARCH :=
+else ifeq ($(HOST_ARCH)-$(ARCH),x86_64-amd64)
+ # 64-bit host can run 64-bit directly
+ QEMU_ARCH :=
+else ifeq ($(ARCH),amd64)
+ QEMU_ARCH := x86_64
+else
+ QEMU_ARCH := $(ARCH)
+endif
+
+# The top of the chroot for qemu must be passed in via the SYSROOT environment
+# variable. In the Chromium OS chroot, this is done automatically by the
+# ebuild.
+
+# If SYSROOT is not defined, disable QEMU testing
+# TODO: which probably means attempting to test should simply fail
+ifneq ($(QEMU_ARCH),)
+ ifeq ($(SYSROOT),)
+ $(warning SYSROOT must be set to the top of the target-specific root \
+when cross-compiling for qemu-based tests to run properly.)
+ QEMU_ARCH :=
+ endif
+endif
+
+ifeq ($(QEMU_ARCH),)
+ # Path to build output for running tests is same as for building
+ BUILD_RUN = $(BUILD)
+else
+ $(info Using qemu for testing.)
+ # Path to build output for running tests is different in the chroot
+ BUILD_RUN = $(subst $(SYSROOT),,$(BUILD))
+
+ QEMU_BIN = qemu-$(QEMU_ARCH)
+ QEMU_OPTS = -drop-ld-preload \
+ -E LD_LIBRARY_PATH=/lib64:/lib:/usr/lib64:/usr/lib \
+ -E HOME=$(HOME) \
+ -E BUILD=$(BUILD_RUN)
+ QEMU_CMD = sudo chroot $(SYSROOT) $(BUILD_RUN)/$(QEMU_BIN) $(QEMU_OPTS) --
+ RUNTEST = $(QEMU_CMD)
endif
# Some things only compile inside the Chromium OS chroot
@@ -86,6 +140,7 @@
CFLAGS += -MMD -MF $@.d
# Code coverage
+# Run like this: COV=1 make runtests coverage
ifneq (${COV},)
#COV_FLAGS = -O0 -fprofile-arcs -ftest-coverage
COV_FLAGS = -O0 --coverage
@@ -149,6 +204,7 @@
install: cgpt_install utils_install
# Coverage
+# TODO: only if COV=1
COV_INFO = $(BUILD)/coverage.info
#coverage: runtests
.PHONY: coverage
@@ -203,8 +259,6 @@
endif
ifeq ($(FIRMWARE_ARCH),)
-$(warning FIRMWARE_ARCH not defined; assuming local compile)
-
# Disable rollback TPM when compiling locally, since otherwise
# load_kernel_test attempts to talk to the TPM.
$(FWLIB): CFLAGS += -DDISABLE_ROLLBACK_TPM
@@ -646,12 +700,34 @@
# Targets to run tests
# Frequently-run tests
+TEST_TARGETS = runcgpttests runmisctests
+
+ifeq ($(MINIMAL),)
+# Bitmap utility isn't compiled for minimal variant
+TEST_TARGETS += runbmptests
+# Scripts don't work under qemu testing
+# TODO: convert scripts to makefile so they can be called directly
+TEST_TARGETS += runtestscripts
+endif
+
+# Qemu setup for cross-compiled tests. Need to copy qemu binary into the
+# sysroot.
+ifneq ($(QEMU_ARCH),)
+TEST_SETUP += qemu_install
+
+.PHONY: qemu_install
+qemu_install:
+ @printf " Copying qemu binary.\n"
+ $(Q)cp -fu /usr/bin/$(QEMU_BIN) $(BUILD)/$(QEMU_BIN)
+ $(Q)chmod a+rx $(BUILD)/$(QEMU_BIN)
+endif
+
.PHONY: runtests
-runtests: runbmptests runcgpttests runfuzztests runmisctests
+runtests: $(TEST_TARGETS)
# Generate test keys
.PHONY: genkeys
-genkeys:
+genkeys: utils
tests/gen_test_keys.sh
# Generate test cases for fuzzing
@@ -660,47 +736,46 @@
tests/gen_fuzz_test_cases.sh
.PHONY: runbmptests
-runbmptests: utils
- cd tests/bitmaps && BMPBLK=${BUILD}/utility/bmpblk_utility \
+runbmptests: $(TEST_SETUP) utils
+ cd tests/bitmaps && BMPBLK=$(BUILD_RUN)/utility/bmpblk_utility \
./TestBmpBlock.py -v
.PHONY: runcgpttests
-runcgpttests: cgpt tests
- ${BUILD}/tests/cgptlib_test
- tests/run_cgpt_tests.sh ${BUILD}/cgpt/cgpt
+runcgpttests: $(TEST_SETUP) cgpt tests
+ $(RUNTEST) $(BUILD_RUN)/tests/cgptlib_test
ifneq ($(IN_CHROOT),)
- ${BUILD}/tests/CgptManagerTests --v=1
+ $(RUNTEST) $(BUILD_RUN)/tests/CgptManagerTests --v=1
endif
-# Exercise vbutil_kernel and vbutil_firmware
-.PHONY: runfuzztests
-runfuzztests: genfuzztestcases utils tests
+.PHONY: runtestscripts
+runtestscripts: $(TEST_SETUP) genfuzztestcases utils tests
+ tests/run_cgpt_tests.sh $(BUILD_RUN)/cgpt/cgpt
tests/run_preamble_tests.sh
- tests/run_vbutil_kernel_arg_tests.sh
-
-.PHONY: runmisctests
-runmisctests: tests utils
- ${BUILD}/tests/rollback_index2_tests
- ${BUILD}/tests/rsa_utility_tests
- ${BUILD}/tests/sha_tests
- ${BUILD}/tests/stateful_util_tests
- ${BUILD}/tests/tpm_bootmode_tests
- ${BUILD}/tests/utility_string_tests
- ${BUILD}/tests/utility_tests
- ${BUILD}/tests/vboot_api_devmode_tests
- ${BUILD}/tests/vboot_api_init_tests
- ${BUILD}/tests/vboot_api_firmware_tests
- ${BUILD}/tests/vboot_audio_tests
- ${BUILD}/tests/vboot_firmware_tests
tests/run_rsa_tests.sh
tests/run_vboot_common_tests.sh
+ tests/run_vbutil_kernel_arg_tests.sh
tests/run_vbutil_tests.sh
+.PHONY: runmisctests
+runmisctests: $(TEST_SETUP) tests utils
+ $(RUNTEST) $(BUILD_RUN)/tests/rollback_index2_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/rsa_utility_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/sha_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/stateful_util_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/tpm_bootmode_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/utility_string_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/utility_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/vboot_api_devmode_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/vboot_api_init_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/vboot_api_firmware_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/vboot_audio_tests
+ $(RUNTEST) $(BUILD_RUN)/tests/vboot_firmware_tests
+
# Run long tests, including all permutations of encryption keys (instead of
# just the ones we use) and tests of currently-unused code (e.g. vboot_ec).
# Not run by automated build.
.PHONY: runlongtests
-runlongtests: genkeys genfuzztestcases tests utils
+runlongtests: $(TEST_SETUP) genkeys genfuzztestcases tests utils
tests/run_preamble_tests.sh --all
tests/run_vboot_common_tests.sh --all
tests/run_vboot_ec_tests.sh