/*
 * Xor Based Zero Run Length Encoding unit tests.
 *
 * Copyright 2013 Red Hat, Inc. and/or its affiliates
 *
 * Authors:
 *  Orit Wasserman  <owasserm@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "include/migration/migration.h"

#define PAGE_SIZE 4096

static void test_uleb(void)
{
    uint32_t i, val;
    uint8_t buf[2];
    int encode_ret, decode_ret;

    for (i = 0; i <= 0x3fff; i++) {
        encode_ret = uleb128_encode_small(&buf[0], i);
        decode_ret = uleb128_decode_small(&buf[0], &val);
        g_assert(encode_ret == decode_ret);
        g_assert(i == val);
    }

    /* decode invalid value */
    buf[0] = 0x80;
    buf[1] = 0x80;

    decode_ret = uleb128_decode_small(&buf[0], &val);
    g_assert(decode_ret == -1);
    g_assert(val == 0);
}

static void test_encode_decode_zero(void)
{
    uint8_t *buffer = g_malloc0(PAGE_SIZE);
    uint8_t *compressed = g_malloc0(PAGE_SIZE);
    int i = 0;
    int dlen = 0;
    int diff_len = g_test_rand_int_range(0, PAGE_SIZE - 1006);

    for (i = diff_len; i > 0; i--) {
        buffer[1000 + i] = i;
    }

    buffer[1000 + diff_len + 3] = 103;
    buffer[1000 + diff_len + 5] = 105;

    /* encode zero page */
    dlen = xbzrle_encode_buffer(buffer, buffer, PAGE_SIZE, compressed,
                       PAGE_SIZE);
    g_assert(dlen == 0);

    g_free(buffer);
    g_free(compressed);
}

static void test_encode_decode_unchanged(void)
{
    uint8_t *compressed = g_malloc0(PAGE_SIZE);
    uint8_t *test = g_malloc0(PAGE_SIZE);
    int i = 0;
    int dlen = 0;
    int diff_len = g_test_rand_int_range(0, PAGE_SIZE - 1006);

    for (i = diff_len; i > 0; i--) {
        test[1000 + i] = i + 4;
    }

    test[1000 + diff_len + 3] = 107;
    test[1000 + diff_len + 5] = 109;

    /* test unchanged buffer */
    dlen = xbzrle_encode_buffer(test, test, PAGE_SIZE, compressed,
                                PAGE_SIZE);
    g_assert(dlen == 0);

    g_free(test);
    g_free(compressed);
}

static void test_encode_decode_1_byte(void)
{
    uint8_t *buffer = g_malloc0(PAGE_SIZE);
    uint8_t *test = g_malloc0(PAGE_SIZE);
    uint8_t *compressed = g_malloc(PAGE_SIZE);
    int dlen = 0, rc = 0;
    uint8_t buf[2];

    test[PAGE_SIZE - 1] = 1;

    dlen = xbzrle_encode_buffer(buffer, test, PAGE_SIZE, compressed,
                       PAGE_SIZE);
    g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2));

    rc = xbzrle_decode_buffer(compressed, dlen, buffer, PAGE_SIZE);
    g_assert(rc == PAGE_SIZE);
    g_assert(memcmp(test, buffer, PAGE_SIZE) == 0);

    g_free(buffer);
    g_free(compressed);
    g_free(test);
}

static void test_encode_decode_overflow(void)
{
    uint8_t *compressed = g_malloc0(PAGE_SIZE);
    uint8_t *test = g_malloc0(PAGE_SIZE);
    uint8_t *buffer = g_malloc0(PAGE_SIZE);
    int i = 0, rc = 0;

    for (i = 0; i < PAGE_SIZE / 2 - 1; i++) {
        test[i * 2] = 1;
    }

    /* encode overflow */
    rc = xbzrle_encode_buffer(buffer, test, PAGE_SIZE, compressed,
                              PAGE_SIZE);
    g_assert(rc == -1);

    g_free(buffer);
    g_free(compressed);
    g_free(test);
}

static void encode_decode_range(void)
{
    uint8_t *buffer = g_malloc0(PAGE_SIZE);
    uint8_t *compressed = g_malloc(PAGE_SIZE);
    uint8_t *test = g_malloc0(PAGE_SIZE);
    int i = 0, rc = 0;
    int dlen = 0;

    int diff_len = g_test_rand_int_range(0, PAGE_SIZE - 1006);

    for (i = diff_len; i > 0; i--) {
        buffer[1000 + i] = i;
        test[1000 + i] = i + 4;
    }

    buffer[1000 + diff_len + 3] = 103;
    test[1000 + diff_len + 3] = 107;

    buffer[1000 + diff_len + 5] = 105;
    test[1000 + diff_len + 5] = 109;

    /* test encode/decode */
    dlen = xbzrle_encode_buffer(test, buffer, PAGE_SIZE, compressed,
                                PAGE_SIZE);

    rc = xbzrle_decode_buffer(compressed, dlen, test, PAGE_SIZE);
    g_assert(rc < PAGE_SIZE);
    g_assert(memcmp(test, buffer, PAGE_SIZE) == 0);

    g_free(buffer);
    g_free(compressed);
    g_free(test);
}

static void test_encode_decode(void)
{
    int i;

    for (i = 0; i < 10000; i++) {
        encode_decode_range();
    }
}

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);
    g_test_rand_int();
    g_test_add_func("/xbzrle/uleb", test_uleb);
    g_test_add_func("/xbzrle/encode_decode_zero", test_encode_decode_zero);
    g_test_add_func("/xbzrle/encode_decode_unchanged",
                    test_encode_decode_unchanged);
    g_test_add_func("/xbzrle/encode_decode_1_byte", test_encode_decode_1_byte);
    g_test_add_func("/xbzrle/encode_decode_overflow",
                    test_encode_decode_overflow);
    g_test_add_func("/xbzrle/encode_decode", test_encode_decode);

    return g_test_run();
}
