Coverage for src/es_testbed/classes/entitymgrs/entitymgr.py: 84%
107 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-23 13:14 -0600
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-23 13:14 -0600
1"""Entity Class Definition"""
2import typing as t
3from elasticsearch8 import Elasticsearch
4from es_testbed.defaults import NAMEMAPPER, PLURALMAP
5from es_testbed.helpers.es_api import delete, get
6from es_testbed.helpers.utils import getlogger, uniq_values
7from ..testplan import TestPlan
9# pylint: disable=missing-docstring,broad-exception-caught
11class EntityMgr:
12 def __init__(
13 self,
14 client: Elasticsearch = None,
15 plan: TestPlan = None,
16 autobuild: t.Optional[bool] = True,
17 ):
18 self.kind = 'entity_type'
19 self.logger = getlogger('es_testbed.EntityMgr')
20 self.client = client
21 self.plan = plan
22 self.autobuild = autobuild
23 self.entity_list = []
24 self.success = False
26 @property
27 def entity_root(self) -> str:
28 return f'{self.plan.prefix}-{self.ident()}-{self.plan.uniq}'
29 @property
30 def indexlist(self) -> t.Sequence[str]:
31 return []
32 @property
33 def last(self) -> str:
34 """Return the most recently appended item"""
35 return self.entity_list[-1]
36 @property
37 def logdisplay(self) -> str:
38 return self.kind
39 @property
40 def name(self) -> str:
41 return f'{self.entity_root}{self.suffix}'
42 @property
43 def pattern(self) -> str:
44 return f'*{self.entity_root}*'
45 @property
46 def suffix(self) -> str:
47 return f'-{len(self.entity_list) + 1:06}'
49 def ident(self, dkey=None):
50 if not dkey:
51 dkey=self.kind
52 return NAMEMAPPER[dkey]
54 def scan(self) -> t.Sequence[str]:
55 """Find all entities matching our pattern"""
56 entities = get(self.client, self.kind, self.pattern)
57 msg = f'{self.kind} entities found matching pattern "{self.pattern}": {entities}'
58 self.logger.debug(msg)
59 return entities
61 def setup(self):
62 pass
64 def teardown(self):
65 display = PLURALMAP[self.kind] if self.kind in PLURALMAP else self.kind
66 if not self.success: 66 ↛ 67line 66 didn't jump to line 67
67 msg = (
68 f'Setup did not complete successfully. '
69 f'Manual cleanup of {display}s may be necessary.'
70 )
71 self.logger.warning(msg)
72 self.verify(correct=True) # Catch any entities that might exist but not be in entity_list
73 if self.entity_list:
74 if self.iterate_clean(): 74 ↛ exitline 74 didn't return from function 'teardown', because the condition on line 74 was never false
75 self.logger.info('Cleanup of %ss completed successfully.', display)
77 def track_index(self, name: str) -> None:
78 pass
80 def iterate_clean(self) -> None:
81 succeed = True
82 positions = []
83 for idx, entity in enumerate(self.entity_list): # There should only be one, but we cover it
84 value = entity
85 if self.kind == 'index':
86 value = entity.name
87 self.logger.debug('Deleting %s %s', self.logdisplay, value)
88 try:
89 delete(self.client, self.kind, value)
90 except Exception as err:
91 succeed = False
92 msg = f'Unable to delete {self.logdisplay}: {value}. Error: {err}'
93 self.logger.error(msg)
94 continue
95 self.logger.info('Deleted %s %s', self.logdisplay, value)
96 positions.append(idx)
97 positions.sort() # Sort first to ensure lowest to highest order
98 for idx in reversed(positions): # Reverse the list and iterate
99 del self.entity_list[idx] # Delete the value at position idx
100 return succeed
102 def verify(self, correct: bool=False) -> t.Union[t.Sequence[str], None]:
103 retval = None
104 diffs = False
105 curr = self.scan() # This is what entity_list _should_ look like.
106 if self.kind == 'index':
107 entities = self.indexlist
108 else:
109 entities = self.entity_list
110 self.logger.debug('Getting unique values from scan output (not in self.entity_list)')
111 scan_diff = uniq_values(entities, curr)
112 self.logger.debug('Getting unique values in self.entity_list (not in scan)')
113 entity_diff = uniq_values(curr, entities)
114 if entity_diff:
115 diffs = True
116 self.logger.warning('Values in entity_list not found in scan: %s', entity_diff)
117 if scan_diff: 117 ↛ 118line 117 didn't jump to line 118, because the condition on line 117 was never true
118 diffs = True
119 self.logger.info('Values in scan not found in entity_list: %s', scan_diff)
120 if diffs:
121 if correct: 121 ↛ 130line 121 didn't jump to line 130, because the condition on line 121 was never false
122 self.logger.info('Correcting entity_list with values from scan: %s', curr)
123 if self.kind == 'index': 123 ↛ 124line 123 didn't jump to line 124, because the condition on line 123 was never true
124 self.entity_list = []
125 for index in curr:
126 self.track_index(index) # We have to re-create the tracked entities
127 else:
128 self.entity_list = curr
129 else:
130 self.logger.warning('Not correcting entity_list! Values should be: %s', curr)
131 retval = curr
132 return retval