From ca7e484a335481c105bdaf32bd5f3a10f496d7a8 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 4 Oct 2021 08:13:21 +0200 Subject: [PATCH 1/2] Attempt to fix flaky GPG test by stopping gpg-agent The new GPG tests fail occasionally, for example in https://github.com/mystor/git-revise/pull/99/checks?check_run_id=3785380820 An excerpt from the job log is added below. I'm not sure if problem is the FileNotFoundError: [Errno 2] No such file or directory: 'S.gpg-agent.extra' or the gpg failed to sign commit line; neither should happen. The first sounds like a race between the GPG agent shutdown and the cleanup of the test's temp dir. Try to fix that by stopping the agent before cleanup. Intuitively, this fix makes sense because it's probably not normal to remove $GNUPGHOME while gpg-agent is running. Extract everything that handles our temporary $GNUPGHOME to a fixture, so we can include a cleanup step. This could be tested by repeating this in the CI a number of times but I'm not sure if that's worth it. Unfortunately, the "gpg failed to sign commit" (very last line of the log below) does not tell us which one failed but that probably wouldn't help either. ============================= test session starts ============================== tests/test_gpgsign.py .E ==================================== ERRORS ==================================== ______________________ ERROR at teardown of test_gpgsign _______________________ @pytest.fixture def short_tmpdir(): with tempfile.TemporaryDirectory() as tdir: > yield py.path.local(tdir) tests/conftest.py:67: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/tempfile.py:809: in __exit__ self.cleanup() /opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/tempfile.py:813: in cleanup _shutil.rmtree(self.name) /opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/shutil.py:486: in rmtree _rmtree_safe_fd(fd, path, onerror) /opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/shutil.py:444: in _rmtree_safe_fd onerror(os.unlink, fullname, sys.exc_info()) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ topfd = 11, path = '/tmp/tmpdqw8v4oq' onerror = .onerror at 0x7fe22474da60> def _rmtree_safe_fd(topfd, path, onerror): ... try: > os.unlink(name, dir_fd=topfd) E FileNotFoundError: [Errno 2] No such file or directory: 'S.gpg-agent.extra' /opt/hostedtoolcache/Python/3.6.15/x64/lib/python3.6/shutil.py:442: FileNotFoundError ----------------------------- Captured stdout call ----------------------------- [master (root-commit) 5aa2dc9] commit 1 Author: Bash Author Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD'] {'check': True} 960d4c0a13a4 commit 1 Updating refs/heads/master (5aa2dc979632e41770014678a2c829369d7eea9a => 960d4c0a13a46b43af7aff0d7cb8ea6f4546f7b0) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD'] {'check': True} c67e6e4a4c25 commit 1 Updating refs/heads/master (960d4c0a13a46b43af7aff0d7cb8ea6f4546f7b0 => c67e6e4a4c25442f3cdf55d03a57639697420357) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD', '--gpg-sign'] {'check': True} 960d4c0a13a4 commit 1 Updating refs/heads/master (c67e6e4a4c25442f3cdf55d03a57639697420357 => 960d4c0a13a46b43af7aff0d7cb8ea6f4546f7b0) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD', '--no-gpg-sign'] {'check': True} c67e6e4a4c25 commit 1 Updating refs/heads/master (960d4c0a13a46b43af7aff0d7cb8ea6f4546f7b0 => c67e6e4a4c25442f3cdf55d03a57639697420357) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD', '-S'] {'check': True} 960d4c0a13a4 commit 1 Updating refs/heads/master (c67e6e4a4c25442f3cdf55d03a57639697420357 => 960d4c0a13a46b43af7aff0d7cb8ea6f4546f7b0) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD', '--gpg-sign'] {'check': True} subprocess exited with non-zero status: 1 [master 6a92b96] commit 2 Author: Bash Author [master 07435aa] commit 3 Author: Bash Author [master 33cebdc] commit 4 Author: Bash Author Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD~~', '--gpg-sign'] {'check': True} 2b2c0313c39a commit 2 6932b3a0cd34 commit 3 018843b015b2 commit 4 Updating refs/heads/master (33cebdc30539bfeb0fc5e5530d1eee3fda277be1 => 018843b015b2221d9d87e10590dee48d90075f7a) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD~', '--no-gpg-sign'] {'check': True} 8e096b818b34 commit 3 af3a5ac5a196 commit 4 Updating refs/heads/master (018843b015b2221d9d87e10590dee48d90075f7a => af3a5ac5a196d0bef501e14b57fb33e3b683e947) Running ['/home/runner/work/git-revise/git-revise/.tox/py36/bin/python', '-m', 'gitrevise', 'HEAD~~', '--gpg-sign'] {'check': True} 2b2c0313c39a commit 2 6932b3a0cd34 commit 3 018843b015b2 commit 4 Updating refs/heads/master (af3a5ac5a196d0bef501e14b57fb33e3b683e947 => 018843b015b2221d9d87e10590dee48d90075f7a) ----------------------------- Captured stderr call ----------------------------- gpg: keybox '/tmp/tmpdqw8v4oq/pubring.kbx' created gpg: /tmp/tmpdqw8v4oq/trustdb.gpg: trustdb created gpg: key 1B1CE6765D1A672E marked as ultimately trusted gpg: directory '/tmp/tmpdqw8v4oq/openpgp-revocs.d' created gpg: revocation certificate stored as '/tmp/tmpdqw8v4oq/openpgp-revocs.d/844AB55D2239CF1037507DA71B1CE6765D1A672E.rev' gpg failed to sign commit --- tests/conftest.py | 15 +++++++++++++++ tests/test_gpgsign.py | 8 +------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index eebe6a2..8edab0f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -67,6 +67,21 @@ def short_tmpdir(): yield py.path.local(tdir) +@pytest.fixture +def gpg(short_tmpdir, monkeypatch): + # On MacOS, pytest's temp paths are too long for gpg-agent. + # See https://github.com/pytest-dev/pytest/issues/5802 + gnupghome = short_tmpdir + monkeypatch.setenv("GNUPGHOME", str(gnupghome)) + gnupghome.chmod(0o700) + (gnupghome / "gpg.conf").write("pinentry-mode loopback") + + try: + yield + finally: + bash("gpgconf --kill all") + + @contextmanager def in_parallel(func, *args, **kwargs): class HelperThread(Thread): diff --git a/tests/test_gpgsign.py b/tests/test_gpgsign.py index f22ceaa..a3b26e5 100644 --- a/tests/test_gpgsign.py +++ b/tests/test_gpgsign.py @@ -4,16 +4,10 @@ from subprocess import CalledProcessError, run -def test_gpgsign(repo, short_tmpdir, monkeypatch): +def test_gpgsign(repo, gpg, monkeypatch): bash("git commit --allow-empty -m 'commit 1'") assert repo.get_commit("HEAD").gpgsig is None - # On MacOS, pytest's temp paths are too long for gpg-agent. - # See https://github.com/pytest-dev/pytest/issues/5802 - gnupghome = short_tmpdir - monkeypatch.setenv("GNUPGHOME", str(gnupghome)) - gnupghome.chmod(0o700) - (gnupghome / "gpg.conf").write("pinentry-mode loopback") user_ident = repo.default_author.signing_key run( ["gpg", "--batch", "--passphrase", "", "--quick-gen-key", user_ident], From e4856785212303a0c49d42a7057cddf99a5ee957 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 4 Oct 2021 21:26:04 +0200 Subject: [PATCH 2/2] Use pathlib's Path over deprecated pylib --- tests/conftest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 8edab0f..daf0c18 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,12 +3,12 @@ import pytest import shlex import os -import py.path import sys import tempfile import textwrap import subprocess import traceback +from pathlib import Path from gitrevise.odb import Repository from contextlib import contextmanager from threading import Thread, Event @@ -64,7 +64,7 @@ def repo(hermetic_seal): @pytest.fixture def short_tmpdir(): with tempfile.TemporaryDirectory() as tdir: - yield py.path.local(tdir) + yield Path(tdir) @pytest.fixture @@ -74,7 +74,7 @@ def gpg(short_tmpdir, monkeypatch): gnupghome = short_tmpdir monkeypatch.setenv("GNUPGHOME", str(gnupghome)) gnupghome.chmod(0o700) - (gnupghome / "gpg.conf").write("pinentry-mode loopback") + (gnupghome / "gpg.conf").write_text("pinentry-mode loopback") try: yield