diff options
Diffstat (limited to 'test/cmd')
| -rw-r--r-- | test/cmd/Makefile | 1 | ||||
| -rw-r--r-- | test/cmd/config.c | 28 | ||||
| -rw-r--r-- | test/cmd/unzip.c | 118 |
3 files changed, 145 insertions, 2 deletions
diff --git a/test/cmd/Makefile b/test/cmd/Makefile index 8d6932f1176..8d36463879d 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -17,6 +17,7 @@ ifdef CONFIG_CONSOLE_RECORD obj-$(CONFIG_CMD_ACPI) += acpi.o endif obj-$(CONFIG_CMD_BDI) += bdinfo.o +obj-$(CONFIG_CMD_CONFIG) += config.o obj-$(CONFIG_COREBOOT_SYSINFO) += coreboot.o obj-$(CONFIG_CMD_FDT) += fdt.o obj-$(CONFIG_CMD_HASH) += hash.o diff --git a/test/cmd/config.c b/test/cmd/config.c new file mode 100644 index 00000000000..5a48060801f --- /dev/null +++ b/test/cmd/config.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Tests for config command + */ + +#include <console.h> +#include <test/cmd.h> +#include <test/ut.h> + +static int cmd_test_config(struct unit_test_state *uts) +{ + ut_assertok(run_command("config", 0)); + ut_assert_skip_to_line("# Automatically generated file; DO NOT EDIT."); + ut_assert_skip_to_linen("# Compiler:"); + ut_assert_skip_to_line("CONFIG_CMD_CONFIG=y"); + + console_record_reset_enable(); + + ut_assertok(run_command("config cmd_config=y", 0)); + ut_assert_nextline("CONFIG_CMD_CONFIG=y"); + ut_assert_console_end(); + + ut_assertok(run_command("config 'this string never appears in .config'", 0)); + ut_assert_console_end(); + + return 0; +} +CMD_TEST(cmd_test_config, UTF_CONSOLE); diff --git a/test/cmd/unzip.c b/test/cmd/unzip.c index 623a2785884..e33b6c3fb3a 100644 --- a/test/cmd/unzip.c +++ b/test/cmd/unzip.c @@ -101,11 +101,10 @@ static int dm_test_cmd_zip_unzip(struct unit_test_state *uts) } DM_TEST(dm_test_cmd_zip_unzip, UTF_CONSOLE); -static int dm_test_cmd_zip_gzwrite(struct unit_test_state *uts) +static int bind_mmc9(struct unit_test_state *uts) { struct udevice *dev; ofnode root, node; - int i, j, ret; /* Enable the mmc9 node for this test */ root = oftree_root(oftree_default()); @@ -113,6 +112,15 @@ static int dm_test_cmd_zip_gzwrite(struct unit_test_state *uts) ut_assert(ofnode_valid(node)); ut_assertok(lists_bind_fdt(gd->dm_root, node, &dev, NULL, false)); + return 0; +} + +static int dm_test_cmd_zip_gzwrite(struct unit_test_state *uts) +{ + int i, j, ret; + + ut_assertok(bind_mmc9(uts)); + for (i = 0; i < ARRAY_SIZE(sizes); i++) { ret = do_test_cmd_zip_unzip(uts, sizes[i], true); if (ret) @@ -132,3 +140,109 @@ static int dm_test_cmd_zip_gzwrite(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_cmd_zip_gzwrite, UTF_CONSOLE); + +/* + * Regression test for the case where a decompression input chunk is + * exhausted at exactly the same time as the write buffer fills up, in + * which case gzwrite() used to call inflate() again with no input, + * receive Z_BUF_ERROR back and treat it as a fatal error. + * + * Craft a gzip file by hand from two stored (uncompressed) deflate + * blocks of 1 KiB each, and pick a chunk size that covers exactly the + * 5 byte header plus payload of the first stored block, so that with a + * 1 KiB write buffer the first chunk runs out precisely when the write + * buffer is full. + */ +#define STORED_BLK_HDR_LEN 5 /* deflate stored block header size */ +#define STORED_BLK_LEN SZ_1K /* payload bytes per stored block */ + +static int gzwrite_chunk_boundary(struct unit_test_state *uts) +{ + static const u8 gzip_hdr[10] = { + 0x1f, 0x8b, /* magic */ + 0x08, /* deflate */ + 0x00, /* no flags */ + 0x00, 0x00, 0x00, 0x00, /* mtime */ + 0x00, /* extra flags */ + 0x03, /* OS: unix */ + }; + unsigned long loadaddr = env_get_ulong("loadaddr", 16, 0); + unsigned long decaddr = loadaddr + SZ_1M; + u8 raw[2 * STORED_BLK_LEN]; + const size_t rawsize = sizeof(raw); + unsigned char *gzmap = map_sysmem(loadaddr, sizeof(gzip_hdr) + + 2 * (STORED_BLK_HDR_LEN + + STORED_BLK_LEN) + 8); + unsigned char *decmap = map_sysmem(decaddr, rawsize); + struct blk_desc *mmc_dev_desc; + const u16 len = STORED_BLK_LEN; + const u16 nlen = ~STORED_BLK_LEN & 0xffff; + size_t gzlen, cnt; + u8 *p = gzmap; + u32 crc; + int i; + + ut_assertok(bind_mmc9(uts)); + + for (i = 0; i < rawsize; i++) + raw[i] = (i * 251) & 0xff; + crc = crc32(0, raw, rawsize); + + memcpy(p, gzip_hdr, sizeof(gzip_hdr)); + p += sizeof(gzip_hdr); + for (i = 0; i < 2; i++) { + *p++ = (i == 1) ? 0x01 : 0x00; /* BFINAL on last block */ + *p++ = len & 0xff; /* LEN */ + *p++ = len >> 8; + *p++ = nlen & 0xff; /* NLEN */ + *p++ = nlen >> 8; + memcpy(p, raw + i * STORED_BLK_LEN, STORED_BLK_LEN); + p += STORED_BLK_LEN; + } + *p++ = crc & 0xff; /* CRC32, little endian */ + *p++ = (crc >> 8) & 0xff; + *p++ = (crc >> 16) & 0xff; + *p++ = (crc >> 24) & 0xff; + *p++ = rawsize & 0xff; /* ISIZE, little endian */ + *p++ = (rawsize >> 8) & 0xff; + *p++ = (rawsize >> 16) & 0xff; + *p++ = (rawsize >> 24) & 0xff; + gzlen = p - gzmap; + + ut_assertok(run_commandf("gzwrite mmc 9 %lx %zx %x", loadaddr, + gzlen, STORED_BLK_LEN)); + ut_assert_skip_to_line("\t%zu bytes, crc 0x%08x", rawsize, crc); + + ut_asserteq(9, blk_get_device_by_str("mmc", "9", &mmc_dev_desc)); + cnt = rawsize / mmc_dev_desc->blksz; + ut_assertok(run_commandf("mmc dev 9")); + ut_assert_nextline("switch to partitions #0, OK"); + ut_assert_nextline("mmc9 is current device"); + + ut_assertok(run_commandf("mmc read %lx 0 %zx", decaddr, cnt)); + ut_assert_nextline("MMC read: dev # 9, block # 0, count %zu ... %zu blocks read: OK", + cnt, cnt); + + ut_asserteq_mem(raw, decmap, rawsize); + + ut_assert_console_end(); + + unmap_sysmem(gzmap); + unmap_sysmem(decmap); + + return 0; +} + +static int dm_test_cmd_gzwrite_chunk_boundary(struct unit_test_state *uts) +{ + int ret; + + /* Input chunk: exactly one stored block header plus its payload */ + ut_assertok(env_set_ulong("gzwrite_chunk", + STORED_BLK_HDR_LEN + STORED_BLK_LEN)); + ret = gzwrite_chunk_boundary(uts); + ut_assertok(env_set("gzwrite_chunk", NULL)); + + return ret; +} +DM_TEST(dm_test_cmd_gzwrite_chunk_boundary, UTF_CONSOLE); |
