source: trunk/integration/test_tor.py

Last change on this file was 5dfc39c, checked in by Itamar Turner-Trauring <itamar@…>, at 2023-11-20T22:44:56Z

Skip on 3.12

  • Property mode set to 100644
File size: 6.0 KB
Line 
1"""
2Ported to Python 3.
3"""
4
5import sys
6from os.path import join
7from os import environ
8
9import pytest
10import pytest_twisted
11
12from . import util
13
14from twisted.python.filepath import (
15    FilePath,
16)
17
18from allmydata.test.common import (
19    write_introducer,
20)
21from allmydata.client import read_config
22from allmydata.util.deferredutil import async_to_deferred
23
24# see "conftest.py" for the fixtures (e.g. "tor_network")
25
26# XXX: Integration tests that involve Tor do not run reliably on
27# Windows.  They are skipped for now, in order to reduce CI noise.
28#
29# https://tahoe-lafs.org/trac/tahoe-lafs/ticket/3347
30if sys.platform.startswith('win'):
31    pytest.skip('Skipping Tor tests on Windows', allow_module_level=True)
32
33@pytest.mark.skipif(sys.version_info[:2] > (3, 11), reason='Chutney still does not support 3.12')
34@pytest_twisted.inlineCallbacks
35def test_onion_service_storage(reactor, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl):
36    """
37    Two nodes and an introducer all configured to use Tahoe.
38
39    The two nodes can talk to the introducer and each other: we upload to one
40    node, read from the other.
41    """
42    carol = yield _create_anonymous_node(reactor, 'carol', 8100, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2)
43    dave = yield _create_anonymous_node(reactor, 'dave', 8101, request, temp_dir, flog_gatherer, tor_network, tor_introducer_furl, 2)
44    yield util.await_client_ready(carol, minimum_number_of_servers=2, timeout=600)
45    yield util.await_client_ready(dave, minimum_number_of_servers=2, timeout=600)
46    yield upload_to_one_download_from_the_other(reactor, temp_dir, carol, dave)
47
48
49@async_to_deferred
50async def upload_to_one_download_from_the_other(reactor, temp_dir, upload_to: util.TahoeProcess, download_from: util.TahoeProcess):
51    """
52    Ensure both nodes are connected to "a grid" by uploading something via one
53    node, and retrieve it using the other.
54    """
55
56    gold_path = join(temp_dir, "gold")
57    with open(gold_path, "w") as f:
58        f.write(
59            "The object-capability model is a computer security model. A "
60            "capability describes a transferable right to perform one (or "
61            "more) operations on a given object."
62        )
63    # XXX could use treq or similar to POST these to their respective
64    # WUIs instead ...
65
66    proto = util._CollectOutputProtocol()
67    reactor.spawnProcess(
68        proto,
69        sys.executable,
70        (
71            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
72            '-d', upload_to.node_dir,
73            'put', gold_path,
74        ),
75        env=environ,
76    )
77    await proto.done
78    cap = proto.output.getvalue().strip().split()[-1]
79    print("capability: {}".format(cap))
80
81    proto = util._CollectOutputProtocol(capture_stderr=False)
82    reactor.spawnProcess(
83        proto,
84        sys.executable,
85        (
86            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
87            '-d', download_from.node_dir,
88            'get', cap,
89        ),
90        env=environ,
91    )
92    await proto.done
93    download_got = proto.output.getvalue().strip()
94    assert download_got == open(gold_path, 'rb').read().strip()
95
96
97@pytest_twisted.inlineCallbacks
98def _create_anonymous_node(reactor, name, web_port, request, temp_dir, flog_gatherer, tor_network, introducer_furl, shares_total: int) -> util.TahoeProcess:
99    node_dir = FilePath(temp_dir).child(name)
100    if node_dir.exists():
101        raise RuntimeError(
102            "A node already exists in '{}'".format(node_dir)
103        )
104    print(f"creating {node_dir.path} with introducer {introducer_furl}")
105    node_dir.makedirs()
106    proto = util._DumpOutputProtocol(None)
107    reactor.spawnProcess(
108        proto,
109        sys.executable,
110        (
111            sys.executable, '-b', '-m', 'allmydata.scripts.runner',
112            'create-node',
113            '--nickname', name,
114            '--webport', str(web_port),
115            '--introducer', introducer_furl,
116            '--hide-ip',
117            '--tor-control-port', tor_network.client_control_endpoint,
118            '--listen', 'tor',
119            '--shares-needed', '1',
120            '--shares-happy', '1',
121            '--shares-total', str(shares_total),
122            node_dir.path,
123        ),
124        env=environ,
125        )
126    yield proto.done
127
128
129    # Which services should this client connect to?
130    write_introducer(node_dir, "default", introducer_furl)
131    util.basic_node_configuration(request, flog_gatherer.furl, node_dir.path)
132
133    config = read_config(node_dir.path, "tub.port")
134    config.set_config("tor", "onion", "true")
135    config.set_config("tor", "onion.external_port", "3457")
136    config.set_config("tor", "control.port", tor_network.client_control_endpoint)
137    config.set_config("tor", "onion.private_key_file", "private/tor_onion.privkey")
138
139    print("running")
140    result = yield util._run_node(reactor, node_dir.path, request, None)
141    print("okay, launched")
142    return result
143
144@pytest.mark.skipif(sys.version_info[:2] > (3, 11), reason='Chutney still does not support 3.12')
145@pytest.mark.skipif(sys.platform.startswith('darwin'), reason='This test has issues on macOS')
146@pytest_twisted.inlineCallbacks
147def test_anonymous_client(reactor, request, temp_dir, flog_gatherer, tor_network, introducer_furl):
148    """
149    A normal node (normie) and a normal introducer are configured, and one node
150    (anonymoose) which is configured to be anonymous by talking via Tor.
151
152    Anonymoose should be able to communicate with normie.
153
154    TODO how to ensure that anonymoose is actually using Tor?
155    """
156    normie = yield util._create_node(
157        reactor, request, temp_dir, introducer_furl, flog_gatherer, "normie",
158        web_port="tcp:9989:interface=localhost",
159        storage=True, needed=1, happy=1, total=1,
160    )
161    yield util.await_client_ready(normie)
162
163    anonymoose = yield _create_anonymous_node(reactor, 'anonymoose', 8102, request, temp_dir, flog_gatherer, tor_network, introducer_furl, 1)
164    yield util.await_client_ready(anonymoose, minimum_number_of_servers=1, timeout=600)
165
166    yield upload_to_one_download_from_the_other(reactor, temp_dir, normie, anonymoose)
Note: See TracBrowser for help on using the repository browser.