-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
157 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import shutil | ||
import subprocess | ||
|
||
import psutil | ||
import pytest | ||
|
||
try: | ||
import gnupg as gnupglib | ||
|
||
HAS_GNUPG = True | ||
except ImportError: | ||
HAS_GNUPG = False | ||
|
||
|
||
pytestmark = [ | ||
pytest.mark.skipif(HAS_GNUPG is False, reason="Needs python-gnupg library"), | ||
pytest.mark.skip_if_binaries_missing("gpg", reason="Needs gpg binary"), | ||
] | ||
|
||
|
||
@pytest.fixture | ||
def gpghome(tmp_path): | ||
root = tmp_path / "gpghome" | ||
root.mkdir(mode=0o0700) | ||
try: | ||
yield root | ||
finally: | ||
# Make sure we don't leave any gpg-agents running behind | ||
gpg_connect_agent = shutil.which("gpg-connect-agent") | ||
if gpg_connect_agent: | ||
gnupghome = root / ".gnupg" | ||
if not gnupghome.is_dir(): | ||
gnupghome = root | ||
try: | ||
subprocess.run( | ||
[gpg_connect_agent, "killagent", "/bye"], | ||
env={"GNUPGHOME": str(gnupghome)}, | ||
shell=False, | ||
check=True, | ||
stdout=subprocess.DEVNULL, | ||
stderr=subprocess.DEVNULL, | ||
) | ||
except subprocess.CalledProcessError: | ||
# This is likely CentOS 7 or Amazon Linux 2 | ||
pass | ||
|
||
# If the above errored or was not enough, as a last resort, let's check | ||
# the running processes. | ||
for proc in psutil.process_iter(): | ||
try: | ||
if "gpg-agent" in proc.name(): | ||
for arg in proc.cmdline(): | ||
if str(root) in arg: | ||
proc.terminate() | ||
except Exception: # pylint: disable=broad-except | ||
pass | ||
|
||
|
||
@pytest.fixture | ||
def gpg(loaders, states, gpghome): | ||
try: | ||
yield states.gpg | ||
finally: | ||
pass | ||
|
||
|
||
@pytest.fixture | ||
def key_a_fp(): | ||
return "EF03765F59EE904930C8A781553A82A058C0C795" | ||
|
||
|
||
@pytest.fixture | ||
def key_a_pub(): | ||
return """\ | ||
-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
mI0EY4fxHQEEAJvXEaaw+o/yZCwMOJbt5FQHbVMMDX/0YI8UdzsE5YCC4iKnoC3x | ||
FwFdkevKj3qp+45iBGLLnalfXIcVGXJGACB+tPHgsfHaXSDQPSfmX6jbZ6pHosSm | ||
v1tTixY+NTJzGL7hDLz2sAXTbYmTbXeE9ifWWk6NcIwZivUbhNRBM+KxABEBAAG0 | ||
LUtleSBBIChHZW5lcmF0ZWQgYnkgU2FsdFN0YWNrKSA8a2V5YUBleGFtcGxlPojR | ||
BBMBCAA7FiEE7wN2X1nukEkwyKeBVTqCoFjAx5UFAmOH8R0CGy8FCwkIBwICIgIG | ||
FQoJCAsCBBYCAwECHgcCF4AACgkQVTqCoFjAx5XURAQAguOwI+49lG0Kby+Bsyv3 | ||
of3GgxvhS1Qa7+ysj088az5GVt0pqVe3SbRVvn/jyC6yZvWuv94KdL3R7hCeEz2/ | ||
JakCRJ4wxEsdeASE8t9H/oTqD0I5asMa9EMvn5ICEGeLsTeQb7OYYihTQj7HJLG6 | ||
pDEmK8EhJDvV/9o0lnhm/9w= | ||
=Wc0O | ||
-----END PGP PUBLIC KEY BLOCK-----""" | ||
|
||
|
||
@pytest.fixture | ||
def gnupg(gpghome): | ||
return gnupglib.GPG(gnupghome=str(gpghome)) | ||
|
||
|
||
@pytest.fixture | ||
def gnupg_keyring(gpghome, keyring): | ||
return gnupglib.GPG(gnupghome=str(gpghome), keyring=keyring) | ||
|
||
|
||
@pytest.fixture(params=["a"]) | ||
def pubkeys_present(gnupg, request): | ||
pubkeys = [request.getfixturevalue(f"key_{x}_pub") for x in request.param] | ||
fingerprints = [request.getfixturevalue(f"key_{x}_fp") for x in request.param] | ||
gnupg.import_keys("\n".join(pubkeys)) | ||
present_keys = gnupg.list_keys() | ||
for fp in fingerprints: | ||
assert any(x["fingerprint"] == fp for x in present_keys) | ||
yield | ||
# cleanup is taken care of by gpghome and tmp_path | ||
|
||
|
||
@pytest.mark.usefixtures("pubkeys_present") | ||
def test_gpg_present_no_changes(gpghome, gpg, gnupg, key_a_fp): | ||
assert gnupg.list_keys(keys=key_a_fp) | ||
ret = gpg.present( | ||
key_a_fp[-16:], trust="unknown", gnupghome=str(gpghome), keyserver="nonexistent" | ||
) | ||
assert ret.result | ||
assert not ret.changes | ||
|
||
|
||
@pytest.mark.skip_unless_on_linux( | ||
reason="Complains about deleting private keys first when they are absent" | ||
) | ||
@pytest.mark.usefixtures("pubkeys_present") | ||
def test_gpg_absent(gpghome, gpg, gnupg, key_a_fp): | ||
assert gnupg.list_keys(keys=key_a_fp) | ||
ret = gpg.absent(key_a_fp[-16:], gnupghome=str(gpghome)) | ||
assert ret.result | ||
assert ret.changes | ||
assert "deleted" in ret.changes | ||
assert ret.changes["deleted"] | ||
|
||
|
||
def test_gpg_absent_no_changes(gpghome, gpg, gnupg, key_a_fp): | ||
assert not gnupg.list_keys(keys=key_a_fp) | ||
ret = gpg.absent(key_a_fp[-16:], gnupghome=str(gpghome)) | ||
assert ret.result | ||
assert not ret.changes | ||
|
||
|
||
@pytest.mark.usefixtures("pubkeys_present") | ||
def test_gpg_absent_test_mode_no_changes(gpghome, gpg, gnupg, key_a_fp): | ||
assert gnupg.list_keys(keys=key_a_fp) | ||
ret = gpg.absent(key_a_fp[-16:], gnupghome=str(gpghome), test=True) | ||
assert ret.result is None | ||
assert ret.changes | ||
assert "deleted" in ret.changes | ||
assert ret.changes["deleted"] | ||
assert gnupg.list_keys(keys=key_a_fp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters