Skip to content

Commit 67f6a33

Browse files
authored
Merge pull request #11 from untergeek/rel/0.11.0
Release 0.11.0 prep
2 parents bac2f28 + 3b2047f commit 67f6a33

31 files changed

+1386
-1410
lines changed

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ keywords = [
3333
dependencies = [
3434
'gitpython==3.1.43',
3535
'dotmap==1.3.30',
36-
'es_client>=8.17.5',
37-
'es-wait>=0.12.0',
38-
'tiered_debug==1.0.0',
36+
'es_client>=8.18.0',
37+
'es-wait>=0.14.0',
38+
'tiered_debug==1.1.0',
3939
]
4040

4141
[project.optional-dependencies]

src/es_testbed/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""Make classes easier to import here"""
22

3-
__version__ = '0.10.0'
3+
__version__ = '0.11.0'
44

55
from es_testbed._base import TestBed
66
from es_testbed._plan import PlanBuilder
7+
from es_testbed.debug import debug
78

8-
__all__ = ['TestBed', 'PlanBuilder']
9+
__all__ = ['TestBed', 'PlanBuilder', 'debug']

src/es_testbed/_base.py

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
from importlib import import_module
66
from datetime import datetime, timezone
77
from shutil import rmtree
8-
import tiered_debug as debug
9-
from es_testbed.exceptions import ResultNotExpected
10-
from es_testbed.defaults import NAMEMAPPER
11-
from es_testbed.helpers.es_api import delete, get
12-
from es_testbed.helpers.utils import prettystr, process_preset
13-
from es_testbed._plan import PlanBuilder
14-
from es_testbed.mgrs import (
8+
from .debug import debug, begin_end
9+
from .defaults import NAMEMAPPER
10+
from .es_api import delete, get
11+
from .exceptions import ResultNotExpected
12+
from .utils import prettystr, process_preset
13+
from ._plan import PlanBuilder
14+
from .mgrs import (
1515
ComponentMgr,
1616
DataStreamMgr,
1717
IlmMgr,
@@ -107,8 +107,8 @@ def __init__(
107107
#: The data_stream entity manager
108108
self.data_streammgr = None
109109

110+
@begin_end()
110111
def _erase(self, kind: str, lst: t.Sequence[str]) -> None:
111-
debug.lv2('Starting method...')
112112
overall_success = True
113113
if not lst:
114114
debug.lv3(f'{kind}: nothing to delete.')
@@ -118,15 +118,14 @@ def _erase(self, kind: str, lst: t.Sequence[str]) -> None:
118118
overall_success = False not in ilm # No False values == True
119119
else:
120120
overall_success = self._while(kind, ','.join(lst))
121-
debug.lv3('Exiting method, returning value')
122-
debug.lv5(f'Value = {overall_success}')
121+
debug.lv5(f'Return value = {overall_success}')
123122
return overall_success
124123

125-
def _fodder_generator(
124+
@begin_end()
125+
def _erase_all(
126126
self,
127127
) -> t.Generator[str, t.Sequence[str], None]:
128128
"""Method to delete everything matching our pattern(s)"""
129-
debug.lv2('Starting method...')
130129
items = ['index', 'data_stream', 'snapshot', 'template', 'component', 'ilm']
131130
for i in items:
132131
if i == 'snapshot' and self.plan.repository is None:
@@ -135,10 +134,9 @@ def _fodder_generator(
135134
pattern = f'*{self.plan.prefix}-{NAMEMAPPER[i]}-{self.plan.uniq}*'
136135
entities = get(self.client, i, pattern, repository=self.plan.repository)
137136
yield (i, entities)
138-
debug.lv3('Exiting method')
139137

138+
@begin_end()
140139
def _while(self, kind: str, item: str) -> bool:
141-
debug.lv2('Starting method...')
142140
count = 1
143141
success = False
144142
exc = None
@@ -160,11 +158,11 @@ def _while(self, kind: str, item: str) -> bool:
160158
)
161159
return success
162160

161+
@begin_end()
163162
def get_ilm_polling(self) -> None:
164163
"""
165164
Get current ILM polling settings and store them in self.plan.polling_interval
166165
"""
167-
debug.lv2('Starting method...')
168166
debug.lv3('Storing current ILM polling settings, if any...')
169167
try:
170168
debug.lv4('TRY: Getting cluster settings')
@@ -191,25 +189,17 @@ def get_ilm_polling(self) -> None:
191189
retval = None # Must be an actual value to go into a DotMap
192190
self.plan.ilm_polling_interval = retval
193191
debug.lv3(f'Stored ILM Polling Interval: {retval}')
194-
debug.lv3('Exiting method')
195192

193+
@begin_end()
196194
def ilm_polling(self, interval: t.Union[str, None] = None) -> t.Dict:
197195
"""Return persistent cluster settings to speed up ILM polling during testing"""
198-
debug.lv2('Starting method...')
199196
retval = {'indices.lifecycle.poll_interval': interval}
200-
debug.lv3('Exiting method, returning value')
201-
debug.lv5(f'Value = {retval}')
197+
debug.lv5(f'Return value = {retval}')
202198
return retval
203199

204-
def set_debug_tier(self, tier: int) -> None:
205-
"""
206-
Set the debug tier globally for this module
207-
"""
208-
debug.set_level(tier)
209-
200+
@begin_end()
210201
def setup(self) -> None:
211202
"""Setup the instance"""
212-
debug.lv2('Starting method...')
213203
start = datetime.now(timezone.utc)
214204
# If we build self.plan here, then we can modify settings before setup()
215205
self.plan = PlanBuilder(settings=self.settings).plan
@@ -219,13 +209,12 @@ def setup(self) -> None:
219209
self.setup_entitymgrs()
220210
end = datetime.now(timezone.utc)
221211
debug.lv1(f'Testbed setup elapsed time: {(end - start).total_seconds()}')
222-
debug.lv3('Exiting method')
223212

213+
@begin_end()
224214
def setup_entitymgrs(self) -> None:
225215
"""
226216
Setup each EntityMgr child class
227217
"""
228-
debug.lv2('Starting method...')
229218
kw = {'client': self.client, 'plan': self.plan}
230219

231220
self.ilmmgr = IlmMgr(**kw)
@@ -242,17 +231,16 @@ def setup_entitymgrs(self) -> None:
242231
if self.plan.type == 'data_stream':
243232
self.data_streammgr = DataStreamMgr(**kw, snapmgr=self.snapshotmgr)
244233
self.data_streammgr.setup()
245-
debug.lv3('Exiting method')
246234

235+
@begin_end()
247236
def teardown(self) -> None:
248237
"""Tear down anything we created"""
249-
debug.lv2('Starting method...')
250238
start = datetime.now(timezone.utc)
251239
successful = True
252240
if self.plan.tmpdir:
253241
debug.lv3(f'Removing tmpdir: {self.plan.tmpdir}')
254242
rmtree(self.plan.tmpdir) # Remove the tmpdir stored here
255-
for kind, list_of_kind in self._fodder_generator():
243+
for kind, list_of_kind in self._erase_all():
256244
if not self._erase(kind, list_of_kind):
257245
successful = False
258246
persist = self.ilm_polling(interval=self.plan.ilm_polling_interval)
@@ -268,4 +256,3 @@ def teardown(self) -> None:
268256
else:
269257
logger.error('Cleanup was unsuccessful/incomplete')
270258
self.plan.cleanup = successful
271-
debug.lv3('Exiting method')

src/es_testbed/_plan.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import typing as t
44
import logging
55
from dotmap import DotMap
6-
import tiered_debug as debug
7-
from es_testbed.defaults import TESTPLAN
8-
from es_testbed.helpers.utils import build_ilm_policy, prettystr, randomstr
6+
from .debug import debug, begin_end
7+
from .defaults import TESTPLAN
8+
from .utils import build_ilm_policy, prettystr, randomstr
99

1010
logger = logging.getLogger(__name__)
1111

@@ -114,8 +114,8 @@ def plan(self) -> DotMap:
114114
"""Return the Plan"""
115115
return self._plan
116116

117+
@begin_end()
117118
def _create_lists(self) -> None:
118-
debug.lv2('Starting method...')
119119
names = [
120120
'indices',
121121
'data_stream',
@@ -126,30 +126,27 @@ def _create_lists(self) -> None:
126126
]
127127
for name in names:
128128
self._plan[name] = []
129-
debug.lv3('Exiting method')
130129

130+
@begin_end()
131131
def setup(self) -> None:
132132
"""Do initial setup of the Plan DotMap"""
133-
debug.lv2('Starting method...')
134133
self._plan.uniq = randomstr(length=8, lowercase=True)
135134
self._create_lists()
136135
self.update(self.settings) # Override with settings.
137136
self.update_rollover_alias()
138137
debug.lv3('Rollover alias updated')
139138
self.update_ilm()
140139
debug.lv5(f'FINAL PLAN: {prettystr(self._plan.toDict())}')
141-
debug.lv3('Exiting method')
142140

141+
@begin_end()
143142
def update(self, settings: t.Dict) -> None:
144143
"""Update the Plan DotMap"""
145-
debug.lv2('Starting method...')
146144
self._plan.update(DotMap(settings))
147145
debug.lv5(f'Updated plan: {prettystr(self._plan.toDict())}')
148-
debug.lv3('Exiting method')
149146

147+
@begin_end()
150148
def update_ilm(self) -> None:
151149
"""Update the ILM portion of the Plan DotMap"""
152-
debug.lv2('Starting method...')
153150
setdefault = False
154151
if 'ilm' not in self._plan:
155152
debug.lv3('key "ilm" is not in plan')
@@ -194,14 +191,12 @@ def update_ilm(self) -> None:
194191
}
195192
debug.lv5(f'KWARGS = {kwargs}')
196193
self._plan.ilm.policy = build_ilm_policy(**kwargs)
197-
debug.lv3('Exiting method')
198194

195+
@begin_end()
199196
def update_rollover_alias(self) -> None:
200197
"""Update the Rollover Alias value"""
201-
debug.lv2('Starting method...')
202198
if self._plan.rollover_alias:
203199
self._plan.rollover_alias = f'{self._plan.prefix}-idx-{self._plan.uniq}'
204200
else:
205201
self._plan.rollover_alias = None
206202
debug.lv5(f'Updated rollover_alias = {self._plan.rollover_alias}')
207-
debug.lv3('Exiting method')

src/es_testbed/debug.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Tiered Debugging module"""
2+
3+
import typing as t
4+
from functools import wraps
5+
from tiered_debug import TieredDebug
6+
7+
debug = TieredDebug()
8+
9+
10+
def begin_end(begin: t.Optional[int] = 2, end: t.Optional[int] = 3) -> t.Callable:
11+
"""Decorator to log the beginning and end of a function.
12+
13+
This decorator will log the beginning and end of a function call at the
14+
specified levels, defaulting to 2 for the beginning and 3 for the ending.
15+
16+
:return: The decorated function.
17+
:rtype: Callable
18+
"""
19+
mmap = {
20+
1: debug.lv1,
21+
2: debug.lv2,
22+
3: debug.lv3,
23+
4: debug.lv4,
24+
5: debug.lv5,
25+
}
26+
27+
def decorator(func: t.Callable) -> t.Callable:
28+
@wraps(func)
29+
def wrapper(*args, **kwargs):
30+
common = f"CALL: {func.__name__}()"
31+
mmap[begin](f"BEGIN {common}", stklvl=debug.stacklevel + 1)
32+
result = func(*args, **kwargs)
33+
mmap[end](f"END {common}", stklvl=debug.stacklevel + 1)
34+
return result
35+
36+
return wrapper
37+
38+
return decorator

src/es_testbed/defaults.py

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,19 @@
33
import typing as t
44

55
EPILOG: str = 'Learn more at https://github.com/untergeek/es-testbed'
6+
"""Epilog for the Click CLI"""
67

78
HELP_OPTIONS: dict = {'help_option_names': ['-h', '--help']}
8-
9-
ARGSCLASSES: list = ['IlmBuilder', 'IlmExplain', 'TestPlan']
9+
"""Default help options for Click commands"""
1010

1111
COLD_PREFIX: str = 'restored-'
12+
"""Prefix for cold searchable snapshot indices"""
13+
1214
FROZEN_PREFIX: str = 'partial-'
15+
"""Prefix for frozen searchable snapshot indices"""
1316

1417
SS_PREFIX: t.Dict[str, str] = {'cold': COLD_PREFIX, 'frozen': FROZEN_PREFIX}
15-
16-
MAPPING: dict = {
17-
'properties': {
18-
'@timestamp': {'type': 'date'},
19-
'message': {'type': 'keyword'},
20-
'number': {'type': 'long'},
21-
'nested': {'properties': {'key': {'type': 'keyword'}}},
22-
'deep': {
23-
'properties': {
24-
'l1': {
25-
'properties': {'l2': {'properties': {'l3': {'type': 'keyword'}}}}
26-
}
27-
}
28-
},
29-
}
30-
}
18+
"""Dictionary of prefixes for searchable snapshot indices"""
3119

3220
NAMEMAPPER: t.Dict[str, str] = {
3321
'index': 'idx',
@@ -38,14 +26,18 @@
3826
'template': 'tmpl',
3927
'snapshot': 'snp',
4028
}
29+
"""Mapping of names to abbreviations for use in the CLI"""
4130

4231
PAUSE_DEFAULT: str = '1.0'
32+
"""Default value for the pause time in seconds"""
4333
PAUSE_ENVVAR: str = 'ES_TESTBED_PAUSE'
34+
"""Environment variable for the pause time"""
4435

4536
PLURALMAP: t.Dict[str, str] = {
4637
'ilm': 'ILM Policies',
4738
'index': 'indices',
4839
}
40+
"""Mapping of singular to plural names for use in the CLI"""
4941

5042
TESTPLAN: dict = {
5143
'type': 'indices',
@@ -77,9 +69,12 @@
7769
'storage': 'shared_cache',
7870
},
7971
}
72+
"""Default values for the ILM tiers"""
8073

8174
TIMEOUT_DEFAULT: str = '30'
75+
"""Default timeout for the testbed in seconds"""
8276
TIMEOUT_ENVVAR: str = 'ES_TESTBED_TIMEOUT'
77+
"""Environment variable for the testbed timeout"""
8378

8479
# Define IlmPhase as a typing alias to be reused multiple times
8580
#
@@ -97,6 +92,7 @@
9792
IlmPhase = t.Dict[
9893
str, t.Union[str, t.Dict[str, str], t.Dict[str, t.Dict[str, t.Dict[str, str]]]]
9994
]
95+
"""ILM Phase type alias"""
10096

10197

10298
def ilmhot() -> IlmPhase:

src/es_testbed/entities/alias.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
# pylint: disable=C0115,C0116,R0902,R0904,R0913,R0917
44
import typing as t
55
import logging
6-
import tiered_debug as debug
7-
from es_testbed.entities.entity import Entity
8-
from es_testbed.helpers.es_api import resolver, rollover
9-
from es_testbed.helpers.utils import prettystr
6+
from ..debug import debug, begin_end
7+
from ..es_api import resolver, rollover
8+
from ..utils import prettystr
9+
from .entity import Entity
1010

1111
if t.TYPE_CHECKING:
1212
from elasticsearch8 import Elasticsearch
@@ -25,14 +25,13 @@ def __init__(
2525
super().__init__(client=client, name=name)
2626
debug.lv3('Alias entity object initialized')
2727

28+
@begin_end()
2829
def rollover(self) -> None:
2930
"""Rollover the alias"""
30-
debug.lv2('Starting method...')
3131
rollover(self.client, self.name)
32-
debug.lv3('Exiting method')
3332

33+
@begin_end()
3434
def verify(self, index_list: t.Sequence[str]) -> bool:
35-
debug.lv2('Starting method...')
3635
retval = False
3736
res = resolver(self.client, self.name)
3837
debug.lv5(f'resolver response: {prettystr(res)}')
@@ -48,6 +47,5 @@ def verify(self, index_list: t.Sequence[str]) -> bool:
4847
debug.lv3(f'Confirm match of indices backed by alias {self.name}')
4948
retval = True
5049
break
51-
debug.lv3('Exiting method, returning value')
52-
debug.lv5(f'Value = {retval}')
50+
debug.lv5(f'Return value = {retval}')
5351
return retval

0 commit comments

Comments
 (0)