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

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 

8 

9# pylint: disable=missing-docstring,broad-exception-caught 

10 

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 

25 

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}' 

48 

49 def ident(self, dkey=None): 

50 if not dkey: 

51 dkey=self.kind 

52 return NAMEMAPPER[dkey] 

53 

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 

60 

61 def setup(self): 

62 pass 

63 

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) 

76 

77 def track_index(self, name: str) -> None: 

78 pass 

79 

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 

101 

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