-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathtest_most_recent.py
132 lines (96 loc) · 4.91 KB
/
test_most_recent.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
"""Functional tests for ``dynamodb_encryption_sdk.material_providers.most_recent``."""
from collections import defaultdict
import pytest
from mock import MagicMock, sentinel
from dynamodb_encryption_sdk.exceptions import NoKnownVersionError
from dynamodb_encryption_sdk.material_providers import CryptographicMaterialsProvider
from dynamodb_encryption_sdk.material_providers.most_recent import MostRecentProvider
from dynamodb_encryption_sdk.material_providers.store import ProviderStore
pytestmark = [pytest.mark.functional, pytest.mark.local]
class SentinelCryptoMaterialsProvider(CryptographicMaterialsProvider):
def __init__(self, name, version):
self.name = name
self.version = version
self._material_description = version
self.provider_calls = []
def encryption_materials(self, encryption_context):
self.provider_calls.append(("encryption_materials", encryption_context))
return getattr(sentinel, "{name}_{version}_encryption".format(name=self.name, version=self.version))
def decryption_materials(self, encryption_context):
self.provider_calls.append(("decryption_materials", encryption_context))
return getattr(sentinel, "{name}_{version}_decryption".format(name=self.name, version=self.version))
class MockProviderStore(ProviderStore):
def __init__(self):
self.provider_calls = []
self._providers = defaultdict(dict)
def get_or_create_provider(self, material_name, version):
self.provider_calls.append(("get_or_create_provider", material_name, version))
try:
return self._providers[material_name][version]
except KeyError:
self._providers[material_name][version] = SentinelCryptoMaterialsProvider(material_name, version)
return self._providers[material_name][version]
def max_version(self, material_name):
self.provider_calls.append(("max_version", material_name))
try:
return sorted(self._providers[material_name].keys())[-1]
except IndexError:
raise NoKnownVersionError('No known version for name: "{}"'.format(material_name))
def version_from_material_description(self, material_description):
self.provider_calls.append(("version_from_material_description", material_description))
return material_description
def test_failed_lock_acquisition():
store = MagicMock(__class__=ProviderStore)
provider = MostRecentProvider(provider_store=store, material_name="my material", version_ttl=10.0)
provider._version = 9
provider._cache.put(provider._version, sentinel.nine)
with provider._lock:
test = provider._get_most_recent_version(allow_local=True)
assert test is sentinel.nine
assert not store.mock_calls
def test_encryption_materials_cache_use():
store = MockProviderStore()
name = "material"
provider = MostRecentProvider(provider_store=store, material_name=name, version_ttl=10.0)
test1 = provider.encryption_materials(sentinel.encryption_context_1)
assert test1 is sentinel.material_0_encryption
assert provider._version == 0
assert len(provider._cache._cache) == 1
expected_calls = [
("max_version", name),
("get_or_create_provider", name, 0),
("version_from_material_description", 0),
]
assert store.provider_calls == expected_calls
test2 = provider.encryption_materials(sentinel.encryption_context_1)
assert test2 is sentinel.material_0_encryption
assert provider._version == 0
assert len(provider._cache._cache) == 1
assert store.provider_calls == expected_calls
def test_decryption_materials_cache_use():
store = MockProviderStore()
name = "material"
provider = MostRecentProvider(provider_store=store, material_name=name, version_ttl=10.0)
context = MagicMock(material_description=0)
test1 = provider.decryption_materials(context)
assert test1 is sentinel.material_0_decryption
assert len(provider._cache._cache) == 1
expected_calls = [("version_from_material_description", 0), ("get_or_create_provider", name, 0)]
assert store.provider_calls == expected_calls
test2 = provider.decryption_materials(context)
assert test2 is sentinel.material_0_decryption
assert len(provider._cache._cache) == 1
expected_calls.append(("version_from_material_description", 0))
assert store.provider_calls == expected_calls