From 9e18f45a80f12ce9affdd06b78068b7fdc020a6d Mon Sep 17 00:00:00 2001 From: juga Date: Fri, 24 Jan 2020 13:56:54 +0000 Subject: [PATCH] Add pytest unit tests so that they all can run with just one pytest command, they can be integrated with python test command and with tox and they can be run separately with different python versions. --- setup.py | 3 + tests/__init__.py | 0 tests/conftest.py | 45 +++++++++ tests/constants.py | 26 +++++ tests/data/README.md | 2 + tests/data/alice@openpgp.example.pub.asc | 14 +++ tests/data/alice@openpgp.example.sec.asc | 16 +++ tests/data/bob@openpgp.example.pub.asc | 42 ++++++++ tests/data/bob@openpgp.example.sec.asc | 82 +++++++++++++++ tests/test_identity.py | 121 +++++++++++++++++++++++ tests/test_message.py | 71 +++++++++++++ tox.ini | 23 +++++ 12 files changed, 445 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/constants.py create mode 100644 tests/data/README.md create mode 100644 tests/data/alice@openpgp.example.pub.asc create mode 100644 tests/data/alice@openpgp.example.sec.asc create mode 100644 tests/data/bob@openpgp.example.pub.asc create mode 100644 tests/data/bob@openpgp.example.sec.asc create mode 100644 tests/test_identity.py create mode 100644 tests/test_message.py create mode 100644 tox.ini diff --git a/setup.py b/setup.py index 4c3db47..c208f65 100644 --- a/setup.py +++ b/setup.py @@ -282,4 +282,7 @@ setup( cmdclass={ 'build_ext': BuildExtCommand, }, + extras_require={ + 'test': ['pytest'], + }, ) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..1aa45d7 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,45 @@ +"""pytest configuration for the unit tests.""" +import pytest + + +@pytest.fixture() +def datadir(request): + """Get, read, open test files from the tests "data" directory.""" + class D: + def __init__(self, basepath): + self.basepath = basepath + + def open(self, name, mode="r"): + return self.basepath.join(name).open(mode) + + def join(self, name): + return self.basepath.join(name).strpath + + def read(self, name): + with self.open(name, "r") as f: + return f.read() + + def readlines(self, name): + with self.open(name, "r") as f: + return f.readlines() + return D(request.fspath.dirpath("data")) + + +@pytest.fixture(scope='function') +def tmpdir(tmpdir_factory, request): + """Create a tmp dir for the tests""" + base = str(hash(request.node.nodeid))[:3] + bn = tmpdir_factory.mktemp(base) + return bn + + +@pytest.fixture() +def alice_sec_key_data(datadir): + key_data = datadir.read('alice@openpgp.example.sec.asc') + return key_data + + +@pytest.fixture() +def bob_pub_key_data(datadir): + key_data = datadir.read('bob@openpgp.example.pub.asc') + return key_data diff --git a/tests/constants.py b/tests/constants.py new file mode 100644 index 0000000..cf5e02b --- /dev/null +++ b/tests/constants.py @@ -0,0 +1,26 @@ +"""Constants for unit tests.""" + + +# XXX: Create these first constants as part of the adapter +OUTGOING_MSG = 1 +INCOMING_MSG = 2 + +ANGLE_ADDR = "<{}>" +NAME_ADDR = "{} {}" + +PEP_NAME = "myself" +PEP_ADDRESS = "myself@pep.fundation" + +BOB_NAME = "Bob Babagge" +BOB_ADDRESS = "bob@openpgp.example" +BOB_FP = "D1A66E1A23B182C9980F788CFBFCC82A015E7330" +BOB_NAME_ADDR = NAME_ADDR.format(BOB_NAME, ANGLE_ADDR.format(BOB_ADDRESS)) + +ALICE_NAME = "Alice Lovelace" +ALICE_ADDRESS = "alice@openpgp.example" +ALICE_FP = "EB85BB5FA33A75E15E944E63F231550C4F47E38E" +ALICE_NAME_ADDR = NAME_ADDR.format(ALICE_NAME, + ANGLE_ADDR.format(ALICE_ADDRESS)) + +SUBJECT = "This is a subject" +BODY = "Hi world!\n" diff --git a/tests/data/README.md b/tests/data/README.md new file mode 100644 index 0000000..0fcfd74 --- /dev/null +++ b/tests/data/README.md @@ -0,0 +1,2 @@ +The data in this directory comes from: +https://datatracker.ietf.org/doc/draft-bre-openpgp-samples/ diff --git a/tests/data/alice@openpgp.example.pub.asc b/tests/data/alice@openpgp.example.pub.asc new file mode 100644 index 0000000..2410510 --- /dev/null +++ b/tests/data/alice@openpgp.example.pub.asc @@ -0,0 +1,14 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: Alice's OpenPGP certificate + +mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U +b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE +ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy +MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO +dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4 +OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s +E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb +DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn +0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE= +=iIGO +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/data/alice@openpgp.example.sec.asc b/tests/data/alice@openpgp.example.sec.asc new file mode 100644 index 0000000..af11bec --- /dev/null +++ b/tests/data/alice@openpgp.example.sec.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Comment: Alice's OpenPGP Transferable Secret Key + +lFgEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U +b7O1u10AAP9XBeW6lzGOLx7zHH9AsUDUTb2pggYGMzd0P3ulJ2AfvQ4RtCZBbGlj +ZSBMb3ZlbGFjZSA8YWxpY2VAb3BlbnBncC5leGFtcGxlPoiQBBMWCAA4AhsDBQsJ +CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE64W7X6M6deFelE5j8jFVDE9H444FAl2l +nzoACgkQ8jFVDE9H447pKwD6A5xwUqIDprBzrHfahrImaYEZzncqb25vkLV2arYf +a78A/R3AwtLQvjxwLDuzk4dUtUwvUYibL2sAHwj2kGaHnfICnF0EXEcE6RIKKwYB +BAGXVQEFAQEHQEL/BiGtq0k84Km1wqQw2DIikVYrQrMttN8d7BPfnr4iAwEIBwAA +/3/xFPG6U17rhTuq+07gmEvaFYKfxRB6sgAYiW6TMTpQEK6IeAQYFggAIBYhBOuF +u1+jOnXhXpROY/IxVQxPR+OOBQJcRwTpAhsMAAoJEPIxVQxPR+OOWdABAMUdSzpM +hzGs1O0RkWNQWbUzQ8nUOeD9wNbjE3zR+yfRAQDbYqvtWQKN4AQLTxVJN5X5AWyb +Pnn+We1aTBhaGa86AQ== +=n8OM +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/data/bob@openpgp.example.pub.asc b/tests/data/bob@openpgp.example.pub.asc new file mode 100644 index 0000000..b58b8c3 --- /dev/null +++ b/tests/data/bob@openpgp.example.pub.asc @@ -0,0 +1,42 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: Bob's OpenPGP certificate + +mQGNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv +/seOXpgecTdOcVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz +/56fW2O0F23qIRd8UUJp5IIlN4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/ +5whqsyroEWDJoSV0yOb25B/iwk/pLUFoyhDG9bj0kIzDxrEqW+7Ba8nocQlecMF3 +X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8Je/ECwUWYUiAZxLIlMv +9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx5wRZ4F0 +qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7eb +SGXrl5ZMpbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wb +vLIwa3T4CyshfT0AEQEAAbQhQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1w +bGU+iQHOBBMBCgA4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE0aZuGiOx +gsmYD3iM+/zIKgFeczAFAl2lnvoACgkQ+/zIKgFeczBvbAv/VNk90a6hG8Od9xTz +XxH5YRFUSGfIA1yjPIVOnKqhMwps2U+sWE3urL+MvjyQRlyRV8oY9IOhQ5Esm6DO +ZYrTnE7qVETm1ajIAP2OFChEc55uH88x/anpPOXOJY7S8jbn3naC9qad75BrZ+3g +9EBUWiy5p8TykP05WSnSxNRt7vFKLfEB4nGkehpwHXOVF0CRNwYle42bg8lpmdXF +DcCZCi+qEbafmTQzkAqyzS3nCh3IAqq6Y0kBuaKLm2tSNUOlZbD+OHYQNZ5Jix7c +ZUzs6Xh4+I55NRWl5smrLq66yOQoFPy9jot/Qxikx/wP3MsAzeGaZSEPc0fHp5G1 +6rlGbxQ3vl8/usUV7W+TMEMljgwd5x8POR6HC8EaCDfVnUBCPi/Gv+egLjsIbPJZ +ZEroiE40e6/UoCiQtlpQB5exPJYSd1Q1txCwueih99PHepsDhmUQKiACszNU+RRo +zAYau2VdHqnRJ7QYdxHDiH49jPK4NTMyb/tJh2TiIwcmsIpGuQGNBF2lnPIBDADW +ML9cbGMrp12CtF9b2P6z9TTT74S8iyBOzaSvdGDQY/sUtZXRg21HWamXnn9sSXvI +DEINOQ6A9QxdxoqWdCHrOuW3ofneYXoG+zeKc4dC86wa1TR2q9vW+RMXSO4uImA+ +Uzula/6k1DogDf28qhCxMwG/i/m9g1c/0aApuDyKdQ1PXsHHNlgd/Dn6rrd5y2AO +baifV7wIhEJnvqgFXDN2RXGjLeCOHV4Q2WTYPg/S4k1nMXVDwZXrvIsA0YwIMgIT +86Rafp1qKlgPNbiIlC1g9RY/iFaGN2b4Ir6GDohBQSfZW2+LXoPZuVE/wGlQ01rh +827KVZW4lXvqsge+wtnWlszcselGATyzqOK9LdHPdZGzROZYI2e8c+paLNDdVPL6 +vdRBUnkCaEkOtl1mr2JpQi5nTU+gTX4IeInC7E+1a9UDF/Y85ybUz8XV8rUnR76U +qVC7KidNepdHbZjjXCt8/Zo+Tec9JNbYNQB/e9ExmDntmlHEsSEQzFwzj8sxH48A +EQEAAYkBtgQYAQoAIBYhBNGmbhojsYLJmA94jPv8yCoBXnMwBQJdpZzyAhsMAAoJ +EPv8yCoBXnMw6f8L/26C34dkjBffTzMj5Bdzm8MtF67OYneJ4TQMw7+41IL4rVcS +KhIhk/3Ud5knaRtP2ef1+5F66h9/RPQOJ5+tvBwhBAcUWSupKnUrdVaZQanYmtSx +cVV2PL9+QEiNN3tzluhaWO//rACxJ+K/ZXQlIzwQVTpNhfGzAaMVV9zpf3u0k14i +tcv6alKY8+rLZvO1wIIeRZLmU0tZDD5HtWDvUV7rIFI1WuoLb+KZgbYn3OWjCPHV +dTrdZ2CqnZbG3SXw6awH9bzRLV9EXkbhIMez0deCVdeo+wFFklh8/5VK2b0vk/+w +qMJxfpa1lHvJLobzOP9fvrswsr92MA2+k901WeISR7qEzcI0Fdg8AyFAExaEK6Vy +jP7SXGLwvfisw34OxuZr3qmx1Sufu4toH3XrB7QJN8XyqqbsGxUCBqWif9RSK4xj +zRTe56iPeiSJJOIciMP9i2ldI+KgLycyeDvGoBj0HCLO3gVaBe4ubVrj5KjhX2PV +NEJd3XZRzaXZE2aAMQ== +=NXei +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/data/bob@openpgp.example.sec.asc b/tests/data/bob@openpgp.example.sec.asc new file mode 100644 index 0000000..59e981b --- /dev/null +++ b/tests/data/bob@openpgp.example.sec.asc @@ -0,0 +1,82 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Comment: Bob's OpenPGP Transferable Secret Key + +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 +=miES +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/test_identity.py b/tests/test_identity.py new file mode 100644 index 0000000..59fdcb9 --- /dev/null +++ b/tests/test_identity.py @@ -0,0 +1,121 @@ +"""Identity unit tests.""" +import os + +from . import constants + + +def test_create_one_identity_succeed(tmpdir): + # Change $HOME before initializing the db + os.environ["HOME"] = str(tmpdir) + # It has to be imported here to get the management db initialized, + import pEp + alice = pEp.Identity() + alice.address = constants.ALICE_ADDRESS + alice.username = constants.ALICE_NAME + alice.fpr = constants.ALICE_FP + + expected_alice = pEp.Identity( + constants.ALICE_ADDRESS, constants.ALICE_NAME, '', + constants.ALICE_FP, 0, '' + ) + + # XXX: Can't compare objects + # assert alice == expected_alice + assert str(alice) == constants.ALICE_NAME_ADDR + assert alice.address == expected_alice.address + assert alice.username == expected_alice.username + # Cause the key is created by pEp + assert alice.fpr == expected_alice.fpr + assert alice.user_id == expected_alice.user_id + assert alice.comm_type == expected_alice.comm_type + assert alice.flags == expected_alice.flags + + # Test that data after updating. + # If the db has not been initialized this would return PEP_GET_KEY_FAILED + alice.update() + assert str(alice) == constants.ALICE_NAME_ADDR + assert alice.address == expected_alice.address + assert alice.username == expected_alice.username + # XXX: shouldn't this be he fpr of the key generated by pEp? + assert alice.fpr == '' + # After updating this changed + assert alice.user_id == "TOFU_alice@openpgp.example" + # After updating this changed + assert alice.comm_type == 3 + assert alice.flags == expected_alice.flags + + +def test_two_identities_succeed(tmpdir, bob_pub_key_data): + os.environ["HOME"] = str(tmpdir) + import pEp + + alice = pEp.Identity( + constants.ALICE_ADDRESS, constants.ALICE_NAME, '', + constants.ALICE_FP, 0, '' + ) + assert alice.address == constants.ALICE_ADDRESS + assert alice.username == constants.ALICE_NAME + assert alice.fpr == constants.ALICE_FP + assert alice.user_id == "" + assert alice.comm_type == 0 + assert alice.flags == 0 + + pEp.import_key(bob_pub_key_data) + + bob = pEp.Identity() + bob.address = constants.BOB_ADDRESS + bob.username = constants.BOB_NAME + bob.fpr = constants.BOB_FP + expected_bob = pEp.Identity( + constants.BOB_ADDRESS, constants.BOB_NAME, '', + constants.BOB_FP, 56, '' + ) + + assert str(bob) == constants.BOB_NAME_ADDR + assert bob.address == expected_bob.address + assert bob.username == expected_bob.username + assert bob.fpr == expected_bob.fpr + assert bob.user_id == "" + assert bob.comm_type == 0 + assert bob.flags == 0 + + # Test that data after updating. + bob.update() + assert str(bob) == constants.BOB_NAME_ADDR + assert bob.address == expected_bob.address + assert bob.username == expected_bob.username + assert bob.fpr == expected_bob.fpr + assert bob.user_id == "TOFU_bob@openpgp.example" + assert bob.comm_type == 56 + assert bob.flags == 0 + + +def test_set_own_key(tmpdir, alice_sec_key_data): + os.environ["HOME"] = str(tmpdir) + import pEp + + pEp.import_key(alice_sec_key_data) + alice = pEp.Identity() + alice.address = constants.ALICE_ADDRESS + alice.username = constants.ALICE_NAME + alice.fpr = constants.ALICE_FP + alice.user_id = constants.ALICE_NAME_ADDR + + expected_alice = pEp.Identity( + constants.ALICE_ADDRESS, constants.ALICE_NAME, '', + constants.ALICE_FP, 0, '' + ) + + pEp.set_own_key(alice, alice.fpr) + # assert str(alice) == constants.ALICE_NAME_ADDR + assert str(alice) == str(expected_alice) + assert alice.address == expected_alice.address + assert alice.username == expected_alice.username + # assert alice.user_id == constants.ALICE_NAME_ADDR + assert alice.user_id == str(expected_alice) + assert alice.fpr == expected_alice.fpr + assert alice.comm_type == 255 + assert alice.flags == 0 + + # After setting own key this would give ValueError: illegal value + # alice.update() diff --git a/tests/test_message.py b/tests/test_message.py new file mode 100644 index 0000000..f54bd58 --- /dev/null +++ b/tests/test_message.py @@ -0,0 +1,71 @@ +"""Message unit tests.""" +import os + +from . import constants + + +def test_msg_enc_dec_roundtrip(tmpdir, alice_sec_key_data, bob_pub_key_data): + os.environ["HOME"] = str(tmpdir) + import pEp + + alice = pEp.Identity( + constants.ALICE_ADDRESS, constants.ALICE_NAME, + constants.ALICE_NAME_ADDR, constants.ALICE_FP, 0, '' + ) + + pEp.import_key(bob_pub_key_data) + bob = pEp.Identity( + constants.BOB_ADDRESS, constants.BOB_NAME, '', + constants.BOB_FP, 56, '' + ) + + msg = pEp.Message(constants.OUTGOING_MSG, alice) + msg.to = [bob] + msg.shortmsg = constants.SUBJECT + msg.longmsg = constants.BODY + assert msg.enc_format == 0 + # XXX: No way to check MIME so far. + + # Test that creating the `Message` with `outgoing_message` is the same. + msg2 = pEp.outgoing_message(alice) + msg2.to = [bob] + msg2.shortmsg = constants.SUBJECT + msg2.longmsg = constants.BODY + assert str(msg2) == str(msg) + + # Encrypt Message + enc_msg = msg.encrypt() + + assert enc_msg.enc_format == 3 + assert str(enc_msg.from_) == constants.ALICE_NAME_ADDR + assert str(enc_msg.to[0]) == constants.BOB_NAME_ADDR + assert enc_msg.shortmsg == "p≡p" + assert enc_msg.longmsg == \ + "this message was encrypted with p≡p https://pEp-project.org" + + # Decrypt message. + dec_msg, key_list, rating, r = enc_msg.decrypt() + assert r == 0 + assert rating == pEp.PEP_rating.PEP_rating_reliable + # It is not known which key is generated for Alice, so check only the + # one for Bob. + assert key_list[-1] == constants.BOB_FP + assert dec_msg.shortmsg == constants.SUBJECT + assert dec_msg.longmsg.replace("\r", "") == msg.longmsg + dec_lines = str(dec_msg).replace("\r", "").split("\n") + expected_dec_lines = """From: Alice Lovelace +To: Bob Babagge +Subject: This is a subject +X-pEp-Version: 2.1 +X-EncStatus: reliable +X-KeyList: + X,X,D1A66E1A23B182C9980F788CFBFCC82A015E7330 +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline; filename="msg.txt" + +Hi world=21 +""".split("\n") + assert dec_lines[:5] == expected_dec_lines[:5] + assert dec_lines[7:] == expected_dec_lines[7:] diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..c5ca3ce --- /dev/null +++ b/tox.ini @@ -0,0 +1,23 @@ +[tox] +skip_missing_interpreters = True +; Python versions ends of life: +; - 3.6: December 2021 +; - 3.7: June 2023 +; - 3.8: October 2024 +envlist = py36, py37, py38, inst, setup, unit + +# test that it can be installed with custom commands and clean env +[testenv:inst] +skip_install = True +commands = + - pip install . +recreate = True + +[testenv:setup] +skip_install = True +commands = python setup.py install +recreate = True + +[testenv:unit] +deps = .[test] +commands = pytest -svv tests