Skip to content

Commit 4547443

Browse files
camillobruniV8 LUCI CQ
authored andcommitted
Only access port forwarding via PortScope
This is in preparation of adding custom port-manager subclasses for LinuxSSH and ADB platforms. Change-Id: If7ebad712732920ca4edf59237b25da0e6f5b229 Reviewed-on: https://chromium-review.googlesource.com/c/crossbench/+/6652280 Commit-Queue: Camillo Bruni <[email protected]> Reviewed-by: Patrick Thier <[email protected]>
1 parent f26ceaf commit 4547443

File tree

5 files changed

+65
-45
lines changed

5 files changed

+65
-45
lines changed

crossbench/plt/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from crossbench.plt import proc_helper
3636
from crossbench.plt.arch import MachineArch
3737
from crossbench.plt.bin import Binary
38-
from crossbench.plt.port_manager import PortManager
38+
from crossbench.plt.port_manager import PortManager, PortScope
3939
from crossbench.plt.remote import RemotePopen
4040

4141
if TYPE_CHECKING:
@@ -571,8 +571,8 @@ def default_tmp_dir(self) -> pth.AnyPath:
571571
return self.path(tempfile.gettempdir())
572572

573573
@property
574-
def ports(self) -> PortManager:
575-
return self._default_port_manager
574+
def ports(self) -> PortScope:
575+
return self._default_port_manager.scope
576576

577577
def port_forward(self, local_port: int, remote_port: int) -> int:
578578
""" Forwards a device remote_port to a local port."""

crossbench/plt/port_manager.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@ class PortScope:
2727
"""
2828

2929
def __init__(self,
30-
platform: Platform,
30+
manager: PortManager,
3131
parent_scope: Self | None = None) -> None:
32-
self._platform = platform
32+
self._manager: PortManager = manager
3333
self._parent_scope: Self | None = parent_scope
3434
assert parent_scope is not self
3535
self.forwarded_ports: dict[int, int] = {}
3636
self.reverse_forwarded_ports: dict[int, int] = {}
3737

38+
@property
39+
def platform(self) -> Platform:
40+
return self._manager.platform
41+
3842
@property
3943
def is_nested(self) -> bool:
4044
return self._parent_scope is not None
@@ -43,6 +47,11 @@ def is_nested(self) -> bool:
4347
def is_empty(self) -> bool:
4448
return not self.forwarded_ports and not self.reverse_forwarded_ports
4549

50+
@contextlib.contextmanager
51+
def nested(self) -> Iterator[PortScope]:
52+
with self._manager.nested() as scope:
53+
yield scope
54+
4655
def is_forwarded_port_used(self, local_port: int) -> bool:
4756
return bool(self.lookup_forwarded_port(local_port))
4857

@@ -72,7 +81,7 @@ def forward(self, local_port: int, remote_port: int) -> int:
7281
raise PortForwardException(
7382
f"Cannot forward local port {local_port} twice, "
7483
"it is already forwarded.")
75-
local_port = self._platform.port_forward(local_port, remote_port)
84+
local_port = self.platform.port_forward(local_port, remote_port)
7685
self.forwarded_ports[local_port] = remote_port
7786
return local_port
7887

@@ -82,14 +91,14 @@ def stop_forward(self, local_port: int) -> None:
8291
f"Cannot stop forwarding local port {local_port}, "
8392
f"it was never forwarded.")
8493
del self.forwarded_ports[local_port]
85-
self._platform.stop_port_forward(local_port)
94+
self.platform.stop_port_forward(local_port)
8695

8796
def reverse_forward(self, remote_port: int, local_port: int) -> int:
8897
if self.is_reverse_forwarded_port_used(remote_port):
8998
raise PortForwardException(
9099
f"Cannot reverse forward remote port {remote_port} twice, "
91100
"it is already forwarded.")
92-
remote_port = self._platform.reverse_port_forward(remote_port, local_port)
101+
remote_port = self.platform.reverse_port_forward(remote_port, local_port)
93102
self.reverse_forwarded_ports[remote_port] = local_port
94103
return remote_port
95104

@@ -99,7 +108,7 @@ def stop_reverse_forward(self, remote_port: int) -> None:
99108
f"Cannot stop reverse forwarding remote port {remote_port}, "
100109
f"it was never forwarded.")
101110
del self.reverse_forwarded_ports[remote_port]
102-
self._platform.stop_reverse_port_forward(remote_port)
111+
self.platform.stop_reverse_port_forward(remote_port)
103112

104113

105114
class PortManager:
@@ -120,11 +129,11 @@ class PortManager:
120129
"""
121130

122131
def __init__(self, platform: Platform, throw: bool = False) -> None:
123-
self._platform = platform
124-
self._throw = throw
132+
self._platform: Platform = platform
133+
self._throw: bool = throw
125134
self._is_active: bool = False
126135
# Keeps track of scoped ports.
127-
self._port_scope: PortScope = PortScope(self._platform, None)
136+
self._port_scope: PortScope = PortScope(self, None)
128137
self._start()
129138

130139
def _start(self):
@@ -137,14 +146,18 @@ def _start(self):
137146
def scope(self) -> PortScope:
138147
return self._port_scope
139148

149+
@property
150+
def platform(self) -> Platform:
151+
return self._platform
152+
140153
@contextlib.contextmanager
141-
def nested(self) -> Iterator[PortManager]:
154+
def nested(self) -> Iterator[PortScope]:
142155
"""Open a nested port scope, all forwarded ports that were opened
143156
during this scope will be closed when leaving the scope. """
144157
old_scope = self._port_scope
145-
self._port_scope = PortScope(self._platform, self._port_scope)
158+
self._port_scope = PortScope(self, self._port_scope)
146159
try:
147-
yield self
160+
yield self._port_scope
148161
finally:
149162
try:
150163
self._stop_current_scoped_ports()

crossbench/probes/web_page_replay/recorder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def __init__(self, probe: WebPageReplayProbe, run: Run) -> None:
213213
})
214214
self._recorder = WprRecorder(**kwargs)
215215
self._browser_platform = run.browser_platform
216-
self._ports: PortScope = run.host_platform.ports.scope
216+
self._ports: PortScope = run.host_platform.ports
217217

218218
@override
219219
def setup(self) -> None:
@@ -245,7 +245,7 @@ def _setup_port_forwarding(self) -> None:
245245
if self._browser_platform.is_remote:
246246
# TODO: Fix run.setup and teardown layering so they they're called with
247247
# the same active port scope.
248-
self._ports = self._browser_platform.ports.scope
248+
self._ports = self._browser_platform.ports
249249
self._ports.reverse_forward(self._recorder.http_port,
250250
self._recorder.http_port)
251251
self._ports.reverse_forward(self._recorder.https_port,

tests/crossbench/mock_helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from crossbench.plt.linux import LinuxPlatform, RemoteLinuxPlatform
2828
from crossbench.plt.linux_ssh import LinuxSshPlatform
2929
from crossbench.plt.macos import MacOSPlatform
30+
from crossbench.plt.port_manager import PortManager
3031
from crossbench.plt.win import WinPlatform
3132
from crossbench.runner.run import Run
3233
from crossbench.stories.story import Story
@@ -94,6 +95,10 @@ def __init__(self, *args, is_battery_powered=False, **kwargs):
9495
def has_display(self) -> bool:
9596
return True
9697

98+
@property
99+
def port_manager(self) -> PortManager:
100+
return self._default_port_manager
101+
97102
def os_details(self):
98103
return {
99104
"system": "mock os system",

tests/crossbench/plt/test_port_manager.py

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import unittest
88

9-
from crossbench.plt.port_manager import PortForwardException
9+
from crossbench.plt.port_manager import PortForwardException, PortManager
1010
from tests import test_helper
1111
from tests.crossbench.mock_helper import LinuxMockPlatform
1212

@@ -49,33 +49,35 @@ class PortManagerTestCase(unittest.TestCase):
4949
def setUp(self):
5050
super().setUp()
5151
self.platform = FakePortLinuxMockPlatform()
52-
self.port_manager = self.platform.ports
53-
self.port_manager.assert_is_active()
52+
self.port_scope = self.platform.ports
53+
self.port_manager: PortManager = self.platform.port_manager
5454

5555
def tearDown(self):
5656
self.assertFalse(self.platform.forwarded_ports)
5757
self.assertFalse(self.platform.reverse_forwarded_ports)
58-
self.assertTrue(self.port_manager.is_empty)
58+
self.assertTrue(self.port_scope.is_empty)
5959
super().tearDown()
6060

6161
def test_default(self):
62-
self.assertTrue(self.port_manager.is_empty)
62+
self.assertTrue(self.port_scope.is_empty)
6363
self.assertFalse(self.port_manager.has_nested_scopes)
64-
self.port_manager.assert_is_active()
6564

6665
def test_nested(self):
67-
with self.port_manager.nested():
66+
self.assertTrue(self.port_scope.is_empty)
67+
with self.port_scope.nested() as scope:
6868
self.assertFalse(self.port_manager.is_empty)
69+
self.assertTrue(self.port_scope.is_empty)
70+
self.assertTrue(scope.is_empty)
6971
self.assertTrue(self.port_manager.has_nested_scopes)
70-
self.port_manager.assert_is_active()
72+
self.assertTrue(self.port_scope.is_empty)
7173

7274
def test_stop(self):
7375
self.port_manager.stop()
74-
self.assertTrue(self.port_manager.is_empty)
76+
self.assertTrue(self.port_scope.is_empty)
7577
self.assertFalse(self.port_manager.has_nested_scopes)
7678

7779
def test_forward_port(self):
78-
with self.port_manager.nested() as port_scope:
80+
with self.port_scope.nested() as port_scope:
7981
returned_local_port = port_scope.forward(12345, 8080)
8082
self.assertEqual(returned_local_port, 12345)
8183
self.assertIn(12345, self.platform.forwarded_ports)
@@ -85,90 +87,90 @@ def test_forward_port(self):
8587
self.assertTrue(port_scope.is_empty)
8688

8789
def test_forward_port_auto_assign(self):
88-
with self.port_manager.nested() as port_scope:
90+
with self.port_scope.nested() as port_scope:
8991
returned_local_port = port_scope.forward(0, 8080)
9092
self.assertEqual(returned_local_port, 60001)
9193
self.assertIn(60001, self.platform.forwarded_ports)
9294

9395
def test_stop_forward_port(self):
94-
with self.port_manager.nested() as port_scope:
96+
with self.port_scope.nested() as port_scope:
9597
port_scope.forward(12345, 8080)
9698
port_scope.stop_forward(12345)
9799
self.assertNotIn(12345, self.platform.forwarded_ports)
98100

99101
def test_forward_port_conflict(self):
100-
with self.port_manager.nested() as port_scope:
102+
with self.port_scope.nested() as port_scope:
101103
port_scope.forward(12345, 8080)
102104
with self.assertRaises(PortForwardException):
103105
# Try to forward same local port
104106
port_scope.forward(12345, 8081)
105107

106108
def test_stop_forward_port_not_forwarded(self):
107-
with self.port_manager.nested() as port_scope:
109+
with self.port_scope.nested() as port_scope:
108110
with self.assertRaises(PortForwardException):
109111
port_scope.stop_forward(12345)
110112

111113
def test_reverse_forward_port(self):
112-
with self.port_manager.nested() as port_scope:
114+
with self.port_scope.nested() as port_scope:
113115
returned_remote_port = port_scope.reverse_forward(54321, 8081)
114116
self.assertEqual(returned_remote_port, 54321)
115117
self.assertIn(54321, self.platform.reverse_forwarded_ports)
116118
self.assertEqual(self.platform.reverse_forwarded_ports[54321], 8081)
117119
self.assertFalse(port_scope.is_empty)
118120

119121
def test_reverse_forward_port_auto_assign(self):
120-
with self.port_manager.nested() as port_scope:
122+
with self.port_scope.nested() as port_scope:
121123
returned_remote_port = port_scope.reverse_forward(0, 8081)
122124
self.assertEqual(returned_remote_port, 60001)
123125
self.assertIn(60001, self.platform.reverse_forwarded_ports)
124126

125127
def test_stop_reverse_forward_port(self):
126-
with self.port_manager.nested() as port_scope:
128+
with self.port_scope.nested() as port_scope:
127129
port_scope.reverse_forward(54321, 8081)
128130
port_scope.stop_reverse_forward(54321)
129131
self.assertNotIn(54321, self.platform.reverse_forwarded_ports)
130132

131133
def test_reverse_forward_port_conflict(self):
132-
with self.port_manager.nested() as port_scope:
134+
with self.port_scope.nested() as port_scope:
133135
port_scope.reverse_forward(54321, 8081)
134136
with self.assertRaises(PortForwardException):
135137
# Try to reverse forward same remote port
136138
port_scope.reverse_forward(54321, 8082)
137139

138140
def test_stop_reverse_forward_port_not_forwarded(self):
139-
with self.port_manager.nested() as port_scope:
141+
with self.port_scope.nested() as port_scope:
140142
with self.assertRaises(PortForwardException):
141143
port_scope.stop_reverse_forward(54321)
142144

143145
def test_nested_cleanup(self):
144-
self.port_manager.forward(1111, 2222)
145-
with self.port_manager.nested() as port_scope:
146+
self.port_scope.forward(1111, 2222)
147+
with self.port_scope.nested() as port_scope:
146148
port_scope.forward(3333, 4444)
147149
self.assertIn(1111, self.platform.forwarded_ports)
148150
self.assertNotIn(3333, self.platform.forwarded_ports)
149151
self.assertFalse(self.port_manager.has_nested_scopes)
150152
self.port_manager.stop()
151-
self.assertTrue(self.port_manager.is_empty)
153+
self.assertTrue(self.port_scope.is_empty)
152154
self.assertNotIn(1111, self.platform.forwarded_ports)
153155
self.assertNotIn(3333, self.platform.forwarded_ports)
154156

155157
def test_forward_nested_cleanup_stop_outer(self):
156-
self.port_manager.forward(1111, 2222)
157-
with self.port_manager.nested() as port_scope:
158+
self.port_scope.forward(1111, 2222)
159+
with self.port_scope.nested() as port_scope:
158160
port_scope.forward(3333, 4444)
159161
port_scope.stop_forward(3333)
160162
with self.assertRaisesRegex(PortForwardException, "1111"):
161163
port_scope.stop_forward(1111)
162-
self.port_manager.stop_forward(1111)
164+
self.port_scope.stop_forward(1111)
163165

164166
def test_reverse_forward_nested_cleanup_stop_outer(self):
165-
self.port_manager.reverse_forward(1111, 2222)
166-
with self.port_manager.nested() as port_scope:
167+
self.port_scope.reverse_forward(1111, 2222)
168+
with self.port_scope.nested() as port_scope:
167169
port_scope.reverse_forward(3333, 4444)
168170
port_scope.stop_reverse_forward(3333)
169171
with self.assertRaisesRegex(PortForwardException, "1111"):
170172
port_scope.stop_reverse_forward(1111)
171-
self.port_manager.stop_reverse_forward(1111)
173+
self.port_scope.stop_reverse_forward(1111)
172174

173175

174176
if __name__ == "__main__":

0 commit comments

Comments
 (0)