Skip to content

Commit 09bf3f5

Browse files
committed
Migrate tests from trial to pytest + pytest-asyncio
1 parent 8f3940d commit 09bf3f5

30 files changed

+2085
-2670
lines changed

.github/workflows/pipeline.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,31 @@ jobs:
7373
strategy:
7474
matrix:
7575
python-version: ['3.10', '3.13']
76-
test-dir: ['tests', 'matrix_is_tester']
7776

7877
steps:
7978
- uses: actions/checkout@v6
8079
- uses: astral-sh/setup-uv@v5
8180
with:
8281
python-version: ${{ matrix.python-version }}
83-
- run: uv run trial ${{ matrix.test-dir }}
82+
- run: uv run pytest tests/
83+
84+
# matrix_is_tester is a black-box integration test suite that launches
85+
# Sydent as a subprocess and makes HTTP requests against it.
86+
run-integration-tests:
87+
name: Integration Tests
88+
if: ${{ !cancelled() && !failure() }}
89+
needs: [check-newsfile, checks]
90+
runs-on: ubuntu-latest
91+
strategy:
92+
matrix:
93+
python-version: ['3.10', '3.13']
94+
95+
steps:
96+
- uses: actions/checkout@v6
97+
- uses: astral-sh/setup-uv@v5
98+
with:
99+
python-version: ${{ matrix.python-version }}
100+
- run: uv run pytest --pyargs matrix_is_tester
84101

85102
# a job which runs once all the other jobs are complete, thus allowing PRs to
86103
# be merged.
@@ -90,6 +107,7 @@ jobs:
90107
- check-newsfile
91108
- checks
92109
- run-tests
110+
- run-integration-tests
93111
runs-on: ubuntu-latest
94112
steps:
95113
- uses: matrix-org/done-action@v3

integration-tests/matrix_is_tester/is_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def agree_to_terms(self, user_accepts):
182182
return resp.json()
183183

184184
def get_versions(self):
185-
resp = requests.get(self.base_url + "/versions")
185+
resp = requests.get(self.base_url + "/_matrix/identity/versions")
186186
return resp.json()
187187

188188
def register(self, matrix_server_name, access_token):

integration-tests/matrix_is_tester/mailsink.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import asyncio
1615
import atexit
16+
import threading
1717
from multiprocessing import Process, Queue
1818

1919
from aiosmtpd.controller import Controller
@@ -55,23 +55,19 @@ def _run_mail_sink(q):
5555
handler = _MailSinkHandler(q)
5656
controller = Controller(handler, hostname="127.0.0.1", port=9925)
5757
controller.start()
58-
# Block forever (the controller runs in a thread)
59-
try:
60-
asyncio.get_event_loop().run_forever()
61-
except KeyboardInterrupt:
62-
pass
63-
finally:
64-
controller.stop()
58+
# Block until terminated
59+
threading.Event().wait()
6560

6661

6762
class MailSink:
6863
def launch(self):
6964
self.queue = Queue()
7065
self.process = Process(target=_run_mail_sink, args=(self.queue,))
66+
self.process.daemon = True
7167
self.process.start()
7268

7369
def get_mail(self):
74-
return self.queue.get(timeout=2.0)
70+
return self.queue.get(timeout=5.0)
7571

7672
def tearDown(self):
7773
self.process.terminate()

integration-tests/matrix_is_tester/test_versions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def test_versions(self):
3535
body = self.api.get_versions()
3636

3737
self.assertIn("versions", body)
38-
self.assertIn(["v1.1"], body["versions"])
38+
self.assertIn("v1.1", body["versions"])
3939

4040

4141
if __name__ == "__main__":

sydent/http/servlets/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ async def get_args(
8888
body = await request.read()
8989
request_args = json_decoder.decode(body.decode("UTF-8"))
9090
except ValueError:
91-
raise MatrixRestError(400, "M_BAD_JSON", "Malformed JSON")
91+
raise MatrixRestError(400, "M_BAD_JSON", "Malformed JSON") from None
9292

9393
# If we didn't get anything from that, and it's a v1 api path, try the request args
9494
if request_args is None and (v1_path or request.method == "GET"):

sydent/http/servlets/blindlysignstuffservlet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,6 @@ async def handle_blindly_sign_stuff_post(
5252
signed = signedjson.sign.sign_json(to_sign, server_name, private_key)
5353
except Exception:
5454
logger.exception("signing failed")
55-
raise MatrixRestError(500, "M_UNKNOWN", "Internal Server Error")
55+
raise MatrixRestError(500, "M_UNKNOWN", "Internal Server Error") from None
5656

5757
return json_response(signed)

sydent/http/servlets/replication.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ async def handle_replication_push_post(request: web.Request) -> web.Response:
8585
logger.warning(
8686
"Peer %s made push connection with malformed JSON", peer.servername
8787
)
88-
raise MatrixRestError(400, "M_BAD_JSON", "Malformed JSON")
88+
raise MatrixRestError(400, "M_BAD_JSON", "Malformed JSON") from None
8989

9090
if "sgAssocs" not in inJson:
9191
logger.warning(

sydent/http/servlets/threepidbindservlet.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,19 @@ async def handle_threepid_bind_post(
5757
404,
5858
"M_NO_VALID_SESSION",
5959
"No valid session was found matching that sid and client secret",
60-
)
60+
) from None
6161
except SessionExpiredException:
6262
raise MatrixRestError(
6363
400,
6464
"M_SESSION_EXPIRED",
6565
"This validation session has expired: call requestToken again",
66-
)
66+
) from None
6767
except SessionNotValidatedException:
6868
raise MatrixRestError(
6969
400,
7070
"M_SESSION_NOT_VALIDATED",
7171
"This validation session has not yet been completed",
72-
)
72+
) from None
7373

7474
res = sydent.threepidBinder.addBinding(s.medium, s.address, mxid)
7575
return json_response(res)

sydent/replication/peer.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def __init__(
144144
if replication_url is None:
145145
if not port:
146146
port = 1001
147-
replication_url = "https://%s:%i" % (server_name, port)
147+
replication_url = f"https://{server_name}:{port}"
148148

149149
if replication_url[-1:] != "/":
150150
replication_url += "/"
@@ -176,7 +176,7 @@ def __init__(
176176
except Exception as e:
177177
raise ConfigError(
178178
f"Unable to decode public key for peer {server_name}: {e}",
179-
)
179+
) from e
180180

181181
self.verify_key = signedjson.key.decode_verify_key_bytes(
182182
SIGNING_KEY_ALGORITHM + ":", pubkey_decoded
@@ -236,9 +236,8 @@ async def pushUpdates(self, sgAssocs: SignedAssociations) -> aiohttp.ClientRespo
236236
raise RemotePeerError(errObj)
237237
except (ValueError, UnicodeDecodeError):
238238
raise Exception(
239-
"Push to %s failed with status %d"
240-
% (self.replication_url, response.status)
241-
)
239+
f"Push to {self.replication_url} failed with status {response.status}"
240+
) from None
242241

243242

244243
class NoSignaturesException(Exception):

sydent/sms/openmarket.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,12 @@ async def sendTextSMS(
108108
if resp.status < 200 or resp.status >= 300:
109109
if response_body is None or "error" not in response_body:
110110
raise Exception(
111-
"OpenMarket API responded with status %d (request ID: %s)"
112-
% (
113-
resp.status,
114-
request_id,
115-
),
111+
f"OpenMarket API responded with status {resp.status} (request ID: {request_id})",
116112
)
117113

118114
error = response_body["error"]
119115
raise Exception(
120-
"OpenMarket API responded with status %d (request ID: %s): %s"
121-
% (
122-
resp.status,
123-
request_id,
124-
error,
125-
),
116+
f"OpenMarket API responded with status {resp.status} (request ID: {request_id}): {error}",
126117
)
127118

128119
ticket_id = None

0 commit comments

Comments
 (0)