From add510701c0809cf89494434c1dccdfc3271df47 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Wed, 16 Nov 2022 11:44:51 -0500 Subject: [PATCH] Run integration tests both with and without HTTP storage protocol. --- .github/workflows/ci.yml | 6 +++++- integration/util.py | 17 +++++++++-------- newsfragments/3937.minor | 0 src/allmydata/protocol_switch.py | 16 ++++++++++++++++ src/allmydata/testing/__init__.py | 18 ++++++++++++++++++ 5 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 newsfragments/3937.minor diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0327014ca..26574066c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -229,7 +229,11 @@ jobs: # aren't too long. On Windows tox won't pass it through so it has no # effect. On Linux it doesn't make a difference one way or another. TMPDIR: "/tmp" - run: tox -e integration + run: | + # Run with Foolscap forced: + __TAHOE_INTEGRATION_FORCE_FOOLSCAP=1 tox -e integration + # Run with Foolscap not forced, which should result in HTTP being used. + __TAHOE_INTEGRATION_FORCE_FOOLSCAP=0 tox -e integration - name: Upload eliot.log in case of failure uses: actions/upload-artifact@v1 diff --git a/integration/util.py b/integration/util.py index ad9249e45..cde837218 100644 --- a/integration/util.py +++ b/integration/util.py @@ -1,14 +1,6 @@ """ Ported to Python 3. """ -from __future__ import unicode_literals -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -from future.utils import PY2 -if PY2: - from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401 import sys import time @@ -38,6 +30,7 @@ from allmydata.util.configutil import ( write_config, ) from allmydata import client +from allmydata.testing import foolscap_only_for_integration_testing import pytest_twisted @@ -300,6 +293,14 @@ def _create_node(reactor, request, temp_dir, introducer_furl, flog_gatherer, nam u'log_gatherer.furl', flog_gatherer, ) + force_foolscap = foolscap_only_for_integration_testing() + if force_foolscap is not None: + set_config( + config, + 'storage', + 'force_foolscap', + str(force_foolscap), + ) write_config(FilePath(config_path), config) created_d.addCallback(created) diff --git a/newsfragments/3937.minor b/newsfragments/3937.minor new file mode 100644 index 000000000..e69de29bb diff --git a/src/allmydata/protocol_switch.py b/src/allmydata/protocol_switch.py index b0af84c33..d88863fdb 100644 --- a/src/allmydata/protocol_switch.py +++ b/src/allmydata/protocol_switch.py @@ -30,6 +30,7 @@ from foolscap.api import Tub from .storage.http_server import HTTPServer, build_nurl from .storage.server import StorageServer +from .testing import foolscap_only_for_integration_testing class _PretendToBeNegotiation(type): @@ -170,6 +171,21 @@ class _FoolscapOrHttps(Protocol, metaclass=_PretendToBeNegotiation): # and later data, otherwise assume HTTPS. self._timeout.cancel() if self._buffer.startswith(b"GET /id/"): + if foolscap_only_for_integration_testing() == False: + # Tahoe will prefer HTTP storage protocol over Foolscap when possible. + # + # If this is branch is taken, we are running a test that should + # be using HTTP for the storage protocol. As such, we + # aggressively disable Foolscap to ensure that HTTP is in fact + # going to be used. If we hit this branch that means our + # expectation that HTTP will be used was wrong, suggesting a + # bug in either the code of the integration testing setup. + # + # This branch should never be hit in production! + self.transport.loseConnection() + print("FOOLSCAP IS DISABLED, I PITY THE FOOLS WHO SEE THIS MESSAGE") + return + # We're a Foolscap Negotiation server protocol instance: transport = self.transport buf = self._buffer diff --git a/src/allmydata/testing/__init__.py b/src/allmydata/testing/__init__.py index e69de29bb..119ae4101 100644 --- a/src/allmydata/testing/__init__.py +++ b/src/allmydata/testing/__init__.py @@ -0,0 +1,18 @@ +import os +from typing import Optional + + +def foolscap_only_for_integration_testing() -> Optional[bool]: + """ + Return whether HTTP storage protocol has been disabled / Foolscap + forced, for purposes of integration testing. + + This is determined by the __TAHOE_INTEGRATION_FORCE_FOOLSCAP environment + variable, which can be 1, 0, or not set, corresponding to results of + ``True``, ``False`` and ``None`` (i.e. default). + """ + force_foolscap = os.environ.get("__TAHOE_INTEGRATION_FORCE_FOOLSCAP") + if force_foolscap is None: + return None + + return bool(int(force_foolscap))