tor-tests work; refactor ports

This commit is contained in:
meejah 2023-07-29 04:04:05 -06:00
parent 6f9b9a3ac1
commit 050ef6cca3
4 changed files with 55 additions and 18 deletions

@ -7,6 +7,7 @@ from __future__ import annotations
import os import os
import sys import sys
import shutil import shutil
from attr import define
from time import sleep from time import sleep
from os import mkdir, environ from os import mkdir, environ
from os.path import join, exists from os.path import join, exists
@ -189,7 +190,7 @@ def introducer_furl(introducer, temp_dir):
include_args=["temp_dir", "flog_gatherer"], include_args=["temp_dir", "flog_gatherer"],
include_result=False, include_result=False,
) )
def tor_introducer(reactor, temp_dir, flog_gatherer, request): def tor_introducer(reactor, temp_dir, flog_gatherer, request, tor_network):
intro_dir = join(temp_dir, 'introducer_tor') intro_dir = join(temp_dir, 'introducer_tor')
print("making Tor introducer in {}".format(intro_dir)) print("making Tor introducer in {}".format(intro_dir))
print("(this can take tens of seconds to allocate Onion address)") print("(this can take tens of seconds to allocate Onion address)")
@ -203,9 +204,7 @@ def tor_introducer(reactor, temp_dir, flog_gatherer, request):
request, request,
( (
'create-introducer', 'create-introducer',
# The control port should agree with the configuration of the '--tor-control-port', tor_network.client_control_endpoint,
# Tor network we bootstrap with chutney.
'--tor-control-port', 'tcp:localhost:8007',
'--hide-ip', '--hide-ip',
'--listen=tor', '--listen=tor',
intro_dir, intro_dir,
@ -306,6 +305,21 @@ def bob(reactor, temp_dir, introducer_furl, flog_gatherer, storage_nodes, reques
@pytest.mark.skipif(sys.platform.startswith('win'), @pytest.mark.skipif(sys.platform.startswith('win'),
'Tor tests are unstable on Windows') 'Tor tests are unstable on Windows')
def chutney(reactor, temp_dir: str) -> tuple[str, dict[str, str]]: def chutney(reactor, temp_dir: str) -> tuple[str, dict[str, str]]:
"""
Instantiate the "networks/hs-v3" Chutney configuration for a local
Tor network.
This provides a small, local Tor network that can run v3 Onion
Services. This has 10 tor processes: 3 authorities, 5
exits+relays, a client (and one service-hosting node we don't use).
We pin a Chutney revision, so things shouldn't change. Currently,
the ONLY node that exposes a valid SocksPort is "008c" (the
client) on 9008.
The control ports start at 8000 (so the ControlPort for the one
client node is 8008).
"""
# Try to find Chutney already installed in the environment. # Try to find Chutney already installed in the environment.
try: try:
import chutney import chutney
@ -363,7 +377,24 @@ def chutney(reactor, temp_dir: str) -> tuple[str, dict[str, str]]:
) )
pytest_twisted.blockon(proto.done) pytest_twisted.blockon(proto.done)
return (chutney_dir, {"PYTHONPATH": join(chutney_dir, "lib")}) return chutney_dir, {"PYTHONPATH": join(chutney_dir, "lib")}
@define
class ChutneyTorNetwork:
"""
Represents a running Chutney (tor) network. Returned by the
"tor_network" fixture.
"""
dir: FilePath
environ: dict
client_control_port: int
@property
def client_control_endpoint(self) -> str:
print("CONTROL", "tcp:localhost:{}".format(self.client_control_port))
return "tcp:localhost:{}".format(self.client_control_port)
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
@ -422,3 +453,11 @@ def tor_network(reactor, temp_dir, chutney, request):
pytest_twisted.blockon(chutney(("status", basic_network))) pytest_twisted.blockon(chutney(("status", basic_network)))
except ProcessTerminated: except ProcessTerminated:
print("Chutney.TorNet status failed (continuing)") print("Chutney.TorNet status failed (continuing)")
# the "8008" comes from configuring "networks/basic" in chutney
# and then examining "net/nodes/008c/torrc" for ControlPort value
return ChutneyTorNetwork(
chutney_root,
chutney_env,
8008,
)

@ -132,8 +132,8 @@ def i2p_introducer_furl(i2p_introducer, temp_dir):
@pytest_twisted.inlineCallbacks @pytest_twisted.inlineCallbacks
@pytest.mark.skip("I2P tests are not functioning at all, for unknown reasons") @pytest.mark.skip("I2P tests are not functioning at all, for unknown reasons")
def test_i2p_service_storage(reactor, request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl): def test_i2p_service_storage(reactor, request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl):
yield _create_anonymous_node(reactor, 'carol_i2p', 8008, request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl) yield _create_anonymous_node(reactor, 'carol_i2p', request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl)
yield _create_anonymous_node(reactor, 'dave_i2p', 8009, request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl) yield _create_anonymous_node(reactor, 'dave_i2p', request, temp_dir, flog_gatherer, i2p_network, i2p_introducer_furl)
# ensure both nodes are connected to "a grid" by uploading # ensure both nodes are connected to "a grid" by uploading
# something via carol, and retrieve it using dave. # something via carol, and retrieve it using dave.
gold_path = join(temp_dir, "gold") gold_path = join(temp_dir, "gold")
@ -179,9 +179,8 @@ def test_i2p_service_storage(reactor, request, temp_dir, flog_gatherer, i2p_netw
@pytest_twisted.inlineCallbacks @pytest_twisted.inlineCallbacks
def _create_anonymous_node(reactor, name, control_port, request, temp_dir, flog_gatherer, i2p_network, introducer_furl): def _create_anonymous_node(reactor, name, request, temp_dir, flog_gatherer, i2p_network, introducer_furl):
node_dir = FilePath(temp_dir).child(name) node_dir = FilePath(temp_dir).child(name)
web_port = "tcp:{}:interface=localhost".format(control_port + 2000)
print("creating", node_dir.path) print("creating", node_dir.path)
node_dir.makedirs() node_dir.makedirs()

@ -38,8 +38,8 @@ def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer, tor_ne
The two nodes can talk to the introducer and each other: we upload to one The two nodes can talk to the introducer and each other: we upload to one
node, read from the other. node, read from the other.
""" """
carol = yield _create_anonymous_node(reactor, 'carol', 8008, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2) carol = yield _create_anonymous_node(reactor, 'carol', 8100, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2)
dave = yield _create_anonymous_node(reactor, 'dave', 8009, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2) dave = yield _create_anonymous_node(reactor, 'dave', 8101, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2)
yield util.await_client_ready(carol, minimum_number_of_servers=2, timeout=600) yield util.await_client_ready(carol, minimum_number_of_servers=2, timeout=600)
yield util.await_client_ready(dave, minimum_number_of_servers=2, timeout=600) yield util.await_client_ready(dave, minimum_number_of_servers=2, timeout=600)
yield upload_to_one_download_from_the_other(reactor, temp_dir, carol, dave) yield upload_to_one_download_from_the_other(reactor, temp_dir, carol, dave)
@ -94,9 +94,8 @@ async def upload_to_one_download_from_the_other(reactor, temp_dir, upload_to: ut
@pytest_twisted.inlineCallbacks @pytest_twisted.inlineCallbacks
def _create_anonymous_node(reactor, name, control_port, request, temp_dir, flog_gatherer, tor_network, introducer_furl, shares_total: int) -> util.TahoeProcess: def _create_anonymous_node(reactor, name, web_port, request, temp_dir, flog_gatherer, tor_network, introducer_furl, shares_total: int) -> util.TahoeProcess:
node_dir = FilePath(temp_dir).child(name) node_dir = FilePath(temp_dir).child(name)
web_port = "tcp:{}:interface=localhost".format(control_port + 2000)
if node_dir.exists(): if node_dir.exists():
raise RuntimeError( raise RuntimeError(
"A node already exists in '{}'".format(node_dir) "A node already exists in '{}'".format(node_dir)
@ -111,10 +110,10 @@ def _create_anonymous_node(reactor, name, control_port, request, temp_dir, flog_
sys.executable, '-b', '-m', 'allmydata.scripts.runner', sys.executable, '-b', '-m', 'allmydata.scripts.runner',
'create-node', 'create-node',
'--nickname', name, '--nickname', name,
'--webport', web_port, '--webport', str(web_port),
'--introducer', introducer_furl, '--introducer', introducer_furl,
'--hide-ip', '--hide-ip',
'--tor-control-port', 'tcp:localhost:{}'.format(control_port), '--tor-control-port', tor_network.client_control_endpoint,
'--listen', 'tor', '--listen', 'tor',
'--shares-needed', '1', '--shares-needed', '1',
'--shares-happy', '1', '--shares-happy', '1',
@ -133,7 +132,7 @@ def _create_anonymous_node(reactor, name, control_port, request, temp_dir, flog_
config = read_config(node_dir.path, "tub.port") config = read_config(node_dir.path, "tub.port")
config.set_config("tor", "onion", "true") config.set_config("tor", "onion", "true")
config.set_config("tor", "onion.external_port", "3457") config.set_config("tor", "onion.external_port", "3457")
config.set_config("tor", "control.port", f"tcp:port={control_port}:host=127.0.0.1") config.set_config("tor", "control.port", tor_network.client_control_endpoint)
config.set_config("tor", "onion.private_key_file", "private/tor_onion.privkey") config.set_config("tor", "onion.private_key_file", "private/tor_onion.privkey")
print("running") print("running")
@ -159,7 +158,7 @@ def test_anonymous_client(reactor, request, temp_dir, flog_gatherer, tor_network
) )
yield util.await_client_ready(normie) yield util.await_client_ready(normie)
anonymoose = yield _create_anonymous_node(reactor, 'anonymoose', 8008, request, temp_dir, flog_gatherer, tor_network, introducer_furl, 1) anonymoose = yield _create_anonymous_node(reactor, 'anonymoose', 8102, request, temp_dir, flog_gatherer, tor_network, introducer_furl, 1)
yield util.await_client_ready(anonymoose, minimum_number_of_servers=1, timeout=600) yield util.await_client_ready(anonymoose, minimum_number_of_servers=1, timeout=600)
yield upload_to_one_download_from_the_other(reactor, temp_dir, normie, anonymoose) yield upload_to_one_download_from_the_other(reactor, temp_dir, normie, anonymoose)

@ -659,7 +659,7 @@ def await_client_ready(tahoe, timeout=10, liveness=60*2, minimum_number_of_serve
print( print(
f"Now: {time.ctime()}\n" f"Now: {time.ctime()}\n"
f"Server last-received-data: {[time.ctime(s['last_received_data']) for s in servers]}" f"Server last-received-data: {[s['last_received_data'] for s in servers]}"
) )
server_times = [ server_times = [