Added test_compress.sh and bunch of files needed by it.
authorLasse Collin <lasse.collin@tukaani.org>
Thu, 17 Jan 2008 22:50:29 +0000 (00:50 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Thu, 17 Jan 2008 22:50:29 +0000 (00:50 +0200)
This new set of tests compress and decompress several
test files with many different compression options.
This set of tests will be extended later.

tests/Makefile.am
tests/bcj_test.c [new file with mode: 0644]
tests/compress_prepared_bcj_sparc [new file with mode: 0644]
tests/compress_prepared_bcj_x86 [new file with mode: 0644]
tests/create_compress_files.c [new file with mode: 0644]
tests/test_compress.sh [new file with mode: 0755]

index d5bb126..fa78bf8 100644 (file)
 ##  Lesser General Public License for more details.
 ##
 
-EXTRA_DIST = files tests.h test_files.sh
+EXTRA_DIST = \
+       files \
+       tests.h \
+       test_files.sh \
+       test_compress.sh \
+       bcj_test.c \
+       compress_prepared_bcj_sparc \
+       compress_prepared_bcj_x86
 
 AM_CPPFLAGS = \
        -I@top_srcdir@/src/common \
@@ -26,6 +33,7 @@ LDADD += @top_builddir@/lib/libgnu.a
 endif
 
 check_PROGRAMS = \
+       create_compress_files \
        test_check \
        test_stream_flags \
        test_filter_flags \
@@ -33,13 +41,15 @@ check_PROGRAMS = \
        test_index \
        test_info
 
-test_check_SOURCES = test_check.c
-test_stream_flags_SOURCES = test_stream_flags.c
-test_filter_flags_SOURCES = test_filter_flags.c
-test_block_header_SOURCES = test_block_header.c
-test_index_SOURCES = test_index.c
-test_info_SOURCES = test_info.c
-
 TESTS = \
-       $(check_PROGRAMS) \
-       test_files.sh
+       test_check \
+       test_stream_flags \
+       test_filter_flags \
+       test_block_header \
+       test_index \
+       test_info \
+       test_files.sh \
+       test_compress.sh
+
+clean-local:
+       -rm -f compress_generated_*
diff --git a/tests/bcj_test.c b/tests/bcj_test.c
new file mode 100644 (file)
index 0000000..d64c5a7
--- /dev/null
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       bcj_test.c
+/// \brief      Source code of compress_prepared_bcj_*
+///
+/// This is a simple program that should make the compiler to generate
+/// PC-relative branches, jumps, and calls. The compiled files can then
+/// be used to test the branch conversion filters. Note that this program
+/// itself does nothing useful.
+///
+/// Compiling: gcc -std=c99 -fPIC bcj_test.c
+/// Don't optimize or strip.
+//
+//  This code has been put into the public domain.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+extern int jump(int a, int b);
+
+
+extern int
+call(int a, int b)
+{
+       if (a < b)
+               a = jump(a, b);
+
+       return a;
+}
+
+
+extern int
+jump(int a, int b)
+{
+       // The loop generates conditional jump backwards.
+       while (1) {
+               if (a < b) {
+                       a *= 2;
+                       a += 3 * b;
+                       break;
+               } else {
+                       // Put enough code here to prevent JMP SHORT on x86.
+                       a += b;
+                       a /= 2;
+                       b += b % 5;
+                       a -= b / 3;
+                       b = 2 * b + a - 1;
+                       a *= b + a + 1;
+                       b += a - 1;
+                       a += b * 2 - a / 5;
+               }
+       }
+
+       return a;
+}
+
+
+int
+main(int argc, char **argv)
+{
+       int a = call(argc, argc + 1);
+       return a == 0;
+}
diff --git a/tests/compress_prepared_bcj_sparc b/tests/compress_prepared_bcj_sparc
new file mode 100644 (file)
index 0000000..ba3ee29
Binary files /dev/null and b/tests/compress_prepared_bcj_sparc differ
diff --git a/tests/compress_prepared_bcj_x86 b/tests/compress_prepared_bcj_x86
new file mode 100644 (file)
index 0000000..48dde27
Binary files /dev/null and b/tests/compress_prepared_bcj_x86 differ
diff --git a/tests/create_compress_files.c b/tests/create_compress_files.c
new file mode 100644 (file)
index 0000000..2e39429
--- /dev/null
@@ -0,0 +1,164 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       create_compress_files.c
+/// \brief      Creates bunch of test files to be compressed
+///
+/// Using a test file generator program saves space in the source code
+/// package considerably.
+//
+//  Copyright (C) 2008 Lasse Collin
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "sysdefs.h"
+#include <stdio.h>
+
+
+// Avoid re-creating the test files every time the tests are run.
+#define create_test(name) \
+do { \
+       if (!file_exists("compress_generated_" #name)) { \
+               FILE *file = file_create("compress_generated_" #name); \
+               write_ ## name(file); \
+               file_finish(file, "compress_generated_" #name); \
+       } \
+} while (0)
+
+
+static bool
+file_exists(const char *filename)
+{
+       // Trying to be somewhat portable by avoiding stat().
+       FILE *file = fopen(filename, "rb");
+       bool ret;
+
+       if (file != NULL) {
+               fclose(file);
+               ret = true;
+       } else {
+               ret = false;
+       }
+
+       return ret;
+}
+
+
+static FILE *
+file_create(const char *filename)
+{
+       FILE *file = fopen(filename, "wb");
+
+       if (file == NULL) {
+               perror(filename);
+               exit(1);
+       }
+
+       return file;
+}
+
+
+static void
+file_finish(FILE *file, const char *filename)
+{
+       const bool ferror_fail = ferror(file);
+       const bool fclose_fail = fclose(file);
+
+       if (ferror_fail || fclose_fail) {
+               perror(filename);
+               exit(1);
+       }
+}
+
+
+// File that repeats "abc\n" a few thousand times. This is targeted
+// especially at Subblock filter's run-length encoder.
+static void
+write_abc(FILE *file)
+{
+       for (size_t i = 0; i < 12345; ++i)
+               fwrite("abc\n", 4, 1, file);
+}
+
+
+// File that doesn't compress. We always use the same random seed to
+// generate identical files on all systems.
+static void
+write_random(FILE *file)
+{
+       uint32_t n = 5;
+
+       for (size_t i = 0; i < 123456; ++i) {
+               n = 101771 * n + 71777;
+
+               putc(n & 0xFF, file);
+               putc((n >> 8) & 0xFF, file);
+               putc((n >> 16) & 0xFF, file);
+               putc(n >> 24, file);
+       }
+}
+
+
+// Text file
+static void
+write_text(FILE *file)
+{
+       static const char *lorem[] = {
+               "Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur",
+               "adipisicing", "elit,", "sed", "do", "eiusmod", "tempor",
+               "incididunt", "ut", "labore", "et", "dolore", "magna",
+               "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis",
+               "nostrud", "exercitation", "ullamco", "laboris", "nisi",
+               "ut", "aliquip", "ex", "ea", "commodo", "consequat.",
+               "Duis", "aute", "irure", "dolor", "in", "reprehenderit",
+               "in", "voluptate", "velit", "esse", "cillum", "dolore",
+               "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint",
+               "occaecat", "cupidatat", "non", "proident,", "sunt", "in",
+               "culpa", "qui", "officia", "deserunt", "mollit", "anim",
+               "id", "est", "laborum."
+       };
+
+       // Let the first paragraph be the original text.
+       for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) {
+               fprintf(file, "%s ", lorem[w]);
+
+               if (w % 7 == 6)
+                       fprintf(file, "\n");
+       }
+
+       // The rest shall be (hopefully) meaningless combinations of
+       // the same words.
+       uint32_t n = 29;
+
+       for (size_t p = 0; p < 500; ++p) {
+               fprintf(file, "\n\n");
+
+               for (size_t w = 0; w < ARRAY_SIZE(lorem); ++w) {
+                       n = 101771 * n + 71777;
+
+                       fprintf(file, "%s ", lorem[n % ARRAY_SIZE(lorem)]);
+
+                       if (w % 7 == 6)
+                               fprintf(file, "\n");
+               }
+       }
+}
+
+
+int
+main(void)
+{
+       create_test(abc);
+       create_test(random);
+       create_test(text);
+       return 0;
+}
diff --git a/tests/test_compress.sh b/tests/test_compress.sh
new file mode 100755 (executable)
index 0000000..5cf21cf
--- /dev/null
@@ -0,0 +1,183 @@
+#!/bin/sh
+
+###############################################################################
+#
+#   Copyright (C) 2008 Lasse Collin
+#
+#   This library is free software; you can redistribute it and/or
+#   modify it under the terms of the GNU Lesser General Public
+#   License as published by the Free Software Foundation; either
+#   version 2.1 of the License, or (at your option) any later version.
+#
+#   This library is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   Lesser General Public License for more details.
+#
+###############################################################################
+
+# Find out if our shell supports functions.
+eval 'unset foo ; foo() { return 42; } ; foo'
+if test $? != 42 ; then
+       echo "/bin/sh doesn't support functions, skipping this test."
+       (exit 77)
+       exit 77
+fi
+
+test_lzma() {
+       ################
+       # Non-streamed #
+       ################
+
+       if $LZMA -c "$@" "$FILE" > tmp_compressed; then
+               :
+       else
+               echo "Non-streamed compressing failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if $LZMA -cd tmp_compressed > tmp_uncompressed ; then
+               :
+       else
+               echo "Decoding of non-streamed file failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if cmp tmp_uncompressed "$FILE" ; then
+               :
+       else
+               echo "Decoded non-streamed file does not match the original: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if $LZMADEC tmp_compressed > tmp_uncompressed ; then
+               :
+       else
+               echo "Decoding of non-streamed file failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if cmp tmp_uncompressed "$FILE" ; then
+               :
+       else
+               echo "Decoded non-streamed file does not match the original: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       ############
+       # Streamed #
+       ############
+
+       if $LZMA -c "$@" < "$FILE" > tmp_compressed; then
+               :
+       else
+               echo "Streamed compressing failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if $LZMA -cd < tmp_compressed > tmp_uncompressed ; then
+               :
+       else
+               echo "Decoding of streamed file failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if cmp tmp_uncompressed "$FILE" ; then
+               :
+       else
+               echo "Decoded streamed file does not match the original: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if $LZMADEC < tmp_compressed > tmp_uncompressed ; then
+               :
+       else
+               echo "Decoding of streamed file failed: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       if cmp tmp_uncompressed "$FILE" ; then
+               :
+       else
+               echo "Decoded streamed file does not match the original: $* $FILE"
+               (exit 1)
+               exit 1
+       fi
+
+       # Show progress:
+       echo . | tr -d '\n\r'
+}
+
+LZMA="../src/lzma/lzma --memory=15Mi --threads=1"
+LZMADEC="../src/lzmadec/lzmadec --memory=4Mi"
+unset LZMA_OPT
+
+# Create the required input files.
+if ./create_compress_files ; then
+       :
+else
+       rm -f compress_*
+       echo "Failed to create files to test compression."
+       (exit 1)
+       exit 1
+fi
+
+# Remove temporary now (in case they are something weird), and on exit.
+rm -f tmp_compressed tmp_uncompressed
+trap 'rm -f tmp_compressed tmp_uncompressed' 0
+
+# Encode and decode each file with various filter configurations.
+# This takes quite a bit of time.
+echo "test_compress.sh:"
+for FILE in compress_generated_* "$srcdir"/compress_prepared_*
+do
+       MSG=`echo "x$FILE" | sed 's,^x,,; s,^.*/,,; s,^compress_,,'`
+       echo "  $MSG" | tr -d '\n\r'
+
+       # Don't test with empty arguments; it breaks some ancient
+       # proprietary /bin/sh versions due to $@ used in test_lzma().
+       test_lzma -1
+       test_lzma -2
+       test_lzma -3
+       test_lzma -4
+
+       for ARGS in \
+               --copy \
+               --subblock \
+               --subblock=size=1 \
+               --subblock=size=1,rle=1 \
+               --subblock=size=1,rle=4 \
+               --subblock=size=4,rle=4 \
+               --subblock=size=8,rle=4 \
+               --subblock=size=8,rle=8 \
+               --subblock=size=4096,rle=12 \
+               --delta=distance=1 \
+               --delta=distance=4 \
+               --delta=distance=256 \
+               --x86 \
+               --powerpc \
+               --ia64 \
+               --arm \
+               --armthumb \
+               --sparc
+       do
+               test_lzma $ARGS
+               test_lzma --subblock $ARGS
+               test_lzma $ARGS --subblock
+               test_lzma --subblock $ARGS --subblock
+       done
+
+       echo
+done
+
+(exit 0)
+exit 0