diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2021-03-06 21:59:46 +0100 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2021-03-06 22:08:36 +0100 | 
| commit | c86d4388c1b427f892670c290c8f28751313640a (patch) | |
| tree | 87ff7c29fe8b977dc4e465cd37230277db2923e9 /tests/libsqfs | |
| parent | 116c638b9d7bc9c34dfc90ab24cb2bec1e526ed7 (diff) | |
Add a simple test case for the xattr_writer_t
The test case basically adds a few key/value pairs and make sure they
are deduplicated correctly, including a case where they are added in
a different order and a case where the value is stored OOL.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'tests/libsqfs')
| -rw-r--r-- | tests/libsqfs/Makemodule.am | 5 | ||||
| -rw-r--r-- | tests/libsqfs/xattr_writer.c | 321 | 
2 files changed, 325 insertions, 1 deletions
| diff --git a/tests/libsqfs/Makemodule.am b/tests/libsqfs/Makemodule.am index cad473c..0ad19d9 100644 --- a/tests/libsqfs/Makemodule.am +++ b/tests/libsqfs/Makemodule.am @@ -4,8 +4,11 @@ test_abi_LDADD = libsquashfs.la  test_table_SOURCES = tests/libsqfs/table.c tests/test.h  test_table_LDADD = libsquashfs.la +test_xattr_writer_SOURCES = tests/libsqfs/xattr_writer.c tests/test.h +test_xattr_writer_LDADD = libsquashfs.la +  LIBSQFS_TESTS = \ -	test_abi test_table +	test_abi test_table test_xattr_writer  check_PROGRAMS += $(LIBSQFS_TESTS)  TESTS += $(LIBSQFS_TESTS) diff --git a/tests/libsqfs/xattr_writer.c b/tests/libsqfs/xattr_writer.c new file mode 100644 index 0000000..d5252e3 --- /dev/null +++ b/tests/libsqfs/xattr_writer.c @@ -0,0 +1,321 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * xattr_writer.c + * + * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "../test.h" + +#include "sqfs/xattr_writer.h" +#include "sqfs/compressor.h" +#include "sqfs/xattr.h" +#include "sqfs/error.h" +#include "sqfs/super.h" +#include "sqfs/io.h" + +static sqfs_u8 file_data[1024]; +static size_t file_used = 0; + +static int dummy_write_at(sqfs_file_t *file, sqfs_u64 offset, +			  const void *buffer, size_t size) +{ +	(void)file; + +	if (offset >= sizeof(file_data)) +		return SQFS_ERROR_OUT_OF_BOUNDS; + +	if (size > (sizeof(file_data) - offset)) +		return SQFS_ERROR_OUT_OF_BOUNDS; + +	if (offset > file_used) +		memset(file_data + file_used, 0, offset - file_used); + +	if ((offset + size) > file_used) +		file_used = offset + size; + +	memcpy(file_data + offset, buffer, size); +	return 0; +} + +static sqfs_u64 dummy_get_size(const sqfs_file_t *file) +{ +	(void)file; +	return file_used; +} + +static sqfs_s32 dummy_compress(sqfs_compressor_t *cmp, const sqfs_u8 *in, +			       sqfs_u32 size, sqfs_u8 *out, sqfs_u32 outsize) +{ +	(void)cmp; +	memcpy(out, in, outsize < size ? outsize : size); +	return 0; +} + +static sqfs_file_t dummy_file = { +	{ NULL, NULL }, +	NULL, +	dummy_write_at, +	dummy_get_size, +	NULL, +}; + +static sqfs_compressor_t dummy_compressor = { +	{ NULL, NULL }, +	NULL, +	NULL, +	NULL, +	dummy_compress, +}; + +/*****************************************************************************/ + +int main(void) +{ +	size_t offset, ool_value_offset, id_offset; +	sqfs_xattr_id_table_t idtbl; +	sqfs_xattr_writer_t *xwr; +	sqfs_xattr_value_t value; +	sqfs_xattr_entry_t key; +	sqfs_xattr_id_t desc; +	sqfs_super_t super; +	char strbuf[32]; +	sqfs_u16 hdr; +	sqfs_u64 ref; +	sqfs_u32 id; +	int ret; + +	/* setup */ +	xwr = sqfs_xattr_writer_create(0); +	TEST_NOT_NULL(xwr); + +	/* record a block of key/value pairs */ +	ret = sqfs_xattr_writer_begin(xwr, 0); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "user.foobar", "test", 4); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "security.selinux", "Xwhatever", 9); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_end(xwr, &id); +	TEST_EQUAL_I(ret, 0); +	TEST_EQUAL_UI(id, 0); + +	/* record a second, different block */ +	ret = sqfs_xattr_writer_begin(xwr, 0); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "user.foobar", "bla", 3); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "security.selinux", "blub", 4); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_end(xwr, &id); +	TEST_EQUAL_I(ret, 0); +	TEST_EQUAL_UI(id, 1); + +	/* same as first block after sorting and gets the same ID */ +	ret = sqfs_xattr_writer_begin(xwr, 0); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "security.selinux", "Xwhatever", 9); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "user.foobar", "test", 4); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_end(xwr, &id); +	TEST_EQUAL_I(ret, 0); +	TEST_EQUAL_UI(id, 0); + +	/* the third assignment overwrites the first, making +	   the block identical to the second one */ +	ret = sqfs_xattr_writer_begin(xwr, 0); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "user.foobar", "mimimi", 6); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "security.selinux", "blub", 4); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "user.foobar", "bla", 3); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_end(xwr, &id); +	TEST_EQUAL_I(ret, 0); +	TEST_EQUAL_UI(id, 1); + +	/* add another block with the same value, so it gets stored OOL */ +	ret = sqfs_xattr_writer_begin(xwr, 0); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_add(xwr, "security.selinux", "Xwhatever", 9); +	TEST_EQUAL_I(ret, 0); + +	ret = sqfs_xattr_writer_end(xwr, &id); +	TEST_EQUAL_I(ret, 0); +	TEST_EQUAL_UI(id, 2); + +	/* serialize */ +	sqfs_super_init(&super, 131072, 0, SQFS_COMP_GZIP); +	ret = sqfs_xattr_writer_flush(xwr, &dummy_file, &super, +				      &dummy_compressor); +	TEST_EQUAL_I(ret, 0); + +	TEST_EQUAL_UI(file_used, 177); + +	/* meta data block holding the key-value-pairs */ +	memcpy(&hdr, file_data, sizeof(hdr)); +	hdr = le16toh(hdr); +	TEST_EQUAL_UI(hdr, (0x8000 | 101)); +	offset = 2; + +	memcpy(&key, file_data + offset, sizeof(key)); +	key.type = le16toh(key.type); +	key.size = le16toh(key.size); +	offset += sizeof(key); +	TEST_EQUAL_UI(key.type, SQFS_XATTR_USER); +	TEST_EQUAL_UI(key.size, 6); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, key.size); +	TEST_STR_EQUAL(strbuf, "foobar"); +	offset += key.size; + +	memcpy(&value, file_data + offset, sizeof(value)); +	value.size = le32toh(value.size); +	offset += sizeof(value); +	TEST_EQUAL_UI(value.size, 4); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, value.size); +	TEST_STR_EQUAL(strbuf, "test"); +	offset += value.size; + +	memcpy(&key, file_data + offset, sizeof(key)); +	key.type = le16toh(key.type); +	key.size = le16toh(key.size); +	offset += sizeof(key); +	TEST_EQUAL_UI(key.type, SQFS_XATTR_SECURITY); +	TEST_EQUAL_UI(key.size, 7); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, key.size); +	TEST_STR_EQUAL(strbuf, "selinux"); +	offset += key.size; + +	ool_value_offset = offset; + +	memcpy(&value, file_data + offset, sizeof(value)); +	value.size = le32toh(value.size); +	offset += sizeof(value); +	TEST_EQUAL_UI(value.size, 9); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, value.size); +	TEST_STR_EQUAL(strbuf, "Xwhatever"); +	offset += value.size; + +	memcpy(&key, file_data + offset, sizeof(key)); +	key.type = le16toh(key.type); +	key.size = le16toh(key.size); +	offset += sizeof(key); +	TEST_EQUAL_UI(key.type, SQFS_XATTR_USER); +	TEST_EQUAL_UI(key.size, 6); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, key.size); +	TEST_STR_EQUAL(strbuf, "foobar"); +	offset += key.size; + +	memcpy(&value, file_data + offset, sizeof(value)); +	value.size = le32toh(value.size); +	offset += sizeof(value); +	TEST_EQUAL_UI(value.size, 3); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, value.size); +	TEST_STR_EQUAL(strbuf, "bla"); +	offset += value.size; + +	memcpy(&key, file_data + offset, sizeof(key)); +	key.type = le16toh(key.type); +	key.size = le16toh(key.size); +	offset += sizeof(key); +	TEST_EQUAL_UI(key.type, SQFS_XATTR_SECURITY); +	TEST_EQUAL_UI(key.size, 7); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, key.size); +	TEST_STR_EQUAL(strbuf, "selinux"); +	offset += key.size; + +	memcpy(&value, file_data + offset, sizeof(value)); +	value.size = le32toh(value.size); +	offset += sizeof(value); +	TEST_EQUAL_UI(value.size, 4); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, value.size); +	TEST_STR_EQUAL(strbuf, "blub"); +	offset += value.size; + +	memcpy(&key, file_data + offset, sizeof(key)); +	key.type = le16toh(key.type); +	key.size = le16toh(key.size); +	offset += sizeof(key); +	TEST_EQUAL_UI(key.type, (SQFS_XATTR_SECURITY | SQFS_XATTR_FLAG_OOL)); +	TEST_EQUAL_UI(key.size, 7); +	memset(strbuf, '\0', sizeof(strbuf)); +	memcpy(strbuf, file_data + offset, key.size); +	TEST_STR_EQUAL(strbuf, "selinux"); +	offset += key.size; + +	memcpy(&value, file_data + offset, sizeof(value)); +	value.size = le32toh(value.size); +	offset += sizeof(value); +	TEST_EQUAL_UI(value.size, 8); +	memcpy(&ref, file_data + offset, sizeof(ref)); +	ref = le64toh(ref); +	TEST_EQUAL_UI(ref, (ool_value_offset - 2)); +	offset += value.size; + +	/* meta data block holding the ID descriptions */ +	id_offset = offset; + +	memcpy(&hdr, file_data + offset, sizeof(hdr)); +	TEST_EQUAL_UI(le16toh(hdr), (0x8000 | (16 * 3))); +	offset += sizeof(hdr); + +	memcpy(&desc, file_data + offset, sizeof(desc)); +	TEST_EQUAL_UI(le64toh(desc.xattr), 0); +	TEST_EQUAL_UI(le32toh(desc.count), 2); +	TEST_EQUAL_UI(le32toh(desc.size), 42); +	offset += sizeof(desc); + +	memcpy(&desc, file_data + offset, sizeof(desc)); +	TEST_EQUAL_UI(le64toh(desc.xattr), 42); +	TEST_EQUAL_UI(le32toh(desc.count), 2); +	TEST_EQUAL_UI(le32toh(desc.size), 36); +	offset += sizeof(desc); + +	memcpy(&desc, file_data + offset, sizeof(desc)); +	TEST_EQUAL_UI(le64toh(desc.xattr), 78); +	TEST_EQUAL_UI(le32toh(desc.count), 1); +	TEST_EQUAL_UI(le32toh(desc.size), 23); +	offset += sizeof(desc); + +	/* the xattr table itself */ +	TEST_EQUAL_UI(super.xattr_id_table_start, offset); + +	memcpy(&idtbl, file_data + offset, sizeof(idtbl)); +	TEST_EQUAL_UI(le64toh(idtbl.xattr_table_start), 0); +	TEST_EQUAL_UI(le32toh(idtbl.xattr_ids), 3); +	offset += sizeof(idtbl); + +	memcpy(&ref, file_data + offset, sizeof(ref)); +	TEST_EQUAL_UI(le64toh(ref), id_offset); +	offset += sizeof(ref); + +	TEST_EQUAL_UI(offset, file_used); + +	/* cleanup */ +	sqfs_destroy(xwr); +	return EXIT_SUCCESS; +} | 
