blob: 87c946529ea286481377f5056d06cb79435b6560 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Steve Anton10542f22019-01-11 17:11:0011#include "rtc_base/test_client.h"
deadbeef22e08142017-06-12 21:30:2812
Yves Gerey3e707812018-11-28 15:47:4913#include <string.h>
Jonas Olssona4d87372019-07-05 17:08:3314
Mirko Bonadei317a1f02019-09-17 15:06:1815#include <memory>
Yves Gerey3e707812018-11-28 15:47:4916#include <utility>
17
Per Kd07900c2023-11-17 09:18:2518#include "api/units/timestamp.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "rtc_base/gunit.h"
Per Kd07900c2023-11-17 09:18:2520#include "rtc_base/network/received_packet.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3121#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 17:11:0022#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2623
24namespace rtc {
25
26// DESIGN: Each packet received is put it into a list of packets.
27// Callers can retrieve received packets from any thread by calling
28// NextPacket.
29
nisse32f25052017-05-08 08:57:1830TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket)
deadbeef22e08142017-06-12 21:30:2831 : TestClient(std::move(socket), nullptr) {}
32
33TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
Sebastian Janssond624c392019-04-17 08:36:0334 ThreadProcessingFakeClock* fake_clock)
Per Kd07900c2023-11-17 09:18:2535 : fake_clock_(fake_clock), socket_(std::move(socket)) {
36 socket_->RegisterReceivedPacketCallback(
37 [&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
38 OnPacket(socket, packet);
39 });
henrike@webrtc.orgf0488722014-05-13 18:00:2640 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
41}
42
nisse32f25052017-05-08 08:57:1843TestClient::~TestClient() {}
henrike@webrtc.orgf0488722014-05-13 18:00:2644
45bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
46 // Wait for our timeout value until the socket reaches the desired state.
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3147 int64_t end = TimeAfter(kTimeoutMs);
48 while (socket_->GetState() != state && TimeUntil(end) > 0) {
deadbeef22e08142017-06-12 21:30:2849 AdvanceTime(1);
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3150 }
henrike@webrtc.orgf0488722014-05-13 18:00:2651 return (socket_->GetState() == state);
52}
53
54int TestClient::Send(const char* buf, size_t size) {
55 rtc::PacketOptions options;
56 return socket_->Send(buf, size, options);
57}
58
Yves Gerey665174f2018-06-19 13:03:0559int TestClient::SendTo(const char* buf,
60 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:2661 const SocketAddress& dest) {
62 rtc::PacketOptions options;
63 return socket_->SendTo(buf, size, dest, options);
64}
65
nisse32f25052017-05-08 08:57:1866std::unique_ptr<TestClient::Packet> TestClient::NextPacket(int timeout_ms) {
henrike@webrtc.orgf0488722014-05-13 18:00:2667 // If no packets are currently available, we go into a get/dispatch loop for
jlmiller@webrtc.orgec499be2015-02-07 22:37:5968 // at most timeout_ms. If, during the loop, a packet arrives, then we can
69 // stop early and return it.
henrike@webrtc.orgf0488722014-05-13 18:00:2670
71 // Note that the case where no packet arrives is important. We often want to
72 // test that a packet does not arrive.
73
74 // Note also that we only try to pump our current thread's message queue.
75 // Pumping another thread's queue could lead to messages being dispatched from
76 // the wrong thread to non-thread-safe objects.
77
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3178 int64_t end = TimeAfter(timeout_ms);
henrike@webrtc.orgf0488722014-05-13 18:00:2679 while (TimeUntil(end) > 0) {
80 {
Markus Handell18523c32020-07-08 15:55:5881 webrtc::MutexLock lock(&mutex_);
nisse32f25052017-05-08 08:57:1882 if (packets_.size() != 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:2683 break;
84 }
85 }
deadbeef22e08142017-06-12 21:30:2886 AdvanceTime(1);
henrike@webrtc.orgf0488722014-05-13 18:00:2687 }
88
89 // Return the first packet placed in the queue.
nisse32f25052017-05-08 08:57:1890 std::unique_ptr<Packet> packet;
Markus Handell18523c32020-07-08 15:55:5891 webrtc::MutexLock lock(&mutex_);
nisse32f25052017-05-08 08:57:1892 if (packets_.size() > 0) {
93 packet = std::move(packets_.front());
94 packets_.erase(packets_.begin());
henrike@webrtc.orgf0488722014-05-13 18:00:2695 }
96
97 return packet;
98}
99
Yves Gerey665174f2018-06-19 13:03:05100bool TestClient::CheckNextPacket(const char* buf,
101 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:26102 SocketAddress* addr) {
103 bool res = false;
nisse32f25052017-05-08 08:57:18104 std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
henrike@webrtc.orgf0488722014-05-13 18:00:26105 if (packet) {
Per Kd07900c2023-11-17 09:18:25106 res = (packet->buf.size() == size &&
107 memcmp(packet->buf.data(), buf, size) == 0 &&
108 CheckTimestamp(packet->packet_time));
henrike@webrtc.orgf0488722014-05-13 18:00:26109 if (addr)
110 *addr = packet->addr;
henrike@webrtc.orgf0488722014-05-13 18:00:26111 }
112 return res;
113}
114
Per Kd07900c2023-11-17 09:18:25115bool TestClient::CheckTimestamp(
116 absl::optional<webrtc::Timestamp> packet_timestamp) {
Stefan Holmer9131efd2016-05-23 16:19:26117 bool res = true;
Per Kd07900c2023-11-17 09:18:25118 if (!packet_timestamp) {
Stefan Holmer9131efd2016-05-23 16:19:26119 res = false;
120 }
Per Kd07900c2023-11-17 09:18:25121 if (prev_packet_timestamp_) {
Stefan Holmer9131efd2016-05-23 16:19:26122 if (packet_timestamp < prev_packet_timestamp_) {
123 res = false;
124 }
Stefan Holmer9131efd2016-05-23 16:19:26125 }
126 prev_packet_timestamp_ = packet_timestamp;
Stefan Holmer9131efd2016-05-23 16:19:26127 return res;
128}
129
deadbeef22e08142017-06-12 21:30:28130void TestClient::AdvanceTime(int ms) {
131 // If the test is using a fake clock, we must advance the fake clock to
132 // advance time. Otherwise, ProcessMessages will work.
133 if (fake_clock_) {
134 SIMULATED_WAIT(false, ms, *fake_clock_);
135 } else {
136 Thread::Current()->ProcessMessages(1);
137 }
138}
139
henrike@webrtc.orgf0488722014-05-13 18:00:26140bool TestClient::CheckNoPacket() {
nisse32f25052017-05-08 08:57:18141 return NextPacket(kNoPacketTimeoutMs) == nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26142}
143
144int TestClient::GetError() {
145 return socket_->GetError();
146}
147
148int TestClient::SetOption(Socket::Option opt, int value) {
149 return socket_->SetOption(opt, value);
150}
151
Yves Gerey665174f2018-06-19 13:03:05152void TestClient::OnPacket(AsyncPacketSocket* socket,
Per Kd07900c2023-11-17 09:18:25153 const rtc::ReceivedPacket& received_packet) {
Markus Handell18523c32020-07-08 15:55:58154 webrtc::MutexLock lock(&mutex_);
Per Kd07900c2023-11-17 09:18:25155 packets_.push_back(std::make_unique<Packet>(received_packet));
henrike@webrtc.orgf0488722014-05-13 18:00:26156}
157
158void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
Taylor Brandstettere7536412016-09-09 20:16:15159 ++ready_to_send_count_;
henrike@webrtc.orgf0488722014-05-13 18:00:26160}
161
Per Kd07900c2023-11-17 09:18:25162TestClient::Packet::Packet(const rtc::ReceivedPacket& received_packet)
163 : addr(received_packet.source_address()),
164 // Copy received_packet payload to a buffer owned by Packet.
165 buf(received_packet.payload().data(), received_packet.payload().size()),
166 packet_time(received_packet.arrival_time()) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26167
168TestClient::Packet::Packet(const Packet& p)
Per Kd07900c2023-11-17 09:18:25169 : addr(p.addr),
170 buf(p.buf.data(), p.buf.size()),
171 packet_time(p.packet_time) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26172
173} // namespace rtc