Skip to content

Commit

Permalink
refactor: duplicate code in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Laateef committed Feb 11, 2024
1 parent 45e2ec0 commit 2ee5f3d
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 129 deletions.
43 changes: 12 additions & 31 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,27 @@
#include "doctest.h"

#include "version.h"

#include "time.h"

#include "date.h"

#include "datetime.h"

#include "ntp/timestamp.h"

#include "ntp/coder.h"

#include "ntp/packet.h"

#include "ntp/tracer.h"

#include "ntp/server.h"

#include "ntp/query_single.h"

#include "ntp/query_series.h"

#include "ntp/query.h"
#include "ntp/client.h"

// Help doctest with printing custom data types
namespace std {
template <class R, class P>
ostream& operator<<(ostream& os, const std::chrono::duration<R, P>& d)
{
return os << std::chrono::steady_clock::duration(d).count();
}
template <class C>
ostream& operator<<(ostream& os, const std::chrono::time_point<C>& tp)
{
return os << tp.time_since_epoch();
}
ostream& operator<<(ostream& os, const Timestamp& timestamp)
{
return os << timestamp.value();
}
template <class T, size_t S>
ostream& operator<<(ostream& os, const std::array<T, S>& data)
{
os << "0x" << setfill('0');
for (const auto b : data) {
os << setw(2) << hex << static_cast<int>(b);
}
return os;
}
ostream& operator<<(ostream& os, const Packet& packet)
{
return os << packet.data();
}
} // namespace std
#include "ntp/client.h"
20 changes: 6 additions & 14 deletions test/ntp/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,18 @@
* LICENSE.txt file in the root directory of this source tree.
*/

#include "xclox/ntp/client.hpp"

#include "tools/server.hpp"
#include "tools/tracer.hpp"
#include "xclox/ntp/client.hpp"

#include "tools/helper.hpp"

using namespace xclox::ntp;
using namespace std::chrono;

TEST_SUITE("Client")
{
auto isClientPacket = [](const Packet& packet) {
return packet.version() == 4 && packet.mode() == 3 && Timestamp(system_clock::now()) - Timestamp(packet.transmitTimestamp()) < seconds(2);
};
auto isServerPacket = [](const Packet& packet) {
return (packet.version() == 3 || packet.version() == 4) && packet.mode() == 4 && Timestamp(system_clock::now()) - Timestamp(packet.transmitTimestamp()) < seconds(2);
};
auto stringify = [](const asio::ip::udp::endpoint& endpoint) {
std::stringstream ss;
ss << endpoint;
return ss.str();
};
struct Context {
Context()
: server1(32101, serverTracer1.callable())
Expand Down Expand Up @@ -151,7 +143,7 @@ TEST_SUITE("Client")
Client(clientTracer.callable()).query(host);
CHECK(clientTracer.wait() == 1);
CHECK(clientTracer.find([&](const std::string& name, const std::string& address, Client::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host && status == Query::Status::Succeeded && isClientPacket(packet) && rtt < milliseconds(100);
return name == host && address == host && status == Query::Status::Succeeded && isClientPacket(packet) && compare(rtt, milliseconds(50));
}) == 1);
}

Expand All @@ -167,7 +159,7 @@ TEST_SUITE("Client")
CHECK(clientTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == "" && status == Query::Status::TimeoutError && packet.isNull() && rtt == seconds(0);
}) == 1);
CHECK(abs(duration_cast<milliseconds>(steady_clock::now() - start).count() - i * 100) < 50);
CHECK(compare(start, milliseconds(i * 100)));
clientTracer.reset();
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/ntp/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "xclox/ntp/packet.hpp"

#include "tools/helper.hpp"

#include <functional>
#include <map>

Expand Down
40 changes: 17 additions & 23 deletions test/ntp/query.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,18 @@
* LICENSE.txt file in the root directory of this source tree.
*/

#include "xclox/ntp/query.hpp"

#include "tools/server.hpp"
#include "tools/tracer.hpp"
#include "xclox/ntp/query.hpp"

#include "tools/helper.hpp"

using namespace xclox::ntp;
using namespace std::chrono;

TEST_SUITE("Query")
{
const auto& MaximumTolerableTime = milliseconds(100);
auto stringify = [](const asio::ip::udp::endpoint& endpoint) {
std::stringstream ss;
ss << endpoint;
return ss.str();
};
auto isServerPacket = [](const Packet& packet) {
return (packet.version() == 3 || packet.version() == 4) && packet.mode() == 4 && Timestamp(system_clock::now()) - Timestamp(packet.transmitTimestamp()) < seconds(2);
};
struct Context {
Context()
: server1(32101, serverTracer1.callable())
Expand Down Expand Up @@ -54,7 +48,7 @@ TEST_SUITE("Query")
Query::start(pool, host, queryTracer.callable());
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host + ":123" && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && rtt < MaximumTolerableTime;
return name == host && address == host + ":123" && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && compare(rtt, milliseconds(1));
}) == 1);
}

Expand All @@ -66,7 +60,7 @@ TEST_SUITE("Query")
Query::start(pool, host, queryTracer.callable());
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == "255.255.255.255:123" && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && rtt < MaximumTolerableTime;
return name == host && address == "255.255.255.255:123" && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && compare(rtt, milliseconds(1));
}) == 1);
}
SUBCASE("number")
Expand All @@ -75,7 +69,7 @@ TEST_SUITE("Query")
Query::start(pool, host, queryTracer.callable());
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && rtt < MaximumTolerableTime;
return name == host && address == host && status == Query::Status::SendError && !packet.isNull() && rtt > nanoseconds(0) && compare(rtt, milliseconds(1));
}) == 1);
}
}
Expand All @@ -88,7 +82,7 @@ TEST_SUITE("Query")
Query::start(pool, host, queryTracer.callable());
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host && status == Query::Status::ReceiveError && packet.isNull() && rtt > nanoseconds(0) && rtt < MaximumTolerableTime;
return name == host && address == host && status == Query::Status::ReceiveError && packet.isNull() && rtt > nanoseconds(0) && compare(rtt, milliseconds(1));
}) == 1);
}

Expand All @@ -99,7 +93,7 @@ TEST_SUITE("Query")
Query::start(pool, host, queryTracer.callable());
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host && status == Query::Status::Succeeded && !packet.isNull() && abs(duration_cast<milliseconds>(rtt).count() - 100) < MaximumTolerableTime.count();
return name == host && address == host && status == Query::Status::Succeeded && !packet.isNull() && compare(rtt, milliseconds(100));
}) == 1);
}

Expand All @@ -109,10 +103,10 @@ TEST_SUITE("Query")
const std::string& host = stringify(server1.endpoint());
const auto& start = steady_clock::now();
Query::start(pool, host, queryTracer.callable());
CHECK(steady_clock::now() - start < MaximumTolerableTime);
CHECK(compare(start, milliseconds(1)));
CHECK(queryTracer.wait() == 1);
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == host && status == Query::Status::Succeeded && !packet.isNull() && abs(duration_cast<milliseconds>(rtt).count() - 200) < MaximumTolerableTime.count();
return name == host && address == host && status == Query::Status::Succeeded && !packet.isNull() && compare(rtt, milliseconds(200));
}) == 1);
}

Expand Down Expand Up @@ -143,7 +137,7 @@ TEST_SUITE("Query")
return name == host && address == "" && status == Query::Status::TimeoutError && packet.isNull() && rtt == seconds(0);
}) == 1);
CHECK(query.expired());
CHECK(abs(duration_cast<milliseconds>(steady_clock::now() - start).count() - timeoutMs) < MaximumTolerableTime.count());
CHECK(compare(start, milliseconds(timeoutMs)));
}

TEST_CASE_FIXTURE(Context, "timeout - query" * doctest::timeout(1))
Expand All @@ -158,7 +152,7 @@ TEST_SUITE("Query")
CHECK(queryTracer.find([&](const std::string& name, const std::string& address, Query::Status status, const Packet& packet, const steady_clock::duration& rtt) {
return name == host && address == "" && status == Query::Status::TimeoutError && packet.isNull() && rtt == seconds(0);
}) == 1);
CHECK(abs(duration_cast<milliseconds>(steady_clock::now() - start).count() - i * 100) < MaximumTolerableTime.count());
CHECK(compare(start, milliseconds(i * 100)));
CHECK(query.expired());
queryTracer.reset();
}
Expand All @@ -176,13 +170,13 @@ TEST_SUITE("Query")
return name == host && address == "" && status == Query::Status::Cancelled && packet.isNull() && rtt == seconds(0);
}) == 1);
CHECK(query.expired());
CHECK(steady_clock::now() - start < MaximumTolerableTime);
CHECK(compare(start, milliseconds(1)));
}

TEST_CASE_FIXTURE(Context, "cancellable during query - multiple times" * doctest::timeout(1))
{
const auto& start = steady_clock::now();
server1.replay(nullptr, 0, milliseconds(100));
server1.replay(nullptr, 0, milliseconds(200));
const std::string& host = stringify(server1.endpoint());
auto query = Query::start(pool, host, queryTracer.callable());
CHECK(serverTracer1.wait() == 1);
Expand All @@ -200,11 +194,11 @@ TEST_SUITE("Query")
return name == host && address == "" && status == Query::Status::Cancelled && packet.isNull() && rtt == seconds(0);
}) == 1);
// The query lasts a bit before it expires on Linux
std::this_thread::sleep_for(milliseconds(50));
std::this_thread::sleep_for(milliseconds(100));
CHECK(query.expired());
CHECK(serverTracer1.counter() == 1);
CHECK(serverTracer1.wait(2) == 2);
CHECK(steady_clock::now() - start < milliseconds(100) + MaximumTolerableTime);
CHECK(compare(start, milliseconds(200)));
}

TEST_CASE_FIXTURE(Context, "cancellable concurrently" * doctest::timeout(1))
Expand Down
Loading

0 comments on commit 2ee5f3d

Please sign in to comment.