cactus-test-definitions 1.6.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.
Potentially problematic release.
This version of cactus-test-definitions might be problematic. Click here for more details.
- 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 +26 -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 +98 -0
- cactus_test_definitions/client/checks.py +127 -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 +108 -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 +288 -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 +274 -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 +739 -0
- cactus_test_definitions/client/procedures/GEN-11.yaml +378 -0
- cactus_test_definitions/client/procedures/GEN-12.yaml +378 -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 +741 -0
- cactus_test_definitions/client/procedures/LOA-11.yaml +378 -0
- cactus_test_definitions/client/procedures/LOA-12.yaml +378 -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 +81 -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 +170 -0
- cactus_test_definitions/server/__init__.py +23 -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 +139 -0
- cactus_test_definitions/server/checks.py +117 -0
- cactus_test_definitions/server/procedures/S-ALL-01.yaml +42 -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-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 +44 -0
- cactus_test_definitions/server/procedures/S-OPT-04.yaml +32 -0
- cactus_test_definitions/server/test_procedures.py +122 -0
- cactus_test_definitions/server/validate.py +30 -0
- cactus_test_definitions/variable_expressions.py +419 -0
- cactus_test_definitions-1.6.0.dist-info/METADATA +289 -0
- cactus_test_definitions-1.6.0.dist-info/RECORD +139 -0
- cactus_test_definitions-1.6.0.dist-info/WHEEL +5 -0
- cactus_test_definitions-1.6.0.dist-info/licenses/LICENSE.txt +22 -0
- cactus_test_definitions-1.6.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 +153 -0
- tests/unit/server/__init__.py +0 -0
- tests/unit/server/test_test_procedures.py +60 -0
- tests/unit/server/test_validate.py +62 -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,137 @@
|
|
|
1
|
+
Description: Support for Multiple End Clients
|
|
2
|
+
Category: Registration
|
|
3
|
+
Classes:
|
|
4
|
+
- A
|
|
5
|
+
|
|
6
|
+
TargetVersions:
|
|
7
|
+
- v1.2
|
|
8
|
+
|
|
9
|
+
Preconditions:
|
|
10
|
+
required_clients:
|
|
11
|
+
- id: CLIENT-A
|
|
12
|
+
- id: CLIENT-B
|
|
13
|
+
|
|
14
|
+
Steps:
|
|
15
|
+
- id: CLIENT-A PRECONDITION
|
|
16
|
+
repeat_until_pass: true
|
|
17
|
+
client: CLIENT-A
|
|
18
|
+
instructions:
|
|
19
|
+
- Create at least 5 DERControls for CLIENT-A
|
|
20
|
+
action:
|
|
21
|
+
type: discovery
|
|
22
|
+
parameters:
|
|
23
|
+
resources:
|
|
24
|
+
- DERControl
|
|
25
|
+
checks:
|
|
26
|
+
- type: end-device
|
|
27
|
+
parameters:
|
|
28
|
+
matches_client: true
|
|
29
|
+
- type: der-control
|
|
30
|
+
parameters:
|
|
31
|
+
minimum_count: 5
|
|
32
|
+
|
|
33
|
+
- id: CLIENT-B PRECONDITION
|
|
34
|
+
repeat_until_pass: true
|
|
35
|
+
client: CLIENT-B
|
|
36
|
+
instructions:
|
|
37
|
+
- Create at least 5 DERControls for CLIENT-B
|
|
38
|
+
action:
|
|
39
|
+
type: discovery
|
|
40
|
+
parameters:
|
|
41
|
+
resources:
|
|
42
|
+
- DERControl
|
|
43
|
+
checks:
|
|
44
|
+
- type: end-device
|
|
45
|
+
parameters:
|
|
46
|
+
matches_client: true
|
|
47
|
+
- type: der-control
|
|
48
|
+
parameters:
|
|
49
|
+
minimum_count: 5
|
|
50
|
+
|
|
51
|
+
- id: CLIENT-A DISCOVER MUPS
|
|
52
|
+
repeat_until_pass: true
|
|
53
|
+
client: CLIENT-A
|
|
54
|
+
instructions:
|
|
55
|
+
- MirrorUsagePoints for CLIENT-A must be initially empty.
|
|
56
|
+
action:
|
|
57
|
+
type: discovery
|
|
58
|
+
parameters:
|
|
59
|
+
resources:
|
|
60
|
+
- MirrorUsagePoint
|
|
61
|
+
checks:
|
|
62
|
+
- type: mirror-usage-point
|
|
63
|
+
parameters:
|
|
64
|
+
matches: false # This will only match an empty list
|
|
65
|
+
|
|
66
|
+
- id: CLIENT-B DISCOVER MUPS
|
|
67
|
+
repeat_until_pass: true
|
|
68
|
+
client: CLIENT-B
|
|
69
|
+
instructions:
|
|
70
|
+
- MirrorUsagePoints for CLIENT-B must be initially empty.
|
|
71
|
+
action:
|
|
72
|
+
type: discovery
|
|
73
|
+
parameters:
|
|
74
|
+
resources:
|
|
75
|
+
- MirrorUsagePoint
|
|
76
|
+
checks:
|
|
77
|
+
- type: mirror-usage-point
|
|
78
|
+
parameters:
|
|
79
|
+
matches: false # This will only match an empty list
|
|
80
|
+
|
|
81
|
+
- id: CLIENT-A CREATE MUPS
|
|
82
|
+
client: CLIENT-A
|
|
83
|
+
action:
|
|
84
|
+
type: upsert-mup
|
|
85
|
+
parameters:
|
|
86
|
+
mup_id: mupa
|
|
87
|
+
location: Device
|
|
88
|
+
reading_types:
|
|
89
|
+
- ActivePowerAverage
|
|
90
|
+
- VoltageSinglePhaseAverage
|
|
91
|
+
checks:
|
|
92
|
+
- type: mirror-usage-point
|
|
93
|
+
parameters:
|
|
94
|
+
matches: true
|
|
95
|
+
location: Device
|
|
96
|
+
reading_types:
|
|
97
|
+
- ActivePowerAverage
|
|
98
|
+
- VoltageSinglePhaseAverage
|
|
99
|
+
|
|
100
|
+
- id: CLIENT-B CREATE MUPS
|
|
101
|
+
client: CLIENT-B
|
|
102
|
+
action:
|
|
103
|
+
type: upsert-mup
|
|
104
|
+
parameters:
|
|
105
|
+
mup_id: mupb
|
|
106
|
+
location: Device
|
|
107
|
+
reading_types:
|
|
108
|
+
- ActivePowerAverage
|
|
109
|
+
- VoltageSinglePhaseAverage
|
|
110
|
+
checks:
|
|
111
|
+
- type: mirror-usage-point
|
|
112
|
+
parameters:
|
|
113
|
+
matches: true
|
|
114
|
+
location: Device
|
|
115
|
+
reading_types:
|
|
116
|
+
- ActivePowerAverage
|
|
117
|
+
- VoltageSinglePhaseAverage
|
|
118
|
+
|
|
119
|
+
- id: CLIENT-A SEND READINGS
|
|
120
|
+
client: CLIENT-A
|
|
121
|
+
action:
|
|
122
|
+
type: insert-readings
|
|
123
|
+
parameters:
|
|
124
|
+
mup_id: mupa
|
|
125
|
+
values:
|
|
126
|
+
ActivePowerAverage: [1000, 1234, 0, -4567]
|
|
127
|
+
VoltageSinglePhaseAverage: [241.1, 232.2, 233.9, 244.1]
|
|
128
|
+
|
|
129
|
+
- id: CLIENT-B SEND READINGS
|
|
130
|
+
client: CLIENT-B
|
|
131
|
+
action:
|
|
132
|
+
type: insert-readings
|
|
133
|
+
parameters:
|
|
134
|
+
mup_id: mupb
|
|
135
|
+
values:
|
|
136
|
+
ActivePowerAverage: [2000, 2234, 0, -8567]
|
|
137
|
+
VoltageSinglePhaseAverage: [243.1, 233.2, 234.9, 240]
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Description: Authorisation
|
|
2
|
+
Category: Registration
|
|
3
|
+
Classes:
|
|
4
|
+
- A
|
|
5
|
+
|
|
6
|
+
TargetVersions:
|
|
7
|
+
- v1.2
|
|
8
|
+
|
|
9
|
+
Preconditions:
|
|
10
|
+
required_clients:
|
|
11
|
+
- id: CLIENT-A
|
|
12
|
+
client_type: device
|
|
13
|
+
- id: CLIENT-B
|
|
14
|
+
client_type: device
|
|
15
|
+
|
|
16
|
+
Steps:
|
|
17
|
+
- id: (A) PRECONDITION
|
|
18
|
+
repeat_until_pass: true
|
|
19
|
+
client: CLIENT-A
|
|
20
|
+
instructions:
|
|
21
|
+
- Create an EndDevice registration for CLIENT-A (or rerun S-ALL-02 / S-ALL-03).
|
|
22
|
+
action:
|
|
23
|
+
type: discovery
|
|
24
|
+
parameters:
|
|
25
|
+
resources:
|
|
26
|
+
- EndDevice
|
|
27
|
+
- DERControlList
|
|
28
|
+
- DER
|
|
29
|
+
checks:
|
|
30
|
+
- type: end-device
|
|
31
|
+
parameters:
|
|
32
|
+
matches_client: true
|
|
33
|
+
|
|
34
|
+
- id: (B) PRECONDITION
|
|
35
|
+
repeat_until_pass: true
|
|
36
|
+
client: CLIENT-B
|
|
37
|
+
instructions:
|
|
38
|
+
- Create an EndDevice registration for CLIENT-B (or rerun S-ALL-02 / S-ALL-03).
|
|
39
|
+
action:
|
|
40
|
+
type: discovery
|
|
41
|
+
parameters:
|
|
42
|
+
resources:
|
|
43
|
+
- EndDevice
|
|
44
|
+
- DERControlList
|
|
45
|
+
- DER
|
|
46
|
+
checks:
|
|
47
|
+
- type: end-device
|
|
48
|
+
parameters:
|
|
49
|
+
matches_client: true
|
|
50
|
+
|
|
51
|
+
- id: (A-B) AUTH EndDeviceList
|
|
52
|
+
client: CLIENT-A
|
|
53
|
+
use_client_context: CLIENT-B
|
|
54
|
+
action:
|
|
55
|
+
type: refresh-resource
|
|
56
|
+
parameters:
|
|
57
|
+
resource: EndDeviceList
|
|
58
|
+
expect_rejection: true
|
|
59
|
+
|
|
60
|
+
- id: (A-B) AUTH DerControlList
|
|
61
|
+
client: CLIENT-A
|
|
62
|
+
use_client_context: CLIENT-B
|
|
63
|
+
action:
|
|
64
|
+
type: refresh-resource
|
|
65
|
+
parameters:
|
|
66
|
+
resource: DERControlList
|
|
67
|
+
expect_rejection: true
|
|
68
|
+
|
|
69
|
+
- id: (A-B) AUTH DERStatus
|
|
70
|
+
client: CLIENT-A
|
|
71
|
+
use_client_context: CLIENT-B
|
|
72
|
+
action:
|
|
73
|
+
type: upsert-der-status
|
|
74
|
+
parameters:
|
|
75
|
+
genConnectStatus: 1
|
|
76
|
+
expect_rejection: true
|
|
77
|
+
|
|
78
|
+
- id: (A-B) AUTH MirrorUsagePoint
|
|
79
|
+
client: CLIENT-A
|
|
80
|
+
use_client_context: CLIENT-B
|
|
81
|
+
action:
|
|
82
|
+
type: upsert-mup
|
|
83
|
+
parameters:
|
|
84
|
+
expect_rejection: true
|
|
85
|
+
mup_id: mupa
|
|
86
|
+
location: Device
|
|
87
|
+
reading_types:
|
|
88
|
+
- ActivePowerAverage
|
|
89
|
+
- VoltageSinglePhaseAverage
|
|
90
|
+
|
|
91
|
+
- id: (A) OK EndDeviceList
|
|
92
|
+
client: CLIENT-A
|
|
93
|
+
action:
|
|
94
|
+
type: refresh-resource
|
|
95
|
+
parameters:
|
|
96
|
+
resource: EndDeviceList
|
|
97
|
+
checks:
|
|
98
|
+
- type: end-device
|
|
99
|
+
parameters:
|
|
100
|
+
matches_client: true
|
|
101
|
+
|
|
102
|
+
- id: (A) DISALLOW ACCESS
|
|
103
|
+
repeat_until_pass: true
|
|
104
|
+
instructions:
|
|
105
|
+
- Remove EndDevice entry for ClientA (or disallow access).
|
|
106
|
+
client: CLIENT-A
|
|
107
|
+
action:
|
|
108
|
+
type: refresh-resource
|
|
109
|
+
parameters:
|
|
110
|
+
resource: EndDeviceList
|
|
111
|
+
expect_rejection_or_empty: true
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Description: Discovery Rejecting In-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: PRECONDITION
|
|
15
|
+
repeat_until_pass: true
|
|
16
|
+
instructions:
|
|
17
|
+
- Create an EndDevice registration for client (or rerun S-ALL-02 / S-ALL-03).
|
|
18
|
+
action:
|
|
19
|
+
type: discovery
|
|
20
|
+
parameters:
|
|
21
|
+
resources:
|
|
22
|
+
- DeviceCapability
|
|
23
|
+
- Time
|
|
24
|
+
- MirrorUsagePointList
|
|
25
|
+
- EndDevice
|
|
26
|
+
- DER
|
|
27
|
+
checks:
|
|
28
|
+
- type: end-device # This will be the check that will block UNTIL there is an existing EndDevice registration
|
|
29
|
+
parameters:
|
|
30
|
+
matches_client: true
|
|
31
|
+
|
|
32
|
+
- id: REGISTER AGAIN
|
|
33
|
+
action:
|
|
34
|
+
type: insert-end-device
|
|
35
|
+
parameters:
|
|
36
|
+
expect_rejection: true
|
|
37
|
+
checks:
|
|
38
|
+
- type: end-device
|
|
39
|
+
parameters:
|
|
40
|
+
matches_client: true
|
|
41
|
+
|
|
42
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Description: Incorrect Connection Point 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: PRECONDITION
|
|
15
|
+
repeat_until_pass: true
|
|
16
|
+
instructions:
|
|
17
|
+
- Create an EndDevice registration for client (or rerun S-ALL-02 / S-ALL-03).
|
|
18
|
+
action:
|
|
19
|
+
type: discovery
|
|
20
|
+
parameters:
|
|
21
|
+
resources:
|
|
22
|
+
- DeviceCapability
|
|
23
|
+
- Time
|
|
24
|
+
- MirrorUsagePointList
|
|
25
|
+
- EndDevice
|
|
26
|
+
- DER
|
|
27
|
+
checks:
|
|
28
|
+
- type: end-device # This will be the check that will block UNTIL there is an existing EndDevice registration
|
|
29
|
+
parameters:
|
|
30
|
+
matches_client: true
|
|
31
|
+
|
|
32
|
+
- id: SEND BAD CONNECTION POINT ID
|
|
33
|
+
action:
|
|
34
|
+
type: upsert-connection-point
|
|
35
|
+
parameters:
|
|
36
|
+
connectionPointId: NOTAVALIDID
|
|
37
|
+
expect_rejection: true
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Description: Connection Point 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: PRECONDITION
|
|
15
|
+
repeat_until_pass: true
|
|
16
|
+
instructions:
|
|
17
|
+
- Create an EndDevice registration for client (or rerun S-ALL-02 / S-ALL-03).
|
|
18
|
+
action:
|
|
19
|
+
type: discovery
|
|
20
|
+
parameters:
|
|
21
|
+
resources:
|
|
22
|
+
- DeviceCapability
|
|
23
|
+
- Time
|
|
24
|
+
- MirrorUsagePointList
|
|
25
|
+
- EndDevice
|
|
26
|
+
- DER
|
|
27
|
+
checks:
|
|
28
|
+
- type: end-device # This will be the check that will block UNTIL there is an existing EndDevice registration
|
|
29
|
+
parameters:
|
|
30
|
+
matches_client: true
|
|
31
|
+
|
|
32
|
+
- id: SEND CONNECTION POINT ID
|
|
33
|
+
action:
|
|
34
|
+
type: upsert-connection-point
|
|
35
|
+
parameters:
|
|
36
|
+
connectionPointId: "1234567890" # A valid NMI (in the testing range)
|
|
37
|
+
checks:
|
|
38
|
+
- type: discovered
|
|
39
|
+
parameters:
|
|
40
|
+
links:
|
|
41
|
+
- ConnectionPoint
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Description: Client Registration and PIN Validation
|
|
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: MATCH PIN
|
|
15
|
+
repeat_until_pass: true
|
|
16
|
+
instructions:
|
|
17
|
+
- Create an EndDevice (with RegistrationLink) registration for client (or rerun S-ALL-02 / S-ALL-03).
|
|
18
|
+
action:
|
|
19
|
+
type: discovery
|
|
20
|
+
parameters:
|
|
21
|
+
resources:
|
|
22
|
+
- Registration
|
|
23
|
+
checks:
|
|
24
|
+
- type: end-device # This will be the check that will block UNTIL there is an existing EndDevice registration
|
|
25
|
+
parameters:
|
|
26
|
+
matches_client: true
|
|
27
|
+
matches_pin: true
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import StrEnum
|
|
3
|
+
from importlib import resources
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
from cactus_test_definitions.csipaus import CSIPAusVersion
|
|
7
|
+
from cactus_test_definitions.schema import UniqueKeyLoader
|
|
8
|
+
from cactus_test_definitions.server.actions import Action
|
|
9
|
+
from cactus_test_definitions.server.checks import Check
|
|
10
|
+
from dataclass_wizard import LoadMeta, YAMLWizard
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestProcedureId(StrEnum):
|
|
14
|
+
"""The set of all available test ID's
|
|
15
|
+
|
|
16
|
+
This should be kept in sync with the current set of test procedures loaded from the procedures directory"""
|
|
17
|
+
|
|
18
|
+
__test__ = False # Prevent pytest from picking up this class
|
|
19
|
+
S_ALL_01 = "S-ALL-01"
|
|
20
|
+
S_ALL_02 = "S-ALL-02"
|
|
21
|
+
S_ALL_03 = "S-ALL-03"
|
|
22
|
+
S_ALL_04 = "S-ALL-04"
|
|
23
|
+
S_ALL_05 = "S-ALL-05"
|
|
24
|
+
S_OPT_01 = "S-OPT-01"
|
|
25
|
+
S_OPT_02 = "S-OPT-02"
|
|
26
|
+
S_OPT_03 = "S-OPT-03"
|
|
27
|
+
S_OPT_04 = "S-OPT-04"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ClientType(StrEnum):
|
|
31
|
+
DEVICE = "device" # This is a direct device client - i.e. the cert will match a SPECIFIC EndDevice
|
|
32
|
+
AGGREGATOR = "aggregator" # This is an aggregator client - i.e. the cert can manage MANY EndDevices
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class RequiredClient:
|
|
37
|
+
"""A RequiredClient is a way for a test to assert that it needs a specific client type or set of clients. The id
|
|
38
|
+
will be used internally within a test to reference a specific client"""
|
|
39
|
+
|
|
40
|
+
id: str # How this client will be referred to within the step's of the test
|
|
41
|
+
client_type: ClientType | None = None # If set - the client type that is required
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass
|
|
45
|
+
class Step:
|
|
46
|
+
"""A step is an action for a client to execute and then a series of checks to validate the results. If the action
|
|
47
|
+
raises an exception OR any of the checks fail, this step will marked as failed and the test will be aborted.
|
|
48
|
+
|
|
49
|
+
Actions might represent a single operation or they may represent a series of polls/checks over a period of time.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
id: str # Descriptive identifier for this step (must be unique)
|
|
53
|
+
action: Action # The action to execute when the step starts
|
|
54
|
+
client: str | None = None # The RequiredClient.id that will execute this step. If None - use the 0th client.
|
|
55
|
+
use_client_context: str | None = (
|
|
56
|
+
None # Specify to allow a request to execute with clientX using the context of clientY
|
|
57
|
+
)
|
|
58
|
+
checks: list[Check] | None = None # The checks (if any) to execute AFTER action completes to determine success
|
|
59
|
+
instructions: list[str] | None = None # Text to display while this step executes
|
|
60
|
+
|
|
61
|
+
repeat_until_pass: bool = False # If True - failing checks will cause this step to re-execute until successful
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class Preconditions:
|
|
66
|
+
"""Preconditions are a way of setting up the test / server before the test begins.
|
|
67
|
+
|
|
68
|
+
Instructions are out-of-band information to show until the preconditions are all met.
|
|
69
|
+
|
|
70
|
+
If any checks are required - they will be polled regularly until ALL pass. For each check poll, a discovery
|
|
71
|
+
will be run to ensure data is available.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
required_clients: list[RequiredClient] # What client(s) need to be supplied to run this test procedure
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass
|
|
78
|
+
class TestProcedure(YAMLWizard):
|
|
79
|
+
"""Top level object for collecting everything relevant to a single TestProcedure"""
|
|
80
|
+
|
|
81
|
+
__test__ = False # Prevent pytest from picking up this class
|
|
82
|
+
description: str # Metadata from test definitions
|
|
83
|
+
category: str # Metadata from test definitions
|
|
84
|
+
classes: list[str] # Metadata from test definitions
|
|
85
|
+
target_versions: list[CSIPAusVersion] # What version(s) of csip-aus is this test targeting?
|
|
86
|
+
preconditions: Preconditions
|
|
87
|
+
steps: list[Step] # What behavior will the test procedure be evaluating?
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
LoadMeta(raise_on_unknown_json_key=True).bind_to(TestProcedure)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def parse_test_procedure(yaml_contents: str) -> TestProcedure:
|
|
94
|
+
"""Given a YAML string - parse a TestProcedure.
|
|
95
|
+
|
|
96
|
+
This will ensure the YAML parser will use all the "strict" extensions to reduce the incidence of errors"""
|
|
97
|
+
|
|
98
|
+
return TestProcedure.from_yaml(
|
|
99
|
+
yaml_contents,
|
|
100
|
+
decoder=yaml.load, # type: ignore
|
|
101
|
+
Loader=UniqueKeyLoader,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_yaml_contents(test_procedure_id: TestProcedureId) -> str:
|
|
106
|
+
"""Finds the YAML contents for the TestProcedure with the specified TestProcedureId"""
|
|
107
|
+
yaml_resource = resources.files("cactus_test_definitions.server.procedures") / f"{test_procedure_id}.yaml"
|
|
108
|
+
with resources.as_file(yaml_resource) as yaml_file:
|
|
109
|
+
with open(yaml_file, "r") as f:
|
|
110
|
+
yaml_contents = f.read()
|
|
111
|
+
return yaml_contents
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_test_procedure(test_procedure_id: TestProcedureId) -> TestProcedure:
|
|
115
|
+
"""Gets the TestProcedure with the nominated ID by loading its definition from disk"""
|
|
116
|
+
yaml_contents = get_yaml_contents(test_procedure_id)
|
|
117
|
+
return parse_test_procedure(yaml_contents)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def get_all_test_procedures() -> dict[TestProcedureId, TestProcedure]:
|
|
121
|
+
"""Gets every TestProcedure, keyed by their TestProcedureId"""
|
|
122
|
+
return {tp_id: get_test_procedure(tp_id) for tp_id in TestProcedureId}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from cactus_test_definitions.errors import TestProcedureDefinitionError
|
|
2
|
+
from cactus_test_definitions.server.actions import validate_action_parameters
|
|
3
|
+
from cactus_test_definitions.server.checks import validate_check_parameters
|
|
4
|
+
from cactus_test_definitions.server.test_procedures import (
|
|
5
|
+
TestProcedure,
|
|
6
|
+
TestProcedureId,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def validate_test_procedure(test_procedure: TestProcedure, test_procedure_id: TestProcedureId):
|
|
11
|
+
# Check preconditions
|
|
12
|
+
if not test_procedure.preconditions.required_clients:
|
|
13
|
+
raise TestProcedureDefinitionError(
|
|
14
|
+
f"{test_procedure_id} has no RequiredClients element. At least 1 entry required"
|
|
15
|
+
)
|
|
16
|
+
required_clients_by_id = dict(((rc.id, rc) for rc in test_procedure.preconditions.required_clients))
|
|
17
|
+
|
|
18
|
+
for step in test_procedure.steps:
|
|
19
|
+
validate_action_parameters(test_procedure_id, step.id, step.action)
|
|
20
|
+
|
|
21
|
+
# Validate step checks
|
|
22
|
+
if step.checks:
|
|
23
|
+
for check in step.checks:
|
|
24
|
+
validate_check_parameters(test_procedure_id, check)
|
|
25
|
+
|
|
26
|
+
# Ensure client exists
|
|
27
|
+
if step.client is not None and step.client not in required_clients_by_id:
|
|
28
|
+
raise TestProcedureDefinitionError(
|
|
29
|
+
f"{test_procedure_id} reference client {step.client} that isn't listed in RequiredClients."
|
|
30
|
+
)
|