mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
This was only used in the `CNetFileTransferer`. Only one function is called. That can also be a `std::function`.
141 lines
4 KiB
C++
141 lines
4 KiB
C++
/* Copyright (C) 2026 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "lib/self_test.h"
|
|
|
|
#include "network/NetFileTransfer.h"
|
|
#include "network/NetMessage.h"
|
|
#include "network/NetSession.h"
|
|
|
|
#include <cstddef>
|
|
#include <functional>
|
|
#include <initializer_list>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
constexpr const char* MESSAGECONTENT{"Some example message content"};
|
|
|
|
class MessageQueues
|
|
{
|
|
public:
|
|
bool SendMessage(const CNetMessage* message)
|
|
{
|
|
switch (message->GetType())
|
|
{
|
|
case NMT_FILE_TRANSFER_REQUEST:
|
|
requests.push_back(*static_cast<const CFileTransferRequestMessage*>(message));
|
|
break;
|
|
case NMT_FILE_TRANSFER_RESPONSE:
|
|
responses.push_back(*static_cast<const CFileTransferResponseMessage*>(message));
|
|
break;
|
|
case NMT_FILE_TRANSFER_DATA:
|
|
data.push_back(*static_cast<const CFileTransferDataMessage*>(message));
|
|
break;
|
|
case NMT_FILE_TRANSFER_ACK:
|
|
acknowledgements.push_back(*static_cast<const CFileTransferAckMessage*>(message));
|
|
break;
|
|
default:
|
|
TS_FAIL("Unhandeled message type");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
std::vector<CFileTransferRequestMessage> requests;
|
|
std::vector<CFileTransferResponseMessage> responses;
|
|
std::vector<CFileTransferDataMessage> data;
|
|
std::vector<CFileTransferAckMessage> acknowledgements;
|
|
};
|
|
|
|
void CheckSizes(MessageQueues& queues, size_t requestSize, size_t responseSize, size_t dataSize,
|
|
size_t acknowledgementSize)
|
|
{
|
|
TS_ASSERT_EQUALS(queues.requests.size(), requestSize);
|
|
TS_ASSERT_EQUALS(queues.responses.size(), responseSize);
|
|
TS_ASSERT_EQUALS(queues.data.size(), dataSize);
|
|
TS_ASSERT_EQUALS(queues.acknowledgements.size(), acknowledgementSize);
|
|
}
|
|
|
|
struct Participant
|
|
{
|
|
MessageQueues queues;
|
|
CNetFileTransferer transferer{queues};
|
|
};
|
|
}
|
|
|
|
class TestFileTransfer : public CxxTest::TestSuite
|
|
{
|
|
public:
|
|
void test_transfer()
|
|
{
|
|
// The client requests some data from the server.
|
|
|
|
Participant server;
|
|
Participant client;
|
|
|
|
bool complete{false};
|
|
|
|
client.transferer.StartTask(CNetFileTransferer::RequestType::LOADGAME,
|
|
[&complete](std::string buffer)
|
|
{
|
|
// This callback is executed exactly once.
|
|
const bool previousComplete{std::exchange(complete, true)};
|
|
TS_ASSERT(!previousComplete);
|
|
TS_ASSERT_STR_EQUALS(buffer, MESSAGECONTENT);
|
|
});
|
|
CheckSizes(client.queues, 1, 0, 0, 0);
|
|
|
|
server.transferer.StartResponse(client.queues.requests.at(0).m_RequestID, MESSAGECONTENT);
|
|
CheckSizes(server.queues, 0, 1, 0, 0);
|
|
|
|
client.transferer.HandleMessageReceive(server.queues.responses.at(0));
|
|
CheckSizes(client.queues, 1, 0, 0, 0);
|
|
|
|
server.transferer.Poll();
|
|
CheckSizes(server.queues, 0, 1, 1, 0);
|
|
|
|
server.transferer.Poll();
|
|
// If `MESSAGECONTENT` would be longer another message would be sent.
|
|
CheckSizes(server.queues, 0, 1, 1, 0);
|
|
|
|
TS_ASSERT(!complete);
|
|
|
|
client.transferer.HandleMessageReceive(server.queues.data.at(0));
|
|
CheckSizes(client.queues, 1, 0, 0, 1);
|
|
|
|
TS_ASSERT(complete);
|
|
|
|
server.transferer.HandleMessageReceive(client.queues.acknowledgements.at(0));
|
|
CheckSizes(server.queues, 0, 1, 1, 0);
|
|
}
|
|
|
|
void test_RequestType()
|
|
{
|
|
for (const auto& requestType : {CNetFileTransferer::RequestType::LOADGAME,
|
|
CNetFileTransferer::RequestType::REJOIN})
|
|
{
|
|
Participant client;
|
|
|
|
client.transferer.StartTask(requestType, [](auto&&){});
|
|
TS_ASSERT_EQUALS(static_cast<CNetFileTransferer::RequestType>(
|
|
client.queues.requests.at(0).m_RequestType), requestType);
|
|
}
|
|
}
|
|
};
|