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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
import pytest
from moto.rds.utils import (
ORDERABLE_DB_INSTANCE_ENCODING,
FilterDef,
apply_filter,
decode_orderable_db_instance,
encode_orderable_db_instance,
merge_filters,
validate_filters,
)
class TestFilterValidation:
@classmethod
def setup_class(cls):
cls.filter_defs = {
"not-implemented": FilterDef(None, ""),
"identifier": FilterDef(["identifier"], "Object Identifiers"),
}
def test_unrecognized_filter_raises_exception(self):
filters = {"invalid-filter-name": ["test-value"]}
with pytest.raises(KeyError) as ex:
validate_filters(filters, self.filter_defs)
assert "Unrecognized filter name: invalid-filter-name" in str(ex)
def test_empty_filter_values_raises_exception(self):
filters = {"identifier": []}
with pytest.raises(ValueError) as ex:
validate_filters(filters, self.filter_defs)
assert "Object Identifiers must not be empty" in str(ex)
def test_unimplemented_filter_raises_exception(self):
filters = {"not-implemented": ["test-value"]}
with pytest.raises(NotImplementedError):
validate_filters(filters, self.filter_defs)
class Resource:
def __init__(self, identifier, **kwargs):
self.identifier = identifier
self.__dict__.update(kwargs)
class TestResourceFiltering:
@classmethod
def setup_class(cls):
cls.filter_defs = {
"identifier": FilterDef(["identifier"], "Object Identifiers"),
"nested-resource": FilterDef(["nested.identifier"], "Nested Identifiers"),
"common-attr": FilterDef(["common_attr"], ""),
"multiple-attrs": FilterDef(["common_attr", "uncommon_attr"], ""),
}
cls.resources = {
"identifier-0": Resource("identifier-0"),
"identifier-1": Resource("identifier-1", common_attr="common"),
"identifier-2": Resource("identifier-2"),
"identifier-3": Resource("identifier-3", nested=Resource("nested-id-1")),
"identifier-4": Resource("identifier-4", common_attr="common"),
"identifier-5": Resource("identifier-5", uncommon_attr="common"),
}
def test_filtering_on_nested_attribute(self):
filters = {"nested-resource": ["nested-id-1"]}
filtered_resources = apply_filter(self.resources, filters, self.filter_defs)
assert len(filtered_resources) == 1
assert "identifier-3" in filtered_resources
def test_filtering_on_common_attribute(self):
filters = {"common-attr": ["common"]}
filtered_resources = apply_filter(self.resources, filters, self.filter_defs)
assert len(filtered_resources) == 2
assert "identifier-1" in filtered_resources
assert "identifier-4" in filtered_resources
def test_filtering_on_multiple_attributes(self):
filters = {"multiple-attrs": ["common"]}
filtered_resources = apply_filter(self.resources, filters, self.filter_defs)
assert len(filtered_resources) == 3
assert "identifier-1" in filtered_resources
assert "identifier-4" in filtered_resources
assert "identifier-5" in filtered_resources
def test_filters_with_multiple_values(self):
filters = {"identifier": ["identifier-0", "identifier-3", "identifier-5"]}
filtered_resources = apply_filter(self.resources, filters, self.filter_defs)
assert len(filtered_resources) == 3
assert "identifier-0" in filtered_resources
assert "identifier-3" in filtered_resources
assert "identifier-5" in filtered_resources
def test_multiple_filters(self):
filters = {
"identifier": ["identifier-1", "identifier-3", "identifier-5"],
"common-attr": ["common"],
"multiple-attrs": ["common"],
}
filtered_resources = apply_filter(self.resources, filters, self.filter_defs)
assert len(filtered_resources) == 1
assert "identifier-1" in filtered_resources
class TestMergingFilters:
def test_when_filters_to_update_is_none(self):
filters_to_update = {"filter-name": ["value1"]}
merged = merge_filters(filters_to_update, None)
assert merged == filters_to_update
def test_when_filters_to_merge_is_none(self):
filters_to_merge = {"filter-name": ["value1"]}
merged = merge_filters(None, filters_to_merge)
assert merged == filters_to_merge
def test_when_both_filters_are_none(self):
merged = merge_filters(None, None)
assert merged == {}
def test_values_are_merged(self):
filters_to_update = {"filter-name": ["value1"]}
filters_to_merge = {"filter-name": ["value2"]}
merged = merge_filters(filters_to_update, filters_to_merge)
assert merged == {"filter-name": ["value1", "value2"]}
def test_complex_merge(self):
filters_to_update = {
"filter-name-1": ["value1"],
"filter-name-2": ["value1", "value2"],
"filter-name-3": ["value1"],
}
filters_to_merge = {
"filter-name-1": ["value2"],
"filter-name-3": ["value2"],
"filter-name-4": ["value1", "value2"],
}
merged = merge_filters(filters_to_update, filters_to_merge)
assert len(merged.keys()) == 4
for value in merged.values():
assert value == ["value1", "value2"]
def test_encode_orderable_db_instance():
"""Verify the data can be encoded/decoded to something more compact.
Data from AWS comes in a specific format.
"""
original = {
"Engine": "neptune",
"EngineVersion": "1.0.3.0",
"DBInstanceClass": "db.r4.2xlarge",
"LicenseModel": "amazon-license",
"AvailabilityZones": [
{"Name": "us-east-1a"},
{"Name": "us-east-1b"},
{"Name": "us-east-1c"},
{"Name": "us-east-1d"},
{"Name": "us-east-1e"},
{"Name": "us-east-1f"},
],
"MultiAZCapable": False,
"ReadReplicaCapable": False,
"Vpc": True,
"SupportsStorageEncryption": True,
"StorageType": "aurora",
"SupportsIops": False,
"SupportsEnhancedMonitoring": False,
"SupportsIAMDatabaseAuthentication": True,
"SupportsPerformanceInsights": False,
"AvailableProcessorFeatures": [],
"SupportedEngineModes": ["provisioned"],
"SupportsKerberosAuthentication": False,
"OutpostCapable": False,
"SupportedActivityStreamModes": [],
"SupportsGlobalDatabases": False,
"SupportsClusters": True,
"Support edNetworkTypes": ["IPV4"],
}
short = encode_orderable_db_instance(original)
assert decode_orderable_db_instance(short) == original
def test_encode_orderable_db_instance__short_format():
"""Verify this works in a random format.
We don't know for sure what AWS returns, so it should always work
regardless of the input.
"""
short = {
"Engine": "neptune",
"EngineVersion": "1.0.3.0",
"DBInstanceClass": "db.r4.2xlarge",
"LicenseModel": "amazon-license",
"SupportsKerberosAuthentication": False,
"OutpostCapable": False,
"SupportedActivityStreamModes": [],
"SupportsGlobalDatabases": False,
"SupportsClusters": True,
"SupportedNetworkTypes": ["IPV4"],
}
assert decode_orderable_db_instance(encode_orderable_db_instance(short)) == short
def test_verify_encoding_is_unique():
assert len(set(ORDERABLE_DB_INSTANCE_ENCODING.values())) == len(
ORDERABLE_DB_INSTANCE_ENCODING.keys()
)
|