/*
 * Block replication tests
 *
 * Copyright (c) 2016 FUJITSU LIMITED
 * Author: Changlong Xie <xiecl.fnst@cn.fujitsu.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 "qapi/error.h"
#include "replication.h"
#include "block/block_int.h"
#include "sysemu/block-backend.h"

#define IMG_SIZE (64 * 1024 * 1024)

/* primary */
#define P_ID "primary-id"
static char p_local_disk[] = "/tmp/p_local_disk.XXXXXX";

/* secondary */
#define S_ID "secondary-id"
#define S_LOCAL_DISK_ID "secondary-local-disk-id"
static char s_local_disk[] = "/tmp/s_local_disk.XXXXXX";
static char s_active_disk[] = "/tmp/s_active_disk.XXXXXX";
static char s_hidden_disk[] = "/tmp/s_hidden_disk.XXXXXX";

/* FIXME: steal from blockdev.c */
QemuOptsList qemu_drive_opts = {
    .name = "drive",
    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
    .desc = {
        { /* end of list */ }
    },
};

#define NOT_DONE 0x7fffffff

static void blk_rw_done(void *opaque, int ret)
{
    *(int *)opaque = ret;
}

static void test_blk_read(BlockBackend *blk, long pattern,
                          int64_t pattern_offset, int64_t pattern_count,
                          int64_t offset, int64_t count,
                          bool expect_failed)
{
    void *pattern_buf = NULL;
    QEMUIOVector qiov;
    void *cmp_buf = NULL;
    int async_ret = NOT_DONE;

    if (pattern) {
        cmp_buf = g_malloc(pattern_count);
        memset(cmp_buf, pattern, pattern_count);
    }

    pattern_buf = g_malloc(count);
    if (pattern) {
        memset(pattern_buf, pattern, count);
    } else {
        memset(pattern_buf, 0x00, count);
    }

    qemu_iovec_init(&qiov, 1);
    qemu_iovec_add(&qiov, pattern_buf, count);

    blk_aio_preadv(blk, offset, &qiov, 0, blk_rw_done, &async_ret);
    while (async_ret == NOT_DONE) {
        main_loop_wait(false);
    }

    if (expect_failed) {
        g_assert(async_ret != 0);
    } else {
        g_assert(async_ret == 0);
        if (pattern) {
            g_assert(memcmp(pattern_buf + pattern_offset,
                            cmp_buf, pattern_count) <= 0);
        }
    }

    g_free(pattern_buf);
    g_free(cmp_buf);
    qemu_iovec_destroy(&qiov);
}

static void test_blk_write(BlockBackend *blk, long pattern, int64_t offset,
                           int64_t count, bool expect_failed)
{
    void *pattern_buf = NULL;
    QEMUIOVector qiov;
    int async_ret = NOT_DONE;

    pattern_buf = g_malloc(count);
    if (pattern) {
        memset(pattern_buf, pattern, count);
    } else {
        memset(pattern_buf, 0x00, count);
    }

    qemu_iovec_init(&qiov, 1);
    qemu_iovec_add(&qiov, pattern_buf, count);

    blk_aio_pwritev(blk, offset, &qiov, 0, blk_rw_done, &async_ret);
    while (async_ret == NOT_DONE) {
        main_loop_wait(false);
    }

    if (expect_failed) {
        g_assert(async_ret != 0);
    } else {
        g_assert(async_ret == 0);
    }

    g_free(pattern_buf);
    qemu_iovec_destroy(&qiov);
}

/*
 * Create a uniquely-named empty temporary file.
 */
static void make_temp(char *template)
{
    int fd;

    fd = mkstemp(template);
    g_assert(fd >= 0);
    close(fd);
}

static void prepare_imgs(void)
{
    Error *local_err = NULL;

    make_temp(p_local_disk);
    make_temp(s_local_disk);
    make_temp(s_active_disk);
    make_temp(s_hidden_disk);

    /* Primary */
    bdrv_img_create(p_local_disk, "qcow2", NULL, NULL, NULL, IMG_SIZE,
                    BDRV_O_RDWR, &local_err, true);
    g_assert(!local_err);

    /* Secondary */
    bdrv_img_create(s_local_disk, "qcow2", NULL, NULL, NULL, IMG_SIZE,
                    BDRV_O_RDWR, &local_err, true);
    g_assert(!local_err);
    bdrv_img_create(s_active_disk, "qcow2", NULL, NULL, NULL, IMG_SIZE,
                    BDRV_O_RDWR, &local_err, true);
    g_assert(!local_err);
    bdrv_img_create(s_hidden_disk, "qcow2", NULL, NULL, NULL, IMG_SIZE,
                    BDRV_O_RDWR, &local_err, true);
    g_assert(!local_err);
}

static void cleanup_imgs(void)
{
    /* Primary */
    unlink(p_local_disk);

    /* Secondary */
    unlink(s_local_disk);
    unlink(s_active_disk);
    unlink(s_hidden_disk);
}

static BlockBackend *start_primary(void)
{
    BlockBackend *blk;
    QemuOpts *opts;
    QDict *qdict;
    Error *local_err = NULL;
    char *cmdline;

    cmdline = g_strdup_printf("driver=replication,mode=primary,node-name=xxx,"
                              "file.driver=qcow2,file.file.filename=%s"
                              , p_local_disk);
    opts = qemu_opts_parse_noisily(&qemu_drive_opts, cmdline, false);
    g_free(cmdline);

    qdict = qemu_opts_to_qdict(opts, NULL);
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");

    blk = blk_new_open(NULL, NULL, qdict, BDRV_O_RDWR, &local_err);
    g_assert(blk);
    g_assert(!local_err);

    monitor_add_blk(blk, P_ID, &local_err);
    g_assert(!local_err);

    qemu_opts_del(opts);

    return blk;
}

static void teardown_primary(void)
{
    BlockBackend *blk;

    /* remove P_ID */
    blk = blk_by_name(P_ID);
    assert(blk);

    monitor_remove_blk(blk);
    blk_unref(blk);
}

static void test_primary_read(void)
{
    BlockBackend *blk;

    blk = start_primary();

    /* read from 0 to IMG_SIZE */
    test_blk_read(blk, 0, 0, IMG_SIZE, 0, IMG_SIZE, true);

    teardown_primary();
}

static void test_primary_write(void)
{
    BlockBackend *blk;

    blk = start_primary();

    /* write from 0 to IMG_SIZE */
    test_blk_write(blk, 0, 0, IMG_SIZE, true);

    teardown_primary();
}

static void test_primary_start(void)
{
    BlockBackend *blk = NULL;
    Error *local_err = NULL;

    blk = start_primary();

    replication_start_all(REPLICATION_MODE_PRIMARY, &local_err);
    g_assert(!local_err);

    /* read from 0 to IMG_SIZE */
    test_blk_read(blk, 0, 0, IMG_SIZE, 0, IMG_SIZE, true);

    /* write 0x22 from 0 to IMG_SIZE */
    test_blk_write(blk, 0x22, 0, IMG_SIZE, false);

    teardown_primary();
}

static void test_primary_stop(void)
{
    Error *local_err = NULL;
    bool failover = true;

    start_primary();

    replication_start_all(REPLICATION_MODE_PRIMARY, &local_err);
    g_assert(!local_err);

    replication_stop_all(failover, &local_err);
    g_assert(!local_err);

    teardown_primary();
}

static void test_primary_do_checkpoint(void)
{
    Error *local_err = NULL;

    start_primary();

    replication_start_all(REPLICATION_MODE_PRIMARY, &local_err);
    g_assert(!local_err);

    replication_do_checkpoint_all(&local_err);
    g_assert(!local_err);

    teardown_primary();
}

static void test_primary_get_error_all(void)
{
    Error *local_err = NULL;

    start_primary();

    replication_start_all(REPLICATION_MODE_PRIMARY, &local_err);
    g_assert(!local_err);

    replication_get_error_all(&local_err);
    g_assert(!local_err);

    teardown_primary();
}

static BlockBackend *start_secondary(void)
{
    QemuOpts *opts;
    QDict *qdict;
    BlockBackend *blk;
    char *cmdline;
    Error *local_err = NULL;

    /* add s_local_disk and forge S_LOCAL_DISK_ID */
    cmdline = g_strdup_printf("file.filename=%s,driver=qcow2", s_local_disk);
    opts = qemu_opts_parse_noisily(&qemu_drive_opts, cmdline, false);
    g_free(cmdline);

    qdict = qemu_opts_to_qdict(opts, NULL);
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");

    blk = blk_new_open(NULL, NULL, qdict, BDRV_O_RDWR, &local_err);
    assert(blk);
    monitor_add_blk(blk, S_LOCAL_DISK_ID, &local_err);
    g_assert(!local_err);

    /* format s_local_disk with pattern "0x11" */
    test_blk_write(blk, 0x11, 0, IMG_SIZE, false);

    qemu_opts_del(opts);

    /* add S_(ACTIVE/HIDDEN)_DISK and forge S_ID */
    cmdline = g_strdup_printf("driver=replication,mode=secondary,top-id=%s,"
                              "file.driver=qcow2,file.file.filename=%s,"
                              "file.backing.driver=qcow2,"
                              "file.backing.file.filename=%s,"
                              "file.backing.backing=%s"
                              , S_ID, s_active_disk, s_hidden_disk
                              , S_LOCAL_DISK_ID);
    opts = qemu_opts_parse_noisily(&qemu_drive_opts, cmdline, false);
    g_free(cmdline);

    qdict = qemu_opts_to_qdict(opts, NULL);
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_DIRECT, "off");
    qdict_set_default_str(qdict, BDRV_OPT_CACHE_NO_FLUSH, "off");

    blk = blk_new_open(NULL, NULL, qdict, BDRV_O_RDWR, &local_err);
    assert(blk);
    monitor_add_blk(blk, S_ID, &local_err);
    g_assert(!local_err);

    qemu_opts_del(opts);

    return blk;
}

static void teardown_secondary(void)
{
    /* only need to destroy two BBs */
    BlockBackend *blk;

    /* remove S_LOCAL_DISK_ID */
    blk = blk_by_name(S_LOCAL_DISK_ID);
    assert(blk);

    monitor_remove_blk(blk);
    blk_unref(blk);

    /* remove S_ID */
    blk = blk_by_name(S_ID);
    assert(blk);

    monitor_remove_blk(blk);
    blk_unref(blk);
}

static void test_secondary_read(void)
{
    BlockBackend *blk;

    blk = start_secondary();

    /* read from 0 to IMG_SIZE */
    test_blk_read(blk, 0, 0, IMG_SIZE, 0, IMG_SIZE, true);

    teardown_secondary();
}

static void test_secondary_write(void)
{
    BlockBackend *blk;

    blk = start_secondary();

    /* write from 0 to IMG_SIZE */
    test_blk_write(blk, 0, 0, IMG_SIZE, true);

    teardown_secondary();
}

static void test_secondary_start(void)
{
    BlockBackend *top_blk, *local_blk;
    Error *local_err = NULL;
    bool failover = true;

    top_blk = start_secondary();
    replication_start_all(REPLICATION_MODE_SECONDARY, &local_err);
    g_assert(!local_err);

    /* read from s_local_disk (0, IMG_SIZE) */
    test_blk_read(top_blk, 0x11, 0, IMG_SIZE, 0, IMG_SIZE, false);

    /* write 0x22 to s_local_disk (IMG_SIZE / 2, IMG_SIZE) */
    local_blk = blk_by_name(S_LOCAL_DISK_ID);
    test_blk_write(local_blk, 0x22, IMG_SIZE / 2, IMG_SIZE / 2, false);

    /* replication will backup s_local_disk to s_hidden_disk */
    test_blk_read(top_blk, 0x11, IMG_SIZE / 2,
                  IMG_SIZE / 2, 0, IMG_SIZE, false);

    /* write 0x33 to s_active_disk (0, IMG_SIZE / 2) */
    test_blk_write(top_blk, 0x33, 0, IMG_SIZE / 2, false);

    /* read from s_active_disk (0, IMG_SIZE/2) */
    test_blk_read(top_blk, 0x33, 0, IMG_SIZE / 2,
                  0, IMG_SIZE / 2, false);

    /* unblock top_bs */
    replication_stop_all(failover, &local_err);
    g_assert(!local_err);

    teardown_secondary();
}


static void test_secondary_stop(void)
{
    BlockBackend *top_blk, *local_blk;
    Error *local_err = NULL;
    bool failover = true;

    top_blk = start_secondary();
    replication_start_all(REPLICATION_MODE_SECONDARY, &local_err);
    g_assert(!local_err);

    /* write 0x22 to s_local_disk (IMG_SIZE / 2, IMG_SIZE) */
    local_blk = blk_by_name(S_LOCAL_DISK_ID);
    test_blk_write(local_blk, 0x22, IMG_SIZE / 2, IMG_SIZE / 2, false);

    /* replication will backup s_local_disk to s_hidden_disk */
    test_blk_read(top_blk, 0x11, IMG_SIZE / 2,
                  IMG_SIZE / 2, 0, IMG_SIZE, false);

    /* write 0x33 to s_active_disk (0, IMG_SIZE / 2) */
    test_blk_write(top_blk, 0x33, 0, IMG_SIZE / 2, false);

    /* do active commit */
    replication_stop_all(failover, &local_err);
    g_assert(!local_err);

    /* read from s_local_disk (0, IMG_SIZE / 2) */
    test_blk_read(top_blk, 0x33, 0, IMG_SIZE / 2,
                  0, IMG_SIZE / 2, false);


    /* read from s_local_disk (IMG_SIZE / 2, IMG_SIZE) */
    test_blk_read(top_blk, 0x22, IMG_SIZE / 2,
                  IMG_SIZE / 2, 0, IMG_SIZE, false);

    teardown_secondary();
}

static void test_secondary_do_checkpoint(void)
{
    BlockBackend *top_blk, *local_blk;
    Error *local_err = NULL;
    bool failover = true;

    top_blk = start_secondary();
    replication_start_all(REPLICATION_MODE_SECONDARY, &local_err);
    g_assert(!local_err);

    /* write 0x22 to s_local_disk (IMG_SIZE / 2, IMG_SIZE) */
    local_blk = blk_by_name(S_LOCAL_DISK_ID);
    test_blk_write(local_blk, 0x22, IMG_SIZE / 2,
                   IMG_SIZE / 2, false);

    /* replication will backup s_local_disk to s_hidden_disk */
    test_blk_read(top_blk, 0x11, IMG_SIZE / 2,
                  IMG_SIZE / 2, 0, IMG_SIZE, false);

    replication_do_checkpoint_all(&local_err);
    g_assert(!local_err);

    /* after checkpoint, read pattern 0x22 from s_local_disk */
    test_blk_read(top_blk, 0x22, IMG_SIZE / 2,
                  IMG_SIZE / 2, 0, IMG_SIZE, false);

    /* unblock top_bs */
    replication_stop_all(failover, &local_err);
    g_assert(!local_err);

    teardown_secondary();
}

static void test_secondary_get_error_all(void)
{
    Error *local_err = NULL;
    bool failover = true;

    start_secondary();
    replication_start_all(REPLICATION_MODE_SECONDARY, &local_err);
    g_assert(!local_err);

    replication_get_error_all(&local_err);
    g_assert(!local_err);

    /* unblock top_bs */
    replication_stop_all(failover, &local_err);
    g_assert(!local_err);

    teardown_secondary();
}

static void sigabrt_handler(int signo)
{
    cleanup_imgs();
}

static void setup_sigabrt_handler(void)
{
    struct sigaction sigact;

    sigact = (struct sigaction) {
        .sa_handler = sigabrt_handler,
        .sa_flags = SA_RESETHAND,
    };
    sigemptyset(&sigact.sa_mask);
    sigaction(SIGABRT, &sigact, NULL);
}

int main(int argc, char **argv)
{
    int ret;
    qemu_init_main_loop(&error_fatal);
    bdrv_init();

    g_test_init(&argc, &argv, NULL);
    setup_sigabrt_handler();

    prepare_imgs();

    /* Primary */
    g_test_add_func("/replication/primary/read",    test_primary_read);
    g_test_add_func("/replication/primary/write",   test_primary_write);
    g_test_add_func("/replication/primary/start",   test_primary_start);
    g_test_add_func("/replication/primary/stop",    test_primary_stop);
    g_test_add_func("/replication/primary/do_checkpoint",
                    test_primary_do_checkpoint);
    g_test_add_func("/replication/primary/get_error_all",
                    test_primary_get_error_all);

    /* Secondary */
    g_test_add_func("/replication/secondary/read",  test_secondary_read);
    g_test_add_func("/replication/secondary/write", test_secondary_write);
    g_test_add_func("/replication/secondary/start", test_secondary_start);
    g_test_add_func("/replication/secondary/stop",  test_secondary_stop);
    g_test_add_func("/replication/secondary/do_checkpoint",
                    test_secondary_do_checkpoint);
    g_test_add_func("/replication/secondary/get_error_all",
                    test_secondary_get_error_all);

    ret = g_test_run();

    cleanup_imgs();

    return ret;
}
