/* Unit test for lib/crc32.c */
#include <config.h>
#include "cunit/cyrunit.h"
#include "crc32.h"

static void test_map(void)
{
    static const char TEXT[] = "lorem ipsum";
    static uint32_t CRC32 = 0x72d7748e;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_unaligned(void)
{
    struct aligned_data {
        char pad1[1];
        char UNALIGNED_TEXT[12];
        char pad2[3];
        char ALIGNED_TEXT[12];
    } __attribute__((packed, aligned (ALIGNOF_UINT32_T)));

    static const struct aligned_data data = {
        { 0 },
        "lorem ipsum",
        { 0 },
        "lorem ipsum",
    };
    static const uint32_t CRC32 = 0x72d7748e;
    uint32_t c;

    c = crc32_map(data.UNALIGNED_TEXT, sizeof(data.UNALIGNED_TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);

    c = crc32_map(data.ALIGNED_TEXT, sizeof(data.ALIGNED_TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_iovec(void)
{
    static const char TEXT1[] = "lorem";
    static const char TEXT2[] = " ipsum";
    static uint32_t CRC32 = 0x72d7748e;
    uint32_t c;
    struct iovec iov[2];

    memset(iov, 0, sizeof(iov));
    iov[0].iov_base = (char *)TEXT1;
    iov[0].iov_len = sizeof(TEXT1)-1;
    iov[1].iov_base = (char *)TEXT2;
    iov[1].iov_len = sizeof(TEXT2)-1;

    c = crc32_iovec(iov, 2);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_zero(void)
{
    static const char TEXT[] = "";
    static uint32_t CRC32 = 0;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_one(void)
{
    static const char TEXT[] = " ";
    static uint32_t CRC32 = 0xe96ccf45;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_nine(void)
{
    static const char TEXT[] = "123456789";
    static uint32_t CRC32 = 0xcbf43926;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_alpha(void)
{
    static const char TEXT[] = "abcdefghijklmnopqrstuvwxyz";
    static uint32_t CRC32 = 0x4c2750bd;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_null(void)
{
    static const char TEXT[] = "\0";
    static uint32_t CRC32 = 0xd202ef8d;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_twonull(void)
{
    static const char TEXT[] = "\0\0";
    static uint32_t CRC32 = 0x41d912ff;
    uint32_t c;

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_bigbuf(void)
{
    static char TEXT[50000];
    static uint32_t CRC32 = 0xa6c997c2;
    uint32_t c;
    size_t i;

    for (i = 0; i < sizeof(TEXT); i++) {
        TEXT[i] = i % 256;
    }

    c = crc32_map(TEXT, sizeof(TEXT)-1);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_iovec_empty(void)
{
    static const char TEXT1[] = "lorem";
    static const char TEXT2[] = " ipsum";
    static uint32_t CRC32 = 0;
    uint32_t c;
    struct iovec iov[2];

    memset(iov, 0, sizeof(iov));
    iov[0].iov_base = (char *)TEXT1;
    iov[0].iov_len = sizeof(TEXT1)-1;
    iov[1].iov_base = (char *)TEXT2;
    iov[1].iov_len = sizeof(TEXT2)-1;

    c = crc32_iovec(iov, 0);
    CU_ASSERT_EQUAL(c, CRC32);
}

static void test_iovec_blank(void)
{
    static const char TEXT1[] = "lorem";
    static const char TEXT2[] = " ipsum";
    static uint32_t CRC32 = 0x72d7748e;
    uint32_t c;
    struct iovec iov[3];

    memset(iov, 0, sizeof(iov));
    iov[0].iov_base = (char *)TEXT1;
    iov[0].iov_len = sizeof(TEXT1)-1;
    iov[1].iov_base = NULL;
    iov[1].iov_len = 0;
    iov[2].iov_base = (char *)TEXT2;
    iov[2].iov_len = sizeof(TEXT2)-1;

    c = crc32_iovec(iov, 3);
    CU_ASSERT_EQUAL(c, CRC32);
}



/* vim: set ft=c: */
