blob: 274b6ca07d277c59fb4112252935bc743b76d993 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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 09:11:00 -080011#include "rtc_base/test_client.h"
deadbeef22e08142017-06-12 14:30:28 -070012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <string.h>
14#include <utility>
15
Karl Wiberg918f50c2018-07-05 11:40:33 +020016#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/gunit.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/thread.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/time_utils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020
21namespace rtc {
22
23// DESIGN: Each packet received is put it into a list of packets.
24// Callers can retrieve received packets from any thread by calling
25// NextPacket.
26
nisse32f25052017-05-08 01:57:18 -070027TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket)
deadbeef22e08142017-06-12 14:30:28 -070028 : TestClient(std::move(socket), nullptr) {}
29
30TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
31 FakeClock* fake_clock)
32 : fake_clock_(fake_clock),
33 socket_(std::move(socket)),
34 prev_packet_timestamp_(-1) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035 socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
36 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
37}
38
nisse32f25052017-05-08 01:57:18 -070039TestClient::~TestClient() {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000040
41bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
42 // Wait for our timeout value until the socket reaches the desired state.
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070043 int64_t end = TimeAfter(kTimeoutMs);
44 while (socket_->GetState() != state && TimeUntil(end) > 0) {
deadbeef22e08142017-06-12 14:30:28 -070045 AdvanceTime(1);
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070046 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047 return (socket_->GetState() == state);
48}
49
50int TestClient::Send(const char* buf, size_t size) {
51 rtc::PacketOptions options;
52 return socket_->Send(buf, size, options);
53}
54
Yves Gerey665174f2018-06-19 15:03:05 +020055int TestClient::SendTo(const char* buf,
56 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000057 const SocketAddress& dest) {
58 rtc::PacketOptions options;
59 return socket_->SendTo(buf, size, dest, options);
60}
61
nisse32f25052017-05-08 01:57:18 -070062std::unique_ptr<TestClient::Packet> TestClient::NextPacket(int timeout_ms) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000063 // If no packets are currently available, we go into a get/dispatch loop for
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000064 // at most timeout_ms. If, during the loop, a packet arrives, then we can
65 // stop early and return it.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000066
67 // Note that the case where no packet arrives is important. We often want to
68 // test that a packet does not arrive.
69
70 // Note also that we only try to pump our current thread's message queue.
71 // Pumping another thread's queue could lead to messages being dispatched from
72 // the wrong thread to non-thread-safe objects.
73
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070074 int64_t end = TimeAfter(timeout_ms);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000075 while (TimeUntil(end) > 0) {
76 {
77 CritScope cs(&crit_);
nisse32f25052017-05-08 01:57:18 -070078 if (packets_.size() != 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000079 break;
80 }
81 }
deadbeef22e08142017-06-12 14:30:28 -070082 AdvanceTime(1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000083 }
84
85 // Return the first packet placed in the queue.
nisse32f25052017-05-08 01:57:18 -070086 std::unique_ptr<Packet> packet;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000087 CritScope cs(&crit_);
nisse32f25052017-05-08 01:57:18 -070088 if (packets_.size() > 0) {
89 packet = std::move(packets_.front());
90 packets_.erase(packets_.begin());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000091 }
92
93 return packet;
94}
95
Yves Gerey665174f2018-06-19 15:03:05 +020096bool TestClient::CheckNextPacket(const char* buf,
97 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000098 SocketAddress* addr) {
99 bool res = false;
nisse32f25052017-05-08 01:57:18 -0700100 std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000101 if (packet) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200102 res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
Niels Möllere6933812018-11-05 13:01:41 +0100103 CheckTimestamp(packet->packet_time_us));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000104 if (addr)
105 *addr = packet->addr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000106 }
107 return res;
108}
109
Stefan Holmer9131efd2016-05-23 18:19:26 +0200110bool TestClient::CheckTimestamp(int64_t packet_timestamp) {
111 bool res = true;
112 if (packet_timestamp == -1) {
113 res = false;
114 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200115 if (prev_packet_timestamp_ != -1) {
116 if (packet_timestamp < prev_packet_timestamp_) {
117 res = false;
118 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200119 }
120 prev_packet_timestamp_ = packet_timestamp;
Stefan Holmer9131efd2016-05-23 18:19:26 +0200121 return res;
122}
123
deadbeef22e08142017-06-12 14:30:28 -0700124void TestClient::AdvanceTime(int ms) {
125 // If the test is using a fake clock, we must advance the fake clock to
126 // advance time. Otherwise, ProcessMessages will work.
127 if (fake_clock_) {
128 SIMULATED_WAIT(false, ms, *fake_clock_);
129 } else {
130 Thread::Current()->ProcessMessages(1);
131 }
132}
133
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000134bool TestClient::CheckNoPacket() {
nisse32f25052017-05-08 01:57:18 -0700135 return NextPacket(kNoPacketTimeoutMs) == nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000136}
137
138int TestClient::GetError() {
139 return socket_->GetError();
140}
141
142int TestClient::SetOption(Socket::Option opt, int value) {
143 return socket_->SetOption(opt, value);
144}
145
Yves Gerey665174f2018-06-19 15:03:05 +0200146void TestClient::OnPacket(AsyncPacketSocket* socket,
147 const char* buf,
148 size_t size,
149 const SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100150 const int64_t& packet_time_us) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151 CritScope cs(&crit_);
Karl Wiberg918f50c2018-07-05 11:40:33 +0200152 packets_.push_back(
Niels Möllere6933812018-11-05 13:01:41 +0100153 absl::make_unique<Packet>(remote_addr, buf, size, packet_time_us));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000154}
155
156void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
Taylor Brandstettere7536412016-09-09 13:16:15 -0700157 ++ready_to_send_count_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000158}
159
Stefan Holmer9131efd2016-05-23 18:19:26 +0200160TestClient::Packet::Packet(const SocketAddress& a,
161 const char* b,
162 size_t s,
Niels Möllere6933812018-11-05 13:01:41 +0100163 int64_t packet_time_us)
164 : addr(a), buf(0), size(s), packet_time_us(packet_time_us) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000165 buf = new char[size];
166 memcpy(buf, b, size);
167}
168
169TestClient::Packet::Packet(const Packet& p)
Niels Möllere6933812018-11-05 13:01:41 +0100170 : addr(p.addr), buf(0), size(p.size), packet_time_us(p.packet_time_us) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000171 buf = new char[size];
172 memcpy(buf, p.buf, size);
173}
174
175TestClient::Packet::~Packet() {
176 delete[] buf;
177}
178
179} // namespace rtc