summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libarchive/test/test_read_data_large.c5
-rw-r--r--libarchive/test/test_read_extract.c4
-rw-r--r--libarchive/test/test_read_large.c5
-rw-r--r--libarchive/test/test_read_pax_truncated.c5
-rw-r--r--libarchive/test/test_read_truncated.c4
-rw-r--r--libarchive/test/test_read_truncated_filter.c17
-rw-r--r--libarchive/test/test_write_format_7zip_large.c5
-rw-r--r--test_utils/test_utils.c81
-rw-r--r--test_utils/test_utils.h5
9 files changed, 110 insertions, 21 deletions
diff --git a/libarchive/test/test_read_data_large.c b/libarchive/test/test_read_data_large.c
index 418020d1..22f46b75 100644
--- a/libarchive/test/test_read_data_large.c
+++ b/libarchive/test/test_read_data_large.c
@@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_data_large.c 201247 2009-12-30 05:59:21Z kientzle $");
/*
@@ -49,7 +50,6 @@ DEFINE_TEST(test_read_data_large)
char tmpfilename[] = "largefile";
int tmpfilefd;
FILE *f;
- unsigned int i;
size_t used;
/* Create a new archive in memory. */
@@ -64,8 +64,7 @@ DEFINE_TEST(test_read_data_large)
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "file");
archive_entry_set_mode(ae, S_IFREG | 0755);
- for (i = 0; i < sizeof(buff2); i++)
- buff2[i] = (unsigned char)rand();
+ fill_with_pseudorandom_data(buff2, sizeof(buff2));
archive_entry_set_size(ae, sizeof(buff2));
assertA(0 == archive_write_header(a, ae));
archive_entry_free(ae);
diff --git a/libarchive/test/test_read_extract.c b/libarchive/test/test_read_extract.c
index 2b1a21e4..c3e0594e 100644
--- a/libarchive/test/test_read_extract.c
+++ b/libarchive/test/test_read_extract.c
@@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_extract.c 201247 2009-12-30 05:59:21Z kientzle $");
#define BUFF_SIZE 1000000
@@ -59,8 +60,7 @@ DEFINE_TEST(test_read_extract)
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "file");
archive_entry_set_mode(ae, S_IFREG | 0755);
- for (i = 0; i < FILE_BUFF_SIZE; i++)
- file_buff[i] = (unsigned char)rand();
+ fill_with_pseudorandom_data(file_buff, FILE_BUFF_SIZE);
archive_entry_set_size(ae, FILE_BUFF_SIZE);
assertA(0 == archive_write_header(a, ae));
assertA(FILE_BUFF_SIZE == archive_write_data(a, file_buff, FILE_BUFF_SIZE));
diff --git a/libarchive/test/test_read_large.c b/libarchive/test/test_read_large.c
index 6966ccbe..2a4c8e86 100644
--- a/libarchive/test/test_read_large.c
+++ b/libarchive/test/test_read_large.c
@@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_large.c 201247 2009-12-30 05:59:21Z kientzle $");
static unsigned char testdata[10 * 1024 * 1024];
@@ -37,7 +38,6 @@ static unsigned char buff[11 * 1024 * 1024];
/* Check correct behavior on large reads. */
DEFINE_TEST(test_read_large)
{
- unsigned int i;
int tmpfilefd;
char tmpfilename[] = "test-read_large.XXXXXX";
size_t used;
@@ -45,8 +45,7 @@ DEFINE_TEST(test_read_large)
struct archive_entry *entry;
FILE *f;
- for (i = 0; i < sizeof(testdata); i++)
- testdata[i] = (unsigned char)(rand());
+ fill_with_pseudorandom_data(testdata, sizeof(testdata));
assert(NULL != (a = archive_write_new()));
assertA(0 == archive_write_set_format_ustar(a));
diff --git a/libarchive/test/test_read_pax_truncated.c b/libarchive/test/test_read_pax_truncated.c
index 1f6e78ac..a6705fa9 100644
--- a/libarchive/test/test_read_pax_truncated.c
+++ b/libarchive/test/test_read_pax_truncated.c
@@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_pax_truncated.c 189483 2009-03-07 03:34:34Z kientzle $");
DEFINE_TEST(test_read_pax_truncated)
@@ -48,8 +49,8 @@ DEFINE_TEST(test_read_pax_truncated)
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "file");
archive_entry_set_mode(ae, S_IFREG | 0755);
- for (i = 0; i < filedata_size; i++)
- filedata[i] = (unsigned char)rand();
+ fill_with_pseudorandom_data(filedata, filedata_size);
+
archive_entry_set_atime(ae, 1, 2);
archive_entry_set_ctime(ae, 3, 4);
archive_entry_set_mtime(ae, 5, 6);
diff --git a/libarchive/test/test_read_truncated.c b/libarchive/test/test_read_truncated.c
index 3991ab2b..117c12ad 100644
--- a/libarchive/test/test_read_truncated.c
+++ b/libarchive/test/test_read_truncated.c
@@ -23,6 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD: src/lib/libarchive/test/test_read_truncated.c,v 1.4 2008/09/01 05:38:33 kientzle Exp $");
static char buff[1000000];
@@ -47,8 +48,7 @@ DEFINE_TEST(test_read_truncated)
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "file");
archive_entry_set_mode(ae, S_IFREG | 0755);
- for (i = 0; i < sizeof(buff2); i++)
- buff2[i] = (unsigned char)rand();
+ fill_with_pseudorandom_data(buff2, sizeof(buff2));
archive_entry_set_size(ae, sizeof(buff2));
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
archive_entry_free(ae);
diff --git a/libarchive/test/test_read_truncated_filter.c b/libarchive/test/test_read_truncated_filter.c
index 4c409cc0..59a6dc85 100644
--- a/libarchive/test/test_read_truncated_filter.c
+++ b/libarchive/test/test_read_truncated_filter.c
@@ -25,6 +25,7 @@
*/
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD$");
/*
@@ -41,7 +42,7 @@ test_truncation(const char *compression,
char path[16];
char *buff, *data;
size_t buffsize, datasize, used1;
- int i, j, r, use_prog;
+ int i, r, use_prog;
buffsize = 2000000;
assert(NULL != (buff = (char *)malloc(buffsize)));
@@ -91,9 +92,7 @@ test_truncation(const char *compression,
free(buff);
return;
}
- for (j = 0; j < (int)datasize; ++j) {
- data[j] = (char)(rand() % 256);
- }
+ fill_with_pseudorandom_data(data, datasize);
failure("%s", path);
if (!assertEqualIntA(a, datasize,
archive_write_data(a, data, datasize))) {
@@ -111,8 +110,13 @@ test_truncation(const char *compression,
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
- assertEqualIntA(a, ARCHIVE_OK,
- archive_read_open_memory(a, buff, used1 - used1/64));
+ r = archive_read_open_memory(a, buff, used1 - used1/64);
+ if (r != ARCHIVE_OK) {
+ assertEqualStringA(a, "truncated bzip2 input",
+ archive_error_string(a));
+ goto out;
+ }
+
for (i = 0; i < 100; i++) {
if (ARCHIVE_OK != archive_read_next_header(a, &ae)) {
failure("Should have non-NULL error message for %s",
@@ -133,6 +137,7 @@ test_truncation(const char *compression,
archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+out:
free(data);
free(buff);
}
diff --git a/libarchive/test/test_write_format_7zip_large.c b/libarchive/test/test_write_format_7zip_large.c
index 5c49f59a..be344a3e 100644
--- a/libarchive/test/test_write_format_7zip_large.c
+++ b/libarchive/test/test_write_format_7zip_large.c
@@ -25,6 +25,7 @@
#include "test.h"
+#include "test_utils.h"
__FBSDID("$FreeBSD$");
#define LARGE_SIZE (16*1024*1024)
@@ -37,7 +38,6 @@ test_large(const char *compression_type)
size_t buffsize = LARGE_SIZE + 1024 * 256;
size_t datasize = LARGE_SIZE;
char *buff, *filedata, *filedata2;
- unsigned i;
assert((buff = malloc(buffsize)) != NULL);
assert((filedata = malloc(datasize)) != NULL);
@@ -87,8 +87,7 @@ test_large(const char *compression_type)
/* NOTE: PPMd cannot handle random data correctly.*/
memset(filedata, 'a', datasize);
} else {
- for (i = 0; i < datasize; i++)
- filedata[i] = (char)rand();
+ fill_with_pseudorandom_data(filedata, datasize);
}
assertEqualInt(datasize, archive_write_data(a, filedata, datasize));
diff --git a/test_utils/test_utils.c b/test_utils/test_utils.c
index 8ea3d3c4..db6c31b2 100644
--- a/test_utils/test_utils.c
+++ b/test_utils/test_utils.c
@@ -26,8 +26,11 @@
#include "test_utils.h"
+#include <errno.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
+#include <assert.h>
/* Filter tests against a glob pattern. Returns non-zero if test matches
* pattern, zero otherwise. A '^' at the beginning of the pattern negates
@@ -122,3 +125,81 @@ int get_test_set(int *test_set, int limit, const char *test,
}
return ((idx == 0)?-1:idx);
}
+
+static inline uint64_t
+xorshift64(uint64_t *state)
+{
+ uint64_t x = *state;
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ *state = x;
+ return (x);
+}
+
+/*
+ * Fill a buffer with reproducible pseudo-random data using a simple xorshift
+ * algorithm. Originally, most tests filled buffers with a loop that calls
+ * rand() once for each byte. However, this initialization can be extremely
+ * slow when running on emulated platforms such as QEMU where 16M calls to
+ * rand() take a long time: Before the test_write_format_7zip_large_copy test
+ * took ~22 seconds, whereas using a xorshift random number generator (that can
+ * be inlined) reduces it to ~17 seconds on QEMU RISC-V.
+ */
+void
+fill_with_pseudorandom_data_seed(uint64_t seed, void *buffer, size_t size)
+{
+ uint64_t *aligned_buffer;
+ size_t num_values;
+ size_t i;
+ size_t unaligned_suffix;
+ size_t unaligned_prefix = 0;
+ /*
+ * To avoid unaligned stores we only fill the aligned part of the buffer
+ * with pseudo-random data and fill the unaligned prefix with 0xab and
+ * the suffix with 0xcd.
+ */
+ if ((uintptr_t)buffer % sizeof(uint64_t)) {
+ unaligned_prefix =
+ sizeof(uint64_t) - (uintptr_t)buffer % sizeof(uint64_t);
+ aligned_buffer =
+ (uint64_t *)((char *)buffer + unaligned_prefix);
+ memset(buffer, 0xab, unaligned_prefix);
+ } else {
+ aligned_buffer = (uint64_t *)buffer;
+ }
+ assert((uintptr_t)aligned_buffer % sizeof(uint64_t) == 0);
+ num_values = (size - unaligned_prefix) / sizeof(uint64_t);
+ unaligned_suffix =
+ size - unaligned_prefix - num_values * sizeof(uint64_t);
+ for (i = 0; i < num_values; i++) {
+ aligned_buffer[i] = xorshift64(&seed);
+ }
+ if (unaligned_suffix) {
+ memset((char *)buffer + size - unaligned_suffix, 0xcd,
+ unaligned_suffix);
+ }
+}
+
+void
+fill_with_pseudorandom_data(void *buffer, size_t size)
+{
+ uint64_t seed;
+ const char* seed_str;
+ /*
+ * Check if a seed has been specified in the environment, otherwise fall
+ * back to using rand() as a seed.
+ */
+ if ((seed_str = getenv("TEST_RANDOM_SEED")) != NULL) {
+ errno = 0;
+ seed = strtoull(seed_str, NULL, 10);
+ if (errno != 0) {
+ fprintf(stderr, "strtoull(%s) failed: %s", seed_str,
+ strerror(errno));
+ seed = rand();
+ }
+ } else {
+ seed = rand();
+ }
+ fill_with_pseudorandom_data_seed(seed, buffer, size);
+}
diff --git a/test_utils/test_utils.h b/test_utils/test_utils.h
index 164c528f..3f61f6b2 100644
--- a/test_utils/test_utils.h
+++ b/test_utils/test_utils.h
@@ -27,6 +27,9 @@
#ifndef TEST_UTILS_H
#define TEST_UTILS_H
+#include <stddef.h>
+#include <stdint.h>
+
struct test_list_t
{
void (*func)(void);
@@ -35,5 +38,7 @@ struct test_list_t
};
int get_test_set(int *, int, const char *, struct test_list_t *);
+void fill_with_pseudorandom_data(void* buffer, size_t size);
+void fill_with_pseudorandom_data_seed(uint64_t seed, void* buffer, size_t size);
#endif /* TEST_UTILS_H */