Coverage for /Users/buh/.pyenv/versions/3.12.2/envs/es-testbed/lib/python3.12/site-packages/es_testbed/classes/testplan.py: 71%

69 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-23 21:55 -0600

1"""TestPlan Class Definition""" 

2import typing as t 

3from es_testbed.exceptions import TestPlanMisconfig 

4from es_testbed.defaults import TESTPLAN 

5from es_testbed.helpers.utils import randomstr, getlogger 

6from .args import Args 

7from .ilm import IlmBuilder 

8# pylint: disable=missing-docstring 

9 

10class TestPlan(Args): 

11 __test__ = False 

12 def __init__( 

13 self, 

14 settings: t.Dict[str, t.Any] = None, 

15 defaults: t.Dict[str, t.Any] = None, 

16 default_entities: bool = True, 

17 ): 

18 if defaults is None: 18 ↛ 20line 18 didn't jump to line 20, because the condition on line 18 was never false

19 defaults = TESTPLAN 

20 super().__init__(settings=settings, defaults=defaults) 

21 self.logger = getlogger('es_testbed.TestPlan') 

22 self.entities = [] 

23 self.ilm = False 

24 self.prefix = None 

25 self.uniq = randomstr(length=8, lowercase=True) 

26 self.repository = None 

27 self.update_settings(settings) 

28 self.logger.debug('settings = %s', self.asdict) 

29 self.update_ilm() 

30 if not self.entities: 30 ↛ exitline 30 didn't return from function '__init__', because the condition on line 30 was never false

31 if default_entities: 31 ↛ exitline 31 didn't return from function '__init__', because the condition on line 31 was never false

32 self.make_default_entities() 

33 

34 ### Example settings 

35 # settings={ 

36 # 'type': 'indices', # Default is indices? Or should it be data_streams? 

37 # 'prefix': 'es-testbed', # Provide this value as a default 

38 # 'rollover_alias': True, # Only respected if 'type' == 'indices'. 

39 # # Will rollover after creation and filling 

40 # 'uniq': 'my-unique-str', # If not provided, randomstr(length=8, lowercase=True) 

41 # 'repository': Only used for snapshots when ILM is not used. 

42 # 'ilm': { # All of these ILM values are defaults 

43 # 'tiers': ['hot', 'delete'], 

44 # 'forcemerge': False, 

45 # 'max_num_segments': 1, 

46 # 'repository': None, 

47 # } 

48 # 

49 # # If these keys aren't specified per entity, then all entities will get this treatment 

50 # # EXCEPT for the is_write_index for aliases and data_streams 

51 # 

52 # 'defaults': { 

53 # 'entity_count': 3, 

54 # 'docs': 10, 

55 # 'match': True, 

56 # 'searchable': tier... 

57 # } 

58 

59 # # Manually specifying entities makes sense for individual indices, but not so much for 

60 # # alias-backed indices or data_streams 

61 # 'entities': [ 

62 # { 

63 # 'docs': 10, 

64 # 'match': True, 

65 # 'searchable': 'frozen' 

66 # }, 

67 # { 

68 # 'docs': 10, 

69 # 'match': False, 

70 # 'searchable': 'cold', 

71 # }, 

72 # { 

73 # 'docs': 10, 

74 # 'match': True, 

75 # 'searchable': 'frozen' 

76 # }, 

77 # ] 

78 # } 

79 def add_entity( 

80 self, 

81 docs: t.Optional[int] = 10, 

82 match: t.Optional[bool] = True, 

83 searchable: t.Optional[str] = None 

84 ) -> None: 

85 entity = {'docs': docs, 'match': match} 

86 if searchable: 

87 entity['searchable'] = searchable 

88 self.entities.append(entity) 

89 

90 def make_default_entities(self) -> None: 

91 if self.settings and isinstance(self.settings, dict): 91 ↛ 94line 91 didn't jump to line 94, because the condition on line 91 was never false

92 if 'defaults' in self.settings: 92 ↛ 94line 92 didn't jump to line 94, because the condition on line 92 was never false

93 defs = self.settings['defaults'] 

94 kwargs = {'docs': defs['docs'], 'match': defs['match'], 'searchable': defs['searchable']} 

95 for _ in range(0, defs['entity_count']): 

96 self.add_entity(**kwargs) 

97 self.logger.debug('Created %s entities', len(self.entities)) 

98 

99 def update_ilm(self) -> None: 

100 if self.use_ilm(): 

101 self.ilm = IlmBuilder() # Set defaults 

102 for k,v in self.settings['ilm'].items(): 

103 self.logger.debug('IlmBuilder.%s = %s', k, v) 

104 setattr(self.ilm, k, v) 

105 # If cold or frozen tiers weren't included in settings['ilm']['tiers'] 

106 # we manually correct here 

107 for entity in self.entities: 107 ↛ 108line 107 didn't jump to line 108, because the loop on line 107 never started

108 if 'searchable' in entity and entity['searchable'] is not None: 

109 if not entity['searchable'] in self.ilm.tiers: 

110 self.ilm.tiers.append(entity['searchable']) 

111 self.logger.debug('ILM settings = %s', 

112 self.ilm.asdict if isinstance(self.ilm, IlmBuilder) else self.ilm) 

113 

114 

115 def use_ilm(self) -> bool: 

116 use_ilm = False 

117 self.logger.debug('INIT: use_ilm = %s', use_ilm) 

118 if 'ilm' in self.settings: 118 ↛ 128line 118 didn't jump to line 128, because the condition on line 118 was never false

119 if isinstance(self.settings['ilm'], dict): # It's a dictionary, not a bool 

120 self.logger.debug('settings["ilm"] is a dictionary') 

121 use_ilm = True 

122 elif isinstance(self.settings['ilm'], bool): 122 ↛ 125line 122 didn't jump to line 125, because the condition on line 122 was never false

123 self.logger.debug('settings["ilm"] is a bool') 

124 use_ilm = self.settings['ilm'] # Accept whatever the boolean value is 

125 elif self.settings['ilm'] is None: # Empty dict is truthy, but is not None 

126 self.logger.debug('settings["ilm"] is None') 

127 use_ilm = False 

128 if self.entities: 128 ↛ 130line 128 didn't jump to line 130, because the condition on line 128 was never true

129 # Detect if cold or frozen tiers were included in settings['ilm']['tiers'] 

130 for entity in self.entities: 

131 if 'searchable' in entity and entity['searchable'] is not None: 

132 self.logger.debug('Test entities contain searchable snapshots') 

133 if not use_ilm: 

134 raise TestPlanMisconfig( 

135 'Searchable entities were found, but ILM is disabled') 

136 self.logger.debug('FINAL: use_ilm = %s', use_ilm) 

137 return use_ilm