File: test_1testsuite.py

package info (click to toggle)
python-aiosmtpd 1.4.6-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,016 kB
  • sloc: python: 8,064; makefile: 159
file content (95 lines) | stat: -rw-r--r-- 3,325 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Copyright 2014-2021 The aiosmtpd Developers
# SPDX-License-Identifier: Apache-2.0

"""Test the sanity of the test suite itself"""

import re
import pytest
import socket

from aiosmtpd.testing import statuscodes
from itertools import combinations


ENFORCE_ENHANCED_STATUS_CODES = False
"""Whether to do strict compliance checking against RFC 2034 § 4"""

RE_ESC = re.compile(rb"(?P<digit1>\d)\.\d+\.\d+\s")


# noinspection PyUnresolvedReferences
@pytest.fixture(scope="module", autouse=True)
def exit_on_fail(request: pytest.FixtureRequest):
    # Behavior of this will be undefined if tests are running in parallel.
    # But since parallel running is not practically possible (the ports will conflict),
    # then I don't think that will be a problem.
    failcount = request.session.testsfailed
    yield
    if request.session.testsfailed != failcount:
        pytest.exit("Test Suite is Not Sane!")


STATUS_CODES = {
    k: v for k, v in vars(statuscodes.SMTP_STATUS_CODES).items() if k.startswith("S")
}


class TestStatusCodes:
    def test_elemtype(self):
        """Ensure status codes are instances of StatusCode"""
        for value in STATUS_CODES.values():
            assert isinstance(value, statuscodes.StatusCode)

    def test_nameval(self):
        """Ensure each status code constant has SMTP Code embedded in the name"""
        for key, value in STATUS_CODES.items():
            assert int(key[1:4]) == value.code

    def test_enhanced(self):
        """Compliance with RFC 2034 § 4"""
        total_correct = 0
        for key, value in STATUS_CODES.items():
            if key == "S250_FQDN":
                # FQDNs are sometimes funky and can be misconstrued as ESC
                # Better to skip em
                continue
            assert isinstance(value, statuscodes.StatusCode)
            m = RE_ESC.match(value.mesg)
            if ENFORCE_ENHANCED_STATUS_CODES:
                assert m is not None, f"{key} does not have Enhanced Status Code"
            elif m is None:
                continue
            esc1 = m.group("digit1")
            # noinspection PyTypeChecker
            assert str(value.code // 100) == esc1.decode(), (
                f"{key}: First digit of Enhanced Status Code different from "
                f"first digit of Standard Status Code"
            )
            # Can't use enumerate(); total_correct does not increase in lockstep with
            # the loop (there are several "continue"s above)
            total_correct += 1  # noqa: SIM113
        assert total_correct > 0

    def test_commands(self):
        """
        Ensure lists in statuscodes are individual objects, so changes in one list
        won't affect the other lists
        """
        lists = [
            statuscodes._COMMON_COMMANDS,
            statuscodes.SUPPORTED_COMMANDS_NOTLS,
            statuscodes.SUPPORTED_COMMANDS_TLS,
            statuscodes.SUPPORTED_COMMANDS_LMTP,
        ]
        for one, two in combinations(lists, 2):
            assert one is not two


class TestHarness:
    def test_fqdn_cached(self):
        """
        Ensure that socket.getfqdn does not change between calls
        """
        fqdn = socket.getfqdn()
        assert isinstance(fqdn, str)
        assert socket.getfqdn() == fqdn, "socket.getfqdn() changed between calls!"