1 | //===-- PortMapTest.cpp ---------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Testing/Support/Error.h" |
10 | #include "gmock/gmock.h" |
11 | #include "gtest/gtest.h" |
12 | |
13 | #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" |
14 | |
15 | using namespace lldb_private::process_gdb_remote; |
16 | |
17 | TEST(PortMapTest, Constructors) { |
18 | // Default construct to empty map |
19 | GDBRemoteCommunicationServerPlatform::PortMap p1; |
20 | ASSERT_TRUE(p1.empty()); |
21 | |
22 | // Empty means no restrictions, return 0 and bind to get a port |
23 | llvm::Expected<uint16_t> available_port = p1.GetNextAvailablePort(); |
24 | ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(0)); |
25 | |
26 | // Adding any port makes it not empty |
27 | p1.AllowPort(port: 1); |
28 | ASSERT_FALSE(p1.empty()); |
29 | |
30 | // So we will return the added port this time |
31 | available_port = p1.GetNextAvailablePort(); |
32 | ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(1)); |
33 | |
34 | // Construct from a range of ports |
35 | GDBRemoteCommunicationServerPlatform::PortMap p2(1, 4); |
36 | ASSERT_FALSE(p2.empty()); |
37 | |
38 | // Use up all the ports |
39 | for (uint16_t expected = 1; expected < 4; ++expected) { |
40 | available_port = p2.GetNextAvailablePort(); |
41 | ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(expected)); |
42 | p2.AssociatePortWithProcess(port: *available_port, pid: 1); |
43 | } |
44 | |
45 | // Now we fail since we're not an empty port map but all ports are used |
46 | available_port = p2.GetNextAvailablePort(); |
47 | ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); |
48 | } |
49 | |
50 | TEST(PortMapTest, FreePort) { |
51 | GDBRemoteCommunicationServerPlatform::PortMap p(1, 4); |
52 | // Use up all the ports |
53 | for (uint16_t port = 1; port < 4; ++port) { |
54 | p.AssociatePortWithProcess(port, pid: 1); |
55 | } |
56 | |
57 | llvm::Expected<uint16_t> available_port = p.GetNextAvailablePort(); |
58 | ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); |
59 | |
60 | // Can't free a port that isn't in the map |
61 | ASSERT_FALSE(p.FreePort(0)); |
62 | ASSERT_FALSE(p.FreePort(4)); |
63 | |
64 | // After freeing a port it becomes available |
65 | ASSERT_TRUE(p.FreePort(2)); |
66 | available_port = p.GetNextAvailablePort(); |
67 | ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(2)); |
68 | } |
69 | |
70 | TEST(PortMapTest, FreePortForProcess) { |
71 | GDBRemoteCommunicationServerPlatform::PortMap p; |
72 | p.AllowPort(port: 1); |
73 | p.AllowPort(port: 2); |
74 | ASSERT_TRUE(p.AssociatePortWithProcess(1, 11)); |
75 | ASSERT_TRUE(p.AssociatePortWithProcess(2, 22)); |
76 | |
77 | // All ports have been used |
78 | llvm::Expected<uint16_t> available_port = p.GetNextAvailablePort(); |
79 | ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); |
80 | |
81 | // Can't free a port for a process that doesn't have any |
82 | ASSERT_FALSE(p.FreePortForProcess(33)); |
83 | |
84 | // You can move a used port to a new pid |
85 | ASSERT_TRUE(p.AssociatePortWithProcess(1, 99)); |
86 | |
87 | ASSERT_TRUE(p.FreePortForProcess(22)); |
88 | available_port = p.GetNextAvailablePort(); |
89 | ASSERT_THAT_EXPECTED(available_port, llvm::Succeeded()); |
90 | ASSERT_EQ(2, *available_port); |
91 | |
92 | // proces 22 no longer has a port |
93 | ASSERT_FALSE(p.FreePortForProcess(22)); |
94 | } |
95 | |
96 | TEST(PortMapTest, AllowPort) { |
97 | GDBRemoteCommunicationServerPlatform::PortMap p; |
98 | |
99 | // Allow port 1 and tie it to process 11 |
100 | p.AllowPort(port: 1); |
101 | ASSERT_TRUE(p.AssociatePortWithProcess(1, 11)); |
102 | |
103 | // Allowing it a second time shouldn't change existing mapping |
104 | p.AllowPort(port: 1); |
105 | llvm::Expected<uint16_t> available_port = p.GetNextAvailablePort(); |
106 | ASSERT_THAT_EXPECTED(available_port, llvm::Failed()); |
107 | |
108 | // A new port is marked as free when allowed |
109 | p.AllowPort(port: 2); |
110 | available_port = p.GetNextAvailablePort(); |
111 | ASSERT_THAT_EXPECTED(available_port, llvm::HasValue(2)); |
112 | |
113 | // 11 should still be tied to port 1 |
114 | ASSERT_TRUE(p.FreePortForProcess(11)); |
115 | } |
116 | |