blob: f23ac2aec06feb86222aeea9c88ed60f3105ded6 [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
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "rtc_base/gunit.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 17:11:0020#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2621
22namespace rtc {
23
24// DESIGN: Each packet received is put it into a list of packets.
25// Callers can retrieve received packets from any thread by calling
26// NextPacket.
27
nisse32f25052017-05-08 08:57:1828TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket)
deadbeef22e08142017-06-12 21:30:2829 : TestClient(std::move(socket), nullptr) {}
30
31TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
Sebastian Janssond624c392019-04-17 08:36:0332 ThreadProcessingFakeClock* fake_clock)
deadbeef22e08142017-06-12 21:30:2833 : fake_clock_(fake_clock),
34 socket_(std::move(socket)),
35 prev_packet_timestamp_(-1) {
henrike@webrtc.orgf0488722014-05-13 18:00:2636 socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
37 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
38}
39
nisse32f25052017-05-08 08:57:1840TestClient::~TestClient() {}
henrike@webrtc.orgf0488722014-05-13 18:00:2641
42bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
43 // Wait for our timeout value until the socket reaches the desired state.
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3144 int64_t end = TimeAfter(kTimeoutMs);
45 while (socket_->GetState() != state && TimeUntil(end) > 0) {
deadbeef22e08142017-06-12 21:30:2846 AdvanceTime(1);
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3147 }
henrike@webrtc.orgf0488722014-05-13 18:00:2648 return (socket_->GetState() == state);
49}
50
51int TestClient::Send(const char* buf, size_t size) {
52 rtc::PacketOptions options;
53 return socket_->Send(buf, size, options);
54}
55
Yves Gerey665174f2018-06-19 13:03:0556int TestClient::SendTo(const char* buf,
57 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:2658 const SocketAddress& dest) {
59 rtc::PacketOptions options;
60 return socket_->SendTo(buf, size, dest, options);
61}
62
nisse32f25052017-05-08 08:57:1863std::unique_ptr<TestClient::Packet> TestClient::NextPacket(int timeout_ms) {
henrike@webrtc.orgf0488722014-05-13 18:00:2664 // If no packets are currently available, we go into a get/dispatch loop for
jlmiller@webrtc.orgec499be2015-02-07 22:37:5965 // at most timeout_ms. If, during the loop, a packet arrives, then we can
66 // stop early and return it.
henrike@webrtc.orgf0488722014-05-13 18:00:2667
68 // Note that the case where no packet arrives is important. We often want to
69 // test that a packet does not arrive.
70
71 // Note also that we only try to pump our current thread's message queue.
72 // Pumping another thread's queue could lead to messages being dispatched from
73 // the wrong thread to non-thread-safe objects.
74
Taylor Brandstetter2b3bf6b2016-05-19 21:57:3175 int64_t end = TimeAfter(timeout_ms);
henrike@webrtc.orgf0488722014-05-13 18:00:2676 while (TimeUntil(end) > 0) {
77 {
Markus Handell18523c32020-07-08 15:55:5878 webrtc::MutexLock lock(&mutex_);
nisse32f25052017-05-08 08:57:1879 if (packets_.size() != 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:2680 break;
81 }
82 }
deadbeef22e08142017-06-12 21:30:2883 AdvanceTime(1);
henrike@webrtc.orgf0488722014-05-13 18:00:2684 }
85
86 // Return the first packet placed in the queue.
nisse32f25052017-05-08 08:57:1887 std::unique_ptr<Packet> packet;
Markus Handell18523c32020-07-08 15:55:5888 webrtc::MutexLock lock(&mutex_);
nisse32f25052017-05-08 08:57:1889 if (packets_.size() > 0) {
90 packet = std::move(packets_.front());
91 packets_.erase(packets_.begin());
henrike@webrtc.orgf0488722014-05-13 18:00:2692 }
93
94 return packet;
95}
96
Yves Gerey665174f2018-06-19 13:03:0597bool TestClient::CheckNextPacket(const char* buf,
98 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:2699 SocketAddress* addr) {
100 bool res = false;
nisse32f25052017-05-08 08:57:18101 std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
henrike@webrtc.orgf0488722014-05-13 18:00:26102 if (packet) {
Stefan Holmer9131efd2016-05-23 16:19:26103 res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
Niels Möllere6933812018-11-05 12:01:41104 CheckTimestamp(packet->packet_time_us));
henrike@webrtc.orgf0488722014-05-13 18:00:26105 if (addr)
106 *addr = packet->addr;
henrike@webrtc.orgf0488722014-05-13 18:00:26107 }
108 return res;
109}
110
Stefan Holmer9131efd2016-05-23 16:19:26111bool TestClient::CheckTimestamp(int64_t packet_timestamp) {
112 bool res = true;
113 if (packet_timestamp == -1) {
114 res = false;
115 }
Stefan Holmer9131efd2016-05-23 16:19:26116 if (prev_packet_timestamp_ != -1) {
117 if (packet_timestamp < prev_packet_timestamp_) {
118 res = false;
119 }
Stefan Holmer9131efd2016-05-23 16:19:26120 }
121 prev_packet_timestamp_ = packet_timestamp;
Stefan Holmer9131efd2016-05-23 16:19:26122 return res;
123}
124
deadbeef22e08142017-06-12 21:30:28125void TestClient::AdvanceTime(int ms) {
126 // If the test is using a fake clock, we must advance the fake clock to
127 // advance time. Otherwise, ProcessMessages will work.
128 if (fake_clock_) {
129 SIMULATED_WAIT(false, ms, *fake_clock_);
130 } else {
131 Thread::Current()->ProcessMessages(1);
132 }
133}
134
henrike@webrtc.orgf0488722014-05-13 18:00:26135bool TestClient::CheckNoPacket() {
nisse32f25052017-05-08 08:57:18136 return NextPacket(kNoPacketTimeoutMs) == nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26137}
138
139int TestClient::GetError() {
140 return socket_->GetError();
141}
142
143int TestClient::SetOption(Socket::Option opt, int value) {
144 return socket_->SetOption(opt, value);
145}
146
Yves Gerey665174f2018-06-19 13:03:05147void TestClient::OnPacket(AsyncPacketSocket* socket,
148 const char* buf,
149 size_t size,
150 const SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 12:01:41151 const int64_t& packet_time_us) {
Markus Handell18523c32020-07-08 15:55:58152 webrtc::MutexLock lock(&mutex_);
Karl Wiberg918f50c2018-07-05 09:40:33153 packets_.push_back(
Mirko Bonadei317a1f02019-09-17 15:06:18154 std::make_unique<Packet>(remote_addr, buf, size, packet_time_us));
henrike@webrtc.orgf0488722014-05-13 18:00:26155}
156
157void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
Taylor Brandstettere7536412016-09-09 20:16:15158 ++ready_to_send_count_;
henrike@webrtc.orgf0488722014-05-13 18:00:26159}
160
Stefan Holmer9131efd2016-05-23 16:19:26161TestClient::Packet::Packet(const SocketAddress& a,
162 const char* b,
163 size_t s,
Niels Möllere6933812018-11-05 12:01:41164 int64_t packet_time_us)
165 : addr(a), buf(0), size(s), packet_time_us(packet_time_us) {
henrike@webrtc.orgf0488722014-05-13 18:00:26166 buf = new char[size];
167 memcpy(buf, b, size);
168}
169
170TestClient::Packet::Packet(const Packet& p)
Niels Möllere6933812018-11-05 12:01:41171 : addr(p.addr), buf(0), size(p.size), packet_time_us(p.packet_time_us) {
henrike@webrtc.orgf0488722014-05-13 18:00:26172 buf = new char[size];
173 memcpy(buf, p.buf, size);
174}
175
176TestClient::Packet::~Packet() {
177 delete[] buf;
178}
179
180} // namespace rtc