-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_04_copy.py
102 lines (69 loc) · 3.1 KB
/
test_04_copy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
""" test copying PGP objects
"""
from __future__ import print_function
import pytest
import copy
import glob
import inspect
import os.path
import six
import pgpy
from pgpy import PGPSignature, PGPUID, PGPMessage, PGPKey
_keys = glob.glob('tests/testdata/keys/*.1.pub.asc') + glob.glob('tests/testdata/keys/*.1.sec.asc')
_msgs = [ 'tests/testdata/messages/message.{}.asc'.format(f) for f in ['signed', 'rsa.cast5.no-mdc', 'rsa.dsa.pass.aes']]
def sig():
return PGPSignature.from_file('tests/testdata/blocks/rsasignature.asc')
def uid():
return PGPUID.new('Abraham Lincoln', comment='Honest Abe', email='[email protected]')
def key(fn):
key, _ = PGPKey.from_file(fn)
return key
def walk_obj(obj, prefix=""):
from enum import Enum
for name, val in inspect.getmembers(obj):
if hasattr(obj.__class__, name):
continue
yield '{}{}'.format(prefix, name), val
if not isinstance(val, Enum):
for n, v in walk_obj(val, prefix="{}{}.".format(prefix, name)):
yield n, v
def check_id(obj):
from datetime import datetime
from enum import Enum
# do some type checking to determine if we should check the identity of an object member
# these types are singletons
if isinstance(obj, (Enum, bool, type(None))):
return False
# these types are immutable
if isinstance(obj, (six.string_types, datetime)):
return False
# integers are kind of a special case.
# ints that do not exceed sys.maxsize are singletons, and in either case are immutable
# this shouldn't apply to MPIs, though, which are subclasses of int
if isinstance(obj, int) and not isinstance(obj, pgpy.packet.types.MPI):
return False
return True
def ksort(key):
# return a tuple of key, key.count('.') so we get a descending alphabetical, ascending depth ordering
return key, key.count('.')
objs = [sig(), uid(),] + [PGPMessage.from_file(m) for m in _msgs] + [key(f) for f in _keys]
cids = ['sig', 'uid',] + [os.path.basename(m) for m in _msgs] + [os.path.basename(f) for f in _keys]
@pytest.mark.parametrize('obj', objs, ids=cids)
def test_copy_obj(request, obj):
obj2 = copy.copy(obj)
objflat = {name: val for name, val in walk_obj(obj, '{}.'.format(request.node.callspec.id))}
obj2flat = {name: val for name, val in walk_obj(obj2, '{}.'.format(request.node.callspec.id))}
for k in sorted(objflat, key=ksort):
print("checking attribute: {} ".format(k), end="")
if isinstance(objflat[k], pgpy.types.SorteDeque):
print("[SorteDeque] ", end="")
assert len(objflat[k]) == len(obj2flat[k])
if not isinstance(objflat[k], (pgpy.types.PGPObject, pgpy.types.SorteDeque)):
print("[{} ]".format(type(objflat[k])), end="")
assert objflat[k] == objflat[k], k
# check identity, but only types that should definitely be copied
if check_id(objflat[k]):
print("[id] {}".format(type(objflat[k])))
assert objflat[k] is not obj2flat[k], "{}: {}".format(type(objflat[k]), k)
else:
print()