test: Add C++ classes wrapping system interfaces.

These are more convenient and safer than the manual vtables we have in
the fuzzer support code. We can override individual member functions,
and C++ will take care of correctly casting and offsetting this-pointers
when needed.
This commit is contained in:
iphydf 2024-01-13 13:43:01 +00:00
parent 4cea4f9ca4
commit bcb6592af5
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
16 changed files with 323 additions and 54 deletions

View File

@ -481,6 +481,8 @@ add_library(test_util STATIC
toxcore/DHT_test_util.hh
toxcore/crypto_core_test_util.cc
toxcore/crypto_core_test_util.hh
toxcore/mem_test_util.cc
toxcore/mem_test_util.hh
toxcore/network_test_util.cc
toxcore/network_test_util.hh
toxcore/test_util.cc

View File

@ -12,7 +12,7 @@ function(fuzz_test target source_dir)
set(CORPUS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/toktok-fuzzer/corpus/${target}_fuzz_test)
file(GLOB CORPUS "${CORPUS_DIR}/*")
add_executable(${target}_fuzz_test ${source_dir}/${target}_fuzz_test.cc)
target_link_libraries(${target}_fuzz_test PRIVATE toxcore_fuzz fuzz_support ${LIBFUZZER_LINKER_FLAGS})
target_link_libraries(${target}_fuzz_test PRIVATE fuzz_support test_util toxcore_fuzz ${LIBFUZZER_LINKER_FLAGS})
if(CORPUS)
add_test(NAME ${target}_fuzz COMMAND ${CROSSCOMPILING_EMULATOR} ${target}_fuzz_test -max_total_time=10 ${CORPUS})
set_property(TEST ${target}_fuzz PROPERTY ENVIRONMENT "LLVM_PROFILE_FILE=${target}.profraw;srcdir=${CMAKE_CURRENT_SOURCE_DIR}")

View File

@ -1,6 +1,5 @@
load("@rules_cc//cc:defs.bzl", "cc_test")
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
load("//tools:no_undefined.bzl", "cc_library")
exports_files(
srcs = [
@ -12,6 +11,7 @@ exports_files(
cc_library(
name = "test_util",
testonly = True,
srcs = ["test_util.cc"],
hdrs = ["test_util.hh"],
)
@ -52,6 +52,17 @@ cc_library(
],
)
cc_library(
name = "mem_test_util",
testonly = True,
srcs = ["mem_test_util.cc"],
hdrs = ["mem_test_util.hh"],
deps = [
":mem",
":test_util",
],
)
cc_test(
name = "mem_test",
size = "small",
@ -162,6 +173,7 @@ cc_library(
cc_library(
name = "crypto_core_test_util",
testonly = True,
srcs = ["crypto_core_test_util.cc"],
hdrs = ["crypto_core_test_util.hh"],
deps = [
@ -240,6 +252,7 @@ cc_test(
size = "small",
srcs = ["mono_time_test.cc"],
deps = [
":mem_test_util",
":mono_time",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -292,6 +305,7 @@ cc_library(
cc_library(
name = "network_test_util",
testonly = True,
srcs = ["network_test_util.cc"],
hdrs = ["network_test_util.hh"],
deps = [
@ -307,6 +321,7 @@ cc_test(
srcs = ["network_test.cc"],
deps = [
":network",
":network_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
@ -341,6 +356,7 @@ cc_test(
size = "small",
srcs = ["ping_array_test.cc"],
deps = [
":mem_test_util",
":mono_time",
":ping_array",
"@com_google_googletest//:gtest",
@ -399,6 +415,7 @@ cc_library(
cc_library(
name = "DHT_test_util",
testonly = True,
srcs = ["DHT_test_util.cc"],
hdrs = ["DHT_test_util.hh"],
deps = [
@ -418,6 +435,7 @@ cc_test(
":DHT",
":DHT_test_util",
":crypto_core",
":mem_test_util",
":network_test_util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -468,7 +486,7 @@ cc_fuzz_test(
name = "forwarding_fuzz_test",
size = "small",
srcs = ["forwarding_fuzz_test.cc"],
#corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"],
corpus = ["//tools/toktok-fuzzer/corpus:forwarding_fuzz_test"],
deps = [
":forwarding",
"//c-toxcore/testing/fuzzing:fuzz_support",
@ -641,12 +659,26 @@ cc_test(
srcs = ["group_announce_test.cc"],
deps = [
":group_announce",
":mem_test_util",
":mono_time",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
cc_fuzz_test(
name = "group_announce_fuzz_test",
size = "small",
testonly = True,
srcs = ["group_announce_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"],
deps = [
":group_announce",
":mem_test_util",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
)
cc_library(
name = "group_onion_announce",
srcs = ["group_onion_announce.c"],
@ -663,17 +695,6 @@ cc_library(
],
)
cc_fuzz_test(
name = "group_announce_fuzz_test",
size = "small",
srcs = ["group_announce_fuzz_test.cc"],
#corpus = ["//tools/toktok-fuzzer/corpus:group_announce_fuzz_test"],
deps = [
":group_announce",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
)
cc_library(
name = "onion_client",
srcs = ["onion_client.c"],
@ -759,8 +780,10 @@ cc_test(
srcs = ["group_moderation_test.cc"],
deps = [
":crypto_core",
":crypto_core_test_util",
":group_moderation",
":logger",
":mem_test_util",
":util",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@ -770,10 +793,12 @@ cc_test(
cc_fuzz_test(
name = "group_moderation_fuzz_test",
size = "small",
testonly = True,
srcs = ["group_moderation_fuzz_test.cc"],
corpus = ["//tools/toktok-fuzzer/corpus:group_moderation_fuzz_test"],
deps = [
":group_moderation",
":mem_test_util",
"//c-toxcore/testing/fuzzing:fuzz_support",
],
)

View File

@ -11,6 +11,7 @@
#include "DHT_test_util.hh"
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
#include "mem_test_util.hh"
#include "network_test_util.hh"
namespace {
@ -326,8 +327,8 @@ TEST(Request, CreateAndParse)
TEST(AnnounceNodes, SetAndTest)
{
Test_Random rng;
const Network *ns = system_network();
const Memory *mem = system_memory();
Test_Memory mem;
Test_Network ns;
Logger *log = logger_new();
ASSERT_NE(log, nullptr);

View File

@ -6,6 +6,7 @@
#include <vector>
#include "../testing/fuzzing/fuzz_support.h"
#include "mem_test_util.hh"
namespace {
@ -48,7 +49,7 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
void TestDoGca(Fuzz_Data &input)
{
const Memory *mem = system_memory();
Test_Memory mem;
std::unique_ptr<Logger, void (*)(Logger *)> logger(logger_new(), logger_kill);
uint64_t clock = 1;

View File

@ -2,13 +2,14 @@
#include <gtest/gtest.h>
#include "mem_test_util.hh"
#include "mono_time.h"
namespace {
struct Announces : ::testing::Test {
protected:
const Memory *mem_ = system_memory();
Test_Memory mem_;
uint64_t clock_ = 1000;
Mono_Time *mono_time_ = nullptr;
GC_Announces_List *gca_ = nullptr;

View File

@ -1,13 +1,15 @@
#include "group_moderation.h"
#include "../testing/fuzzing/fuzz_support.h"
#include "mem_test_util.hh"
namespace {
void TestModListUnpack(Fuzz_Data &input)
{
CONSUME1_OR_RETURN(const uint16_t, num_mods, input);
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
mod_list_unpack(&mods, input.data(), input.size(), num_mods);
mod_list_cleanup(&mods);
}

View File

@ -7,7 +7,9 @@
#include <vector>
#include "crypto_core.h"
#include "crypto_core_test_util.hh"
#include "logger.h"
#include "mem_test_util.hh"
#include "util.h"
namespace {
@ -18,7 +20,8 @@ using ModerationHash = std::array<uint8_t, MOD_MODERATION_HASH_SIZE>;
TEST(ModList, PackedSizeOfEmptyModListIsZero)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
EXPECT_EQ(mod_list_packed_size(&mods), 0);
uint8_t byte = 1;
@ -28,14 +31,16 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero)
TEST(ModList, UnpackingZeroSizeArrayIsNoop)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
const uint8_t byte = 1;
EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0);
}
TEST(ModList, AddRemoveMultipleMods)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
uint8_t sig_pk1[32] = {1};
uint8_t sig_pk2[32] = {2};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1));
@ -47,7 +52,8 @@ TEST(ModList, AddRemoveMultipleMods)
TEST(ModList, PackingAndUnpackingList)
{
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
@ -55,7 +61,7 @@ TEST(ModList, PackingAndUnpackingList)
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
Moderation mods2{system_memory()};
Moderation mods2{mem};
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size());
EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data()));
}
@ -63,13 +69,14 @@ TEST(ModList, PackingAndUnpackingList)
TEST(ModList, UnpackingTooManyModsFails)
{
using ModListEntry = std::array<uint8_t, MOD_LIST_ENTRY_SIZE>;
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data()));
std::vector<uint8_t> packed(mod_list_packed_size(&mods));
mod_list_pack(&mods, packed.data());
Moderation mods2{system_memory()};
Moderation mods2{mem};
EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1);
EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data()));
}
@ -78,16 +85,17 @@ TEST(ModList, UnpackingFromEmptyBufferFails)
{
std::vector<uint8_t> packed(1);
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
EXPECT_EQ(mod_list_unpack(&mods, packed.data(), 0, 1), -1);
}
TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
{
const Random *rng = system_random();
ASSERT_NE(rng, nullptr);
Test_Memory mem;
Test_Random rng;
Moderation mods{system_memory()};
Moderation mods{mem};
// Fill with random data, check that it's zeroed.
ModerationHash hash;
@ -98,21 +106,24 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer)
TEST(ModList, RemoveIndexFromEmptyModListFails)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
EXPECT_FALSE(mod_list_remove_index(&mods, 0));
EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX));
}
TEST(ModList, RemoveEntryFromEmptyModListFails)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
uint8_t sig_pk[32] = {0};
EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk));
}
TEST(ModList, ModListRemoveIndex)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_remove_index(&mods, 0));
@ -120,20 +131,23 @@ TEST(ModList, ModListRemoveIndex)
TEST(ModList, CleanupOnEmptyModsIsNoop)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
mod_list_cleanup(&mods);
}
TEST(ModList, EmptyModListCannotVerifyAnySigPk)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
uint8_t sig_pk[32] = {1};
EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk));
}
TEST(ModList, ModListAddVerifyRemoveSigPK)
{
Moderation mods{system_memory()};
Test_Memory mem;
Moderation mods{mem};
uint8_t sig_pk[32] = {1};
EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk));
EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk));
@ -143,7 +157,8 @@ TEST(ModList, ModListAddVerifyRemoveSigPK)
TEST(ModList, ModListHashCheck)
{
Moderation mods1{system_memory()};
Test_Memory mem;
Moderation mods1{mem};
uint8_t sig_pk1[32] = {1};
std::array<uint8_t, MOD_MODERATION_HASH_SIZE> hash1;
@ -165,7 +180,8 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails)
TEST(SanctionsList, PackUnpackSanctionsCreds)
{
Moderation mod{system_memory()};
Test_Memory mem;
Moderation mod{mem};
std::array<uint8_t, MOD_SANCTIONS_CREDS_SIZE> packed;
EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE);
EXPECT_EQ(
@ -177,7 +193,8 @@ protected:
ExtPublicKey pk;
ExtSecretKey sk;
Logger *log = logger_new();
Moderation mod{system_memory()};
Test_Memory mem;
Moderation mod{mem};
Mod_Sanction sanctions[2] = {};
const uint8_t sanctioned_pk1[32] = {1};

26
toxcore/mem_test_util.cc Normal file
View File

@ -0,0 +1,26 @@
#include "mem_test_util.hh"
#include <cstdlib>
Memory_Funcs const Memory_Class::vtable = {
Method<mem_malloc_cb, Memory_Class>::invoke<&Memory_Class::malloc>,
Method<mem_calloc_cb, Memory_Class>::invoke<&Memory_Class::calloc>,
Method<mem_realloc_cb, Memory_Class>::invoke<&Memory_Class::realloc>,
Method<mem_free_cb, Memory_Class>::invoke<&Memory_Class::free>,
};
Memory_Class::~Memory_Class() = default;
void *Test_Memory::malloc(void *obj, uint32_t size) { return mem->funcs->malloc(mem->obj, size); }
void *Test_Memory::calloc(void *obj, uint32_t nmemb, uint32_t size)
{
return mem->funcs->calloc(mem->obj, nmemb, size);
}
void *Test_Memory::realloc(void *obj, void *ptr, uint32_t size)
{
return mem->funcs->realloc(mem->obj, ptr, size);
}
void Test_Memory::free(void *obj, void *ptr) { return mem->funcs->free(mem->obj, ptr); }

39
toxcore/mem_test_util.hh Normal file
View File

@ -0,0 +1,39 @@
#ifndef C_TOXCORE_TOXCORE_MEM_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_MEM_TEST_UTIL_H
#include "mem.h"
#include "test_util.hh"
struct Memory_Class {
static Memory_Funcs const vtable;
Memory const self;
operator Memory const *() const { return &self; }
Memory_Class(Memory_Class const &) = default;
Memory_Class()
: self{&vtable, this}
{
}
virtual ~Memory_Class();
virtual mem_malloc_cb malloc = 0;
virtual mem_calloc_cb calloc = 0;
virtual mem_realloc_cb realloc = 0;
virtual mem_free_cb free = 0;
};
/**
* Base test Memory class that just forwards to system_memory. Can be
* subclassed to override individual (or all) functions.
*/
class Test_Memory : public Memory_Class {
const Memory *mem = REQUIRE_NOT_NULL(system_memory());
void *malloc(void *obj, uint32_t size) override;
void *calloc(void *obj, uint32_t nmemb, uint32_t size) override;
void *realloc(void *obj, void *ptr, uint32_t size) override;
void free(void *obj, void *ptr) override;
};
#endif // C_TOXCORE_TOXCORE_MEM_TEST_UTIL_H

View File

@ -5,11 +5,13 @@
#include <chrono>
#include <thread>
#include "mem_test_util.hh"
namespace {
TEST(MonoTime, UnixTimeIncreasesOverTime)
{
const Memory *mem = system_memory();
Test_Memory mem;
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);
@ -28,7 +30,7 @@ TEST(MonoTime, UnixTimeIncreasesOverTime)
TEST(MonoTime, IsTimeout)
{
const Memory *mem = system_memory();
Test_Memory mem;
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);
@ -46,7 +48,7 @@ TEST(MonoTime, IsTimeout)
TEST(MonoTime, IsTimeoutReal)
{
const Memory *mem = system_memory();
Test_Memory mem;
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);
@ -67,7 +69,7 @@ TEST(MonoTime, IsTimeoutReal)
TEST(MonoTime, CustomTime)
{
const Memory *mem = system_memory();
Test_Memory mem;
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);

View File

@ -2,8 +2,17 @@
#include <gtest/gtest.h>
#include "network_test_util.hh"
namespace {
TEST(TestUtil, ProducesNonNullNetwork)
{
Test_Network net;
const Network *ns = net;
EXPECT_NE(ns, nullptr);
}
TEST(IpNtoa, DoesntWriteOutOfBounds)
{
Ip_Ntoa ip_str;

View File

@ -2,6 +2,81 @@
#include <iomanip>
Network_Funcs const Network_Class::vtable = {
Method<net_close_cb, Network_Class>::invoke<&Network_Class::close>,
Method<net_accept_cb, Network_Class>::invoke<&Network_Class::accept>,
Method<net_bind_cb, Network_Class>::invoke<&Network_Class::bind>,
Method<net_listen_cb, Network_Class>::invoke<&Network_Class::listen>,
Method<net_recvbuf_cb, Network_Class>::invoke<&Network_Class::recvbuf>,
Method<net_recv_cb, Network_Class>::invoke<&Network_Class::recv>,
Method<net_recvfrom_cb, Network_Class>::invoke<&Network_Class::recvfrom>,
Method<net_send_cb, Network_Class>::invoke<&Network_Class::send>,
Method<net_sendto_cb, Network_Class>::invoke<&Network_Class::sendto>,
Method<net_socket_cb, Network_Class>::invoke<&Network_Class::socket>,
Method<net_socket_nonblock_cb, Network_Class>::invoke<&Network_Class::socket_nonblock>,
Method<net_getsockopt_cb, Network_Class>::invoke<&Network_Class::getsockopt>,
Method<net_setsockopt_cb, Network_Class>::invoke<&Network_Class::setsockopt>,
Method<net_getaddrinfo_cb, Network_Class>::invoke<&Network_Class::getaddrinfo>,
Method<net_freeaddrinfo_cb, Network_Class>::invoke<&Network_Class::freeaddrinfo>,
};
int Test_Network::close(void *obj, int sock) { return net->funcs->close(net->obj, sock); }
int Test_Network::accept(void *obj, int sock) { return net->funcs->accept(net->obj, sock); }
int Test_Network::bind(void *obj, int sock, const Network_Addr *addr)
{
return net->funcs->bind(net->obj, sock, addr);
}
int Test_Network::listen(void *obj, int sock, int backlog)
{
return net->funcs->listen(net->obj, sock, backlog);
}
int Test_Network::recvbuf(void *obj, int sock) { return net->funcs->recvbuf(net->obj, sock); }
int Test_Network::recv(void *obj, int sock, uint8_t *buf, size_t len)
{
return net->funcs->recv(net->obj, sock, buf, len);
}
int Test_Network::recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr)
{
return net->funcs->recvfrom(net->obj, sock, buf, len, addr);
}
int Test_Network::send(void *obj, int sock, const uint8_t *buf, size_t len)
{
return net->funcs->send(net->obj, sock, buf, len);
}
int Test_Network::sendto(
void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr)
{
return net->funcs->sendto(net->obj, sock, buf, len, addr);
}
int Test_Network::socket(void *obj, int domain, int type, int proto)
{
return net->funcs->socket(net->obj, domain, type, proto);
}
int Test_Network::socket_nonblock(void *obj, int sock, bool nonblock)
{
return net->funcs->socket_nonblock(net->obj, sock, nonblock);
}
int Test_Network::getsockopt(
void *obj, int sock, int level, int optname, void *optval, size_t *optlen)
{
return net->funcs->getsockopt(net->obj, sock, level, optname, optval, optlen);
}
int Test_Network::setsockopt(
void *obj, int sock, int level, int optname, const void *optval, size_t optlen)
{
return net->funcs->setsockopt(net->obj, sock, level, optname, optval, optlen);
}
int Test_Network::getaddrinfo(void *obj, int family, Network_Addr **addrs)
{
return net->funcs->getaddrinfo(net->obj, family, addrs);
}
int Test_Network::freeaddrinfo(void *obj, Network_Addr *addrs)
{
return net->funcs->freeaddrinfo(net->obj, addrs);
}
Network_Class::~Network_Class() = default;
IP_Port increasing_ip_port::operator()()
{
IP_Port ip_port;

View File

@ -7,6 +7,60 @@
#include "network.h"
#include "test_util.hh"
struct Network_Class {
static Network_Funcs const vtable;
Network const self;
operator Network const *() const { return &self; }
Network_Class(Network_Class const &) = default;
Network_Class()
: self{&vtable, this}
{
}
virtual ~Network_Class();
virtual net_close_cb close = 0;
virtual net_accept_cb accept = 0;
virtual net_bind_cb bind = 0;
virtual net_listen_cb listen = 0;
virtual net_recvbuf_cb recvbuf = 0;
virtual net_recv_cb recv = 0;
virtual net_recvfrom_cb recvfrom = 0;
virtual net_send_cb send = 0;
virtual net_sendto_cb sendto = 0;
virtual net_socket_cb socket = 0;
virtual net_socket_nonblock_cb socket_nonblock = 0;
virtual net_getsockopt_cb getsockopt = 0;
virtual net_setsockopt_cb setsockopt = 0;
virtual net_getaddrinfo_cb getaddrinfo = 0;
virtual net_freeaddrinfo_cb freeaddrinfo = 0;
};
/**
* Base test Network class that just forwards to system_network. Can be
* subclassed to override individual (or all) functions.
*/
class Test_Network : public Network_Class {
const Network *net = REQUIRE_NOT_NULL(system_network());
int close(void *obj, int sock) override;
int accept(void *obj, int sock) override;
int bind(void *obj, int sock, const Network_Addr *addr) override;
int listen(void *obj, int sock, int backlog) override;
int recvbuf(void *obj, int sock) override;
int recv(void *obj, int sock, uint8_t *buf, size_t len) override;
int recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) override;
int send(void *obj, int sock, const uint8_t *buf, size_t len) override;
int sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) override;
int socket(void *obj, int domain, int type, int proto) override;
int socket_nonblock(void *obj, int sock, bool nonblock) override;
int getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen) override;
int setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen) override;
int getaddrinfo(void *obj, int family, Network_Addr **addrs) override;
int freeaddrinfo(void *obj, Network_Addr *addrs) override;
};
template <>
struct Deleter<Networking_Core> : Function_Deleter<Networking_Core, kill_networking> { };

View File

@ -4,6 +4,7 @@
#include <memory>
#include "mem_test_util.hh"
#include "mono_time.h"
namespace {
@ -15,7 +16,7 @@ struct Ping_Array_Deleter {
using Ping_Array_Ptr = std::unique_ptr<Ping_Array, Ping_Array_Deleter>;
struct Mono_Time_Deleter {
Mono_Time_Deleter(const Memory *mem)
Mono_Time_Deleter(const Test_Memory &mem)
: mem_(mem)
{
}
@ -29,21 +30,21 @@ using Mono_Time_Ptr = std::unique_ptr<Mono_Time, Mono_Time_Deleter>;
TEST(PingArray, MinimumTimeoutIsOne)
{
const Memory *mem = system_memory();
Test_Memory mem;
EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
}
TEST(PingArray, MinimumArraySizeIsOne)
{
const Memory *mem = system_memory();
Test_Memory mem;
EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr);
EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr);
}
TEST(PingArray, ArraySizeMustBePowerOfTwo)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr arr;
arr.reset(ping_array_new(mem, 2, 1));
@ -59,7 +60,7 @@ TEST(PingArray, ArraySizeMustBePowerOfTwo)
TEST(PingArray, StoredDataCanBeRetrieved)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
@ -78,7 +79,7 @@ TEST(PingArray, StoredDataCanBeRetrieved)
TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
@ -101,7 +102,7 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect)
TEST(PingArray, ZeroLengthDataCanBeAdded)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
@ -118,7 +119,7 @@ TEST(PingArray, ZeroLengthDataCanBeAdded)
TEST(PingArray, PingId0IsInvalid)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
@ -131,7 +132,7 @@ TEST(PingArray, PingId0IsInvalid)
// Protection against replay attacks.
TEST(PingArray, DataCanOnlyBeRetrievedOnce)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);
@ -149,7 +150,7 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce)
TEST(PingArray, PingIdMustMatchOnCheck)
{
const Memory *mem = system_memory();
Test_Memory mem;
Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1));
Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem);

View File

@ -3,6 +3,8 @@
#include <algorithm>
#include <array>
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <type_traits>
#include <vector>
@ -66,4 +68,16 @@ Container sorted(Container arr, Less less)
return arr;
}
template <typename T>
T *require_not_null(const char *file, int line, T *ptr)
{
if (ptr == nullptr) {
std::fprintf(stderr, "unexpected null pointer at %s:%d\n", file, line);
std::exit(7);
}
return ptr;
}
#define REQUIRE_NOT_NULL(ptr) require_not_null(__FILE__, __LINE__, ptr)
#endif // C_TOXCORE_TOXCORE_TEST_UTIL_H