Skip to content

Commit c9ae34d

Browse files
authored
Merge branch 'master' into cve-2020-14343
2 parents 4b3276c + 7a0c6b5 commit c9ae34d

File tree

7 files changed

+94
-1
lines changed

7 files changed

+94
-1
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
[Unreleased]: https://github.com/chaostoolkit/chaostoolkit-lib/compare/1.16.0...HEAD
66

7+
### Added
8+
9+
- Activities can be requested not to be executed on a per activity basis, not
10+
just as all or none. This can be used by a control to dynamically make
11+
a decision on what to run.
12+
- Test that demonstrate how to wrap controls into decorators [#197][197]
13+
14+
[197]: https://github.com/chaostoolkit/chaostoolkit-lib/issues/197
15+
716
## [1.16.0][] - 2020-12-02
817

918
[1.16.0]: https://github.com/chaostoolkit/chaostoolkit-lib/compare/1.15.1...1.16.0

chaoslib/activity.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ def execute_activity(experiment: Experiment, activity: Activity,
144144

145145
with controls(level="activity", experiment=experiment, context=activity,
146146
configuration=configuration, secrets=secrets) as control:
147+
dry = activity.get("dry", dry)
147148
pauses = activity.get("pauses", {})
148149
pause_before = pauses.get("before")
149150
if pause_before:

requirements-dev.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
requests-mock
22
coverage
33
pycodestyle
4-
pytest>=2.8
4+
pytest~=5.0; python_version < '3.6'
5+
pytest~=6.2; python_version >= '3.6'
56
pytest-cov
67
pytest-sugar
78
ply==3.4
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from functools import wraps
2+
from itertools import count
3+
from typing import Callable
4+
5+
from logzero import logger
6+
7+
from chaoslib.types import Journal
8+
9+
counter = None
10+
11+
12+
def initcounter(f: Callable) -> Callable:
13+
@wraps(f)
14+
def wrapped(*args, **kwargs) -> None:
15+
global counter
16+
counter = count()
17+
f(*args, **kwargs)
18+
return wrapped
19+
20+
21+
def keepcount(f: Callable) -> Callable:
22+
@wraps(f)
23+
def wrapped(*args, **kwargs) -> None:
24+
next(counter)
25+
f(*args, **kwargs)
26+
return wrapped
27+
28+
29+
@keepcount
30+
def after_activity_control(**kwargs):
31+
logger.info("Activity is called")
32+
33+
34+
@initcounter
35+
def configure_control(**kwargs):
36+
logger.info("configure is called")
37+
38+
39+
def after_experiment_control(state: Journal, **kwargs):
40+
state["counted_activities"] = next(counter)

tests/fixtures/experiments.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,17 @@
310310
}
311311
]
312312

313+
ExperimentWithDecoratedControls = deepcopy(ExperimentNoControls)
314+
ExperimentWithDecoratedControls["controls"] = [
315+
{
316+
"name": "dummy",
317+
"provider": {
318+
"type": "python",
319+
"module": "fixtures.controls.dummy_with_decorated_control"
320+
}
321+
}
322+
]
323+
313324
ExperimentWithControlsRequiringSecrets = deepcopy(ExperimentWithControls)
314325
ExperimentWithControlsRequiringSecrets["secrets"] = {
315326
"mystuff": {
@@ -1003,3 +1014,21 @@
10031014
}
10041015
]
10051016
}
1017+
1018+
ExperimentWithBypassedActivity = {
1019+
"version": "1.0.0",
1020+
"title": "do stuff",
1021+
"description": "n/a",
1022+
"method": [
1023+
{
1024+
"type": "action",
1025+
"name": "say-hello",
1026+
"dry": True,
1027+
"provider": {
1028+
"type": "process",
1029+
"path": "echo",
1030+
"arguments": "hello"
1031+
}
1032+
}
1033+
]
1034+
}

tests/test_control.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,3 +580,9 @@ def test_secrets_are_passed_to_all_control_hookpoints():
580580
"after_hypothesis_control", "before_activity_control",
581581
"after_activity_control"):
582582
assert exp["{}_secrets".format(hookpoint)] == secrets, "{} was not provided the secrets".format(hookpoint)
583+
584+
585+
def test_control_can_be_decorated_functions():
586+
exp = deepcopy(experiments.ExperimentWithDecoratedControls)
587+
state = run_experiment(exp)
588+
assert state["counted_activities"] == 4

tests/test_experiment.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ def test_can_run_experiment_in_dry_mode():
137137
assert isinstance(journal, dict)
138138

139139

140+
def test_can_run_experiment_with_activity_in_dry_mode():
141+
experiment = experiments.ExperimentWithBypassedActivity.copy()
142+
journal = run_experiment(experiment)
143+
assert isinstance(journal, dict)
144+
assert journal["run"][0]["output"] == None
145+
146+
140147
def test_can_iterate_over_activities():
141148
g = run_activities(
142149
experiments.Experiment, configuration=None, secrets=None, pool=None,

0 commit comments

Comments
 (0)