/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2017-2023 Brett Sheffield <bacs@librecast.net> */

/*
 * testing lc_socket_new() / lc_socket_close()
 * test is intended to be run under valgrind (`make memcheck/0001`) to check for
 * leaks
 */

#include "test.h"
#include "falloc.h"
#include <librecast/net.h>

int main(void)
{
	lc_ctx_t *lctx;
	lc_socket_t *sock, *sock2;

	test_name("lc_socket_new() / lc_socket_close()");

	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	sock = lc_socket_new(lctx);
	if (!test_assert(sock != NULL, "lc_socket_new()")) goto err_ctx_free;

	lc_socket_close(sock);
	lc_ctx_free(lctx);

	/* lc_ctx_free() should clean up socket without needing explicit lc_socket_close() */
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	sock = lc_socket_new(lctx);
	if (!test_assert(sock != NULL, "sock allocated")) goto err_ctx_free;
	sock2 = lc_socket_new(lctx);
	(void) sock2; /* "use" variable to keep compiler happy */
	if (!test_assert(sock != NULL, "sock2 allocated")) goto err_ctx_free;
	lc_ctx_free(lctx);

	/* Say bye to valgrind - it finds the things that happen next upsetting */
	if (RUNNING_ON_VALGRIND) return test_status;

	/* force ENOMEM */
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	falloc_setfail(1);
	sock = lc_socket_new(lctx); /* will fail with ENOMEM */
	test_assert(errno == ENOMEM, "lc_socket_new() - ENOMEM");
	test_assert(sock == NULL, "lc_socket_new() - ENOMEM, return NULL");
err_ctx_free:
	lc_ctx_free(lctx);
	return test_status;
}
