blob: 4167ab5d1c1589d92f787f161b0a29353408a6e8 [file] [log] [blame]
Charles 'Buck' Krasic762317f2018-03-30 20:08:091// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/udp_socket_posix.h"
6
Bence Béky98447b12018-05-08 03:14:017#include "net/base/completion_callback.h"
Charles 'Buck' Krasic762317f2018-03-30 20:08:098#include "net/base/net_errors.h"
9#include "net/log/test_net_log.h"
10#include "net/log/test_net_log_entry.h"
11#include "net/log/test_net_log_util.h"
12#include "net/socket/datagram_socket.h"
Bence Béky98447b12018-05-08 03:14:0113#include "net/test/test_with_scoped_task_environment.h"
Charles 'Buck' Krasic762317f2018-03-30 20:08:0914#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18using ::testing::_;
19using ::testing::InSequence;
20using ::testing::Invoke;
21using ::testing::InvokeWithoutArgs;
22using ::testing::Return;
23
24namespace net {
25
26namespace test {
27
28namespace {
29
30const size_t kMaxPacketSize = 1500;
31const size_t kNumMsgs = 3;
32const std::string kHelloMsg = "Hello world";
33const std::string kSecondMsg = "Second buffer";
34const std::string kThirdMsg = "Third buffer";
35
36int SetWouldBlock() {
37 errno = EWOULDBLOCK;
38 return -1;
39}
40
41#if HAVE_SENDMMSG
42int SetNotImplemented() {
43 errno = ENOSYS;
44 return -1;
45}
46#endif
47
48bool WatcherSetInvalidHandle() {
49 errno = EBADF;
50 return false;
51}
52
53int SetInvalidHandle() {
54 errno = EBADF;
55 return -1;
56}
57
58} // namespace
59
60class MockUDPSocketPosixSender : public UDPSocketPosixSender {
61 public:
62 MOCK_CONST_METHOD4(
63 Send,
64 ssize_t(int sockfd, const void* buf, size_t len, int flags));
65 MOCK_CONST_METHOD4(Sendmmsg,
66 int(int sockfd,
67 struct mmsghdr* msgvec,
68 unsigned int vlen,
69 unsigned int flags));
70
71 public:
72 SendResult InternalSendBuffers(int fd, DatagramBuffers buffers) const {
73 return UDPSocketPosixSender::InternalSendBuffers(fd, std::move(buffers));
74 }
75#if HAVE_SENDMMSG
76 SendResult InternalSendmmsgBuffers(int fd, DatagramBuffers buffers) const {
77 return UDPSocketPosixSender::InternalSendmmsgBuffers(fd,
78 std::move(buffers));
79 }
80#endif
81
82 private:
83 ~MockUDPSocketPosixSender() override{};
84};
85
86class MockUDPSocketPosix : public UDPSocketPosix {
87 public:
88 MockUDPSocketPosix(DatagramSocket::BindType bind_type,
89 net::NetLog* net_log,
90 const net::NetLogSource& source)
91 : UDPSocketPosix(bind_type, net_log, source) {
92 sender_ = new MockUDPSocketPosixSender();
93 }
94
95 MockUDPSocketPosixSender* sender() {
96 return static_cast<MockUDPSocketPosixSender*>(sender_.get());
97 }
98
99 MOCK_METHOD0(InternalWatchFileDescriptor, bool());
100 MOCK_METHOD0(InternalStopWatchingFileDescriptor, void());
101
102 void FlushPending() { UDPSocketPosix::FlushPending(); }
103
104 void DidSendBuffers(SendResult buffers) {
105 UDPSocketPosix::DidSendBuffers(std::move(buffers));
106 }
107
108 void Enqueue(const std::string& msg, DatagramBuffers* buffers) {
109 datagram_buffer_pool_->Enqueue(msg.data(), msg.length(), buffers);
110 }
111
112 void SetWriteCallback(CompletionCallback callback) {
113 UDPSocketPosix::SetWriteCallback(std::move(callback));
114 }
115
116 void IncreaseWriteAsyncOutstanding(int increment) {
117 UDPSocketPosix::IncreaseWriteAsyncOutstanding(increment);
118 }
119
120 void SetPendingWrites(DatagramBuffers buffers) {
121 pending_writes_ = std::move(buffers);
122 }
123
124 void OnFileCanWriteWithoutBlocking() {
125 write_async_watcher_->OnFileCanWriteWithoutBlocking(1);
126 }
127};
128
Bence Béky98447b12018-05-08 03:14:01129class UDPSocketPosixTest : public TestWithScopedTaskEnvironment {
Charles 'Buck' Krasic762317f2018-03-30 20:08:09130 public:
131 UDPSocketPosixTest()
Bence Béky98447b12018-05-08 03:14:01132 : TestWithScopedTaskEnvironment(
133 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
134 socket_(DatagramSocket::DEFAULT_BIND, &client_log_, NetLogSource()),
Charles 'Buck' Krasic762317f2018-03-30 20:08:09135 callback_fired_(false),
136 weak_factory_(this) {
137 write_callback_ = base::BindRepeating(&UDPSocketPosixTest::OnWriteComplete,
138 weak_factory_.GetWeakPtr());
139 }
140
141 void SetUp() override {
Charles 'Buck' Krasic762317f2018-03-30 20:08:09142 socket_.SetWriteAsyncEnabled(true);
143 socket_.SetMaxPacketSize(kMaxPacketSize);
144 }
145
Charles 'Buck' Krasic762317f2018-03-30 20:08:09146 void AddBuffer(const std::string& msg) {
147 socket_.IncreaseWriteAsyncOutstanding(1);
148 socket_.Enqueue(msg, &buffers_);
149 }
150
151 void AddBuffers() {
152 for (size_t i = 0; i < kNumMsgs; i++) {
153 AddBuffer(msgs_[i]);
154 }
155 }
156
157 void SaveBufferPtrs() {
158 int i = 0;
159 for (auto it = buffers_.cbegin(); it != buffers_.cend(); it++) {
160 buffer_ptrs_[i] = it->get();
161 i++;
162 }
163 }
164
165 void VerifyBufferPtrs() {
166 int i = 0;
167 for (auto it = buffers_.cbegin(); it != buffers_.cend(); it++) {
168 EXPECT_EQ(buffer_ptrs_[i], it->get());
169 i++;
170 }
171 }
172
173 void VerifyBuffersDequeued() {
174 AddBuffers();
175 VerifyBufferPtrs();
176 buffers_.clear();
177 }
178
179 void ResetWriteCallback() {
180 callback_fired_ = false;
181 rv_ = 0;
182 }
183
184 void OnWriteComplete(int rv) {
185 callback_fired_ = true;
186 rv_ = rv;
187 }
188
189 int WriteAsync(int i) {
190 return socket_.WriteAsync(msgs_[i].data(), lengths_[i], write_callback_,
191 TRAFFIC_ANNOTATION_FOR_TESTS);
192 }
193
194 void ExpectSend(int i) {
195 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
196 .WillOnce(Return(lengths_[i]));
197 }
198
199 void ExpectSendWillBlock(int i) {
200 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
201 .WillOnce(InvokeWithoutArgs(SetWouldBlock));
202 EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
203 }
204
205 void ExpectSendWillError(int i) {
206 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[i], _))
207 .WillOnce(InvokeWithoutArgs(SetInvalidHandle));
208 }
209
210 void ExpectSends() {
211 InSequence dummy;
212 for (size_t i = 0; i < kNumMsgs; i++) {
213 ExpectSend(static_cast<int>(i));
214 }
215 }
216
217 void ExpectSendmmsg() {
218 EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
219 .WillOnce(Return(kNumMsgs));
220 }
221
222 TestNetLog client_log_;
223 MockUDPSocketPosix socket_;
224 DatagramBuffers buffers_;
225 bool callback_fired_;
226 int rv_;
227 std::string msgs_[kNumMsgs] = {kHelloMsg, kSecondMsg, kThirdMsg};
228 int lengths_[kNumMsgs] = {kHelloMsg.length(), kSecondMsg.length(),
229 kThirdMsg.length()};
230 int total_lengths_ =
231 kHelloMsg.length() + kSecondMsg.length() + kThirdMsg.length();
232 DatagramBuffer* buffer_ptrs_[kNumMsgs];
233 CompletionCallback write_callback_;
234#if HAVE_SENDMMSG
235 struct iovec msg_iov_[kNumMsgs];
236 struct mmsghdr msgvec_[kNumMsgs];
237#endif
238 base::WeakPtrFactory<UDPSocketPosixTest> weak_factory_;
239};
240
241TEST_F(UDPSocketPosixTest, InternalSendBuffers) {
242 AddBuffers();
243 ExpectSends();
244 SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
245 DatagramBuffers& buffers = result.buffers;
246 EXPECT_EQ(0, result.rv);
247 EXPECT_EQ(3, result.write_count);
248 EXPECT_EQ(kNumMsgs, buffers.size());
249}
250
251TEST_F(UDPSocketPosixTest, InternalSendBuffersWriteError) {
252 AddBuffers();
253 {
254 InSequence dummy;
255 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
256 .WillOnce(Return(lengths_[0]));
257 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[1], _))
258 .WillOnce(InvokeWithoutArgs(SetWouldBlock));
259 }
260 SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
261 DatagramBuffers& buffers = result.buffers;
262 EXPECT_EQ(ERR_IO_PENDING, result.rv);
263 EXPECT_EQ(1, result.write_count);
264 EXPECT_EQ(kNumMsgs, buffers.size());
265}
266
267#if HAVE_SENDMMSG
268
269TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffers) {
270 AddBuffers();
271 ExpectSendmmsg();
272 SendResult result =
273 socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
274 DatagramBuffers& buffers = result.buffers;
275 EXPECT_EQ(0, result.rv);
276 EXPECT_EQ(3, result.write_count);
277 EXPECT_EQ(kNumMsgs, buffers.size());
278}
279
280TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffersWriteShort) {
281 AddBuffers();
282 EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
283 .WillOnce(Return(1));
284 SendResult result =
285 socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
286 DatagramBuffers& buffers = result.buffers;
287 EXPECT_EQ(0, result.rv);
288 EXPECT_EQ(1, result.write_count);
289 EXPECT_EQ(kNumMsgs, buffers.size());
290}
291
292TEST_F(UDPSocketPosixTest, InternalSendmmsgBuffersWriteError) {
293 AddBuffers();
294 EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
295 .WillOnce(InvokeWithoutArgs(SetWouldBlock));
296 SendResult result =
297 socket_.sender()->InternalSendmmsgBuffers(1, std::move(buffers_));
298 DatagramBuffers& buffers = result.buffers;
299 EXPECT_EQ(ERR_IO_PENDING, result.rv);
300 EXPECT_EQ(0, result.write_count);
301 EXPECT_EQ(kNumMsgs, buffers.size());
302}
303
304TEST_F(UDPSocketPosixTest, SendInternalSend) {
305 AddBuffers();
306 ExpectSends();
307 SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
308 EXPECT_EQ(0, result.rv);
309 EXPECT_EQ(3, result.write_count);
310 EXPECT_EQ(kNumMsgs, result.buffers.size());
311}
312
313TEST_F(UDPSocketPosixTest, SendInternalSendmmsg) {
314 socket_.sender()->SetSendmmsgEnabled(true);
315 AddBuffers();
316 ExpectSendmmsg();
317 SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
318 EXPECT_EQ(0, result.rv);
319 EXPECT_EQ(3, result.write_count);
320 EXPECT_EQ(kNumMsgs, result.buffers.size());
321}
322
323TEST_F(UDPSocketPosixTest, SendInternalSendmmsgFallback) {
324 socket_.sender()->SetSendmmsgEnabled(true);
325 AddBuffers();
326 {
327 InSequence dummy;
328 EXPECT_CALL(*socket_.sender(), Sendmmsg(_, _, kNumMsgs, _))
329 .WillOnce(InvokeWithoutArgs(SetNotImplemented));
330 ExpectSends();
331 }
332 SendResult result = socket_.sender()->SendBuffers(1, std::move(buffers_));
333 EXPECT_EQ(0, result.rv);
334 EXPECT_EQ(3, result.write_count);
335 EXPECT_EQ(kNumMsgs, result.buffers.size());
336}
337
338#endif // HAVE_SENDMMSG
339
340TEST_F(UDPSocketPosixTest, DidSendBuffers) {
341 AddBuffers();
342 SaveBufferPtrs();
343 SendResult send_result(0, kNumMsgs, std::move(buffers_));
344 socket_.DidSendBuffers(std::move(send_result));
345 EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
346 VerifyBuffersDequeued();
347 TestNetLogEntry::List client_entries;
348 client_log_.GetEntries(&client_entries);
349 EXPECT_EQ(4u, client_entries.size());
350 EXPECT_TRUE(
351 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
352 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
353 NetLogEventType::UDP_BYTES_SENT,
354 NetLogEventPhase::NONE));
355 EXPECT_TRUE(LogContainsEvent(client_entries, 2,
356 NetLogEventType::UDP_BYTES_SENT,
357 NetLogEventPhase::NONE));
358 EXPECT_TRUE(LogContainsEvent(client_entries, 3,
359 NetLogEventType::UDP_BYTES_SENT,
360 NetLogEventPhase::NONE));
361 EXPECT_FALSE(callback_fired_);
362}
363
364TEST_F(UDPSocketPosixTest, DidSendBuffersAsync) {
365 AddBuffers();
366 SendResult send_result(0, kNumMsgs, std::move(buffers_));
367 ResetWriteCallback();
368 socket_.SetWriteCallback(write_callback_);
369 socket_.DidSendBuffers(std::move(send_result));
370 EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
371 TestNetLogEntry::List client_entries;
372 client_log_.GetEntries(&client_entries);
373 EXPECT_EQ(4u, client_entries.size());
374 EXPECT_TRUE(
375 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
376 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
377 NetLogEventType::UDP_BYTES_SENT,
378 NetLogEventPhase::NONE));
379 EXPECT_TRUE(LogContainsEvent(client_entries, 2,
380 NetLogEventType::UDP_BYTES_SENT,
381 NetLogEventPhase::NONE));
382 EXPECT_TRUE(LogContainsEvent(client_entries, 3,
383 NetLogEventType::UDP_BYTES_SENT,
384 NetLogEventPhase::NONE));
385 EXPECT_TRUE(callback_fired_);
386 EXPECT_EQ(rv_, total_lengths_);
387}
388
389TEST_F(UDPSocketPosixTest, DidSendBuffersError) {
390 AddBuffers();
391 SendResult send_result(ERR_INVALID_HANDLE, 1, std::move(buffers_));
392 ResetWriteCallback();
393 socket_.SetWriteCallback(write_callback_);
394 socket_.DidSendBuffers(std::move(send_result));
395 EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
396 TestNetLogEntry::List client_entries;
397 client_log_.GetEntries(&client_entries);
398 EXPECT_EQ(2u, client_entries.size());
399 EXPECT_TRUE(
400 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
401 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
402 NetLogEventType::UDP_BYTES_SENT,
403 NetLogEventPhase::NONE));
404 EXPECT_TRUE(callback_fired_);
405 EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
406}
407
408TEST_F(UDPSocketPosixTest, DidSendBuffersShort) {
409 AddBuffers();
410 SendResult send_result(0, 1, std::move(buffers_));
411 ResetWriteCallback();
412 socket_.SetWriteCallback(write_callback_);
413 socket_.DidSendBuffers(std::move(send_result));
414 EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
415 TestNetLogEntry::List client_entries;
416 client_log_.GetEntries(&client_entries);
417 EXPECT_EQ(2u, client_entries.size());
418 EXPECT_TRUE(
419 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
420 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
421 NetLogEventType::UDP_BYTES_SENT,
422 NetLogEventPhase::NONE));
423 EXPECT_TRUE(callback_fired_);
424 EXPECT_EQ(rv_, lengths_[0]);
425}
426
427TEST_F(UDPSocketPosixTest, DidSendBuffersPending) {
428 AddBuffers();
429 SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
430 ResetWriteCallback();
431 socket_.SetWriteCallback(write_callback_);
432 EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
433 socket_.DidSendBuffers(std::move(send_result));
434 EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
435 TestNetLogEntry::List client_entries;
436 client_log_.GetEntries(&client_entries);
437 EXPECT_EQ(2u, client_entries.size());
438 EXPECT_TRUE(
439 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
440 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
441 NetLogEventType::UDP_BYTES_SENT,
442 NetLogEventPhase::NONE));
443 EXPECT_TRUE(callback_fired_);
444 EXPECT_EQ(rv_, lengths_[0]);
445}
446
447TEST_F(UDPSocketPosixTest, DidSendBuffersWatchError) {
448 AddBuffers();
449 SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
450 ResetWriteCallback();
451 socket_.SetWriteCallback(write_callback_);
452 EXPECT_CALL(socket_, InternalWatchFileDescriptor())
453 .WillOnce(InvokeWithoutArgs(WatcherSetInvalidHandle));
454 socket_.DidSendBuffers(std::move(send_result));
455 EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
456 TestNetLogEntry::List client_entries;
457 client_log_.GetEntries(&client_entries);
458 EXPECT_EQ(3u, client_entries.size());
459 EXPECT_TRUE(
460 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
461 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
462 NetLogEventType::UDP_BYTES_SENT,
463 NetLogEventPhase::NONE));
464 EXPECT_TRUE(LogContainsEvent(client_entries, 2,
465 NetLogEventType::UDP_SEND_ERROR,
466 NetLogEventPhase::NONE));
467 EXPECT_TRUE(callback_fired_);
468 EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
469}
470
471TEST_F(UDPSocketPosixTest, DidSendBuffersStopWatch) {
472 AddBuffers();
473 SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
474 ResetWriteCallback();
475 socket_.SetWriteCallback(write_callback_);
476 EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
477 socket_.DidSendBuffers(std::move(send_result));
478 buffers_ = socket_.GetUnwrittenBuffers();
479 EXPECT_EQ(2u, buffers_.size());
480 TestNetLogEntry::List client_entries;
481 client_log_.GetEntries(&client_entries);
482 EXPECT_EQ(2u, client_entries.size());
483 EXPECT_TRUE(
484 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
485 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
486 NetLogEventType::UDP_BYTES_SENT,
487 NetLogEventPhase::NONE));
488 EXPECT_TRUE(callback_fired_);
489 EXPECT_EQ(rv_, lengths_[0]);
490
491 SendResult send_result2(0, 2, std::move(buffers_));
492 ResetWriteCallback();
493 socket_.SetWriteCallback(write_callback_);
494 EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
495
496 socket_.DidSendBuffers(std::move(send_result2));
497
498 EXPECT_EQ(0u, socket_.GetUnwrittenBuffers().size());
499 client_log_.GetEntries(&client_entries);
500 EXPECT_EQ(4u, client_entries.size());
501 EXPECT_TRUE(
502 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
503 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
504 NetLogEventType::UDP_BYTES_SENT,
505 NetLogEventPhase::NONE));
506 EXPECT_TRUE(LogContainsEvent(client_entries, 2,
507 NetLogEventType::UDP_BYTES_SENT,
508 NetLogEventPhase::NONE));
509 EXPECT_TRUE(LogContainsEvent(client_entries, 3,
510 NetLogEventType::UDP_BYTES_SENT,
511 NetLogEventPhase::NONE));
512 EXPECT_TRUE(callback_fired_);
513 EXPECT_EQ(rv_, lengths_[1] + lengths_[2]);
514}
515
516TEST_F(UDPSocketPosixTest, DidSendBuffersErrorStopWatch) {
517 AddBuffers();
518 SendResult send_result(ERR_IO_PENDING, 1, std::move(buffers_));
519 ResetWriteCallback();
520 socket_.SetWriteCallback(write_callback_);
521 EXPECT_CALL(socket_, InternalWatchFileDescriptor()).WillOnce(Return(true));
522 socket_.DidSendBuffers(std::move(send_result));
523 buffers_ = socket_.GetUnwrittenBuffers();
524 EXPECT_EQ(2u, buffers_.size());
525 TestNetLogEntry::List client_entries;
526 client_log_.GetEntries(&client_entries);
527 EXPECT_EQ(2u, client_entries.size());
528 EXPECT_TRUE(
529 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
530 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
531 NetLogEventType::UDP_BYTES_SENT,
532 NetLogEventPhase::NONE));
533 EXPECT_TRUE(callback_fired_);
534 EXPECT_EQ(rv_, lengths_[0]);
535
536 SendResult send_result2(ERR_INVALID_HANDLE, 0, std::move(buffers_));
537 ResetWriteCallback();
538 socket_.SetWriteCallback(write_callback_);
539 EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
540
541 socket_.DidSendBuffers(std::move(send_result2));
542
543 EXPECT_EQ(2u, socket_.GetUnwrittenBuffers().size());
544 client_log_.GetEntries(&client_entries);
545 EXPECT_EQ(2u, client_entries.size());
546 EXPECT_TRUE(
547 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
548 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
549 NetLogEventType::UDP_BYTES_SENT,
550 NetLogEventPhase::NONE));
551 EXPECT_TRUE(callback_fired_);
552 EXPECT_EQ(rv_, ERR_INVALID_HANDLE);
553}
554
555TEST_F(UDPSocketPosixTest, DidSendBuffersDelayCallbackWhileTooManyBuffers) {
556 for (int i = 0; i < kWriteAsyncCallbackBuffersThreshold + 2; i++) {
557 AddBuffer(msgs_[0]);
558 }
559 SendResult send_result(0, 2, std::move(buffers_));
560 ResetWriteCallback();
561 socket_.SetWriteCallback(write_callback_);
562 socket_.DidSendBuffers(std::move(send_result));
563 TestNetLogEntry::List client_entries;
564 client_log_.GetEntries(&client_entries);
565 EXPECT_EQ(3u, client_entries.size());
566 EXPECT_TRUE(
567 LogContainsBeginEvent(client_entries, 0, NetLogEventType::SOCKET_ALIVE));
568 EXPECT_TRUE(LogContainsEvent(client_entries, 1,
569 NetLogEventType::UDP_BYTES_SENT,
570 NetLogEventPhase::NONE));
571 EXPECT_TRUE(LogContainsEvent(client_entries, 2,
572 NetLogEventType::UDP_BYTES_SENT,
573 NetLogEventPhase::NONE));
574 // bytes written but no callback because socket_.pending_writes_ is full.
575 EXPECT_FALSE(callback_fired_);
576
577 // now the rest
578 buffers_ = socket_.GetUnwrittenBuffers();
579 EXPECT_EQ(kWriteAsyncCallbackBuffersThreshold,
580 static_cast<int>(buffers_.size()));
581 SendResult send_result2(0, buffers_.size(), std::move(buffers_));
582 ResetWriteCallback();
583 socket_.SetWriteCallback(write_callback_);
584 socket_.DidSendBuffers(std::move(send_result2));
585 EXPECT_TRUE(callback_fired_);
586 // rv includes bytes from previous invocation.
587 EXPECT_EQ(rv_, (kWriteAsyncCallbackBuffersThreshold + 2) * lengths_[0]);
588}
589
590TEST_F(UDPSocketPosixTest, FlushPendingLocal) {
591 socket_.SetWriteMultiCoreEnabled(false);
592 AddBuffers();
593 ExpectSends();
594 socket_.SetPendingWrites(std::move(buffers_));
595 ResetWriteCallback();
596 socket_.SetWriteCallback(write_callback_);
597 socket_.FlushPending();
598 EXPECT_TRUE(callback_fired_);
599 EXPECT_EQ(rv_, total_lengths_);
600}
601
602TEST_F(UDPSocketPosixTest, FlushPendingMultiCore) {
603 socket_.SetWriteMultiCoreEnabled(true);
604 AddBuffers();
605 ExpectSends();
606 socket_.SetPendingWrites(std::move(buffers_));
607 ResetWriteCallback();
608 socket_.SetWriteCallback(write_callback_);
609 socket_.FlushPending();
610 EXPECT_FALSE(callback_fired_);
611 RunUntilIdle();
612 EXPECT_TRUE(callback_fired_);
613 EXPECT_EQ(rv_, total_lengths_);
614}
615
616TEST_F(UDPSocketPosixTest, WriteAsyncNoBatching) {
617 socket_.SetWriteBatchingActive(false);
618 socket_.SetWriteMultiCoreEnabled(true);
619 DatagramBuffers buffers;
620 ExpectSend(0);
621 int rv = WriteAsync(0);
622 EXPECT_EQ(lengths_[0], rv);
623 ExpectSend(1);
624 rv = WriteAsync(1);
625 EXPECT_EQ(lengths_[1], rv);
626 ExpectSend(2);
627 rv = WriteAsync(2);
628 EXPECT_EQ(lengths_[2], rv);
629}
630
631TEST_F(UDPSocketPosixTest, WriteAsyncNoBatchingErrIOPending) {
632 socket_.SetWriteBatchingActive(false);
633 socket_.SetWriteMultiCoreEnabled(true);
634 DatagramBuffers buffers;
635 ExpectSend(0);
636 int rv = WriteAsync(0);
637 EXPECT_EQ(lengths_[0], rv);
638 ExpectSendWillBlock(1);
639 rv = WriteAsync(1);
640 EXPECT_EQ(ERR_IO_PENDING, rv);
641 EXPECT_CALL(socket_, InternalStopWatchingFileDescriptor());
642 ExpectSend(1);
643 socket_.OnFileCanWriteWithoutBlocking();
644 EXPECT_TRUE(callback_fired_);
645 EXPECT_EQ(rv_, lengths_[1]);
646}
647
648TEST_F(UDPSocketPosixTest, WriteAsyncNoBatchingError) {
649 socket_.SetWriteBatchingActive(false);
650 socket_.SetWriteMultiCoreEnabled(true);
651 DatagramBuffers buffers;
652 ExpectSend(0);
653 int rv = WriteAsync(0);
654 EXPECT_EQ(lengths_[0], rv);
655 ExpectSendWillError(1);
656 rv = WriteAsync(1);
657 EXPECT_EQ(ERR_INVALID_HANDLE, rv);
658}
659
660TEST_F(UDPSocketPosixTest, WriteAsyncBasicDelay) {
661 socket_.SetWriteBatchingActive(true);
662 socket_.SetWriteMultiCoreEnabled(true);
663 DatagramBuffers buffers;
664 ASSERT_LT(kWriteAsyncMinBuffersThreshold, 3);
665 ASSERT_GT(kWriteAsyncPostBuffersThreshold, 3);
666 int rv = WriteAsync(0);
667 EXPECT_EQ(0, rv);
668 rv = WriteAsync(1);
669 EXPECT_EQ(0, rv);
670 rv = WriteAsync(2);
671 EXPECT_EQ(0, rv);
672 // Cause the write async timer to fire and above writes to flush.
673 ExpectSends();
674 FastForwardBy(kWriteAsyncMsThreshold);
675 RunUntilIdle();
676 rv = WriteAsync(0);
677 EXPECT_EQ(total_lengths_, rv);
678}
679
680TEST_F(UDPSocketPosixTest, WriteAsyncPostBuffersThresholdLocal) {
681 socket_.SetWriteBatchingActive(true);
682 socket_.SetWriteMultiCoreEnabled(false);
683 DatagramBuffers buffers;
684 int rv = 0;
685 for (int i = 0; i < kWriteAsyncPostBuffersThreshold - 1; i++) {
686 WriteAsync(0);
687 EXPECT_EQ(0, rv);
688 }
689 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
690 .Times(kWriteAsyncPostBuffersThreshold)
691 .WillRepeatedly(Return(lengths_[0]));
692 rv = WriteAsync(0);
693 EXPECT_EQ(kWriteAsyncPostBuffersThreshold * lengths_[0], rv);
694}
695
696TEST_F(UDPSocketPosixTest, WriteAsyncPostBuffersThresholdRemote) {
697 socket_.SetWriteBatchingActive(true);
698 socket_.SetWriteMultiCoreEnabled(true);
699 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
700 .Times(kWriteAsyncPostBuffersThreshold)
701 .WillRepeatedly(Return(lengths_[0]));
702 DatagramBuffers buffers;
703 int rv = 0;
704 for (int i = 0; i < kWriteAsyncPostBuffersThreshold; i++) {
705 WriteAsync(0);
706 EXPECT_EQ(0, rv);
707 }
708 RunUntilIdle();
709 rv = WriteAsync(0);
710 EXPECT_EQ(kWriteAsyncPostBuffersThreshold * lengths_[0], rv);
711}
712
713TEST_F(UDPSocketPosixTest, WriteAsyncPostBlocks) {
714 socket_.SetWriteBatchingActive(true);
715 socket_.SetWriteMultiCoreEnabled(true);
716 DatagramBuffers buffers;
717 for (int i = 0; i < kWriteAsyncMaxBuffersThreshold; i++) {
718 socket_.Enqueue(msgs_[0], &buffers_);
719 }
720 EXPECT_CALL(*socket_.sender(), Send(_, _, lengths_[0], _))
721 .Times(kWriteAsyncMaxBuffersThreshold)
722 .WillRepeatedly(Return(lengths_[0]));
723 int rv = socket_.WriteAsync(std::move(buffers_), write_callback_,
724 TRAFFIC_ANNOTATION_FOR_TESTS);
725 EXPECT_EQ(ERR_IO_PENDING, rv);
726 EXPECT_FALSE(callback_fired_);
727 RunUntilIdle();
728 EXPECT_TRUE(callback_fired_);
729 EXPECT_EQ(rv_, kWriteAsyncMaxBuffersThreshold * lengths_[0]);
730}
731
732} // namespace test
733
734} // namespace net