igzip: Add unit tests for adler and crc32_gzip

Also renamed test helper function, fixed clang warnings and adler usage.

Change-Id: I4ad22d046809483456608be1f4fdc4adbf0e09e4
Signed-off-by: Greg Tucker <greg.b.tucker@intel.com>
This commit is contained in:
Greg Tucker 2017-05-05 18:47:30 -07:00 committed by Xiaodong Liu
parent e1f5284ff8
commit a8966b6709
7 changed files with 312 additions and 25 deletions

View File

@ -26,6 +26,7 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**********************************************************************/ **********************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include "crc.h" #include "crc.h"

View File

@ -67,6 +67,7 @@ extern_hdrs += include/igzip_lib.h
pkginclude_HEADERS += include/types.h pkginclude_HEADERS += include/types.h
check_tests += igzip/igzip_rand_test check_tests += igzip/igzip_rand_test
unit_tests += igzip/checksum32_funcs_test
perf_tests += igzip/igzip_perf igzip/igzip_sync_flush_perf perf_tests += igzip/igzip_perf igzip/igzip_sync_flush_perf
@ -113,7 +114,7 @@ other_tests += igzip/igzip_inflate_perf
other_tests += igzip/igzip_inflate_test other_tests += igzip/igzip_inflate_test
other_tests += igzip/igzip_fuzz_inflate other_tests += igzip/igzip_fuzz_inflate
lsrc += igzip/igzip_inflate.c lsrc += igzip/igzip_inflate.c
other_src += igzip/crc_inflate.h other_src += igzip/checksum_test_ref.h
igzip_inflate_perf: LDLIBS += -lz igzip_inflate_perf: LDLIBS += -lz
igzip_igzip_inflate_perf_LDADD = libisal.la igzip_igzip_inflate_perf_LDADD = libisal.la

View File

@ -0,0 +1,282 @@
// <COPYRIGHT_TAG>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "igzip_checksums.h"
#include "checksum_test_ref.h"
#include "types.h"
#ifndef TEST_SEED
# define TEST_SEED 0x1234
#endif
#define MAX_BUF 512
#define TEST_SIZE 20
typedef uint32_t(*checksum32_func_t) (uint32_t, const unsigned char *, uint64_t);
typedef struct func_case {
char *note;
checksum32_func_t checksum32_func_call;
checksum32_func_t checksum32_ref_call;
} func_case_t;
func_case_t test_funcs[] = {
{"checksum32_adler", isal_adler32, adler_ref},
{"crc32_gzip_refl", crc32_gzip, crc32_gzip_refl_ref}
};
// Generates pseudo-random data
void rand_buffer(unsigned char *buf, long buffer_size)
{
long i;
for (i = 0; i < buffer_size; i++)
buf[i] = rand();
}
// Test cases
int zeros_test(func_case_t * test_func);
int simple_pattern_test(func_case_t * test_func);
int seeds_sizes_test(func_case_t * test_func);
int eob_test(func_case_t * test_func);
int update_test(func_case_t * test_func);
int update_over_mod_test(func_case_t * test_func);
int verbose = 0;
void *buf_alloc = NULL;
int main(int argc, char *argv[])
{
int fail = 0, fail_case;
int i, ret;
func_case_t *test_func;
verbose = argc - 1;
// Align to MAX_BUF boundary
ret = posix_memalign(&buf_alloc, MAX_BUF, MAX_BUF * TEST_SIZE);
if (ret) {
printf("alloc error: Fail");
return -1;
}
srand(TEST_SEED);
printf("CHECKSUM32 Tests seed=0x%x\n", TEST_SEED);
for (i = 0; i < sizeof(test_funcs) / sizeof(test_funcs[0]); i++) {
fail_case = 0;
test_func = &test_funcs[i];
printf("Test %s ", test_func->note);
fail_case += zeros_test(test_func);
fail_case += simple_pattern_test(test_func);
fail_case += seeds_sizes_test(test_func);
fail_case += eob_test(test_func);
fail_case += update_test(test_func);
fail_case += update_over_mod_test(test_func);
printf("Test %s done: %s\n", test_func->note, fail_case ? "Fail" : "Pass");
if (fail_case) {
printf("\n%s Failed %d tests\n", test_func->note, fail_case);
fail++;
}
}
printf("CHECKSUM32 Tests all done: %s\n", fail ? "Fail" : "Pass");
return fail;
}
// Test of all zeros
int zeros_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
unsigned char *buf = NULL;
buf = (unsigned char *)buf_alloc;
memset(buf, 0, MAX_BUF * 10);
c_dut = test_func->checksum32_func_call(TEST_SEED, buf, MAX_BUF * 10);
c_ref = test_func->checksum32_ref_call(TEST_SEED, buf, MAX_BUF * 10);
if (c_dut != c_ref) {
fail++;
printf("\n opt ref\n");
printf(" ------ ------\n");
printf("checksum zero = 0x%8x 0x%8x \n", c_dut, c_ref);
} else
printf(".");
return fail;
}
// Another simple test pattern
int simple_pattern_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
unsigned char *buf = NULL;
buf = (unsigned char *)buf_alloc;
memset(buf, 0x8a, MAX_BUF);
c_dut = test_func->checksum32_func_call(TEST_SEED, buf, MAX_BUF);
c_ref = test_func->checksum32_ref_call(TEST_SEED, buf, MAX_BUF);
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum all 8a = 0x%8x 0x%8x\n", c_dut, c_ref);
else
printf(".");
return fail;
}
int seeds_sizes_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
int i;
uint32_t r, s;
unsigned char *buf = NULL;
// Do a few random tests
buf = (unsigned char *)buf_alloc; //reset buf
r = rand();
rand_buffer(buf, MAX_BUF * TEST_SIZE);
for (i = 0; i < TEST_SIZE; i++) {
c_dut = test_func->checksum32_func_call(r, buf, MAX_BUF);
c_ref = test_func->checksum32_ref_call(r, buf, MAX_BUF);
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum rand%3d = 0x%8x 0x%8x\n", i, c_dut, c_ref);
else
printf(".");
buf += MAX_BUF;
}
// Do a few random sizes
buf = (unsigned char *)buf_alloc; //reset buf
r = rand();
for (i = MAX_BUF; i >= 0; i--) {
c_dut = test_func->checksum32_func_call(r, buf, i);
c_ref = test_func->checksum32_ref_call(r, buf, i);
if (c_dut != c_ref) {
fail++;
printf("fail random size%i 0x%8x 0x%8x\n", i, c_dut, c_ref);
} else
printf(".");
}
// Try different seeds
for (s = 0; s < 20; s++) {
buf = (unsigned char *)buf_alloc; //reset buf
r = rand(); // just to get a new seed
rand_buffer(buf, MAX_BUF * TEST_SIZE); // new pseudo-rand data
if (verbose)
printf("seed = 0x%x\n", r);
for (i = 0; i < TEST_SIZE; i++) {
c_dut = test_func->checksum32_func_call(r, buf, MAX_BUF);
c_ref = test_func->checksum32_ref_call(r, buf, MAX_BUF);
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum rand%3d = 0x%8x 0x%8x\n", i, c_dut, c_ref);
else
printf(".");
buf += MAX_BUF;
}
}
return fail;
}
// Run tests at end of buffer
int eob_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
int i;
unsigned char *buf = NULL;
buf = (unsigned char *)buf_alloc; //reset buf
buf = buf + ((MAX_BUF - 1) * TEST_SIZE); //Line up TEST_SIZE from end
for (i = 0; i < TEST_SIZE; i++) {
c_dut = test_func->checksum32_func_call(TEST_SEED, buf + i, TEST_SIZE - i);
c_ref = test_func->checksum32_ref_call(TEST_SEED, buf + i, TEST_SIZE - i);
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum eob rand%3d = 0x%8x 0x%8x\n", i, c_dut, c_ref);
else
printf(".");
}
return fail;
}
int update_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
int i;
uint32_t r;
unsigned char *buf = NULL;
buf = (unsigned char *)buf_alloc; //reset buf
r = rand();
// Process the whole buf with reference func single call.
c_ref = test_func->checksum32_ref_call(r, buf, MAX_BUF * TEST_SIZE);
// Process buf with update method.
for (i = 0; i < TEST_SIZE; i++) {
c_dut = test_func->checksum32_func_call(r, buf, MAX_BUF);
// Update checksum seeds and buf pointer.
r = c_dut;
buf += MAX_BUF;
}
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum rand%3d = 0x%8x 0x%8x\n", i, c_dut, c_ref);
else
printf(".");
return fail;
}
int update_over_mod_test(func_case_t * test_func)
{
uint32_t c_dut, c_ref;
int fail = 0;
int i;
unsigned char *buf = NULL;
buf = malloc(ADLER_MOD);
memset(buf, 0xff, ADLER_MOD);
c_ref = c_dut = rand();
// Process buf with update method.
for (i = 0; i < 20; i++) {
c_ref = test_func->checksum32_ref_call(c_ref, buf, ADLER_MOD - 64);
c_dut = test_func->checksum32_func_call(c_dut, buf, ADLER_MOD - 64);
}
if (c_dut != c_ref)
fail++;
if (verbose)
printf("checksum rand%3d = 0x%8x 0x%8x\n", i, c_dut, c_ref);
else
printf(".");
free(buf);
return fail;
}

View File

@ -1,5 +1,9 @@
#ifndef INFLATE_CRC_TABLE /*
#define INFLATE_CRC_TABLE * Reference checksums used in compression tests
*/
#ifndef CHECKSUM_TEST_REF_H
#define CHECKSUM_TEST_REF_H
uint32_t inflate_crc_table[256] = { uint32_t inflate_crc_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
@ -68,30 +72,29 @@ uint32_t inflate_crc_table[256] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
uint32_t find_crc(uint8_t * start, uint32_t length) uint32_t crc32_gzip_refl_ref(uint32_t crc, const unsigned char *buf, uint64_t len)
{ {
uint32_t crc = ~0; uint64_t i;
uint8_t *end = start + length; crc = ~crc;
for (i = 0; i < len; i++)
while (start < end) crc = (crc >> 8) ^ inflate_crc_table[(crc & 0xff) ^ buf[i]];
crc = (crc >> 8) ^ inflate_crc_table[(crc & 0x000000FF) ^ *start++];
return ~crc; return ~crc;
} }
#define ADLER_MOD 65521 #define ADLER_MOD 65521
uint32_t find_adler(uint8_t * start, uint32_t length)
uint32_t adler_ref(uint32_t init, const unsigned char *buf, uint64_t len)
{ {
uint32_t A = 1; uint64_t i;
uint32_t B = 0; uint32_t a = init & 0xffff;
uint8_t *end = start + length; uint32_t b = init >> 16;
while (start < end) { for (i = 0; i < len; i++) {
A = (A + *start) % ADLER_MOD; a = (a + buf[i]) % ADLER_MOD;
B = (B + A) % ADLER_MOD; b = (b + a) % ADLER_MOD;
start++;
} }
return (b << 16) | a;
return (B << 16) | A;
} }
#endif #endif /* CHECKSUM_TEST_REF_H */

View File

@ -58,7 +58,7 @@ int usage(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FILE *in, *out = NULL; FILE *in = NULL, *out = NULL;
unsigned char *inbuf, *outbuf, *level_buf = NULL; unsigned char *inbuf, *outbuf, *level_buf = NULL;
int i, c, iterations = 0, inbuf_size = 0; int i, c, iterations = 0, inbuf_size = 0;
uint64_t infile_size, outbuf_size; uint64_t infile_size, outbuf_size;

View File

@ -33,7 +33,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "igzip_lib.h" #include "igzip_lib.h"
#include "crc_inflate.h" #include "checksum_test_ref.h"
#include "inflate_std_vects.h" #include "inflate_std_vects.h"
#include <math.h> #include <math.h>
#include "test.h" #include "test.h"
@ -366,7 +366,7 @@ uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncom
uint64_t trl, ret = 0; uint64_t trl, ret = 0;
uint32_t crc; uint32_t crc;
crc = find_crc(uncompress_buf, uncompress_len); crc = crc32_gzip_refl_ref(0, uncompress_buf, uncompress_len);
trl = ((uint64_t) uncompress_len << 32) | crc; trl = ((uint64_t) uncompress_len << 32) | crc;
if (crc != inflate_crc || trl != gzip_trl) if (crc != inflate_crc || trl != gzip_trl)
@ -381,7 +381,7 @@ uint32_t check_zlib_trl(uint32_t zlib_trl, uint32_t inflate_adler, uint8_t * unc
uint32_t trl, ret = 0; uint32_t trl, ret = 0;
uint32_t adler; uint32_t adler;
adler = find_adler(uncompress_buf, uncompress_len); adler = adler_ref(1, uncompress_buf, uncompress_len);
trl = trl =
(adler >> 24) | ((adler >> 8) & 0xFF00) | (adler << 24) | ((adler & 0xFF00) << 8); (adler >> 24) | ((adler >> 8) & 0xFF00) | (adler << 24) | ((adler & 0xFF00) << 8);

View File

@ -57,7 +57,7 @@ int usage(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FILE *in, *out = NULL; FILE *in = NULL, *out = NULL;
unsigned char *inbuf, *outbuf, *level_buf = NULL; unsigned char *inbuf, *outbuf, *level_buf = NULL;
int i, c, iterations = 0; int i, c, iterations = 0;
uint64_t infile_size, outbuf_size; uint64_t infile_size, outbuf_size;