These two signals were sigslot::multi_thraded_local, so a new copy of the Trampoline template was created for them. Sideswipe: Namespace an unit test file. Bug: webrtc:42222066 Change-Id: I21c88eaba9acc691fa01f68048cd270b01535a01 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/420581 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#46054}
193 lines
7.3 KiB
C++
193 lines
7.3 KiB
C++
/*
|
|
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "rtc_base/async_udp_socket.h"
|
|
|
|
#include <cstdint>
|
|
#include <deque>
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include "api/environment/environment.h"
|
|
#include "api/units/time_delta.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "rtc_base/async_packet_socket.h"
|
|
#include "rtc_base/mock_socket.h"
|
|
#include "rtc_base/network/received_packet.h"
|
|
#include "rtc_base/socket.h"
|
|
#include "rtc_base/socket_address.h"
|
|
#include "rtc_base/virtual_socket_server.h"
|
|
#include "system_wrappers/include/clock.h"
|
|
#include "test/create_test_environment.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
|
|
namespace webrtc {
|
|
|
|
using ::testing::_;
|
|
using ::testing::MockFunction;
|
|
using ::testing::NotNull;
|
|
|
|
TEST(AsyncUDPSocketTest, SetSocketOptionIfEctChange) {
|
|
const SocketAddress kAddr("22.22.22.22", 0);
|
|
VirtualSocketServer socket_server;
|
|
std::unique_ptr<AsyncUDPSocket> udp_socket =
|
|
AsyncUDPSocket::Create(CreateTestEnvironment(), kAddr, socket_server);
|
|
ASSERT_THAT(udp_socket, NotNull());
|
|
|
|
int ect = 0;
|
|
udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
|
|
ASSERT_EQ(ect, 0);
|
|
|
|
uint8_t buffer[] = "hello";
|
|
AsyncSocketPacketOptions packet_options;
|
|
packet_options.ect_1 = false;
|
|
udp_socket->SendTo(buffer, 5, kAddr, packet_options);
|
|
udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
|
|
EXPECT_EQ(ect, 0);
|
|
|
|
packet_options.ect_1 = true;
|
|
udp_socket->SendTo(buffer, 5, kAddr, packet_options);
|
|
udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
|
|
EXPECT_EQ(ect, 1);
|
|
|
|
packet_options.ect_1 = false;
|
|
udp_socket->SendTo(buffer, 5, kAddr, packet_options);
|
|
udp_socket->GetOption(Socket::OPT_SEND_ECN, &ect);
|
|
EXPECT_EQ(ect, 0);
|
|
}
|
|
|
|
TEST(AsyncUDPSocketTest, ArrivalTimeStampCanBeBeforeCurrentTime) {
|
|
SimulatedClock webrtc_clock(Timestamp::Seconds(456));
|
|
Environment env = CreateTestEnvironment({.time = &webrtc_clock});
|
|
std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
|
|
MockSocket* socket_ptr = socket.get();
|
|
AsyncUDPSocket async_socket(env, std::move(socket));
|
|
testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
|
|
received_packet_callback;
|
|
async_socket.RegisterReceivedPacketCallback(
|
|
received_packet_callback.AsStdFunction());
|
|
|
|
const Timestamp kSocketEpoch = Timestamp::Seconds(123);
|
|
EXPECT_CALL(*socket_ptr, RecvFrom(_))
|
|
.WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
|
|
buffer.payload = "hello";
|
|
buffer.arrival_time = kSocketEpoch;
|
|
return buffer.payload.size();
|
|
});
|
|
EXPECT_CALL(received_packet_callback, Call)
|
|
.WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
|
|
EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
|
|
});
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
|
|
// Let 10ms pass until next read event.
|
|
webrtc_clock.AdvanceTime(TimeDelta::Millis(10));
|
|
|
|
EXPECT_CALL(*socket_ptr, RecvFrom(_))
|
|
.WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
|
|
buffer.payload = "hello";
|
|
// But only 5 ms has passed since the last received packet.
|
|
buffer.arrival_time = kSocketEpoch + TimeDelta::Millis(5);
|
|
return buffer.payload.size();
|
|
});
|
|
EXPECT_CALL(received_packet_callback, Call)
|
|
.WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
|
|
EXPECT_EQ(packet.arrival_time(),
|
|
webrtc_clock.CurrentTime() - TimeDelta::Millis(5));
|
|
});
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
}
|
|
|
|
TEST(AsyncUDPSocketTest, InitiallyBufferedPacketsGetSameArrivalTime) {
|
|
SimulatedClock webrtc_clock(Timestamp::Seconds(456));
|
|
Environment env = CreateTestEnvironment({.time = &webrtc_clock});
|
|
std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
|
|
MockSocket* socket_ptr = socket.get();
|
|
AsyncUDPSocket async_socket(env, std::move(socket));
|
|
testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
|
|
received_packet_callback;
|
|
async_socket.RegisterReceivedPacketCallback(
|
|
received_packet_callback.AsStdFunction());
|
|
|
|
// Simulate that three packets are received with some time delta.
|
|
const Timestamp kSocketEpoch = Timestamp::Seconds(123);
|
|
std::deque<Timestamp> socket_arrival_times = {
|
|
kSocketEpoch, kSocketEpoch + TimeDelta::Millis(10),
|
|
kSocketEpoch + TimeDelta::Millis(20)};
|
|
|
|
EXPECT_CALL(*socket_ptr, RecvFrom(_))
|
|
.Times(3)
|
|
.WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
|
|
buffer.payload = "hello";
|
|
buffer.arrival_time = socket_arrival_times.front();
|
|
socket_arrival_times.pop_front();
|
|
return buffer.payload.size();
|
|
});
|
|
|
|
EXPECT_CALL(received_packet_callback, Call)
|
|
.Times(3)
|
|
.WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
|
|
// Despite the packets being received at different times, they all have
|
|
// the same timestamp.
|
|
EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
|
|
});
|
|
// But assume, CPU is blocked and can not read the packet at the pace they
|
|
// arrive. Instead they are read one after each other a bit later.
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
}
|
|
|
|
TEST(AsyncUDPSocketTest, ArrivalTimeStampCanNotBeAfterCurrentTime) {
|
|
SimulatedClock webrtc_clock(Timestamp::Seconds(456));
|
|
Environment env = CreateTestEnvironment({.time = &webrtc_clock});
|
|
std::unique_ptr<MockSocket> socket = std::make_unique<MockSocket>();
|
|
MockSocket* socket_ptr = socket.get();
|
|
AsyncUDPSocket async_socket(env, std::move(socket));
|
|
testing::MockFunction<void(AsyncPacketSocket*, const ReceivedIpPacket&)>
|
|
received_packet_callback;
|
|
async_socket.RegisterReceivedPacketCallback(
|
|
received_packet_callback.AsStdFunction());
|
|
|
|
const Timestamp kSocketEpoch = Timestamp::Seconds(123);
|
|
EXPECT_CALL(*socket_ptr, RecvFrom(_))
|
|
.WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
|
|
buffer.payload = "hello";
|
|
buffer.arrival_time = kSocketEpoch;
|
|
return buffer.payload.size();
|
|
});
|
|
EXPECT_CALL(received_packet_callback, Call)
|
|
.WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
|
|
EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
|
|
});
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
|
|
// Let 10ms pass until next read event.
|
|
webrtc_clock.AdvanceTime(TimeDelta::Millis(10));
|
|
|
|
EXPECT_CALL(*socket_ptr, RecvFrom(_))
|
|
.WillRepeatedly([&](Socket::ReceiveBuffer& buffer) {
|
|
buffer.payload = "hello";
|
|
// But the next packet indicate it is received 25 ms after the previous.
|
|
buffer.arrival_time = kSocketEpoch + TimeDelta::Millis(25);
|
|
return buffer.payload.size();
|
|
});
|
|
EXPECT_CALL(received_packet_callback, Call)
|
|
.WillRepeatedly([&](AsyncPacketSocket*, const ReceivedIpPacket& packet) {
|
|
// We still expect the arrival time to be set no later than the current
|
|
// time.
|
|
EXPECT_EQ(packet.arrival_time(), webrtc_clock.CurrentTime());
|
|
});
|
|
socket_ptr->NotifyReadEvent(socket_ptr);
|
|
}
|
|
|
|
} // namespace webrtc
|