Coverage for /Users/buh/.pyenv/versions/3.12.2/envs/es-testbed/lib/python3.12/site-packages/es_testbed/classes/plan.py: 71%
78 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-27 20:59 -0600
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-27 20:59 -0600
1"""TestPlan Class Definition"""
3import typing as t
4from dotmap import DotMap
5from es_testbed.defaults import TESTPLAN
6from es_testbed.helpers.utils import build_ilm_policy, getlogger, randomstr
8# pylint: disable=missing-docstring
11class PlanBuilder:
13 def __init__(
14 self,
15 settings: t.Dict = None,
16 default_entities: bool = True,
17 autobuild: t.Optional[bool] = True,
18 ):
19 self.logger = getlogger('es_testbed.PlanBuilder')
20 self.default_entities = default_entities
21 if settings is None: 21 ↛ 22line 21 didn't jump to line 22, because the condition on line 21 was never true
22 settings = TESTPLAN
23 self.settings = settings
24 self._plan = DotMap(TESTPLAN)
25 self._plan.cleanup = 'UNKNOWN'
26 if autobuild: 26 ↛ exitline 26 didn't return from function '__init__', because the condition on line 26 was never false
27 self.setup()
29 # ## Example settings
30 # settings={
31 # 'type': 'indices', # Default is indices? Or should it be data_streams?
32 # 'prefix': 'es-testbed', # Provide this value as a default
33 # 'rollover_alias': False, # Only respected if 'type' == 'indices'.
34 # # Will rollover after creation and filling 1st
35 # # If True, will be overridden to value of alias
36 # # If False, will be overridden with None
37 # 'uniq': 'my-unique-str', # If not provided, randomstr()
38 # 'repository': # Only used for cold/frozen tier for snapshots
39 # 'ilm': { # All of these ILM values are defaults
40 # 'enabled': False,
41 # 'tiers': ['hot', 'delete'],
42 # 'forcemerge': False,
43 # 'max_num_segments': 1,
44 # }
45 #
46 # # If these keys aren't specified per entity, then all entities will get this
47 # # treatment
48 # # EXCEPT for the is_write_index for aliases and data_streams
49 #
50 # 'defaults': {
51 # 'entity_count': 3,
52 # 'docs': 10,
53 # 'match': True,
54 # 'searchable': tier...
55 # }
56 #
57 # # Manually specifying entities makes sense for individual indices, but not so
58 # # much for
59 # # alias-backed indices or data_streams
60 # 'entities': [
61 # {
62 # 'docs': 10,
63 # 'match': True,
64 # 'searchable': 'frozen'
65 # },
66 # {
67 # 'docs': 10,
68 # 'match': False,
69 # 'searchable': 'cold',
70 # },
71 # {
72 # 'docs': 10,
73 # 'match': True,
74 # 'searchable': 'hot'
75 # },
76 # ]
77 # }
79 @property
80 def plan(self) -> DotMap:
81 return self._plan
83 def _create_lists(self) -> None:
84 names = [
85 'indices',
86 'data_stream',
87 'snapshots',
88 'ilm_policies',
89 'index_templates',
90 'component_templates',
91 ]
92 for name in names:
93 self._plan[name] = []
95 def add_entity(
96 self,
97 docs: t.Optional[int] = 10,
98 match: t.Optional[bool] = True,
99 searchable: t.Optional[str] = None,
100 ) -> None:
101 entity = {'docs': docs, 'match': match}
102 if searchable:
103 entity['searchable'] = searchable
104 self._plan.entities.append(entity)
106 def make_default_entities(self) -> None:
107 defs = TESTPLAN['defaults'] # Start with defaults
108 if 'defaults' in self._plan: 108 ↛ 110line 108 didn't jump to line 110
109 defs = self._plan.defaults
110 kwargs = {
111 'docs': defs['docs'],
112 'match': defs['match'],
113 'searchable': defs['searchable'],
114 }
115 for _ in range(0, defs['entity_count']):
116 self.add_entity(**kwargs)
117 self.logger.debug(
118 'Plan will create %s (backing) indices', len(self._plan.entities)
119 )
121 def setup(self) -> None:
122 self._plan.uniq = randomstr(length=8, lowercase=True)
123 self._create_lists()
124 self.update(self.settings) # Override with settings.
125 self.update_rollover_alias()
126 self.update_ilm()
127 if not self._plan.entities: 127 ↛ 130line 127 didn't jump to line 130, because the condition on line 127 was never false
128 if self.default_entities: 128 ↛ 130line 128 didn't jump to line 130, because the condition on line 128 was never false
129 self.make_default_entities()
130 self.logger.debug('Test Plan: %s', self._plan.pprint())
132 def update(self, settings: t.Dict) -> None:
133 self._plan.update(**settings)
135 def update_ilm(self) -> None:
136 setdefault = False
137 if 'ilm' not in self._plan: 137 ↛ 138line 137 didn't jump to line 138, because the condition on line 137 was never true
138 self.logger.debug('key "ilm" is not in plan')
139 setdefault = True
140 if isinstance(self._plan.ilm, dict): 140 ↛ 143line 140 didn't jump to line 143, because the condition on line 140 was never false
141 _ = DotMap(self._plan.ilm)
142 self._plan.ilm = _
143 if isinstance(self._plan.ilm, DotMap): 143 ↛ 150line 143 didn't jump to line 150, because the condition on line 143 was never false
144 if 'enabled' not in self._plan.ilm: 144 ↛ 146line 144 didn't jump to line 146, because the condition on line 144 was never true
145 # Override with defaults
146 self.logger.debug(
147 'plan.ilm does not have key "enabled". Overriding with defaults'
148 )
149 setdefault = True
150 elif isinstance(self._plan.ilm, bool):
151 if self._plan.ilm:
152 self.logger.warning(
153 '"plan.ilm: True" is incorrect. Use plan.ilm.enabled: True'
154 )
155 self.logger.debug('plan.ilm is boolean. Overriding with defaults')
156 setdefault = True
157 if setdefault: 157 ↛ 158line 157 didn't jump to line 158, because the condition on line 157 was never true
158 self.logger.debug('Setting defaults for ILM')
159 self._plan.ilm = DotMap(TESTPLAN['ilm'])
160 ilm = self._plan.ilm
161 for entity in self._plan.entities: 161 ↛ 162line 161 didn't jump to line 162, because the loop on line 161 never started
162 if 'searchable' in entity and entity['searchable'] is not None:
163 if not entity['searchable'] in ilm.tiers:
164 ilm.tiers.append(entity['searchable'])
165 kwargs = {
166 'tiers': ilm.tiers,
167 'forcemerge': ilm.forcemerge,
168 'max_num_segments': ilm.max_num_segments,
169 'repository': self._plan.repository,
170 }
171 self._plan.ilm.policy = build_ilm_policy(**kwargs)
173 def update_rollover_alias(self) -> None:
174 if self._plan.rollover_alias:
175 self._plan.rollover_alias = f'{self._plan.prefix}-idx-{self._plan.uniq}'
176 else:
177 self._plan.rollover_alias = None