/*
* Copyright (C) Photon Vision.
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see .
*/
#include
#include
#include
#include
TEST(TimeSyncProtocolTest, Smoketest) {
using namespace wpi::tsp;
using namespace std::chrono_literals;
TimeSyncServer server{5812};
TimeSyncClient client{"127.0.0.1", 5812, 100ms};
server.Start();
client.Start();
for (int i = 0; i < 10; i++) {
std::this_thread::sleep_for(100ms);
TimeSyncClient::Metadata m = client.GetMetadata();
wpi::println("Offset={} rtt={}", m.offset, m.rtt2);
}
server.Stop();
}
TEST(TimeSyncClientTest, CalculateZero) {
using namespace wpi::tsp;
using namespace std::chrono_literals;
// GIVEN a fresh client
TimeSyncClient client{"127.0.0.1", 5812, 100ms};
// AND a ping-pong sent with no delay
// client -> server -> client
uint64_t ping_client_time{100};
uint64_t pong_server_time{100};
uint64_t pong_client_time{100};
// setup our ping/pong packets
TspPing ping{.version = 1, .message_id = 1, .client_time = ping_client_time};
TspPong pong{ping, pong_server_time};
// WHEN we update statistics
client.UpdateStatistics(pong_client_time, ping, pong);
// THEN the statistics will reflect no delay
EXPECT_EQ(0, client.GetMetadata().offset);
EXPECT_EQ(0, client.GetMetadata().rtt2);
EXPECT_EQ(1u, client.GetMetadata().pongsReceived);
EXPECT_EQ(pong_client_time, client.GetMetadata().lastPongTime);
}
TEST(TimeSyncClientTest, CalculateZeroOffset) {
using namespace wpi::tsp;
using namespace std::chrono_literals;
// GIVEN a fresh client
TimeSyncClient client{"127.0.0.1", 5812, 100ms};
// AND a ping-pong sent with 10ms delay each way
// client -> server -> client
uint64_t ping_client_time{100};
uint64_t pong_server_time{110};
uint64_t pong_client_time{120};
// setup our ping/pong packets
TspPing ping{.version = 1, .message_id = 1, .client_time = ping_client_time};
TspPong pong{ping, pong_server_time};
// WHEN we update statistics
client.UpdateStatistics(pong_client_time, ping, pong);
// THEN the statistics will reflect no offset, and the expected rtt2
// (client-to-client) latency
EXPECT_EQ(0, client.GetMetadata().offset);
EXPECT_EQ(20, client.GetMetadata().rtt2);
EXPECT_EQ(1u, client.GetMetadata().pongsReceived);
EXPECT_EQ(pong_client_time, client.GetMetadata().lastPongTime);
}
TEST(TimeSyncClientTest, CalculateZeroRtt) {
using namespace wpi::tsp;
using namespace std::chrono_literals;
// GIVEN a fresh client
TimeSyncClient client{"127.0.0.1", 5812, 100ms};
// AND a ping-pong sent with no delay
// client -> server -> client
uint64_t ping_client_time{100};
uint64_t pong_server_time{123};
uint64_t pong_client_time{100};
// setup our ping/pong packets
TspPing ping{.version = 1, .message_id = 1, .client_time = ping_client_time};
TspPong pong{ping, pong_server_time};
// WHEN we update statistics
client.UpdateStatistics(pong_client_time, ping, pong);
// THEN the statistics will reflect the expected 23ms offset
EXPECT_EQ(23, client.GetMetadata().offset);
EXPECT_EQ(0, client.GetMetadata().rtt2);
EXPECT_EQ(1u, client.GetMetadata().pongsReceived);
EXPECT_EQ(pong_client_time, client.GetMetadata().lastPongTime);
}
TEST(TimeSyncClientTest, CalculateBoth) {
using namespace wpi::tsp;
using namespace std::chrono_literals;
// GIVEN a fresh client
TimeSyncClient client{"127.0.0.1", 5812, 100ms};
// AND a ping-pong sent with no delay
// client -> server -> client
int64_t offset{-234};
int64_t network_latency{23};
uint64_t ping_client_time{100};
uint64_t pong_server_time{ping_client_time + offset + network_latency};
uint64_t pong_client_time{ping_client_time + 2 * network_latency};
// setup our ping/pong packets
TspPing ping{.version = 1, .message_id = 1, .client_time = ping_client_time};
TspPong pong{ping, pong_server_time};
// WHEN we update statistics
client.UpdateStatistics(pong_client_time, ping, pong);
// THEN the statistics will reflect the expected latency and RTT
EXPECT_EQ(offset, client.GetMetadata().offset);
EXPECT_EQ(network_latency * 2, client.GetMetadata().rtt2);
EXPECT_EQ(1u, client.GetMetadata().pongsReceived);
EXPECT_EQ(pong_client_time, client.GetMetadata().lastPongTime);
}