mirror of
https://github.com/transmission/transmission
synced 2025-03-03 10:15:45 +00:00
refactor: remove libtransmission::Buffer (#5676)
* refactor: use StackBuffer in announcer-udp * chore: update buffer tests * refactor: remove unused libtransmission::Buffer superseded by libtransmission::StackBuffer
This commit is contained in:
parent
635268854b
commit
9afced725a
4 changed files with 32 additions and 144 deletions
|
@ -50,7 +50,7 @@ using tau_connection_t = uint64_t;
|
|||
using tau_transaction_t = uint32_t;
|
||||
|
||||
using InBuf = libtransmission::BufferReader<std::byte>;
|
||||
using PayloadBuffer = libtransmission::Buffer;
|
||||
using PayloadBuffer = libtransmission::StackBuffer<4096, std::byte>;
|
||||
|
||||
constexpr auto TauConnectionTtlSecs = time_t{ 45 };
|
||||
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
|
||||
#include <small/vector.hpp>
|
||||
|
||||
#include <event2/buffer.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "net.h" // tr_socket_t
|
||||
#include "tr-assert.h"
|
||||
#include "utils-ev.h"
|
||||
#include "utils.h" // for tr_htonll(), tr_ntohll()
|
||||
|
||||
namespace libtransmission
|
||||
|
@ -285,61 +281,4 @@ private:
|
|||
size_t end_pos_ = {};
|
||||
};
|
||||
|
||||
class Buffer final
|
||||
: public BufferReader<std::byte>
|
||||
, public BufferWriter<std::byte>
|
||||
{
|
||||
public:
|
||||
using value_type = std::byte;
|
||||
|
||||
Buffer() = default;
|
||||
Buffer(Buffer&&) = default;
|
||||
Buffer(Buffer const&) = delete;
|
||||
Buffer& operator=(Buffer&&) = default;
|
||||
Buffer& operator=(Buffer const&) = delete;
|
||||
|
||||
template<typename T>
|
||||
explicit Buffer(T const& data)
|
||||
{
|
||||
add(data);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t size() const noexcept override
|
||||
{
|
||||
return evbuffer_get_length(buf_.get());
|
||||
}
|
||||
|
||||
[[nodiscard]] value_type const* data() const override
|
||||
{
|
||||
return reinterpret_cast<value_type const*>(evbuffer_pullup(buf_.get(), -1));
|
||||
}
|
||||
|
||||
void drain(size_t n_bytes) override
|
||||
{
|
||||
evbuffer_drain(buf_.get(), n_bytes);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<value_type*, size_t> reserve_space(size_t n_bytes) override
|
||||
{
|
||||
auto iov = evbuffer_iovec{};
|
||||
evbuffer_reserve_space(buf_.get(), n_bytes, &iov, 1);
|
||||
TR_ASSERT(iov.iov_len >= n_bytes);
|
||||
reserved_space_ = iov;
|
||||
return { static_cast<value_type*>(iov.iov_base), static_cast<size_t>(iov.iov_len) };
|
||||
}
|
||||
|
||||
void commit_space(size_t n_bytes) override
|
||||
{
|
||||
TR_ASSERT(reserved_space_);
|
||||
TR_ASSERT(reserved_space_->iov_len >= n_bytes);
|
||||
reserved_space_->iov_len = n_bytes;
|
||||
evbuffer_commit_space(buf_.get(), &*reserved_space_, 1);
|
||||
reserved_space_.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
evhelpers::evbuffer_unique_ptr buf_{ evbuffer_new() };
|
||||
std::optional<evbuffer_iovec> reserved_space_;
|
||||
};
|
||||
|
||||
} // namespace libtransmission
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
using namespace std::literals;
|
||||
|
||||
using MessageBuffer = libtransmission::StackBuffer<4096, std::byte>;
|
||||
|
||||
class AnnouncerUdpTest : public ::testing::Test
|
||||
{
|
||||
private:
|
||||
|
@ -111,8 +113,9 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] static uint32_t parseConnectionRequest(libtransmission::Buffer& buf)
|
||||
[[nodiscard]] static uint32_t parseConnectionRequest(std::vector<char> data)
|
||||
{
|
||||
auto buf = MessageBuffer(data);
|
||||
EXPECT_EQ(ProtocolId, buf.to_uint64());
|
||||
EXPECT_EQ(ConnectAction, buf.to_uint32());
|
||||
return buf.to_uint32();
|
||||
|
@ -147,8 +150,9 @@ protected:
|
|||
return std::make_pair(buildScrapeRequestFromResponse(response), response);
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto parseScrapeRequest(libtransmission::Buffer& buf, uint64_t expected_connection_id)
|
||||
[[nodiscard]] static auto parseScrapeRequest(std::vector<char> data, uint64_t expected_connection_id)
|
||||
{
|
||||
auto buf = MessageBuffer(data);
|
||||
EXPECT_EQ(expected_connection_id, buf.to_uint64());
|
||||
EXPECT_EQ(ScrapeAction, buf.to_uint32());
|
||||
auto const transaction_id = buf.to_uint32();
|
||||
|
@ -165,14 +169,14 @@ protected:
|
|||
[[nodiscard]] static auto waitForAnnouncerToSendMessage(MockMediator& mediator)
|
||||
{
|
||||
libtransmission::test::waitFor(mediator.eventBase(), [&mediator]() { return !std::empty(mediator.sent_); });
|
||||
auto buf = libtransmission::Buffer(mediator.sent_.back().buf_);
|
||||
auto buf = std::move(mediator.sent_.back().buf_);
|
||||
mediator.sent_.pop_back();
|
||||
return buf;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool sendError(tr_announcer_udp& announcer, uint32_t transaction_id, std::string_view errmsg)
|
||||
{
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(ErrorAction);
|
||||
buf.add_uint32(transaction_id);
|
||||
buf.add(errmsg);
|
||||
|
@ -187,7 +191,7 @@ protected:
|
|||
[[nodiscard]] static auto sendConnectionResponse(tr_announcer_udp& announcer, uint32_t transaction_id)
|
||||
{
|
||||
auto const connection_id = tr_rand_obj<uint64_t>();
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(ConnectAction);
|
||||
buf.add_uint32(transaction_id);
|
||||
buf.add_uint64(connection_id);
|
||||
|
@ -250,8 +254,9 @@ protected:
|
|||
EXPECT_EQ(actual.external_ip, expected.external_ip);
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto parseAnnounceRequest(libtransmission::Buffer& buf, uint64_t connection_id)
|
||||
[[nodiscard]] static auto parseAnnounceRequest(std::vector<char> data, uint64_t connection_id)
|
||||
{
|
||||
auto buf = MessageBuffer{ data };
|
||||
auto req = UdpAnnounceReq{};
|
||||
req.connection_id = buf.to_uint64();
|
||||
req.action = buf.to_uint32();
|
||||
|
@ -313,20 +318,18 @@ TEST_F(AnnouncerUdpTest, canScrape)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto connect_transaction_id = parseConnectionRequest(sent);
|
||||
auto connect_transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
|
||||
// Have the tracker respond to the request
|
||||
auto const connection_id = sendConnectionResponse(*announcer, connect_transaction_id);
|
||||
|
||||
// The announcer should have sent a UDP scrape request.
|
||||
// Inspect that request for validity.
|
||||
sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto [scrape_transaction_id, info_hashes] = parseScrapeRequest(sent, connection_id);
|
||||
auto [scrape_transaction_id, info_hashes] = parseScrapeRequest(waitForAnnouncerToSendMessage(mediator), connection_id);
|
||||
expectEqual(request, info_hashes);
|
||||
|
||||
// Have the tracker respond to the request
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(ScrapeAction);
|
||||
buf.add_uint32(scrape_transaction_id);
|
||||
buf.add_uint32(expected_response.rows[0].seeders);
|
||||
|
@ -350,8 +353,7 @@ TEST_F(AnnouncerUdpTest, canScrape)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
sent = waitForAnnouncerToSendMessage(mediator);
|
||||
std::tie(scrape_transaction_id, info_hashes) = parseScrapeRequest(sent, connection_id);
|
||||
std::tie(scrape_transaction_id, info_hashes) = parseScrapeRequest(waitForAnnouncerToSendMessage(mediator), connection_id);
|
||||
expectEqual(request, info_hashes);
|
||||
}
|
||||
|
||||
|
@ -368,8 +370,7 @@ TEST_F(AnnouncerUdpTest, canDestructCleanlyEvenWhenBusy)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto const connect_transaction_id = parseConnectionRequest(sent);
|
||||
auto const connect_transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
EXPECT_NE(0U, connect_transaction_id);
|
||||
|
||||
// now just end the test before responding to the request.
|
||||
|
@ -396,18 +397,16 @@ TEST_F(AnnouncerUdpTest, canMultiScrape)
|
|||
announcer->scrape(request, [&response](tr_scrape_response const& resp) { response = resp; });
|
||||
|
||||
// Announcer will request a connection. Verify and grant the request
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto connect_transaction_id = parseConnectionRequest(sent);
|
||||
auto connect_transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
auto const connection_id = sendConnectionResponse(*announcer, connect_transaction_id);
|
||||
|
||||
// The announcer should have sent a UDP scrape request.
|
||||
// Inspect that request for validity.
|
||||
sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto [scrape_transaction_id, info_hashes] = parseScrapeRequest(sent, connection_id);
|
||||
auto [scrape_transaction_id, info_hashes] = parseScrapeRequest(waitForAnnouncerToSendMessage(mediator), connection_id);
|
||||
expectEqual(request, info_hashes);
|
||||
|
||||
// Have the tracker respond to the request
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(ScrapeAction);
|
||||
buf.add_uint32(scrape_transaction_id);
|
||||
for (int i = 0; i < expected_response.row_count; ++i)
|
||||
|
@ -457,16 +456,16 @@ TEST_F(AnnouncerUdpTest, canHandleScrapeError)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto connect_transaction_id = parseConnectionRequest(sent);
|
||||
auto connect_transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
|
||||
// Have the tracker respond to the request
|
||||
auto const connection_id = sendConnectionResponse(*announcer, connect_transaction_id);
|
||||
|
||||
// The announcer should have sent a UDP scrape request.
|
||||
// Inspect that request for validity.
|
||||
sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto const [scrape_transaction_id, info_hashes] = parseScrapeRequest(sent, connection_id);
|
||||
auto const [scrape_transaction_id, info_hashes] = parseScrapeRequest(
|
||||
waitForAnnouncerToSendMessage(mediator),
|
||||
connection_id);
|
||||
|
||||
// Have the tracker respond to the request with an "unable to scrape" error
|
||||
EXPECT_TRUE(sendError(*announcer, scrape_transaction_id, expected_response.errmsg));
|
||||
|
@ -506,8 +505,7 @@ TEST_F(AnnouncerUdpTest, canHandleConnectError)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto transaction_id = parseConnectionRequest(sent);
|
||||
auto transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
|
||||
// Have the tracker respond to the request with an "unable to connect" error
|
||||
EXPECT_TRUE(sendError(*announcer, transaction_id, expected_response.errmsg));
|
||||
|
@ -537,11 +535,10 @@ TEST_F(AnnouncerUdpTest, handleMessageReturnsFalseOnInvalidMessage)
|
|||
|
||||
// The announcer should have sent a UDP connection request.
|
||||
// Inspect that request for validity.
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto transaction_id = parseConnectionRequest(sent);
|
||||
auto transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
|
||||
// send a connection response but with an *invalid* transaction id
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(ConnectAction);
|
||||
buf.add_uint32(transaction_id + 1);
|
||||
buf.add_uint64(tr_rand_obj<uint64_t>());
|
||||
|
@ -551,7 +548,7 @@ TEST_F(AnnouncerUdpTest, handleMessageReturnsFalseOnInvalidMessage)
|
|||
EXPECT_FALSE(announcer->handle_message(std::data(arr), response_size));
|
||||
|
||||
// send a connection response but with an *invalid* action
|
||||
buf = {};
|
||||
buf.clear();
|
||||
buf.add_uint32(ScrapeAction);
|
||||
buf.add_uint32(transaction_id);
|
||||
buf.add_uint64(tr_rand_obj<uint64_t>());
|
||||
|
@ -617,18 +614,16 @@ TEST_F(AnnouncerUdpTest, canAnnounce)
|
|||
announcer->announce(request, [&response](tr_announce_response const& resp) { response = resp; });
|
||||
|
||||
// Announcer will request a connection. Verify and grant the request
|
||||
auto sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto connect_transaction_id = parseConnectionRequest(sent);
|
||||
auto connect_transaction_id = parseConnectionRequest(waitForAnnouncerToSendMessage(mediator));
|
||||
auto const connection_id = sendConnectionResponse(*announcer, connect_transaction_id);
|
||||
|
||||
// The announcer should have sent a UDP announce request.
|
||||
// Inspect that request for validity.
|
||||
sent = waitForAnnouncerToSendMessage(mediator);
|
||||
auto udp_ann_req = parseAnnounceRequest(sent, connection_id);
|
||||
auto udp_ann_req = parseAnnounceRequest(waitForAnnouncerToSendMessage(mediator), connection_id);
|
||||
expectEqual(request, udp_ann_req);
|
||||
|
||||
// Have the tracker respond to the request
|
||||
auto buf = libtransmission::Buffer{};
|
||||
auto buf = MessageBuffer{};
|
||||
buf.add_uint32(AnnounceAction);
|
||||
buf.add_uint32(udp_ann_req.transaction_id);
|
||||
buf.add_uint32(expected_response.interval);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
using BufferTest = ::testing::Test;
|
||||
using namespace std::literals;
|
||||
using Buffer = libtransmission::Buffer;
|
||||
using Buffer = libtransmission::StackBuffer<1024, std::byte>;
|
||||
|
||||
TEST_F(BufferTest, startsWithInSingleSegment)
|
||||
{
|
||||
|
@ -62,52 +62,6 @@ TEST_F(BufferTest, startsWithInMultiSegment)
|
|||
EXPECT_TRUE(buf->starts_with("Hello, World!"sv));
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, Move)
|
||||
{
|
||||
auto constexpr TwoChars = "12"sv;
|
||||
auto constexpr SixChars = "123456"sv;
|
||||
auto constexpr TenChars = "1234567890"sv;
|
||||
|
||||
auto a = Buffer{ TwoChars };
|
||||
auto b = Buffer{ SixChars };
|
||||
auto c = Buffer{ TenChars };
|
||||
|
||||
auto lens = std::array<size_t, 3>{ std::size(TwoChars), std::size(SixChars), std::size(TenChars) };
|
||||
|
||||
EXPECT_EQ(lens[0], std::size(a));
|
||||
EXPECT_EQ(lens[1], std::size(b));
|
||||
EXPECT_EQ(lens[2], std::size(c));
|
||||
|
||||
std::swap(a, b);
|
||||
EXPECT_EQ(lens[0], std::size(b));
|
||||
EXPECT_EQ(lens[1], std::size(a));
|
||||
EXPECT_EQ(lens[2], std::size(c));
|
||||
|
||||
std::swap(a, c);
|
||||
EXPECT_EQ(lens[0], std::size(b));
|
||||
EXPECT_EQ(lens[1], std::size(c));
|
||||
EXPECT_EQ(lens[2], std::size(a));
|
||||
|
||||
std::swap(b, c);
|
||||
EXPECT_EQ(lens[0], std::size(c));
|
||||
EXPECT_EQ(lens[1], std::size(b));
|
||||
EXPECT_EQ(lens[2], std::size(a));
|
||||
|
||||
a.add(std::data(TwoChars), std::size(TwoChars));
|
||||
|
||||
{
|
||||
auto constexpr OneChar = "1"sv;
|
||||
auto d = Buffer{ OneChar };
|
||||
|
||||
std::swap(a, d);
|
||||
EXPECT_EQ(1U, std::size(a));
|
||||
}
|
||||
|
||||
EXPECT_EQ(1U, std::size(a));
|
||||
a.add(std::data(TwoChars), std::size(TwoChars));
|
||||
EXPECT_EQ(3U, std::size(a));
|
||||
}
|
||||
|
||||
TEST_F(BufferTest, Numbers)
|
||||
{
|
||||
for (auto i = 0; i < 100; ++i)
|
||||
|
|
Loading…
Reference in a new issue