mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
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:
parent
4cea4f9ca4
commit
bcb6592af5
|
@ -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
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
26
toxcore/mem_test_util.cc
Normal 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
39
toxcore/mem_test_util.hh
Normal 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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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> { };
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user