/*
 * Copyright (c) Meta Platforms, Inc. and affiliates
 *
 * Authors: Mattias Nissler <mnissler@meta.com>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of Nutanix nor the names of its contributors may be
 *        used to endorse or promote products derived from this software without
 *        specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 *  DAMAGE.
 *
 */

#undef NDEBUG /* so assert() works in release builds */
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/eventfd.h>
#include <unistd.h>

#include "fd_cache.h"

/* See fd_cache.c */
extern bool kcmp_checked;
extern bool kcmp_available;

static int
make_tmpfile()
{
    char template[] = "libvfio_user_fd_cache_tests_tmp_XXXXXX";
    int fd;

    fd = mkstemp(template);
    assert(fd != -1);
    assert(unlink(template) == 0);

    return fd;
}

static void
test_tmpfile()
{
    int fd1, fd2, fd3;

    fd1 = make_tmpfile();
    fd2 = dup(fd1);
    assert(fd2 != -1);
    assert(fd2 != fd1);

    assert(fd_cache_is_same_file(fd1, fd2) == 0);

    /* Confirm that the cache recognizes duplicated file descriptors. */
    fd1 = fd_cache_get(fd1);
    assert(fd1 != -1);
    fd2 = fd_cache_get(fd2);
    assert(fd2 != -1);
    assert(fd1 == fd2);

    /* Make sure an unrelated file descriptor doesn't get de-duplicated. */
    fd3 = make_tmpfile();
    assert(fd3 != -1);
    fd3 = fd_cache_get(fd3);
    assert(fd3 != -1);
    assert(fd1 != fd3);

    assert(fd_cache_put(&fd1) == 0);
    assert(fd_cache_put(&fd2) == 0);
    assert(fd_cache_put(&fd3) == 0);
}

static void
test_eventfd()
{
    int fd1, fd2;

    fd1 = eventfd(0, 0);
    assert(fd1 != -1);
    fd2 = dup(fd1);
    assert(fd2 != -1);

    assert(fd_cache_is_same_file(fd1, fd2) == 0);

    fd1 = fd_cache_get(fd1);
    assert(fd1 != -1);
    fd2 = fd_cache_get(fd2);
    assert(fd2 != -1);

    /*
     * If we don't have kcmp, file descriptors for non-regular files can't be
     * de-duplicated reliably, so make sure the cache ignores them.
     */
    if (kcmp_available) {
        assert(fd1 == fd2);
    } else {
        assert(fd1 != fd2);
    }

    assert(fd_cache_put(&fd1) == 0);
    assert(fd_cache_put(&fd2) == 0);
}

int
main(void)
{
    test_tmpfile();
    test_eventfd();

    /* Enable fallback mode for the remaining test cases. */
    kcmp_checked = true;
    kcmp_available = false;

    /* Run tests again, with the fallback force-enabled. */
    test_tmpfile();
    test_eventfd();

    return 0;
}

/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */
