Changeset - 624d5e9c4b4a
[Not reviewed]
0 3 0
Branko Majic (branko) - 2 months ago 2024-02-23 21:19:26
branko@majic.rs
GC-45: Replace freezegun with time-machine for data/time-related tests:

- The freezegun is no longer maintained, and it also does not handle
timezones that well.
- The time-machine project seems to be actively maintained, and
provides the same functionality.
3 files changed with 41 insertions and 40 deletions:
0 comments (0 inline, 0 general)
setup.py
Show inline comments
 
@@ -37,13 +37,13 @@ doc_requirements = [
 

	
 
test_lint_requirements = [
 
    'flake8>=7.0,<7.1',
 
]
 

	
 
test_requirements = [
 
    'freezegun>=1.3,<1.4',
 
    'time-machine>=2.13,<2.14',
 
    'pytest>=8.0,<8.1',
 
    'pytest-cov>=4.1,<4.2',
 
    'tox>=4.13,<4.14',
 
    'pexpect>=4.9,<4.10',
 
]
 

	
tests/test_commands.py
Show inline comments
 
@@ -16,25 +16,26 @@
 
#
 
# You should have received a copy of the GNU General Public License along with
 
# Gimmecert.  If not, see <http://www.gnu.org/licenses/>.
 
#
 

	
 
import argparse
 
import datetime
 
import io
 
import os
 
import sys
 

	
 
import cryptography.x509
 
from cryptography.hazmat.primitives.asymmetric import ec
 

	
 
import gimmecert.commands
 
import gimmecert.crypto
 

	
 
import pytest
 
from unittest import mock
 
from freezegun import freeze_time
 
from time_machine import travel
 

	
 

	
 
def test_init_sets_up_directory_structure(tmpdir):
 
    base_dir = tmpdir.join('.gimmecert')
 
    ca_dir = tmpdir.join('.gimmecert', 'ca')
 
    server_dir = tmpdir.join('.gimmecert', 'server')
 
@@ -643,16 +644,16 @@ def test_status_reports_uninitialised_directory(tmpdir):
 
    (('ecdsa', ec.SECP521R1), 'secp521r1 ECDSA'),
 
])
 
def test_status_reports_ca_hierarchy_information(tmpdir, ca_key_specification, ca_key_representation):
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, 3, ca_key_specification)
 

	
 
    with freeze_time('2018-06-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 6, 1, 0, 15, 0), tick=False):
 
        status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stdout_lines = stdout.split("\n")
 
    stderr = stderr_stream.getvalue()
 

	
 
@@ -693,28 +694,28 @@ def test_status_reports_server_certificate_information(tmpdir):
 

	
 
    myserver3_csr_file = tmpdir.join('server3.csr.pem')
 
    myserver3_private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 
    myserver3_csr = gimmecert.crypto.generate_csr('blah', myserver3_private_key)
 
    gimmecert.storage.write_csr(myserver3_csr, myserver3_csr_file.strpath)
 

	
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, 3, ("rsa", 2048))
 

	
 
    with freeze_time('2018-02-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 2, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver1', None, None, ("rsa", 1024))
 

	
 
    with freeze_time('2018-03-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 3, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver2', ['myservice1.example.com', 'myservice2.example.com'], None, None)
 

	
 
    with freeze_time('2018-04-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 4, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver3', None, myserver3_csr_file.strpath, None)
 

	
 
    with freeze_time('2018-05-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 5, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver4', None, None, ("ecdsa", ec.SECP256R1))
 

	
 
    with freeze_time('2018-06-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 6, 1, 0, 15, 0), tick=False):
 
        status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stdout_lines = stdout.split("\n")
 
    stderr = stderr_stream.getvalue()
 

	
 
@@ -783,28 +784,28 @@ def test_status_reports_client_certificate_information(tmpdir):
 

	
 
    myclient3_csr_file = tmpdir.join('client3.csr.pem')
 
    myclient3_private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 
    myclient3_csr = gimmecert.crypto.generate_csr('blah', myclient3_private_key)
 
    gimmecert.storage.write_csr(myclient3_csr, myclient3_csr_file.strpath)
 

	
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, 3, ("rsa", 2048))
 

	
 
    with freeze_time('2018-02-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 2, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient1', None, ("rsa", 1024))
 

	
 
    with freeze_time('2018-03-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 3, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient2', None, None)
 

	
 
    with freeze_time('2018-04-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 4, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient3', myclient3_csr_file.strpath, None)
 

	
 
    with freeze_time('2018-05-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 5, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient4', None, ("ecdsa", ec.SECP384R1))
 

	
 
    with freeze_time('2018-06-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 6, 1, 0, 15, 0), tick=False):
 
        status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stdout_lines = stdout.split("\n")
 
    stderr = stderr_stream.getvalue()
 

	
 
@@ -861,13 +862,13 @@ def test_status_reports_client_certificate_information(tmpdir):
 

	
 
def test_status_reports_no_server_certificates_were_issued(tmpdir):
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    # Just create some sample data, but no server certificates.
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, 1, ("rsa", 2048))
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient1', None, None)
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient2', None, None)
 

	
 
    status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
@@ -882,13 +883,13 @@ def test_status_reports_no_server_certificates_were_issued(tmpdir):
 

	
 
def test_status_reports_no_client_certificates_were_issued(tmpdir):
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    # Just create some sample data, but no client certificates.
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, tmpdir.basename, 1, ("rsa", 2048))
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver1', None, None, None)
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver2', None, None, None)
 

	
 
    status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
@@ -921,19 +922,19 @@ def test_certificate_marked_as_not_valid_or_expired_as_appropriate(tmpdir, subje
 
    """
 

	
 
    stdout_stream = io.StringIO()
 
    stderr_stream = io.StringIO()
 

	
 
    # Perform action on our fixed issuance date.
 
    with freeze_time(issuance_date):
 
    with travel(issuance_date, tick=False):
 
        gimmecert.commands.init(io.StringIO(), io.StringIO(), tmpdir.strpath, "My Project", 1, ("rsa", 2048))
 
        gimmecert.commands.server(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myserver', None, None, None)
 
        gimmecert.commands.client(io.StringIO(), io.StringIO(), tmpdir.strpath, 'myclient', None, None)
 

	
 
    # Move to specific date in future/past for different validity checks.
 
    with freeze_time(status_date):
 
    with travel(status_date, tick=False):
 
        status_code = gimmecert.commands.status(stdout_stream, stderr_stream, tmpdir.strpath)
 

	
 
    stdout = stdout_stream.getvalue()
 
    stdout_lines = stdout.split("\n")
 
    stderr = stderr_stream.getvalue()
 

	
tests/test_crypto.py
Show inline comments
 
@@ -26,13 +26,13 @@ import cryptography.hazmat.primitives.asymmetric.rsa
 
import cryptography.x509
 
from dateutil.relativedelta import relativedelta
 

	
 
import gimmecert.crypto
 

	
 
import pytest
 
from freezegun import freeze_time
 
from time_machine import travel
 

	
 

	
 
def test_get_dn():
 
    dn = gimmecert.crypto.get_dn('My test')
 
    assert isinstance(dn, cryptography.x509.Name)
 
    assert len(dn) == 1
 
@@ -45,28 +45,28 @@ def test_get_validity_range_returns_datetime_tuple():
 
    not_before, not_after = gimmecert.crypto.get_validity_range()
 

	
 
    assert isinstance(not_before, datetime.datetime)
 
    assert isinstance(not_after, datetime.datetime)
 

	
 

	
 
@freeze_time('2018-01-01 00:15:00')
 
@travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False)
 
def test_get_validity_range_not_before_is_within_15_minutes_of_now():
 
    not_before, _ = gimmecert.crypto.get_validity_range()
 

	
 
    assert not_before == datetime.datetime(2018, 1, 1, 0, 0)
 

	
 

	
 
@freeze_time('2018-01-01 00:15:00')
 
@travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False)
 
def test_get_validity_range_is_one_year_and_15_minutes():
 
    not_before, not_after = gimmecert.crypto.get_validity_range()
 
    difference = relativedelta(not_after, not_before)
 

	
 
    assert difference == relativedelta(years=1, minutes=15)
 

	
 

	
 
@freeze_time('2018-01-01 00:15:00.100')
 
@travel(datetime.datetime(2018, 1, 1, 0, 15, 0, 100), tick=False)
 
def test_get_validity_range_drops_microseconds():
 
    not_before, not_after = gimmecert.crypto.get_validity_range()
 

	
 
    assert not_before.microsecond == 0
 
    assert not_after.microsecond == 0
 

	
 
@@ -349,47 +349,47 @@ def test_issue_server_certificate_has_correct_public_key(key_specification):
 

	
 
    certificate = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.public_key().public_numbers() == private_key.public_key().public_numbers()
 

	
 

	
 
@freeze_time('2018-01-01 00:15:00')
 
@travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False)
 
def test_issue_server_certificate_not_before_is_15_minutes_in_past():
 
    ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    certificate = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.not_valid_before == datetime.datetime(2018, 1, 1, 0, 0)
 

	
 

	
 
def test_issue_server_certificate_not_before_does_not_exceed_ca_validity():
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 

	
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    with freeze_time(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1), tick=False):
 
        certificate1 = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate1.not_valid_before == issuer_certificate.not_valid_before
 

	
 

	
 
def test_issue_server_certificate_not_after_does_not_exceed_ca_validity():
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 

	
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    with freeze_time(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1), tick=False):
 
        certificate1 = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate1.not_valid_after == issuer_certificate.not_valid_after
 

	
 

	
 
def test_issue_server_certificate_incorporates_additional_dns_subject_alternative_names():
 
@@ -485,47 +485,47 @@ def test_issue_client_certificate_has_correct_public_key(key_specification):
 

	
 
    certificate = gimmecert.crypto.issue_client_certificate('myclient', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.public_key().public_numbers() == private_key.public_key().public_numbers()
 

	
 

	
 
@freeze_time('2018-01-01 00:15:00')
 
@travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False)
 
def test_issue_client_certificate_not_before_is_15_minutes_in_past():
 
    ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    certificate = gimmecert.crypto.issue_client_certificate('myclient', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.not_valid_before == datetime.datetime(2018, 1, 1, 0, 0)
 

	
 

	
 
def test_issue_client_certificate_not_before_does_not_exceed_ca_validity():
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 

	
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    with freeze_time(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1), tick=False):
 
        certificate1 = gimmecert.crypto.issue_client_certificate('myclient', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate1.not_valid_before == issuer_certificate.not_valid_before
 

	
 

	
 
def test_issue_client_certificate_not_after_does_not_exceed_ca_validity():
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 

	
 
    issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
    private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 

	
 
    with freeze_time(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1), tick=False):
 
        certificate1 = gimmecert.crypto.issue_client_certificate('myclient', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate1.not_valid_after == issuer_certificate.not_valid_after
 

	
 

	
 
def test_renew_certificate_returns_certificate():
 
@@ -561,55 +561,55 @@ def test_renew_certificate_has_correct_content(key_specification):
 
    assert [e for e in old_certificate.extensions] == [e for e in new_certificate.extensions]
 

	
 

	
 
def test_renew_certificate_not_before_is_15_minutes_in_past():
 

	
 
    # Initial server certificate.
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 
        issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
        private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 
        old_certificate = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    # Renew certificate.
 
    with freeze_time('2018-06-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 6, 1, 0, 15, 0), tick=False):
 
        certificate = gimmecert.crypto.renew_certificate(old_certificate, private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.not_valid_before == datetime.datetime(2018, 6, 1, 0, 0)
 

	
 

	
 
def test_renew_certificate_not_before_does_not_exceed_ca_validity():
 

	
 
    # Initial server certificate.
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 
        issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
        private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 
        old_certificate = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    # Renew certificate.
 
    with freeze_time(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_before - datetime.timedelta(seconds=1), tick=False):
 
        certificate = gimmecert.crypto.renew_certificate(old_certificate, private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.not_valid_before == issuer_certificate.not_valid_before
 

	
 

	
 
def test_renew_certificate_not_after_does_not_exceed_ca_validity():
 

	
 
    # Initial server certificate.
 
    with freeze_time('2018-01-01 00:15:00'):
 
    with travel(datetime.datetime(2018, 1, 1, 0, 15, 0), tick=False):
 
        ca_hierarchy = gimmecert.crypto.generate_ca_hierarchy('My Project', 1, gimmecert.crypto.KeyGenerator("rsa", 2048))
 
        issuer_private_key, issuer_certificate = ca_hierarchy[0]
 

	
 
        private_key = gimmecert.crypto.KeyGenerator('rsa', 2048)()
 
        old_certificate = gimmecert.crypto.issue_server_certificate('myserver', private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    # Renew certificate.
 
    with freeze_time(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1)):
 
    with travel(issuer_certificate.not_valid_after + datetime.timedelta(seconds=1), tick=False):
 
        certificate = gimmecert.crypto.renew_certificate(old_certificate, private_key.public_key(), issuer_private_key, issuer_certificate)
 

	
 
    assert certificate.not_valid_after == issuer_certificate.not_valid_after
 

	
 

	
 
def test_generate_csr_returns_csr_with_passed_in_dn():
0 comments (0 inline, 0 general)