Backport more meaningful tests

This commit is contained in:
jeanluc 2022-12-11 14:19:07 +01:00 committed by Pedro Algarvio
parent 3dbf49190f
commit 311e2938c0
3 changed files with 157 additions and 94 deletions

View file

@ -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)

View file

@ -1073,15 +1073,3 @@ def test_gpg_receive_keys_no_user_id():
res = gpg.receive_keys(keys="abc", user="abc")
assert res["res"] is False
assert "no user ID" in res["message"][0]
def test_gpg_delete_key_honors_gnupghome():
with patch("salt.modules.gpg._create_gpg") as create:
with patch("salt.modules.gpg.get_key") as get_key:
gnupghome = "/pls_respect_me"
get_key.return_value = None
gpg.delete_key("foo", gnupghome=gnupghome)
create.assert_called_with(None, gnupghome)
get_key.assert_called_with(
keyid="foo", fingerprint=None, user=None, gnupghome=gnupghome
)

View file

@ -92,25 +92,6 @@ def gpg_receive(request):
yield recv
@pytest.fixture()
def gpg_delete(request):
delete = Mock(spec="salt.modules.gpg.delete_key")
delete.return_value = getattr(
request, "param", {"res": True, "message": "Public key for A deleted"}
)
with patch.dict(gpg.__salt__, {"gpg.delete_key": delete}):
yield delete
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_present_no_changes(gpg_receive, gpg_trust):
ret = gpg.present("A")
assert ret["result"]
assert not ret["changes"]
gpg_receive.assert_not_called()
gpg_trust.assert_not_called()
@pytest.mark.usefixtures("gpg_list_keys")
@pytest.mark.parametrize(
"gpg_trust,expected",
@ -122,8 +103,8 @@ def test_gpg_present_no_changes(gpg_receive, gpg_trust):
)
def test_gpg_present_trust_change(gpg_receive, gpg_trust, expected):
ret = gpg.present("A", trust="marginally")
assert ret["result"] == expected
assert bool(ret["changes"]) == expected
assert ret["result"] is expected
assert bool(ret["changes"]) is expected
gpg_trust.assert_called_once()
gpg_receive.assert_not_called()
@ -147,8 +128,8 @@ def test_gpg_present_trust_change(gpg_receive, gpg_trust, expected):
)
def test_gpg_present_new_key(gpg_receive, gpg_trust, expected):
ret = gpg.present("new")
assert ret["result"] == expected
assert bool(ret["changes"]) == expected
assert ret["result"] is expected
assert bool(ret["changes"]) is expected
gpg_receive.assert_called_once()
gpg_trust.assert_not_called()
@ -165,9 +146,9 @@ def test_gpg_present_new_key(gpg_receive, gpg_trust, expected):
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_present_new_key_and_trust(gpg_receive, gpg_trust, expected):
ret = gpg.present("new", trust="marginally")
assert ret["result"] == expected
assert ret["result"] is expected
# the key is always marked as added
assert bool(ret["changes"])
assert ret["changes"]
gpg_receive.assert_called_once()
gpg_trust.assert_called_once()
@ -180,60 +161,4 @@ def test_gpg_present_test_mode_no_changes(gpg_receive, gpg_trust, key, trust):
gpg_receive.assert_not_called()
gpg_trust.assert_not_called()
assert ret["result"] is None
assert bool(ret["changes"])
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_absent_no_changes(gpg_delete):
ret = gpg.absent("nonexistent")
assert ret["result"]
assert not ret["changes"]
gpg_delete.assert_not_called()
@pytest.mark.usefixtures("gpg_list_keys")
@pytest.mark.parametrize(
"gpg_delete,expected",
[
({"res": True, "message": "Public key for A deleted"}, True),
(
{
"res": False,
"message": "Secret key exists, delete first or pass delete_secret=True.",
},
False,
),
],
indirect=["gpg_delete"],
)
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_absent_delete_key(gpg_delete, expected):
ret = gpg.absent("A")
assert ret["result"] == expected
assert bool(ret["changes"]) == expected
gpg_delete.assert_called_once()
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_absent_test_mode_no_changes(gpg_delete):
with patch.dict(gpg.__opts__, {"test": True}):
ret = gpg.absent("A")
gpg_delete.assert_not_called()
assert ret["result"] is None
assert bool(ret["changes"])
def test_gpg_absent_list_keys_with_gnupghome_and_user(gpg_list_keys):
gnupghome = "/pls_respect_me"
user = "imthereaswell"
gpg.absent("nonexistent", gnupghome=gnupghome, user=user)
gpg_list_keys.assert_called_with(gnupghome=gnupghome, user=user)
@pytest.mark.usefixtures("gpg_list_keys")
def test_gpg_absent_delete_key_called_with_correct_kwargs(gpg_delete):
key = "A"
user = "hellothere"
gnupghome = "/pls_sir"
gpg.absent(key, user=user, gnupghome=gnupghome)
gpg_delete.assert_called_with(keyid=key, gnupghome=gnupghome, user=user)
assert ret["changes"]