gpgme/lang/python/tests/support.py
Justus Winter ac48499538
python: Make tests more robust.
* lang/python/tests/support.py (TemporaryDirectory): Always use our
own version even if 'tempfile.TemporaryDirectory' is provided, because
we need to use 'shutil.rmtree(..., ignore_errors=True)' to avoid it
tripping over gpg-agent deleting its own sockets.

Signed-off-by: Justus Winter <justus@g10code.com>
2017-03-14 12:20:24 +01:00

111 lines
3.5 KiB
Python

# Copyright (C) 2016 g10 Code GmbH
#
# This file is part of GPGME.
#
# GPGME is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# GPGME is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import, print_function, unicode_literals
del absolute_import, print_function, unicode_literals
import contextlib
import shutil
import sys
import os
import tempfile
import time
import gpg
# known keys
alpha = "A0FF4590BB6122EDEF6E3C542D727CC768697734"
bob = "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2"
encrypt_only = "F52770D5C4DB41408D918C9F920572769B9FE19C"
sign_only = "7CCA20CCDE5394CEE71C9F0BFED153F12F18F45D"
no_such_key = "A" * 40
def make_filename(name):
return os.path.join(os.environ['top_srcdir'], 'tests', 'gpg', name)
def in_srcdir(name):
return os.path.join(os.environ['srcdir'], name)
def init_gpgme(proto):
gpg.core.engine_check_version(proto)
verbose = int(os.environ.get('verbose', 0)) > 1
def print_data(data):
if verbose:
try:
# See if it is a file-like object.
data.seek(0, os.SEEK_SET)
data = data.read()
except:
# Hope for the best.
pass
if hasattr(sys.stdout, "buffer"):
sys.stdout.buffer.write(data)
else:
sys.stdout.write(data)
def mark_key_trusted(ctx, key):
class Editor(object):
def __init__(self):
self.steps = ["trust", "save"]
def edit(self, status, args, out):
if args == "keyedit.prompt":
result = self.steps.pop(0)
elif args == "edit_ownertrust.value":
result = "5"
elif args == "edit_ownertrust.set_ultimate.okay":
result = "Y"
elif args == "keyedit.save.okay":
result = "Y"
else:
result = None
return result
with gpg.Data() as sink:
ctx.op_edit(key, Editor().edit, sink, sink)
# Python3.2 and up has tempfile.TemporaryDirectory, but we cannot use
# that, because there shutil.rmtree is used without
# ignore_errors=True, and that races against gpg-agent deleting its
# sockets.
class TemporaryDirectory(object):
def __enter__(self):
self.path = tempfile.mkdtemp()
return self.path
def __exit__(self, *args):
shutil.rmtree(self.path, ignore_errors=True)
@contextlib.contextmanager
def EphemeralContext():
with TemporaryDirectory() as tmp:
home = os.environ['GNUPGHOME']
shutil.copy(os.path.join(home, "gpg.conf"), tmp)
shutil.copy(os.path.join(home, "gpg-agent.conf"), tmp)
with gpg.Context(home_dir=tmp) as ctx:
yield ctx
# Ask the agent to quit.
agent_socket = os.path.join(tmp, "S.gpg-agent")
ctx.protocol = gpg.constants.protocol.ASSUAN
ctx.set_engine_info(ctx.protocol, file_name=agent_socket)
ctx.assuan_transact(["KILLAGENT"])
# Block until it is really gone.
while os.path.exists(agent_socket):
time.sleep(.01)