summaryrefslogtreecommitdiff
path: root/test/test-main.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2022-09-06 20:27:05 -0600
committerTom Rini <trini@konsulko.com>2022-09-29 16:09:56 -0400
commit0e4b697f884d1f2190a9972b662abc8498159333 (patch)
tree0d81dadb200fadc7a74a0d1cece914af244f4fa7 /test/test-main.c
parent98306987659769607642474954b2bf9555808542 (diff)
test: Make a copy of the device tree before running a test
When the flat device tree changes it can mess up the live tree since that uses the flat tree for its strings. This affects only a few sandbox tests which modify the device tree, but the number will grow as ofnode support for writing improves. While the control FDT is not intended to change while U-Boot is running, some tests do so. For example, the ofnode interface only supports modifying properties in the control FDT, so tests must use that. To solve this problem, keep a copy of the FDT and restore it as needed when the test is finished. The copy only happens on sandbox (except SPL builds), to reduce memory usage and because these tests are not useful on other boards. For other boards, a checksum is taken to ensure that nothing changes. It would be possible to always checksum the FDT on sandbox and only restore it if needed, but this is slightly slower than restoring it every time, at least with crc8. Move the code which checks for success to the very end, for clarity. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'test/test-main.c')
-rw-r--r--test/test-main.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/test/test-main.c b/test/test-main.c
index 7a3871624c..082821ef3e 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -9,14 +9,51 @@
#include <cyclic.h>
#include <dm.h>
#include <event.h>
+#include <os.h>
#include <dm/root.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
#include <test/test.h>
#include <test/ut.h>
+#include <u-boot/crc.h>
DECLARE_GLOBAL_DATA_PTR;
+/**
+ * enum fdtchk_t - what to do with the device tree (gd->fdt_blob)
+ *
+ * This affects what happens with the device tree before and after a test
+ *
+ * @FDTCHK_NONE: Do nothing
+ * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and
+ * compare it afterwards to detect any changes
+ * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards
+ */
+enum fdtchk_t {
+ FDTCHK_NONE,
+ FDTCHK_CHECKSUM,
+ FDTCHK_COPY,
+};
+
+/**
+ * fdt_action() - get the required action for the FDT
+ *
+ * @return the action that should be taken for this build
+ */
+static enum fdtchk_t fdt_action(void)
+{
+ /* Do a copy for sandbox (but only the U-Boot build, not SPL) */
+ if (CONFIG_IS_ENABLED(SANDBOX))
+ return FDTCHK_COPY;
+
+ /* For sandbox SPL builds, do nothing */
+ if (IS_ENABLED(CONFIG_SANDBOX))
+ return FDTCHK_NONE;
+
+ /* For all other boards, do a checksum */
+ return FDTCHK_CHECKSUM;
+}
+
/* This is valid when a test is running, NULL otherwise */
static struct unit_test_state *cur_test_state;
@@ -46,6 +83,9 @@ static int dm_test_pre_run(struct unit_test_state *uts)
uts->testdev = NULL;
uts->force_fail_alloc = false;
uts->skip_post_probe = false;
+ if (fdt_action() == FDTCHK_CHECKSUM)
+ uts->fdt_chksum = crc8(0, gd->fdt_blob,
+ fdt_totalsize(gd->fdt_blob));
gd->dm_root = NULL;
malloc_disable_testing();
if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA))
@@ -64,6 +104,25 @@ static int dm_test_post_run(struct unit_test_state *uts)
{
int id;
+ if (gd->fdt_blob) {
+ switch (fdt_action()) {
+ case FDTCHK_COPY:
+ memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size);
+ break;
+ case FDTCHK_CHECKSUM: {
+ uint chksum;
+
+ chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob));
+
+ if (chksum != uts->fdt_chksum)
+ printf("Device tree changed: cannot run live tree tests\n");
+ break;
+ }
+ case FDTCHK_NONE:
+ break;
+ }
+ }
+
/*
* With of-platdata-inst the uclasses are created at build time. If we
* destroy them we cannot get them back since uclass_add() is not
@@ -443,8 +502,23 @@ int ut_run_list(const char *category, const char *prefix,
uts.of_root = gd_of_root();
uts.runs_per_test = runs_per_test;
+ if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) {
+ uts.fdt_size = fdt_totalsize(gd->fdt_blob);
+ uts.fdt_copy = os_malloc(uts.fdt_size);
+ if (!uts.fdt_copy) {
+ printf("Out of memory for device tree copy\n");
+ return -ENOMEM;
+ }
+ memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size);
+ }
ret = ut_run_tests(&uts, prefix, tests, count, select_name);
+ /* Best efforts only...ignore errors */
+ if (has_dm_tests)
+ dm_test_restore(uts.of_root);
+ if (IS_ENABLED(CONFIG_SANDBOX))
+ os_free(uts.fdt_copy);
+
if (ret == -ENOENT)
printf("Test '%s' not found\n", select_name);
else