xref: /aosp_15_r20/external/webrtc/rtc_base/test_client.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/test_client.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <utility>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker namespace rtc {
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker // DESIGN: Each packet received is put it into a list of packets.
25*d9f75844SAndroid Build Coastguard Worker //         Callers can retrieve received packets from any thread by calling
26*d9f75844SAndroid Build Coastguard Worker //         NextPacket.
27*d9f75844SAndroid Build Coastguard Worker 
TestClient(std::unique_ptr<AsyncPacketSocket> socket)28*d9f75844SAndroid Build Coastguard Worker TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket)
29*d9f75844SAndroid Build Coastguard Worker     : TestClient(std::move(socket), nullptr) {}
30*d9f75844SAndroid Build Coastguard Worker 
TestClient(std::unique_ptr<AsyncPacketSocket> socket,ThreadProcessingFakeClock * fake_clock)31*d9f75844SAndroid Build Coastguard Worker TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
32*d9f75844SAndroid Build Coastguard Worker                        ThreadProcessingFakeClock* fake_clock)
33*d9f75844SAndroid Build Coastguard Worker     : fake_clock_(fake_clock),
34*d9f75844SAndroid Build Coastguard Worker       socket_(std::move(socket)),
35*d9f75844SAndroid Build Coastguard Worker       prev_packet_timestamp_(-1) {
36*d9f75844SAndroid Build Coastguard Worker   socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
37*d9f75844SAndroid Build Coastguard Worker   socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
38*d9f75844SAndroid Build Coastguard Worker }
39*d9f75844SAndroid Build Coastguard Worker 
~TestClient()40*d9f75844SAndroid Build Coastguard Worker TestClient::~TestClient() {}
41*d9f75844SAndroid Build Coastguard Worker 
CheckConnState(AsyncPacketSocket::State state)42*d9f75844SAndroid Build Coastguard Worker bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
43*d9f75844SAndroid Build Coastguard Worker   // Wait for our timeout value until the socket reaches the desired state.
44*d9f75844SAndroid Build Coastguard Worker   int64_t end = TimeAfter(kTimeoutMs);
45*d9f75844SAndroid Build Coastguard Worker   while (socket_->GetState() != state && TimeUntil(end) > 0) {
46*d9f75844SAndroid Build Coastguard Worker     AdvanceTime(1);
47*d9f75844SAndroid Build Coastguard Worker   }
48*d9f75844SAndroid Build Coastguard Worker   return (socket_->GetState() == state);
49*d9f75844SAndroid Build Coastguard Worker }
50*d9f75844SAndroid Build Coastguard Worker 
Send(const char * buf,size_t size)51*d9f75844SAndroid Build Coastguard Worker int TestClient::Send(const char* buf, size_t size) {
52*d9f75844SAndroid Build Coastguard Worker   rtc::PacketOptions options;
53*d9f75844SAndroid Build Coastguard Worker   return socket_->Send(buf, size, options);
54*d9f75844SAndroid Build Coastguard Worker }
55*d9f75844SAndroid Build Coastguard Worker 
SendTo(const char * buf,size_t size,const SocketAddress & dest)56*d9f75844SAndroid Build Coastguard Worker int TestClient::SendTo(const char* buf,
57*d9f75844SAndroid Build Coastguard Worker                        size_t size,
58*d9f75844SAndroid Build Coastguard Worker                        const SocketAddress& dest) {
59*d9f75844SAndroid Build Coastguard Worker   rtc::PacketOptions options;
60*d9f75844SAndroid Build Coastguard Worker   return socket_->SendTo(buf, size, dest, options);
61*d9f75844SAndroid Build Coastguard Worker }
62*d9f75844SAndroid Build Coastguard Worker 
NextPacket(int timeout_ms)63*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TestClient::Packet> TestClient::NextPacket(int timeout_ms) {
64*d9f75844SAndroid Build Coastguard Worker   // If no packets are currently available, we go into a get/dispatch loop for
65*d9f75844SAndroid Build Coastguard Worker   // at most timeout_ms.  If, during the loop, a packet arrives, then we can
66*d9f75844SAndroid Build Coastguard Worker   // stop early and return it.
67*d9f75844SAndroid Build Coastguard Worker 
68*d9f75844SAndroid Build Coastguard Worker   // Note that the case where no packet arrives is important.  We often want to
69*d9f75844SAndroid Build Coastguard Worker   // test that a packet does not arrive.
70*d9f75844SAndroid Build Coastguard Worker 
71*d9f75844SAndroid Build Coastguard Worker   // Note also that we only try to pump our current thread's message queue.
72*d9f75844SAndroid Build Coastguard Worker   // Pumping another thread's queue could lead to messages being dispatched from
73*d9f75844SAndroid Build Coastguard Worker   // the wrong thread to non-thread-safe objects.
74*d9f75844SAndroid Build Coastguard Worker 
75*d9f75844SAndroid Build Coastguard Worker   int64_t end = TimeAfter(timeout_ms);
76*d9f75844SAndroid Build Coastguard Worker   while (TimeUntil(end) > 0) {
77*d9f75844SAndroid Build Coastguard Worker     {
78*d9f75844SAndroid Build Coastguard Worker       webrtc::MutexLock lock(&mutex_);
79*d9f75844SAndroid Build Coastguard Worker       if (packets_.size() != 0) {
80*d9f75844SAndroid Build Coastguard Worker         break;
81*d9f75844SAndroid Build Coastguard Worker       }
82*d9f75844SAndroid Build Coastguard Worker     }
83*d9f75844SAndroid Build Coastguard Worker     AdvanceTime(1);
84*d9f75844SAndroid Build Coastguard Worker   }
85*d9f75844SAndroid Build Coastguard Worker 
86*d9f75844SAndroid Build Coastguard Worker   // Return the first packet placed in the queue.
87*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Packet> packet;
88*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&mutex_);
89*d9f75844SAndroid Build Coastguard Worker   if (packets_.size() > 0) {
90*d9f75844SAndroid Build Coastguard Worker     packet = std::move(packets_.front());
91*d9f75844SAndroid Build Coastguard Worker     packets_.erase(packets_.begin());
92*d9f75844SAndroid Build Coastguard Worker   }
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker   return packet;
95*d9f75844SAndroid Build Coastguard Worker }
96*d9f75844SAndroid Build Coastguard Worker 
CheckNextPacket(const char * buf,size_t size,SocketAddress * addr)97*d9f75844SAndroid Build Coastguard Worker bool TestClient::CheckNextPacket(const char* buf,
98*d9f75844SAndroid Build Coastguard Worker                                  size_t size,
99*d9f75844SAndroid Build Coastguard Worker                                  SocketAddress* addr) {
100*d9f75844SAndroid Build Coastguard Worker   bool res = false;
101*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
102*d9f75844SAndroid Build Coastguard Worker   if (packet) {
103*d9f75844SAndroid Build Coastguard Worker     res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
104*d9f75844SAndroid Build Coastguard Worker            CheckTimestamp(packet->packet_time_us));
105*d9f75844SAndroid Build Coastguard Worker     if (addr)
106*d9f75844SAndroid Build Coastguard Worker       *addr = packet->addr;
107*d9f75844SAndroid Build Coastguard Worker   }
108*d9f75844SAndroid Build Coastguard Worker   return res;
109*d9f75844SAndroid Build Coastguard Worker }
110*d9f75844SAndroid Build Coastguard Worker 
CheckTimestamp(int64_t packet_timestamp)111*d9f75844SAndroid Build Coastguard Worker bool TestClient::CheckTimestamp(int64_t packet_timestamp) {
112*d9f75844SAndroid Build Coastguard Worker   bool res = true;
113*d9f75844SAndroid Build Coastguard Worker   if (packet_timestamp == -1) {
114*d9f75844SAndroid Build Coastguard Worker     res = false;
115*d9f75844SAndroid Build Coastguard Worker   }
116*d9f75844SAndroid Build Coastguard Worker   if (prev_packet_timestamp_ != -1) {
117*d9f75844SAndroid Build Coastguard Worker     if (packet_timestamp < prev_packet_timestamp_) {
118*d9f75844SAndroid Build Coastguard Worker       res = false;
119*d9f75844SAndroid Build Coastguard Worker     }
120*d9f75844SAndroid Build Coastguard Worker   }
121*d9f75844SAndroid Build Coastguard Worker   prev_packet_timestamp_ = packet_timestamp;
122*d9f75844SAndroid Build Coastguard Worker   return res;
123*d9f75844SAndroid Build Coastguard Worker }
124*d9f75844SAndroid Build Coastguard Worker 
AdvanceTime(int ms)125*d9f75844SAndroid Build Coastguard Worker void TestClient::AdvanceTime(int ms) {
126*d9f75844SAndroid Build Coastguard Worker   // If the test is using a fake clock, we must advance the fake clock to
127*d9f75844SAndroid Build Coastguard Worker   // advance time. Otherwise, ProcessMessages will work.
128*d9f75844SAndroid Build Coastguard Worker   if (fake_clock_) {
129*d9f75844SAndroid Build Coastguard Worker     SIMULATED_WAIT(false, ms, *fake_clock_);
130*d9f75844SAndroid Build Coastguard Worker   } else {
131*d9f75844SAndroid Build Coastguard Worker     Thread::Current()->ProcessMessages(1);
132*d9f75844SAndroid Build Coastguard Worker   }
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker 
CheckNoPacket()135*d9f75844SAndroid Build Coastguard Worker bool TestClient::CheckNoPacket() {
136*d9f75844SAndroid Build Coastguard Worker   return NextPacket(kNoPacketTimeoutMs) == nullptr;
137*d9f75844SAndroid Build Coastguard Worker }
138*d9f75844SAndroid Build Coastguard Worker 
GetError()139*d9f75844SAndroid Build Coastguard Worker int TestClient::GetError() {
140*d9f75844SAndroid Build Coastguard Worker   return socket_->GetError();
141*d9f75844SAndroid Build Coastguard Worker }
142*d9f75844SAndroid Build Coastguard Worker 
SetOption(Socket::Option opt,int value)143*d9f75844SAndroid Build Coastguard Worker int TestClient::SetOption(Socket::Option opt, int value) {
144*d9f75844SAndroid Build Coastguard Worker   return socket_->SetOption(opt, value);
145*d9f75844SAndroid Build Coastguard Worker }
146*d9f75844SAndroid Build Coastguard Worker 
OnPacket(AsyncPacketSocket * socket,const char * buf,size_t size,const SocketAddress & remote_addr,const int64_t & packet_time_us)147*d9f75844SAndroid Build Coastguard Worker void TestClient::OnPacket(AsyncPacketSocket* socket,
148*d9f75844SAndroid Build Coastguard Worker                           const char* buf,
149*d9f75844SAndroid Build Coastguard Worker                           size_t size,
150*d9f75844SAndroid Build Coastguard Worker                           const SocketAddress& remote_addr,
151*d9f75844SAndroid Build Coastguard Worker                           const int64_t& packet_time_us) {
152*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock lock(&mutex_);
153*d9f75844SAndroid Build Coastguard Worker   packets_.push_back(
154*d9f75844SAndroid Build Coastguard Worker       std::make_unique<Packet>(remote_addr, buf, size, packet_time_us));
155*d9f75844SAndroid Build Coastguard Worker }
156*d9f75844SAndroid Build Coastguard Worker 
OnReadyToSend(AsyncPacketSocket * socket)157*d9f75844SAndroid Build Coastguard Worker void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
158*d9f75844SAndroid Build Coastguard Worker   ++ready_to_send_count_;
159*d9f75844SAndroid Build Coastguard Worker }
160*d9f75844SAndroid Build Coastguard Worker 
Packet(const SocketAddress & a,const char * b,size_t s,int64_t packet_time_us)161*d9f75844SAndroid Build Coastguard Worker TestClient::Packet::Packet(const SocketAddress& a,
162*d9f75844SAndroid Build Coastguard Worker                            const char* b,
163*d9f75844SAndroid Build Coastguard Worker                            size_t s,
164*d9f75844SAndroid Build Coastguard Worker                            int64_t packet_time_us)
165*d9f75844SAndroid Build Coastguard Worker     : addr(a), buf(0), size(s), packet_time_us(packet_time_us) {
166*d9f75844SAndroid Build Coastguard Worker   buf = new char[size];
167*d9f75844SAndroid Build Coastguard Worker   memcpy(buf, b, size);
168*d9f75844SAndroid Build Coastguard Worker }
169*d9f75844SAndroid Build Coastguard Worker 
Packet(const Packet & p)170*d9f75844SAndroid Build Coastguard Worker TestClient::Packet::Packet(const Packet& p)
171*d9f75844SAndroid Build Coastguard Worker     : addr(p.addr), buf(0), size(p.size), packet_time_us(p.packet_time_us) {
172*d9f75844SAndroid Build Coastguard Worker   buf = new char[size];
173*d9f75844SAndroid Build Coastguard Worker   memcpy(buf, p.buf, size);
174*d9f75844SAndroid Build Coastguard Worker }
175*d9f75844SAndroid Build Coastguard Worker 
~Packet()176*d9f75844SAndroid Build Coastguard Worker TestClient::Packet::~Packet() {
177*d9f75844SAndroid Build Coastguard Worker   delete[] buf;
178*d9f75844SAndroid Build Coastguard Worker }
179*d9f75844SAndroid Build Coastguard Worker 
180*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
181