blob: 56a9f8c99bbb0a773bbcb6db6ab0c82138098737 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/testclient.h"
deadbeef22e08142017-06-12 14:30:28 -070012
Karl Wiberg918f50c2018-07-05 11:40:33 +020013#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "rtc_base/gunit.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/thread.h"
16#include "rtc_base/timeutils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017
18namespace rtc {
19
20// DESIGN: Each packet received is put it into a list of packets.
21// Callers can retrieve received packets from any thread by calling
22// NextPacket.
23
nisse32f25052017-05-08 01:57:18 -070024TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket)
deadbeef22e08142017-06-12 14:30:28 -070025 : TestClient(std::move(socket), nullptr) {}
26
27TestClient::TestClient(std::unique_ptr<AsyncPacketSocket> socket,
28 FakeClock* fake_clock)
29 : fake_clock_(fake_clock),
30 socket_(std::move(socket)),
31 prev_packet_timestamp_(-1) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032 socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
33 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
34}
35
nisse32f25052017-05-08 01:57:18 -070036TestClient::~TestClient() {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037
38bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
39 // Wait for our timeout value until the socket reaches the desired state.
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070040 int64_t end = TimeAfter(kTimeoutMs);
41 while (socket_->GetState() != state && TimeUntil(end) > 0) {
deadbeef22e08142017-06-12 14:30:28 -070042 AdvanceTime(1);
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070043 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000044 return (socket_->GetState() == state);
45}
46
47int TestClient::Send(const char* buf, size_t size) {
48 rtc::PacketOptions options;
49 return socket_->Send(buf, size, options);
50}
51
Yves Gerey665174f2018-06-19 15:03:05 +020052int TestClient::SendTo(const char* buf,
53 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000054 const SocketAddress& dest) {
55 rtc::PacketOptions options;
56 return socket_->SendTo(buf, size, dest, options);
57}
58
nisse32f25052017-05-08 01:57:18 -070059std::unique_ptr<TestClient::Packet> TestClient::NextPacket(int timeout_ms) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060 // If no packets are currently available, we go into a get/dispatch loop for
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000061 // at most timeout_ms. If, during the loop, a packet arrives, then we can
62 // stop early and return it.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000063
64 // Note that the case where no packet arrives is important. We often want to
65 // test that a packet does not arrive.
66
67 // Note also that we only try to pump our current thread's message queue.
68 // Pumping another thread's queue could lead to messages being dispatched from
69 // the wrong thread to non-thread-safe objects.
70
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070071 int64_t end = TimeAfter(timeout_ms);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000072 while (TimeUntil(end) > 0) {
73 {
74 CritScope cs(&crit_);
nisse32f25052017-05-08 01:57:18 -070075 if (packets_.size() != 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000076 break;
77 }
78 }
deadbeef22e08142017-06-12 14:30:28 -070079 AdvanceTime(1);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000080 }
81
82 // Return the first packet placed in the queue.
nisse32f25052017-05-08 01:57:18 -070083 std::unique_ptr<Packet> packet;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000084 CritScope cs(&crit_);
nisse32f25052017-05-08 01:57:18 -070085 if (packets_.size() > 0) {
86 packet = std::move(packets_.front());
87 packets_.erase(packets_.begin());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000088 }
89
90 return packet;
91}
92
Yves Gerey665174f2018-06-19 15:03:05 +020093bool TestClient::CheckNextPacket(const char* buf,
94 size_t size,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000095 SocketAddress* addr) {
96 bool res = false;
nisse32f25052017-05-08 01:57:18 -070097 std::unique_ptr<Packet> packet = NextPacket(kTimeoutMs);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000098 if (packet) {
Stefan Holmer9131efd2016-05-23 18:19:26 +020099 res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
Niels Möller15ca5a92018-11-01 14:32:47 +0100100 CheckTimestamp(packet->packet_time));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000101 if (addr)
102 *addr = packet->addr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000103 }
104 return res;
105}
106
Stefan Holmer9131efd2016-05-23 18:19:26 +0200107bool TestClient::CheckTimestamp(int64_t packet_timestamp) {
108 bool res = true;
109 if (packet_timestamp == -1) {
110 res = false;
111 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200112 if (prev_packet_timestamp_ != -1) {
113 if (packet_timestamp < prev_packet_timestamp_) {
114 res = false;
115 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200116 }
117 prev_packet_timestamp_ = packet_timestamp;
Stefan Holmer9131efd2016-05-23 18:19:26 +0200118 return res;
119}
120
deadbeef22e08142017-06-12 14:30:28 -0700121void TestClient::AdvanceTime(int ms) {
122 // If the test is using a fake clock, we must advance the fake clock to
123 // advance time. Otherwise, ProcessMessages will work.
124 if (fake_clock_) {
125 SIMULATED_WAIT(false, ms, *fake_clock_);
126 } else {
127 Thread::Current()->ProcessMessages(1);
128 }
129}
130
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000131bool TestClient::CheckNoPacket() {
nisse32f25052017-05-08 01:57:18 -0700132 return NextPacket(kNoPacketTimeoutMs) == nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000133}
134
135int TestClient::GetError() {
136 return socket_->GetError();
137}
138
139int TestClient::SetOption(Socket::Option opt, int value) {
140 return socket_->SetOption(opt, value);
141}
142
Yves Gerey665174f2018-06-19 15:03:05 +0200143void TestClient::OnPacket(AsyncPacketSocket* socket,
144 const char* buf,
145 size_t size,
146 const SocketAddress& remote_addr,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000147 const PacketTime& packet_time) {
148 CritScope cs(&crit_);
Karl Wiberg918f50c2018-07-05 11:40:33 +0200149 packets_.push_back(
150 absl::make_unique<Packet>(remote_addr, buf, size, packet_time));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151}
152
153void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
Taylor Brandstettere7536412016-09-09 13:16:15 -0700154 ++ready_to_send_count_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155}
156
Stefan Holmer9131efd2016-05-23 18:19:26 +0200157TestClient::Packet::Packet(const SocketAddress& a,
158 const char* b,
159 size_t s,
160 const PacketTime& packet_time)
161 : addr(a), buf(0), size(s), packet_time(packet_time) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000162 buf = new char[size];
163 memcpy(buf, b, size);
164}
165
166TestClient::Packet::Packet(const Packet& p)
Stefan Holmer9131efd2016-05-23 18:19:26 +0200167 : addr(p.addr), buf(0), size(p.size), packet_time(p.packet_time) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000168 buf = new char[size];
169 memcpy(buf, p.buf, size);
170}
171
172TestClient::Packet::~Packet() {
173 delete[] buf;
174}
175
176} // namespace rtc