cactus-test-definitions 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cactus_test_definitions/__init__.py +39 -0
- cactus_test_definitions/__pycache__/__init__.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/actions.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/checks.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/csipaus.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/errors.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/events.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/parameters.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/schema.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
- cactus_test_definitions/__pycache__/test_procedures.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/variable_expressions.cpython-312.pyc +0 -0
- cactus_test_definitions/__pycache__/version.cpython-312.pyc +0 -0
- cactus_test_definitions/client/__init__.py +30 -0
- cactus_test_definitions/client/__pycache__/__init__.cpython-312.pyc +0 -0
- cactus_test_definitions/client/__pycache__/actions.cpython-312.pyc +0 -0
- cactus_test_definitions/client/__pycache__/checks.cpython-312.pyc +0 -0
- cactus_test_definitions/client/__pycache__/events.cpython-312.pyc +0 -0
- cactus_test_definitions/client/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
- cactus_test_definitions/client/__pycache__/validate.cpython-312.pyc +0 -0
- cactus_test_definitions/client/actions.py +99 -0
- cactus_test_definitions/client/checks.py +128 -0
- cactus_test_definitions/client/events.py +71 -0
- cactus_test_definitions/client/procedures/ALL-01.yaml +94 -0
- cactus_test_definitions/client/procedures/ALL-02.yaml +113 -0
- cactus_test_definitions/client/procedures/ALL-03-REJ.yaml +69 -0
- cactus_test_definitions/client/procedures/ALL-03.yaml +110 -0
- cactus_test_definitions/client/procedures/ALL-04.yaml +69 -0
- cactus_test_definitions/client/procedures/ALL-05.yaml +117 -0
- cactus_test_definitions/client/procedures/ALL-06.yaml +128 -0
- cactus_test_definitions/client/procedures/ALL-07.yaml +76 -0
- cactus_test_definitions/client/procedures/ALL-08.yaml +78 -0
- cactus_test_definitions/client/procedures/ALL-09.yaml +111 -0
- cactus_test_definitions/client/procedures/ALL-10.yaml +128 -0
- cactus_test_definitions/client/procedures/ALL-11.yaml +111 -0
- cactus_test_definitions/client/procedures/ALL-12.yaml +126 -0
- cactus_test_definitions/client/procedures/ALL-13.yaml +112 -0
- cactus_test_definitions/client/procedures/ALL-14.yaml +165 -0
- cactus_test_definitions/client/procedures/ALL-15.yaml +109 -0
- cactus_test_definitions/client/procedures/ALL-16.yaml +102 -0
- cactus_test_definitions/client/procedures/ALL-17.yaml +63 -0
- cactus_test_definitions/client/procedures/ALL-18.yaml +289 -0
- cactus_test_definitions/client/procedures/ALL-19.yaml +78 -0
- cactus_test_definitions/client/procedures/ALL-20.yaml +136 -0
- cactus_test_definitions/client/procedures/ALL-21.yaml +203 -0
- cactus_test_definitions/client/procedures/ALL-22.yaml +82 -0
- cactus_test_definitions/client/procedures/ALL-23.yaml +158 -0
- cactus_test_definitions/client/procedures/ALL-24.yaml +132 -0
- cactus_test_definitions/client/procedures/ALL-25-EXT.yaml +228 -0
- cactus_test_definitions/client/procedures/ALL-25.yaml +136 -0
- cactus_test_definitions/client/procedures/ALL-26.yaml +147 -0
- cactus_test_definitions/client/procedures/ALL-27.yaml +144 -0
- cactus_test_definitions/client/procedures/ALL-28.yaml +273 -0
- cactus_test_definitions/client/procedures/ALL-29.yaml +87 -0
- cactus_test_definitions/client/procedures/ALL-30.yaml +188 -0
- cactus_test_definitions/client/procedures/BES-01.yaml +136 -0
- cactus_test_definitions/client/procedures/BES-02.yaml +137 -0
- cactus_test_definitions/client/procedures/BES-03.yaml +135 -0
- cactus_test_definitions/client/procedures/BES-04.yaml +228 -0
- cactus_test_definitions/client/procedures/DRA-01.yaml +54 -0
- cactus_test_definitions/client/procedures/DRA-02.yaml +64 -0
- cactus_test_definitions/client/procedures/DRD-01.yaml +667 -0
- cactus_test_definitions/client/procedures/DRL-01.yaml +327 -0
- cactus_test_definitions/client/procedures/GEN-01.yaml +73 -0
- cactus_test_definitions/client/procedures/GEN-02.yaml +72 -0
- cactus_test_definitions/client/procedures/GEN-03.yaml +160 -0
- cactus_test_definitions/client/procedures/GEN-04.yaml +161 -0
- cactus_test_definitions/client/procedures/GEN-05.yaml +89 -0
- cactus_test_definitions/client/procedures/GEN-06.yaml +90 -0
- cactus_test_definitions/client/procedures/GEN-07.yaml +145 -0
- cactus_test_definitions/client/procedures/GEN-08.yaml +145 -0
- cactus_test_definitions/client/procedures/GEN-09.yaml +117 -0
- cactus_test_definitions/client/procedures/GEN-10.yaml +793 -0
- cactus_test_definitions/client/procedures/GEN-11.yaml +402 -0
- cactus_test_definitions/client/procedures/GEN-12.yaml +402 -0
- cactus_test_definitions/client/procedures/GEN-13.yaml +70 -0
- cactus_test_definitions/client/procedures/LOA-01.yaml +73 -0
- cactus_test_definitions/client/procedures/LOA-02.yaml +73 -0
- cactus_test_definitions/client/procedures/LOA-03.yaml +160 -0
- cactus_test_definitions/client/procedures/LOA-04.yaml +161 -0
- cactus_test_definitions/client/procedures/LOA-05.yaml +89 -0
- cactus_test_definitions/client/procedures/LOA-06.yaml +89 -0
- cactus_test_definitions/client/procedures/LOA-07.yaml +145 -0
- cactus_test_definitions/client/procedures/LOA-08.yaml +145 -0
- cactus_test_definitions/client/procedures/LOA-09.yaml +117 -0
- cactus_test_definitions/client/procedures/LOA-10.yaml +793 -0
- cactus_test_definitions/client/procedures/LOA-11.yaml +402 -0
- cactus_test_definitions/client/procedures/LOA-12.yaml +402 -0
- cactus_test_definitions/client/procedures/LOA-13.yaml +71 -0
- cactus_test_definitions/client/procedures/MUL-01.yaml +92 -0
- cactus_test_definitions/client/procedures/MUL-02.yaml +80 -0
- cactus_test_definitions/client/procedures/MUL-03.yaml +74 -0
- cactus_test_definitions/client/test_procedures.py +185 -0
- cactus_test_definitions/client/validate.py +98 -0
- cactus_test_definitions/csipaus.py +83 -0
- cactus_test_definitions/errors.py +15 -0
- cactus_test_definitions/parameters.py +153 -0
- cactus_test_definitions/py.typed +0 -0
- cactus_test_definitions/schema.py +22 -0
- cactus_test_definitions/server/README.md +172 -0
- cactus_test_definitions/server/__init__.py +27 -0
- cactus_test_definitions/server/__pycache__/__init__.cpython-312.pyc +0 -0
- cactus_test_definitions/server/__pycache__/actions.cpython-312.pyc +0 -0
- cactus_test_definitions/server/__pycache__/checks.cpython-312.pyc +0 -0
- cactus_test_definitions/server/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
- cactus_test_definitions/server/__pycache__/validate.cpython-312.pyc +0 -0
- cactus_test_definitions/server/actions.py +140 -0
- cactus_test_definitions/server/checks.py +152 -0
- cactus_test_definitions/server/procedures/S-ALL-01.yaml +45 -0
- cactus_test_definitions/server/procedures/S-ALL-02.yaml +65 -0
- cactus_test_definitions/server/procedures/S-ALL-03.yaml +65 -0
- cactus_test_definitions/server/procedures/S-ALL-04.yaml +137 -0
- cactus_test_definitions/server/procedures/S-ALL-05.yaml +111 -0
- cactus_test_definitions/server/procedures/S-ALL-06.yaml +111 -0
- cactus_test_definitions/server/procedures/S-ALL-07.yaml +100 -0
- cactus_test_definitions/server/procedures/S-ALL-08.yaml +77 -0
- cactus_test_definitions/server/procedures/S-ALL-09.yaml +43 -0
- cactus_test_definitions/server/procedures/S-ALL-10.yaml +68 -0
- cactus_test_definitions/server/procedures/S-ALL-11.yaml +36 -0
- cactus_test_definitions/server/procedures/S-ALL-12.yaml +36 -0
- cactus_test_definitions/server/procedures/S-ALL-13.yaml +36 -0
- cactus_test_definitions/server/procedures/S-ALL-14.yaml +36 -0
- cactus_test_definitions/server/procedures/S-ALL-15.yaml +79 -0
- cactus_test_definitions/server/procedures/S-ALL-16.yaml +79 -0
- cactus_test_definitions/server/procedures/S-ALL-17.yaml +39 -0
- cactus_test_definitions/server/procedures/S-ALL-18.yaml +35 -0
- cactus_test_definitions/server/procedures/S-ALL-19.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-20.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-21.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-22.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-23.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-24.yaml +37 -0
- cactus_test_definitions/server/procedures/S-ALL-25.yaml +151 -0
- cactus_test_definitions/server/procedures/S-ALL-41.yaml +343 -0
- cactus_test_definitions/server/procedures/S-ALL-42.yaml +81 -0
- cactus_test_definitions/server/procedures/S-ALL-43.yaml +146 -0
- cactus_test_definitions/server/procedures/S-ALL-44.yaml +51 -0
- cactus_test_definitions/server/procedures/S-ALL-45.yaml +34 -0
- cactus_test_definitions/server/procedures/S-ALL-48.yaml +29 -0
- cactus_test_definitions/server/procedures/S-ALL-49.yaml +56 -0
- cactus_test_definitions/server/procedures/S-ALL-51.yaml +35 -0
- cactus_test_definitions/server/procedures/S-ALL-52.yaml +35 -0
- cactus_test_definitions/server/procedures/S-ALL-53.yaml +42 -0
- cactus_test_definitions/server/procedures/S-ALL-55.yaml +45 -0
- cactus_test_definitions/server/procedures/S-ALL-56.yaml +36 -0
- cactus_test_definitions/server/procedures/S-ALL-57.yaml +62 -0
- cactus_test_definitions/server/procedures/S-OPT-01.yaml +42 -0
- cactus_test_definitions/server/procedures/S-OPT-02.yaml +40 -0
- cactus_test_definitions/server/procedures/S-OPT-03.yaml +47 -0
- cactus_test_definitions/server/procedures/S-OPT-04.yaml +32 -0
- cactus_test_definitions/server/procedures/S-OPT-05.yaml +33 -0
- cactus_test_definitions/server/test_procedures.py +156 -0
- cactus_test_definitions/server/validate.py +30 -0
- cactus_test_definitions/variable_expressions.py +419 -0
- cactus_test_definitions-1.8.0.dist-info/METADATA +289 -0
- cactus_test_definitions-1.8.0.dist-info/RECORD +173 -0
- cactus_test_definitions-1.8.0.dist-info/WHEEL +5 -0
- cactus_test_definitions-1.8.0.dist-info/licenses/LICENSE.txt +22 -0
- cactus_test_definitions-1.8.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/unit/__init__.py +0 -0
- tests/unit/client/__init__.py +0 -0
- tests/unit/client/test_actions.py +72 -0
- tests/unit/client/test_checks.py +71 -0
- tests/unit/client/test_events.py +36 -0
- tests/unit/client/test_test_procedures.py +103 -0
- tests/unit/client/test_validate.py +200 -0
- tests/unit/server/__init__.py +0 -0
- tests/unit/server/test_test_procedures.py +60 -0
- tests/unit/server/test_validate.py +75 -0
- tests/unit/test_csipaus.py +49 -0
- tests/unit/test_parameters.py +197 -0
- tests/unit/test_variable_expressions.py +402 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
|
|
2
|
+
# Server Test Schema
|
|
3
|
+
|
|
4
|
+
This is for the **SERVER** test procedures.
|
|
5
|
+
|
|
6
|
+
At its most basic level, a server test is a series of actions by a virtual "client" that will probe the server and look for unexpected behaviour/responses.
|
|
7
|
+
|
|
8
|
+
## Clients and Context
|
|
9
|
+
|
|
10
|
+
Each test will define one or more "virtual clients" as a precondition. These can be restricted to a specific client type (eg Aggregator or Device) or left unspecified.
|
|
11
|
+
|
|
12
|
+
At the beginning of each test, the client will only know it's LFDI, PEN, PIN and certificate details. Through running actions it will discover resources and populate a local "context" which represents the last seen CSIP-Aus resources. Each client's context is seperate, so if Client A performs discovery, those resources will be invisible to Client B.
|
|
13
|
+
|
|
14
|
+
## Steps Schema
|
|
15
|
+
|
|
16
|
+
The most basic building block of a server `TestProcedure` is a `Step`. Each `Step` will always define a single `Action` which dictates the behaviour of a virtual client (eg sending a particular request) which is then followed by a series of `Check` objects to evaluate. In order for a step to pass it must:
|
|
17
|
+
|
|
18
|
+
1) Execute with any errors (eg - able to successfully make a HTTP request to the utility server)
|
|
19
|
+
2) Have all checks return passed
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Steps:
|
|
23
|
+
- id: DISCOVERY
|
|
24
|
+
action:
|
|
25
|
+
type: discovery
|
|
26
|
+
parameters:
|
|
27
|
+
resources:
|
|
28
|
+
- DeviceCapability
|
|
29
|
+
- Time
|
|
30
|
+
- MirrorUsagePointList
|
|
31
|
+
- EndDevice
|
|
32
|
+
- DER
|
|
33
|
+
checks:
|
|
34
|
+
- type: discovered
|
|
35
|
+
parameters:
|
|
36
|
+
resources:
|
|
37
|
+
- DeviceCapability
|
|
38
|
+
- Time
|
|
39
|
+
- MirrorUsagePointList
|
|
40
|
+
- EndDevice
|
|
41
|
+
- DER
|
|
42
|
+
links:
|
|
43
|
+
- ConnectionPoint
|
|
44
|
+
- Registration
|
|
45
|
+
- DERCapability
|
|
46
|
+
- DERSettings
|
|
47
|
+
- DERStatus
|
|
48
|
+
- type: end-device
|
|
49
|
+
parameters:
|
|
50
|
+
matches_client: true
|
|
51
|
+
- type: time-synced
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Step Schema:
|
|
55
|
+
```
|
|
56
|
+
Steps:
|
|
57
|
+
- DESCRIPTIVE_TITLE_OF_STEP: # This is used for display
|
|
58
|
+
action: #
|
|
59
|
+
type: # string identifier of the action type - see table below
|
|
60
|
+
parameters: # Any parameters to modify the default behaviour of the action - see table below
|
|
61
|
+
checks: # A list of Check definitions that will need to be true for this event to trigger - see section on Checks below
|
|
62
|
+
- type: # string identifier of the check type - see table below
|
|
63
|
+
parameters: # Any parameters to modify the default behaviour of the check - see table below
|
|
64
|
+
|
|
65
|
+
client: # The string descriptor of the "Required Client" in the preconditions that will execute this step
|
|
66
|
+
# (Defaults to the first required client)
|
|
67
|
+
|
|
68
|
+
use_client_context: # The string descriptor of the "Required Client" in the preconditions whose context/memory
|
|
69
|
+
# of discovered resources will be used (for testing cross client authentication issues)
|
|
70
|
+
instructions: # List of text strings to render while this test is executing
|
|
71
|
+
repeat_until_pass: # Most steps if failed will abort the test, setting this to true will repeat this step regularly
|
|
72
|
+
# until a pass is recorded (eg - use it to prompt a server to inject a DERControl)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Actions
|
|
77
|
+
|
|
78
|
+
These are the currently defined `Action` elements that can be included in a test.
|
|
79
|
+
|
|
80
|
+
This is an example of an `Action` elements that trigger a client to requests links from the device capability URI until all nominated resources are reached.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
action:
|
|
84
|
+
type: discovery
|
|
85
|
+
parameters:
|
|
86
|
+
resources:
|
|
87
|
+
- Time
|
|
88
|
+
- MirrorUsagePointList
|
|
89
|
+
- EndDevice
|
|
90
|
+
- DER
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
| **name** | **params** | **description** |
|
|
95
|
+
| -------- | ---------- | --------------- |
|
|
96
|
+
| `discovery` | `resources: list[CSIPAusResource]` `next_polling_window: bool/None` `list_limit: int/None` | Performs a full discovery / refresh of the client's context from DeviceCapability downwards, looking to discover the specific resources. Can be delayed until the next polling window and/or fixed to ONLY fetch a maximum number of entities. |
|
|
97
|
+
| `notifications` | `sub_id: str` `collect: bool/None` `disable: bool/None` | `sub_id` must match a previously created subscription. If `collect`, consumes subscription notifications and inserts them into the current context, if `disable` causes the subscription notification webhook to simulate an outage (return HTTP 5XX) |
|
|
98
|
+
| `wait` | `duration_seconds: int` | Performs no action for the nominated period of time |
|
|
99
|
+
| `refresh-resource` | `resource: CSIPAusResource` `expect_rejection: bool/None` `expect_rejection_or_empty: bool/None` | Forces a particular resource to be refreshed (using existing hrefs in context). Can be set to expect a HTTP 4XX ErrorResponse and/or an empty list resource (if appropriate). |
|
|
100
|
+
| `insert-end-device` | `force_lfdi: str/None` `expect_rejection: bool/None` | Causes the client to submit a new EndDevice registration and resolves the returned Location header |
|
|
101
|
+
| `upsert-connection-point` | `connectionPointId: str` `expect_rejection: bool/None` | Causes the client to submit a new ConnectionPoint with ID for the client's EndDevice |
|
|
102
|
+
| `upsert-mup` | `mup_id: str` `location: CSIPAusReadingLocation` `reading_types: list[CSIPAusReadingType]` `mmr_mrids: list[str]/None` `pow10_multiplier: int/None` `expect_rejection: bool/None` | Submits a MirrorUsagePoint with MirrorMeterReading's. Will ensure stable MRID values for the same sets of parameters (unless overridden with mmr_mrids). `mup_id` will alias this MirrorUsagePoint for future action calls. |
|
|
103
|
+
| `insert-readings` | `mup_id: str` `values: ReadingTypeValues` `expect_rejection: bool/None` | Begins the submission of readings (at MUP post rate, to an earlier call to `upsert-mup` with the same `mup_id`). Will interleave transmission with subsequent steps (non blocking) if multiple sets of values are specified |
|
|
104
|
+
| `upsert-der-status` | `genConnectStatus: int/None` `operationalModeStatus: int/None` `alarmStatus: int/None` `expect_rejection: bool/None` | Sends DERStatus - validates that the server persisted the values correctly |
|
|
105
|
+
| `upsert-der-capability` | `type: int` `rtgMaxW: int` `modesSupported: int` `doeModesSupported: int` | Sends DERCapability - validates that the server persisted the values correctly |
|
|
106
|
+
| `upsert-der-settings` | `setMaxW: int` `setGradW: int` `modesEnabled: int` `doeModesEnabled: int` | Sends DERSettings - validates that the server persisted the values correctly |
|
|
107
|
+
| `send-malformed-der-settings` | `updatedTime_missing: bool` | Sends a malformed DERSettings - expects a failure and that the server will NOT change anything |
|
|
108
|
+
| `send-malformed-response` | `mrid_unknown: bool` `endDeviceLFDI_unknown: bool` `response_invalid: bool` | Sends a malformed Response (using the most recent DERControl replyTo) - expects a failure response |
|
|
109
|
+
| `create-subscription` | `sub_id: str` `resource: CSIPAusResource` | Sends a new Subscription - validates that the server persisted the values correctly via Location. `sub_id` will alias this subscription for future action calls. |
|
|
110
|
+
| `delete-subscription` | `sub_id: str` | Sends a deletion for a previously created Subscription. |
|
|
111
|
+
| `respond-der-controls` | None | Enumerates all known DERControls and sends a Response for any that require it. |
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
### Checks
|
|
115
|
+
|
|
116
|
+
A `Check` is a boolean test of what the client has in its current context. They are typically defined as a success/failure condition to be run at the end of a `Step`.
|
|
117
|
+
|
|
118
|
+
| **name** | **params** | **description** |
|
|
119
|
+
| -------- | ---------- | --------------- |
|
|
120
|
+
| `discovered` | `resources: list[CSIPAusResource]` `links: list[CSIPAusResource]` | Does the client's context have the nominated resources (or the parent resource with an appropriate link). |
|
|
121
|
+
| `time-sync` | None | Does the client have a TimeResponse and does it closely map to the client's local time. |
|
|
122
|
+
| `function-set-assignment` | `minimum_count: int/None` `maximum_count: int/None` `matches_client_edev: bool/None` | Are there the correct number of FunctionSetAssignments that may or may not belong solely under the client's EndDevice (or any accessible EndDevice) |
|
|
123
|
+
| `end-device-list` | `minimum_count: int/None` `maximum_count: int/None` `poll_rate: int/None` `sub_id: str/None` | Are there a correct number of EndDeviceList that match the filter criteria |
|
|
124
|
+
| `end-device` | `matches_client: bool` `matches_pin` | Is there an EndDevice that matches the client's LFDI (can be negatively asserted) and does it have a specific Registration PIN |
|
|
125
|
+
| `der-program` | `minimum_count: int/None` `maximum_count: int/None` `primacy: int/None` `fsa_index: int/None` `sub_id: str/None` | Are there enough DERProgram(s) that satisfy the filter criteria? `fsa_index` matches DERPrograms that belong to the nth (0 based) FunctionSetAssignment (negative values count from end of list - eg -1 would match the last FSA) |
|
|
126
|
+
| `der-control` | `minimum_count: int/None` `maximum_count: int/None` `latest: bool/None` `opModImpLimW: float/None` `opModExpLimW: float/None` `opModLoadLimW: float/None` `opModGenLimW: float/None` `opModEnergize: bool/None` `opModConnect: bool/None` `opModFixedW: float/None` `rampTms: int/None` `randomizeStart: int/None` `event_status: int/None` `responseRequired: int/None` `derp_primacy: int/None` `sub_id: str/None` | Are there enough DERProgram(s) that satisfy the filter criteria? `latest` will ONLY match the most recent DERControl. |
|
|
127
|
+
| `default-der-control` | `minimum_count: int/None` `maximum_count: int/None` `opModExpLimW: float/None` `opModLoadLimW: float/None` `opModGenLimW: float/None` `setGradW: int/None` `sub_id: str/None` | Are there the correct number of DefaultDERControl instances with the specified values |
|
|
128
|
+
| `mirror-usage-point` | `matches: bool` `location: CSIPAusReadingLocation/None` `reading_types: list[CSIPAusReadingType]/None` `mmr_mrids: list[str]/None` `post_rate_seconds: int/None` | Does a MirrorUsagePoint exist with the specified values (or not exist if `matches` is false). Only asserts specified values. |
|
|
129
|
+
| `subscription` | `matches: bool` `resource: CSIPAusResource`| Does a Subscription exist for the specified resource (or not exist if `matches` is false). |
|
|
130
|
+
| `poll-rate` | `resource: CSIPAusResource` `poll_rate_seconds: int` | Does the nominated resource have the specified poll rate. |
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
### Parameter Variable Resolution
|
|
134
|
+
|
|
135
|
+
Any `parameter` element expects a series of name/value pairs to pass to the "parent" `Action` or `Check` . For example:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
parameters:
|
|
139
|
+
number_param: 123
|
|
140
|
+
text_param: Text Content
|
|
141
|
+
date_param: 2020-01-02 03:04:05Z
|
|
142
|
+
csip_aus_resource: EndDeviceList
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
But placeholder variables may also be used to reference things that aren't known until the test is underway. For example, the following would instead set `number_param` to the current setMaxW supplied by the client while `date_param` would be set to the moment in time that the `Action`, `Check` or `Event` is being evaluated.
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
parameters:
|
|
150
|
+
number_param: $setMaxW
|
|
151
|
+
text_param: Text Content
|
|
152
|
+
date_param: $now
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The following are all the `NamedVariable` types currently implemented (these are distinct from the named variables
|
|
157
|
+
defined in the client test procedures)
|
|
158
|
+
|
|
159
|
+
| **name** | **description** |
|
|
160
|
+
| -------- | --------------- |
|
|
161
|
+
| `$now` | Resolves to the current moment in time (timezone aware). Returns a datetime |
|
|
162
|
+
| `$setMaxW` | Resolves to the current client configuration value for `DERSetting.setMaxW` as a number. |
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
Expressions are also supported.
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
parameters:
|
|
169
|
+
number_param: $(setMaxW / 2)
|
|
170
|
+
text_param: Text Content
|
|
171
|
+
date_param: $(now - '5 mins')
|
|
172
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from cactus_test_definitions.server.actions import ACTION_PARAMETER_SCHEMA, Action
|
|
2
|
+
from cactus_test_definitions.server.checks import CHECK_PARAMETER_SCHEMA, Check
|
|
3
|
+
from cactus_test_definitions.server.test_procedures import (
|
|
4
|
+
Preconditions,
|
|
5
|
+
Step,
|
|
6
|
+
TestProcedure,
|
|
7
|
+
TestProcedureId,
|
|
8
|
+
get_all_test_procedures,
|
|
9
|
+
get_test_procedure,
|
|
10
|
+
get_yaml_contents,
|
|
11
|
+
parse_test_procedure,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"TestProcedureId",
|
|
16
|
+
"Action",
|
|
17
|
+
"ACTION_PARAMETER_SCHEMA",
|
|
18
|
+
"Check",
|
|
19
|
+
"CHECK_PARAMETER_SCHEMA",
|
|
20
|
+
"Step",
|
|
21
|
+
"Preconditions",
|
|
22
|
+
"TestProcedure",
|
|
23
|
+
"get_all_test_procedures",
|
|
24
|
+
"get_test_procedure",
|
|
25
|
+
"get_yaml_contents",
|
|
26
|
+
"parse_test_procedure",
|
|
27
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from cactus_test_definitions.errors import TestProcedureDefinitionError
|
|
5
|
+
from cactus_test_definitions.parameters import (
|
|
6
|
+
ParameterSchema,
|
|
7
|
+
ParameterType,
|
|
8
|
+
validate_parameters,
|
|
9
|
+
)
|
|
10
|
+
from cactus_test_definitions.variable_expressions import (
|
|
11
|
+
parse_variable_expression_body,
|
|
12
|
+
try_extract_variable_expression,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Action:
|
|
18
|
+
type: str
|
|
19
|
+
client: str | None = None # use the client with this id to execute this action. If None, use the 0th client
|
|
20
|
+
parameters: dict[str, Any] = None # type: ignore # This will be forced in __post_init__
|
|
21
|
+
|
|
22
|
+
def __post_init__(self):
|
|
23
|
+
"""Some parameter values might contain variable expressions (eg: a string "$now") that needs to be replaced
|
|
24
|
+
with an parsed Expression object instead."""
|
|
25
|
+
if self.parameters is None:
|
|
26
|
+
self.parameters = {}
|
|
27
|
+
|
|
28
|
+
for k, v in self.parameters.items():
|
|
29
|
+
variable_expr = try_extract_variable_expression(v)
|
|
30
|
+
if variable_expr:
|
|
31
|
+
self.parameters[k] = parse_variable_expression_body(variable_expr, k)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# The parameter schema for each action, keyed by the action name
|
|
35
|
+
ACTION_PARAMETER_SCHEMA: dict[str, dict[str, ParameterSchema]] = {
|
|
36
|
+
"discovery": {
|
|
37
|
+
"resources": ParameterSchema(True, ParameterType.ListCSIPAusResource), # What resources to try and resolve?
|
|
38
|
+
"next_polling_window": ParameterSchema(
|
|
39
|
+
False, ParameterType.Boolean
|
|
40
|
+
), # If set - delay this until the upcoming polling window (eg- wait for the next whole minute)
|
|
41
|
+
"list_limit": ParameterSchema(False, ParameterType.Integer),
|
|
42
|
+
}, # Performs a full discovery / refresh of the client's context from DeviceCapability downwards
|
|
43
|
+
"notifications": {
|
|
44
|
+
"sub_id": ParameterSchema(True, ParameterType.String), # Must match a previously created subscription
|
|
45
|
+
"collect": ParameterSchema(
|
|
46
|
+
False, ParameterType.Boolean
|
|
47
|
+
), # Collects latest subscription notifications into context
|
|
48
|
+
"disable": ParameterSchema(False, ParameterType.Boolean), # Simulates HTTP 5XX outage at the endpoint
|
|
49
|
+
},
|
|
50
|
+
"wait": {
|
|
51
|
+
"duration_seconds": ParameterSchema(True, ParameterType.Integer)
|
|
52
|
+
}, # Waits (doing nothing - blocking other step actions) until the specified time period has passed
|
|
53
|
+
"comms-status": {
|
|
54
|
+
"notifications_enabled": ParameterSchema(True, ParameterType.Boolean) # Enable/Disble notification webhook
|
|
55
|
+
}, # Enables or disables certain communications
|
|
56
|
+
"refresh-resource": {
|
|
57
|
+
"resource": ParameterSchema(True, ParameterType.CSIPAusResource),
|
|
58
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # if set - expect 4XX and ErrorPayload
|
|
59
|
+
"expect_rejection_or_empty": ParameterSchema(
|
|
60
|
+
False, ParameterType.Boolean
|
|
61
|
+
), # Similar to expect_rejection but also allow en empty list (if it's a list resource)
|
|
62
|
+
}, # Force an existing resource (in the client's context) to be re-fetched via href. Updates context on success
|
|
63
|
+
"insert-end-device": {
|
|
64
|
+
"force_lfdi": ParameterSchema(False, ParameterType.String), # Forces the use of this LFDI
|
|
65
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # If set - expect 4XX and ErrorPayload
|
|
66
|
+
}, # Inserts an EndDevice and then validates the returned Location header
|
|
67
|
+
"upsert-connection-point": {
|
|
68
|
+
"connectionPointId": ParameterSchema(True, ParameterType.String),
|
|
69
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # If set - expect ErrorPayload reasonCode 1
|
|
70
|
+
},
|
|
71
|
+
"upsert-mup": {
|
|
72
|
+
"mup_id": ParameterSchema(True, ParameterType.String), # Used to alias the returned MUP ID
|
|
73
|
+
"location": ParameterSchema(True, ParameterType.CSIPAusReadingLocation),
|
|
74
|
+
"reading_types": ParameterSchema(True, ParameterType.ListCSIPAusReadingType),
|
|
75
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # If set - expect 4XX and ErrorPayload
|
|
76
|
+
"mmr_mrids": ParameterSchema(
|
|
77
|
+
False, ParameterType.ListString
|
|
78
|
+
), # Must correspond 1-1 with reading_types. Used for forcing specific mrid values
|
|
79
|
+
"pow10_multiplier": ParameterSchema(
|
|
80
|
+
False, ParameterType.Integer
|
|
81
|
+
), # Force the use a particular pow10. Defaults to 0 otherwise
|
|
82
|
+
}, # Register a MUP with the specified values. MMR's based on hash of current client / reading types
|
|
83
|
+
"insert-readings": {
|
|
84
|
+
"mup_id": ParameterSchema(True, ParameterType.String), # Must be previously defined with register-mup
|
|
85
|
+
"values": ParameterSchema(
|
|
86
|
+
True, ParameterType.ReadingTypeValues
|
|
87
|
+
), # The sequences of values to send at the MUP post rate
|
|
88
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # If set - expect 4XX and ErrorPayload
|
|
89
|
+
}, # Sends readings - validates that the telemetry is parsed correctly by the server
|
|
90
|
+
"upsert-der-status": {
|
|
91
|
+
"genConnectStatus": ParameterSchema(False, ParameterType.Integer),
|
|
92
|
+
"operationalModeStatus": ParameterSchema(False, ParameterType.Integer),
|
|
93
|
+
"alarmStatus": ParameterSchema(False, ParameterType.Integer),
|
|
94
|
+
"expect_rejection": ParameterSchema(False, ParameterType.Boolean), # If set - expect 4XX and ErrorPayload
|
|
95
|
+
}, # Sends DERStatus - validates that the server persisted the values correctly
|
|
96
|
+
"upsert-der-capability": {
|
|
97
|
+
"type": ParameterSchema(True, ParameterType.Integer),
|
|
98
|
+
"rtgMaxW": ParameterSchema(True, ParameterType.Integer),
|
|
99
|
+
"modesSupported": ParameterSchema(True, ParameterType.Integer),
|
|
100
|
+
"doeModesSupported": ParameterSchema(True, ParameterType.Integer),
|
|
101
|
+
}, # Sends DERCapability - validates that the server persisted the values correctly
|
|
102
|
+
"upsert-der-settings": {
|
|
103
|
+
"setMaxW": ParameterSchema(True, ParameterType.Integer),
|
|
104
|
+
"setGradW": ParameterSchema(True, ParameterType.Integer),
|
|
105
|
+
"modesEnabled": ParameterSchema(True, ParameterType.Integer),
|
|
106
|
+
"doeModesEnabled": ParameterSchema(True, ParameterType.Integer),
|
|
107
|
+
}, # Sends DERSettings - validates that the server persisted the values correctly
|
|
108
|
+
"send-malformed-der-settings": {
|
|
109
|
+
"updatedTime_missing": ParameterSchema(True, ParameterType.Boolean), # If true - updatedTime will be stripped
|
|
110
|
+
}, # Sends a malformed DERSettings - expects a failure and that the server will NOT change anything
|
|
111
|
+
"send-malformed-response": {
|
|
112
|
+
"mrid_unknown": ParameterSchema(True, ParameterType.Boolean), # If true - mrid will be random
|
|
113
|
+
"endDeviceLFDI_unknown": ParameterSchema(True, ParameterType.Boolean), # If true - endDeviceLfdi will be random
|
|
114
|
+
"response_invalid": ParameterSchema(True, ParameterType.Boolean), # If true - response will be a reserved value
|
|
115
|
+
}, # Sends a malformed Response (using the most recent DERControl replyTo) - expects a failure response
|
|
116
|
+
"create-subscription": {
|
|
117
|
+
"sub_id": ParameterSchema(True, ParameterType.String), # Used to alias the returned subscription ID
|
|
118
|
+
"resource": ParameterSchema(True, ParameterType.CSIPAusResource),
|
|
119
|
+
}, # Sends a new Subscription - validates that the server persisted the values correctly via Location
|
|
120
|
+
"delete-subscription": {
|
|
121
|
+
"sub_id": ParameterSchema(True, ParameterType.String), # Must match a previously
|
|
122
|
+
}, # Sends a Subscription deletion
|
|
123
|
+
"respond-der-controls": {}, # Enumerates all known DERControls and sends a Response for any that require it
|
|
124
|
+
}
|
|
125
|
+
VALID_ACTION_NAMES: set[str] = set(ACTION_PARAMETER_SCHEMA.keys())
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def validate_action_parameters(procedure_name: str, step_name: str, action: Action) -> None:
|
|
129
|
+
"""Validates the action parameters for the parent TestProcedure based on the ACTION_PARAMETER_SCHEMA
|
|
130
|
+
|
|
131
|
+
raises TestProcedureDefinitionError on failure"""
|
|
132
|
+
location = f"{procedure_name}.step[{step_name}]" # Descriptive location
|
|
133
|
+
|
|
134
|
+
parameter_schema = ACTION_PARAMETER_SCHEMA.get(action.type, None)
|
|
135
|
+
if parameter_schema is None:
|
|
136
|
+
raise TestProcedureDefinitionError(
|
|
137
|
+
f"{location} has an invalid action name '{action.type}'. Valid Names: {VALID_ACTION_NAMES}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
validate_parameters(location, action.parameters, parameter_schema)
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from cactus_test_definitions.errors import TestProcedureDefinitionError
|
|
5
|
+
from cactus_test_definitions.parameters import (
|
|
6
|
+
ParameterSchema,
|
|
7
|
+
ParameterType,
|
|
8
|
+
validate_parameters,
|
|
9
|
+
)
|
|
10
|
+
from cactus_test_definitions.variable_expressions import (
|
|
11
|
+
parse_variable_expression_body,
|
|
12
|
+
try_extract_variable_expression,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class Check:
|
|
18
|
+
"""A check represents some validation logic that runs during a Test Step and provides a pass/fail result with a
|
|
19
|
+
description. It will typically inspect the state of the client based on what it has seen from the server
|
|
20
|
+
|
|
21
|
+
eg: Ensuring that the client was able to see an EndDevice registration"""
|
|
22
|
+
|
|
23
|
+
type: str
|
|
24
|
+
parameters: dict[str, Any] = None # type: ignore # This will be forced in __post_init__
|
|
25
|
+
|
|
26
|
+
def __post_init__(self):
|
|
27
|
+
"""Some parameter values might contain variable expressions (eg: a string "$now") that needs to be replaced
|
|
28
|
+
with an parsed Expression object instead."""
|
|
29
|
+
if self.parameters is None:
|
|
30
|
+
self.parameters = {}
|
|
31
|
+
for k, v in self.parameters.items():
|
|
32
|
+
variable_expr = try_extract_variable_expression(v)
|
|
33
|
+
if variable_expr:
|
|
34
|
+
self.parameters[k] = parse_variable_expression_body(variable_expr, k)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# The parameter schema for each action, keyed by the action name
|
|
38
|
+
CHECK_PARAMETER_SCHEMA: dict[str, dict[str, ParameterSchema]] = {
|
|
39
|
+
"discovered": {
|
|
40
|
+
"resources": ParameterSchema(False, ParameterType.ListCSIPAusResource),
|
|
41
|
+
"links": ParameterSchema(False, ParameterType.ListCSIPAusResource),
|
|
42
|
+
},
|
|
43
|
+
"time-synced": {}, # Passes if the current Time resource is synced with this client's date/time
|
|
44
|
+
"function-set-assignment": {
|
|
45
|
+
"minimum_count": ParameterSchema(False, ParameterType.Integer), # Needs at least this many FSAs to pass
|
|
46
|
+
"maximum_count": ParameterSchema(False, ParameterType.Integer), # Needs at most this many FSAs to pass
|
|
47
|
+
"matches_client_edev": ParameterSchema(
|
|
48
|
+
False, ParameterType.Boolean
|
|
49
|
+
), # If True - only FSAs assigned to the client's EndDevice will be counted
|
|
50
|
+
"sub_id": ParameterSchema(
|
|
51
|
+
False, ParameterType.String
|
|
52
|
+
), # If set - only FSAs received via this subscription will be counted
|
|
53
|
+
},
|
|
54
|
+
"end-device-list": {
|
|
55
|
+
"minimum_count": ParameterSchema(False, ParameterType.Integer), # Needs at least this many edev lists to pass
|
|
56
|
+
"maximum_count": ParameterSchema(False, ParameterType.Integer), # Needs at most this many edev lists to pass
|
|
57
|
+
"poll_rate": ParameterSchema(
|
|
58
|
+
False, ParameterType.Integer
|
|
59
|
+
), # If set - will only count an EndDeviceList with this exact pollRate
|
|
60
|
+
"sub_id": ParameterSchema(
|
|
61
|
+
False, ParameterType.String
|
|
62
|
+
), # If set - only EndDeviceLists received via this subscription will be counted
|
|
63
|
+
},
|
|
64
|
+
"end-device": {
|
|
65
|
+
"matches_client": ParameterSchema(
|
|
66
|
+
True, ParameterType.Boolean
|
|
67
|
+
), # assert the existence / non existence of an EndDevice for the current client
|
|
68
|
+
"matches_pin": ParameterSchema(
|
|
69
|
+
False, ParameterType.Boolean
|
|
70
|
+
), # if set - The matches_client criteria will ALSO check the registration PIN for the EndDevice. Default False
|
|
71
|
+
},
|
|
72
|
+
"der-program": {
|
|
73
|
+
"minimum_count": ParameterSchema(False, ParameterType.Integer), # Needs at least this many derps to pass
|
|
74
|
+
"maximum_count": ParameterSchema(False, ParameterType.Integer), # Needs at most this many derps to pass
|
|
75
|
+
"primacy": ParameterSchema(False, ParameterType.Integer), # Filters derps based on this primacy value
|
|
76
|
+
"fsa_index": ParameterSchema(
|
|
77
|
+
False, ParameterType.Integer
|
|
78
|
+
), # Filters derps that belong to the nth (0 based) FunctionSetAssignment index
|
|
79
|
+
"sub_id": ParameterSchema(
|
|
80
|
+
False, ParameterType.String
|
|
81
|
+
), # Filters derps to only those received via this named subscription
|
|
82
|
+
},
|
|
83
|
+
"der-control": {
|
|
84
|
+
"minimum_count": ParameterSchema(False, ParameterType.Integer), # Needs at least this many controls to pass
|
|
85
|
+
"maximum_count": ParameterSchema(False, ParameterType.Integer), # Needs at most this many controls to pass
|
|
86
|
+
"latest": ParameterSchema(False, ParameterType.Boolean), # forces filter checks against the most recent control
|
|
87
|
+
"opModImpLimW": ParameterSchema(False, ParameterType.Float), # Filters controls based on this value
|
|
88
|
+
"opModExpLimW": ParameterSchema(False, ParameterType.Float), # Filters controls based on this value
|
|
89
|
+
"opModLoadLimW": ParameterSchema(False, ParameterType.Float), # Filters controls based on this value
|
|
90
|
+
"opModGenLimW": ParameterSchema(False, ParameterType.Float), # Filters controls based on this value
|
|
91
|
+
"opModEnergize": ParameterSchema(False, ParameterType.Boolean), # Filters controls based on this value
|
|
92
|
+
"opModConnect": ParameterSchema(False, ParameterType.Boolean), # Filters controls based on this value
|
|
93
|
+
"opModFixedW": ParameterSchema(False, ParameterType.Float), # Filters controls based on this value
|
|
94
|
+
"rampTms": ParameterSchema(False, ParameterType.Integer), # Filter on this val. 0 means negative assertion
|
|
95
|
+
"randomizeStart": ParameterSchema(False, ParameterType.Integer), # Filter on this val (in seconds)
|
|
96
|
+
"event_status": ParameterSchema(False, ParameterType.Integer), # Filter on Event.status value
|
|
97
|
+
"responseRequired": ParameterSchema(False, ParameterType.Integer), # Filter on responseRequired value
|
|
98
|
+
"derp_primacy": ParameterSchema(
|
|
99
|
+
False, ParameterType.Integer
|
|
100
|
+
), # Filter to control's belonging to a DERProgram with this primacy value
|
|
101
|
+
"sub_id": ParameterSchema(
|
|
102
|
+
False, ParameterType.String
|
|
103
|
+
), # Filters control to only those received via this named subscription
|
|
104
|
+
"duration": ParameterSchema(False, ParameterType.Integer), # Filter on duration value
|
|
105
|
+
}, # Matches many DERControls (specified by minimum_count) against additional other filter criteria
|
|
106
|
+
"default-der-control": {
|
|
107
|
+
"minimum_count": ParameterSchema(False, ParameterType.Integer), # Needs at least this many default der controls
|
|
108
|
+
"maximum_count": ParameterSchema(False, ParameterType.Integer), # Needs at most this many default der controls
|
|
109
|
+
"opModImpLimW": ParameterSchema(False, ParameterType.Float),
|
|
110
|
+
"opModExpLimW": ParameterSchema(False, ParameterType.Float),
|
|
111
|
+
"opModGenLimW": ParameterSchema(False, ParameterType.Float),
|
|
112
|
+
"opModLoadLimW": ParameterSchema(False, ParameterType.Float),
|
|
113
|
+
"setGradW": ParameterSchema(False, ParameterType.Integer), # Hundredths of a percent / second
|
|
114
|
+
"sub_id": ParameterSchema(
|
|
115
|
+
False, ParameterType.String
|
|
116
|
+
), # Filters default control to only those received via this named subscription
|
|
117
|
+
"derp_primacy": ParameterSchema(
|
|
118
|
+
False, ParameterType.Integer
|
|
119
|
+
), # Filter to control's belonging to a DERProgram with this primacy value
|
|
120
|
+
}, # matches any DefaultDERControl with the specified values
|
|
121
|
+
"mirror-usage-point": {
|
|
122
|
+
"matches": ParameterSchema(True, ParameterType.Boolean), # True for positive assert, False for negative assert
|
|
123
|
+
"location": ParameterSchema(False, ParameterType.CSIPAusReadingLocation), # If not specified - match anything
|
|
124
|
+
"reading_types": ParameterSchema(False, ParameterType.ListCSIPAusReadingType), # If not specified - match all
|
|
125
|
+
"mmr_mrids": ParameterSchema(
|
|
126
|
+
False, ParameterType.ListString
|
|
127
|
+
), # Must correspond 1-1 with reading_types. Used for forcing specific mrid values
|
|
128
|
+
"post_rate_seconds": ParameterSchema(False, ParameterType.Integer), # Only asserted if specified
|
|
129
|
+
}, # True if the matches assertion finds a MirrorUsagePoint with the specified parameters (requires exact match)
|
|
130
|
+
"subscription": {
|
|
131
|
+
"matches": ParameterSchema(True, ParameterType.Boolean), # True for positive assert, False for negative assert
|
|
132
|
+
"resource": ParameterSchema(True, ParameterType.CSIPAusResource),
|
|
133
|
+
}, # Matches the existence/nonexistence of a subscription for the specified resource
|
|
134
|
+
"poll-rate": {
|
|
135
|
+
"resource": ParameterSchema(True, ParameterType.CSIPAusResource),
|
|
136
|
+
"poll_rate_seconds": ParameterSchema(True, ParameterType.Integer),
|
|
137
|
+
}, # Asserts a specific poll rate value
|
|
138
|
+
}
|
|
139
|
+
VALID_CHECK_NAMES: set[str] = set(CHECK_PARAMETER_SCHEMA.keys())
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def validate_check_parameters(procedure_name: str, check: Check) -> None:
|
|
143
|
+
"""Validates the check parameters for the parent TestProcedure based on the CHECK_PARAMETER_SCHEMA
|
|
144
|
+
|
|
145
|
+
raises TestProcedureDefinitionError on failure"""
|
|
146
|
+
location = f"{procedure_name} Check: {check.type}" # Descriptive location of this action being validated
|
|
147
|
+
|
|
148
|
+
parameter_schema = CHECK_PARAMETER_SCHEMA.get(check.type, None)
|
|
149
|
+
if parameter_schema is None:
|
|
150
|
+
raise TestProcedureDefinitionError(f"{location} not a valid action name. {VALID_CHECK_NAMES}")
|
|
151
|
+
|
|
152
|
+
validate_parameters(location, check.parameters, parameter_schema)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Description: Discovery with Out-Of-Band registration
|
|
2
|
+
Category: Registration
|
|
3
|
+
Classes:
|
|
4
|
+
- A
|
|
5
|
+
|
|
6
|
+
TargetVersions:
|
|
7
|
+
- v1.2
|
|
8
|
+
|
|
9
|
+
Preconditions:
|
|
10
|
+
required_clients:
|
|
11
|
+
- id: client
|
|
12
|
+
|
|
13
|
+
Steps:
|
|
14
|
+
- id: DISCOVERY
|
|
15
|
+
repeat_until_pass: true
|
|
16
|
+
instructions:
|
|
17
|
+
- Create an EndDevice record with an lfdi/sfdi that matches your client. Ensure it has a single DER record.
|
|
18
|
+
action:
|
|
19
|
+
type: discovery
|
|
20
|
+
parameters:
|
|
21
|
+
resources:
|
|
22
|
+
- DeviceCapability
|
|
23
|
+
- Time
|
|
24
|
+
- MirrorUsagePointList
|
|
25
|
+
- EndDevice
|
|
26
|
+
- DER
|
|
27
|
+
checks:
|
|
28
|
+
- type: discovered
|
|
29
|
+
parameters:
|
|
30
|
+
resources:
|
|
31
|
+
- DeviceCapability
|
|
32
|
+
- Time
|
|
33
|
+
- MirrorUsagePointList
|
|
34
|
+
- EndDevice
|
|
35
|
+
- DER
|
|
36
|
+
links:
|
|
37
|
+
- ConnectionPoint
|
|
38
|
+
- Registration
|
|
39
|
+
- DERCapability
|
|
40
|
+
- DERSettings
|
|
41
|
+
- DERStatus
|
|
42
|
+
- type: end-device
|
|
43
|
+
parameters:
|
|
44
|
+
matches_client: true
|
|
45
|
+
- type: time-synced
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Description: Discovery with In-Band Registration for Direct Clients
|
|
2
|
+
Category: Registration
|
|
3
|
+
Classes:
|
|
4
|
+
- A
|
|
5
|
+
|
|
6
|
+
TargetVersions:
|
|
7
|
+
- v1.2
|
|
8
|
+
|
|
9
|
+
Preconditions:
|
|
10
|
+
required_clients:
|
|
11
|
+
- id: client
|
|
12
|
+
client_type: device
|
|
13
|
+
|
|
14
|
+
Steps:
|
|
15
|
+
- id: PRECONDITION
|
|
16
|
+
repeat_until_pass: true
|
|
17
|
+
instructions:
|
|
18
|
+
- Remove any existing EndDevice registrations for client.
|
|
19
|
+
action:
|
|
20
|
+
type: discovery
|
|
21
|
+
parameters:
|
|
22
|
+
resources:
|
|
23
|
+
- DeviceCapability
|
|
24
|
+
- Time
|
|
25
|
+
- MirrorUsagePointList
|
|
26
|
+
- EndDevice
|
|
27
|
+
- DER
|
|
28
|
+
checks:
|
|
29
|
+
- type: discovered
|
|
30
|
+
parameters:
|
|
31
|
+
resources:
|
|
32
|
+
- DeviceCapability
|
|
33
|
+
- Time
|
|
34
|
+
- MirrorUsagePointList
|
|
35
|
+
- EndDeviceList
|
|
36
|
+
- type: end-device # This will be the check that will block if there is an existing EndDevice registration
|
|
37
|
+
parameters:
|
|
38
|
+
matches_client: false
|
|
39
|
+
- type: time-synced
|
|
40
|
+
|
|
41
|
+
- id: REGISTER
|
|
42
|
+
action:
|
|
43
|
+
type: insert-end-device
|
|
44
|
+
checks:
|
|
45
|
+
- type: end-device
|
|
46
|
+
parameters:
|
|
47
|
+
matches_client: true
|
|
48
|
+
|
|
49
|
+
- id: FETCHING DER INFO
|
|
50
|
+
repeat_until_pass: true
|
|
51
|
+
instructions:
|
|
52
|
+
- Populate DERList with an entry that has a DERCapabilityLink, DERSettingsLink and DERStatusLink.
|
|
53
|
+
action:
|
|
54
|
+
type: discovery
|
|
55
|
+
parameters:
|
|
56
|
+
resources:
|
|
57
|
+
- DER
|
|
58
|
+
checks:
|
|
59
|
+
- type: discovered
|
|
60
|
+
parameters:
|
|
61
|
+
links:
|
|
62
|
+
- DERCapability
|
|
63
|
+
- DERSettings
|
|
64
|
+
- DERStatus
|
|
65
|
+
|