mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-06 02:02:30 +00:00
193 lines
7.2 KiB
C++
193 lines
7.2 KiB
C++
#include "config.h"
|
|
|
|
#include "test/helpers/mock_function.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
|
|
#include "torrent/event.h"
|
|
#include "torrent/net/socket_address.h"
|
|
#include "torrent/net/fd.h"
|
|
#include "torrent/utils/log.h"
|
|
#include "torrent/utils/random.h"
|
|
|
|
#define MOCK_CLEANUP_MAP(MOCK_FUNC) \
|
|
CPPUNIT_ASSERT_MESSAGE("expected mock function calls not completed for '" #MOCK_FUNC "'", mock_cleanup_map(&MOCK_FUNC) || ignore_assert);
|
|
#define MOCK_LOG(log_fmt, ...) \
|
|
lt_log_print(torrent::LOG_MOCK_CALLS, "%s: " log_fmt, __func__, __VA_ARGS__);
|
|
|
|
namespace {
|
|
void
|
|
mock_clear(bool ignore_assert) {
|
|
MOCK_CLEANUP_MAP(torrent::fd__accept);
|
|
MOCK_CLEANUP_MAP(torrent::fd__bind);
|
|
MOCK_CLEANUP_MAP(torrent::fd__close);
|
|
MOCK_CLEANUP_MAP(torrent::fd__connect);
|
|
MOCK_CLEANUP_MAP(torrent::fd__fcntl_int);
|
|
MOCK_CLEANUP_MAP(torrent::fd__listen);
|
|
MOCK_CLEANUP_MAP(torrent::fd__setsockopt_int);
|
|
MOCK_CLEANUP_MAP(torrent::fd__socket);
|
|
|
|
MOCK_CLEANUP_MAP(torrent::random_uniform_uint16);
|
|
MOCK_CLEANUP_MAP(torrent::random_uniform_uint32);
|
|
|
|
mock_compare_map<torrent::Event>::values.clear();
|
|
}
|
|
} // namespace
|
|
|
|
void
|
|
mock_init() {
|
|
log_add_group_output(torrent::LOG_MOCK_CALLS, "test_output");
|
|
mock_clear(true);
|
|
}
|
|
|
|
void
|
|
mock_cleanup() {
|
|
mock_clear(false);
|
|
}
|
|
|
|
void
|
|
mock_redirect_defaults([[maybe_unused]] mock_redirect_flags flags) {
|
|
mock_redirect(torrent::fd__bind, std::function<int(int socket, const sockaddr *address, socklen_t address_len)>([](int socket, const sockaddr *address, socklen_t address_len) {
|
|
return ::bind(socket, address, address_len);
|
|
}));
|
|
|
|
mock_redirect(torrent::fd__close, std::function<int(int fildes)>([](int fildes) { return ::close(fildes); }));
|
|
mock_redirect(torrent::fd__fcntl_int, std::function<int(int fildes, int cmd, int arg)>([](int fildes, int cmd, int arg) { return ::fcntl(fildes, cmd, arg); }));
|
|
mock_redirect(torrent::fd__setsockopt_int, std::function<int(int socket, int level, int option_name, int option_value)>([](int socket, int level, int option_name, int option_value) { return ::setsockopt(socket, level, option_name, &option_value, sizeof(int)); }));
|
|
mock_redirect(torrent::fd__socket, std::function<int(int domain, int type, int protocol)>([](int domain, int type, int protocol) { return ::socket(domain, type, protocol); }));
|
|
}
|
|
|
|
namespace torrent {
|
|
|
|
//
|
|
// Mock functions for 'torrent/net/fd.h':
|
|
//
|
|
|
|
int fd__accept(int socket, sockaddr *address, socklen_t *address_len) {
|
|
MOCK_LOG("entry socket:%i address:%s address_len:%u",
|
|
socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
|
|
auto ret = mock_call<int>(__func__, &torrent::fd__accept, socket, address, address_len);
|
|
MOCK_LOG("exit socket:%i address:%s address_len:%u",
|
|
socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
|
|
return ret;
|
|
}
|
|
|
|
int fd__bind(int socket, const sockaddr *address, socklen_t address_len) {
|
|
MOCK_LOG("socket:%i address:%s address_len:%u",
|
|
socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
|
|
return mock_call<int>(__func__, &torrent::fd__bind, socket, address, address_len);
|
|
}
|
|
|
|
int fd__close(int fildes) {
|
|
MOCK_LOG("filedes:%i", fildes);
|
|
return mock_call<int>(__func__, &torrent::fd__close, fildes);
|
|
}
|
|
|
|
int fd__connect(int socket, const sockaddr *address, socklen_t address_len) {
|
|
MOCK_LOG("socket:%i address:%s address_len:%u",
|
|
socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
|
|
return mock_call<int>(__func__, &torrent::fd__connect, socket, address, address_len);
|
|
}
|
|
|
|
int fd__fcntl_int(int fildes, int cmd, int arg) {
|
|
MOCK_LOG("filedes:%i cmd:%i arg:%i", fildes, cmd, arg);
|
|
return mock_call<int>(__func__, &torrent::fd__fcntl_int, fildes, cmd, arg);
|
|
}
|
|
|
|
int fd__listen(int socket, int backlog) {
|
|
MOCK_LOG("socket:%i backlog:%i", socket, backlog);
|
|
return mock_call<int>(__func__, &torrent::fd__listen, socket, backlog);
|
|
}
|
|
|
|
int fd__setsockopt_int(int socket, int level, int option_name, int option_value) {
|
|
MOCK_LOG("socket:%i level:%i option_name:%i option_value:%i",
|
|
socket, level, option_name, option_value);
|
|
return mock_call<int>(__func__, &torrent::fd__setsockopt_int, socket, level, option_name, option_value);
|
|
}
|
|
|
|
int fd__socket(int domain, int type, int protocol) {
|
|
MOCK_LOG("domain:%i type:%i protocol:%i", domain, type, protocol);
|
|
return mock_call<int>(__func__, &torrent::fd__socket, domain, type, protocol);
|
|
}
|
|
|
|
//
|
|
// Mock functions for 'torrent/common.h':
|
|
//
|
|
|
|
namespace this_thread {
|
|
|
|
void event_open(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_open, event);
|
|
}
|
|
|
|
void event_open_and_count(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_open_and_count, event);
|
|
}
|
|
|
|
void event_close_and_count(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_close_and_count, event);
|
|
}
|
|
|
|
void event_closed_and_count(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_closed_and_count, event);
|
|
}
|
|
|
|
void event_insert_read(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_insert_read, event);
|
|
}
|
|
|
|
void event_insert_write(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_insert_write, event);
|
|
}
|
|
|
|
void event_insert_error(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_insert_error, event);
|
|
}
|
|
|
|
void event_remove_read(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_remove_read, event);
|
|
}
|
|
|
|
void event_remove_write(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_remove_write, event);
|
|
}
|
|
|
|
void event_remove_error(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_remove_error, event);
|
|
}
|
|
|
|
void event_remove_and_close(Event* event) {
|
|
MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
|
|
return mock_call<void>(__func__, &torrent::this_thread::event_remove_and_close, event);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Mock functions for 'torrent/utils/random.h':
|
|
//
|
|
|
|
uint16_t random_uniform_uint16(uint16_t min, uint16_t max) {
|
|
MOCK_LOG("min:%" PRIu16 " max:%" PRIu16, min, max);
|
|
return mock_call<uint16_t>(__func__, &torrent::random_uniform_uint16, min, max);
|
|
}
|
|
|
|
uint32_t random_uniform_uint32(uint32_t min, uint32_t max) {
|
|
MOCK_LOG("min:%" PRIu32 " max:%" PRIu32, min, max);
|
|
return mock_call<uint32_t>(__func__, &torrent::random_uniform_uint32, min, max);
|
|
}
|
|
|
|
}
|