blob: 5c73d1468e76a86c76766bd1d2bcde9b857afbed [file] [log] [blame]
Ryan Keanedeb48b32019-06-28 16:24:40 -07001// Copyright 2019 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 "platform/api/udp_socket.h"
6
7#include "gtest/gtest.h"
Ryan Keanea4dfaa12019-08-19 10:30:20 -07008#include "platform/api/time.h"
9#include "platform/test/fake_clock.h"
10#include "platform/test/fake_task_runner.h"
Ryan Keanedeb48b32019-06-28 16:24:40 -070011#include "platform/test/mock_udp_socket.h"
12
13namespace openscreen {
14namespace platform {
15
16// Under some conditions, calling a callback can result in an exception
17// "terminate called after throwing an instance of 'std::bad_function_call'"
18// which will then crash the running code. This test ensures that deleting a
19// new, unmodified UDP Socket object doesn't hit this edge case.
20TEST(UdpSocketTest, TestDeletionWithoutCallbackSet) {
Ryan Keanea4dfaa12019-08-19 10:30:20 -070021 FakeClock clock(Clock::now());
22 FakeTaskRunner task_runner(&clock);
23 MockUdpSocket::MockClient client;
24 UdpSocket* socket =
25 new MockUdpSocket(&task_runner, &client, UdpSocket::Version::kV4);
Ryan Keanedeb48b32019-06-28 16:24:40 -070026 delete socket;
27}
28
29TEST(UdpSocketTest, TestCallbackCalledOnDeletion) {
Ryan Keanea4dfaa12019-08-19 10:30:20 -070030 FakeClock clock(Clock::now());
31 FakeTaskRunner task_runner(&clock);
32 MockUdpSocket::MockClient client;
33 UdpSocket* socket =
34 new MockUdpSocket(&task_runner, &client, UdpSocket::Version::kV4);
Ryan Keanedeb48b32019-06-28 16:24:40 -070035 int call_count = 0;
36 std::function<void(UdpSocket*)> callback = [&call_count](UdpSocket* socket) {
37 call_count++;
38 };
39 socket->SetDeletionCallback(callback);
40
41 EXPECT_EQ(call_count, 0);
42 delete socket;
43
44 EXPECT_EQ(call_count, 1);
45}
46
Yuri Wiitalade01e532019-08-06 18:12:02 -070047// Tests that a UdpSocket that does not specify any address or port will
48// successfully Bind(), and that the operating system will return the
49// auto-assigned socket name (i.e., the local endpoint's port will not be zero).
50TEST(UdpSocketTest, ResolvesLocalEndpoint_IPv4) {
51 const uint8_t kIpV4AddrAny[4] = {};
Ryan Keanea4dfaa12019-08-19 10:30:20 -070052 FakeClock clock(Clock::now());
53 FakeTaskRunner task_runner(&clock);
54 MockUdpSocket::MockClient client;
55 ErrorOr<UdpSocketUniquePtr> create_result = UdpSocket::Create(
56 &task_runner, &client, IPEndpoint{IPAddress(kIpV4AddrAny), 0});
Yuri Wiitalade01e532019-08-06 18:12:02 -070057 ASSERT_TRUE(create_result) << create_result.error();
58 const auto socket = create_result.MoveValue();
59 const Error bind_result = socket->Bind();
60 ASSERT_TRUE(bind_result.ok()) << bind_result;
61 const IPEndpoint local_endpoint = socket->GetLocalEndpoint();
62 EXPECT_NE(local_endpoint.port, 0) << local_endpoint;
63}
64
65// Tests that a UdpSocket that does not specify any address or port will
66// successfully Bind(), and that the operating system will return the
67// auto-assigned socket name (i.e., the local endpoint's port will not be zero).
68TEST(UdpSocketTest, ResolvesLocalEndpoint_IPv6) {
69 const uint8_t kIpV6AddrAny[16] = {};
Ryan Keanea4dfaa12019-08-19 10:30:20 -070070 FakeClock clock(Clock::now());
71 FakeTaskRunner task_runner(&clock);
72 MockUdpSocket::MockClient client;
73 ErrorOr<UdpSocketUniquePtr> create_result = UdpSocket::Create(
74 &task_runner, &client, IPEndpoint{IPAddress(kIpV6AddrAny), 0});
Yuri Wiitalade01e532019-08-06 18:12:02 -070075 ASSERT_TRUE(create_result) << create_result.error();
76 const auto socket = create_result.MoveValue();
77 const Error bind_result = socket->Bind();
78 ASSERT_TRUE(bind_result.ok()) << bind_result;
79 const IPEndpoint local_endpoint = socket->GetLocalEndpoint();
80 EXPECT_NE(local_endpoint.port, 0) << local_endpoint;
81}
82
Ryan Keanedeb48b32019-06-28 16:24:40 -070083} // namespace platform
84} // namespace openscreen