Skip to content
This repository was archived by the owner on Jan 20, 2024. It is now read-only.

Commit 89be575

Browse files
Add new hook on_plugin_not_found for Verification Controller (#41)
* Add New hook on_plugin_not_found for Verification Controller * Update Changelog
1 parent d483a2a commit 89be575

File tree

9 files changed

+113
-7
lines changed

9 files changed

+113
-7
lines changed

Makefile

+6-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ autogen:
2121
ychaos manual --file docs/cli/manual.md > /dev/null
2222

2323
# Builds documentation and serves on http://localhost:8000
24-
.PHONEY: doc
24+
.PHONY: doc
2525
doc:
2626
chmod +x develop/doc.sh
2727
./develop/doc.sh
2828

29-
.PHONEY: docbuild
29+
.PHONY: docbuild
3030
docbuild:
3131
mkdocs build
32+
33+
.PHONY: schema
34+
schema:
35+
python3 develop/autogen_schema.py

docs/releases.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
## Version 0.x.x
44

5-
## Next release (Version 0.1.0)
5+
## Next Release (0.2.0)
6+
7+
1. Fix throwing error when a verification plugin implementation is not found or in development stage
8+
by [Shashank Sharma](https://github.com/shashankrnr32)
9+
10+
## Version 0.1.0
611

712
1. Add documentation to YChaos by [Shashank Sharma](https://github.com/shashankrnr32)
813

src/ychaos/cli/verify.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from ..core.verification.controller import VerificationController
99
from ..core.verification.data import VerificationStateData
1010
from ..testplan import SystemState
11-
from ..testplan.verification import VerificationConfig
11+
from ..testplan.verification import VerificationConfig, VerificationType
1212
from . import YChaosCLIHook, YChaosTestplanInputSubCommand
1313

1414
__all__ = ["Verify"]
@@ -125,6 +125,12 @@ def __call__(self, index: int, config: VerificationConfig):
125125
f"Running [i]{self.state.value.lower()}[/i] state verification of type={config.type.value}[{index}]"
126126
)
127127

128+
class OnPluginNotFoundHook(VerificationHook):
129+
def __call__(self, index: int, plugin_type: VerificationType):
130+
self.console.log(
131+
f"The verification plugin type=[i]{plugin_type.value}[/i][{index}] is not available for use."
132+
)
133+
128134
class OnEachPluginEndHook(VerificationHook):
129135
def __call__(
130136
self,
@@ -150,6 +156,9 @@ def __call__(
150156
verification_controller.register_hook(
151157
"on_each_plugin_end", OnEachPluginEndHook(self.app, self.state)
152158
)
159+
verification_controller.register_hook(
160+
"on_plugin_not_found", OnPluginNotFoundHook(self.app, self.state)
161+
)
153162

154163
self.console.log(
155164
f"Starting [i]{self.state.value.lower()}[/i] state verification."

src/ychaos/core/verification/controller.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ def callable_hook(index: int, config: VerificationConfig, state_data: Verificati
7676
def callable_hook(verify_list: List[bool]): ...
7777
```
7878
79+
=== "on_plugin_not_found"
80+
Hook that gets called when a plugin available in schema is not ready for usage/not implemented.
81+
This case is possible for the plugins that are in Beta/development phase
82+
83+
```python
84+
def callable_hook(index:int, plugin_type: VerificationType): ...
85+
```
86+
7987
---
8088
Each of the hooks get called on a certain event. The caller can register as many hooks for a particular event,
8189
by calling the `register_hook(event_name, hook_method)` method. All the hooks are executed sequentially. The best example
@@ -86,6 +94,7 @@ def callable_hook(verify_list: List[bool]): ...
8694
"on_start",
8795
"on_each_plugin_start",
8896
"on_each_plugin_end",
97+
"on_plugin_not_found",
8998
"on_end",
9099
)
91100

@@ -148,9 +157,17 @@ def execute(self) -> bool:
148157
msg=f"Starting {verification_plugin.type.value} verification"
149158
)
150159
plugin_class = VERIFICATION_PLUGIN_MAP.get(
151-
verification_plugin.type.value
160+
verification_plugin.type.value, None
152161
)
153-
assert plugin_class is not None
162+
163+
if plugin_class is None:
164+
# This can happen when a new plugin is not implemented yet, but is
165+
# available in the schema
166+
self.execute_hooks(
167+
"on_plugin_not_found", index, verification_plugin.type
168+
)
169+
continue
170+
154171
plugin = plugin_class(verification_plugin.config, data)
155172

156173
# Call all the hooks that were registered for `verification_plugin_start`.

src/ychaos/testplan/resources/schema.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"enum": [
4747
"python_module",
4848
"http_request",
49-
"sdv4"
49+
"sdv4",
50+
"noop"
5051
]
5152
},
5253
"VerificationConfig": {

src/ychaos/testplan/verification.py

+7
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class SDv4Verification(SchemaModel):
141141
job_timeout: PositiveInt = Field(default=3600, description="Job Timeout in seconds")
142142

143143

144+
class NoOpConfig(SchemaModel):
145+
pass
146+
147+
144148
class VerificationType(AEnum):
145149
"""
146150
Defines the Type of plugin to be used for verification.
@@ -153,6 +157,9 @@ class VerificationType(AEnum):
153157
HTTP_REQUEST = "http_request", SimpleNamespace(schema=HTTPRequestVerification)
154158
SDV4_VERIFICATION = "sdv4", SimpleNamespace(schema=SDv4Verification)
155159

160+
# For Testing purpose, cannot be used by users.
161+
NOOP = "noop", SimpleNamespace(schema=NoOpConfig)
162+
156163

157164
class VerificationConfig(SchemaModel):
158165
"""

tests/cli/test_verify.py

+21
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,24 @@ def test_verification_for_valid_test_plan_with_invalid_plugin_path_when_not_stri
189189
self.assertTrue(
190190
"The system is verified to be in steady state" in app.get_console_output()
191191
)
192+
193+
def test_verification_for_valid_testplan_with_unimplemented_plugin(self):
194+
args = Namespace()
195+
args.cls = self.cls
196+
197+
testplan_path = self.testplans_directory.joinpath("valid/testplan6.yaml")
198+
199+
# Required Arguments for VerificationCommand
200+
args.testplan = str(testplan_path.resolve())
201+
args.state = "steady"
202+
203+
# Create a Mocked CLI App
204+
app = MockApp(args)
205+
args.app = app
206+
207+
self.assertEqual(0, args.cls.main(args))
208+
209+
self.assertTrue(
210+
"The verification plugin type=noop[0] is not available for use."
211+
in app.get_console_output()
212+
)

tests/core/verification/test_controller.py

+31
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from ychaos.core.verification.controller import VerificationController
99
from ychaos.testplan import SystemState
1010
from ychaos.testplan.schema import TestPlan
11+
from ychaos.testplan.verification import VerificationConfig, VerificationType
1112

1213

1314
class TestVerificationController(TestCase):
@@ -89,3 +90,33 @@ def test_verfication_controller_dump_json_data(self):
8990
self.assertListEqual(
9091
verification_data, verification_controller.get_encoded_verification_data()
9192
)
93+
94+
def test_verification_controller_for_plugin_not_found(self):
95+
self.mock_testplan.verification[0] = VerificationConfig(
96+
states=[
97+
SystemState.STEADY,
98+
],
99+
type=VerificationType.NOOP,
100+
config=dict(),
101+
)
102+
103+
verification_controller = VerificationController(
104+
self.mock_testplan, SystemState.STEADY, list()
105+
)
106+
107+
class MockOnPluginNotFoundHook:
108+
def __init__(self):
109+
self.test_var = False
110+
111+
def __call__(self, *args):
112+
self.test_var = True
113+
114+
mock_on_plugin_not_found_hook = MockOnPluginNotFoundHook()
115+
verification_controller.register_hook(
116+
"on_plugin_not_found", mock_on_plugin_not_found_hook
117+
)
118+
119+
is_verified = verification_controller.execute()
120+
self.assertTrue(is_verified)
121+
122+
self.assertTrue(mock_on_plugin_not_found_hook.test_var)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
description: A valid mock testplan file with un-implemented verification plugin
2+
verification:
3+
- states:
4+
- CHAOS
5+
- STEADY
6+
type: noop
7+
config: {}
8+
attack:
9+
target_type: self
10+
agents:
11+
- type: no_op

0 commit comments

Comments
 (0)