cactus-test-definitions 1.0.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.

Files changed (135) hide show
  1. cactus_test_definitions/__init__.py +39 -0
  2. cactus_test_definitions/__pycache__/__init__.cpython-312.pyc +0 -0
  3. cactus_test_definitions/__pycache__/actions.cpython-312.pyc +0 -0
  4. cactus_test_definitions/__pycache__/checks.cpython-312.pyc +0 -0
  5. cactus_test_definitions/__pycache__/csipaus.cpython-312.pyc +0 -0
  6. cactus_test_definitions/__pycache__/errors.cpython-312.pyc +0 -0
  7. cactus_test_definitions/__pycache__/events.cpython-312.pyc +0 -0
  8. cactus_test_definitions/__pycache__/parameters.cpython-312.pyc +0 -0
  9. cactus_test_definitions/__pycache__/schema.cpython-312.pyc +0 -0
  10. cactus_test_definitions/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
  11. cactus_test_definitions/__pycache__/test_procedures.cpython-312.pyc +0 -0
  12. cactus_test_definitions/__pycache__/variable_expressions.cpython-312.pyc +0 -0
  13. cactus_test_definitions/__pycache__/version.cpython-312.pyc +0 -0
  14. cactus_test_definitions/client/__init__.py +26 -0
  15. cactus_test_definitions/client/__pycache__/__init__.cpython-312.pyc +0 -0
  16. cactus_test_definitions/client/__pycache__/actions.cpython-312.pyc +0 -0
  17. cactus_test_definitions/client/__pycache__/checks.cpython-312.pyc +0 -0
  18. cactus_test_definitions/client/__pycache__/events.cpython-312.pyc +0 -0
  19. cactus_test_definitions/client/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
  20. cactus_test_definitions/client/actions.py +98 -0
  21. cactus_test_definitions/client/checks.py +117 -0
  22. cactus_test_definitions/client/events.py +71 -0
  23. cactus_test_definitions/client/procedures/ALL-01.yaml +94 -0
  24. cactus_test_definitions/client/procedures/ALL-02.yaml +108 -0
  25. cactus_test_definitions/client/procedures/ALL-03-REJ.yaml +69 -0
  26. cactus_test_definitions/client/procedures/ALL-03.yaml +110 -0
  27. cactus_test_definitions/client/procedures/ALL-04.yaml +69 -0
  28. cactus_test_definitions/client/procedures/ALL-05.yaml +117 -0
  29. cactus_test_definitions/client/procedures/ALL-06.yaml +128 -0
  30. cactus_test_definitions/client/procedures/ALL-07.yaml +76 -0
  31. cactus_test_definitions/client/procedures/ALL-08.yaml +78 -0
  32. cactus_test_definitions/client/procedures/ALL-09.yaml +103 -0
  33. cactus_test_definitions/client/procedures/ALL-10.yaml +128 -0
  34. cactus_test_definitions/client/procedures/ALL-11.yaml +111 -0
  35. cactus_test_definitions/client/procedures/ALL-12.yaml +108 -0
  36. cactus_test_definitions/client/procedures/ALL-13.yaml +112 -0
  37. cactus_test_definitions/client/procedures/ALL-14.yaml +165 -0
  38. cactus_test_definitions/client/procedures/ALL-15.yaml +109 -0
  39. cactus_test_definitions/client/procedures/ALL-16.yaml +102 -0
  40. cactus_test_definitions/client/procedures/ALL-17.yaml +63 -0
  41. cactus_test_definitions/client/procedures/ALL-18.yaml +288 -0
  42. cactus_test_definitions/client/procedures/ALL-19.yaml +78 -0
  43. cactus_test_definitions/client/procedures/ALL-20.yaml +136 -0
  44. cactus_test_definitions/client/procedures/ALL-21.yaml +203 -0
  45. cactus_test_definitions/client/procedures/ALL-22.yaml +82 -0
  46. cactus_test_definitions/client/procedures/ALL-23.yaml +158 -0
  47. cactus_test_definitions/client/procedures/ALL-24.yaml +132 -0
  48. cactus_test_definitions/client/procedures/ALL-25.yaml +136 -0
  49. cactus_test_definitions/client/procedures/ALL-26.yaml +147 -0
  50. cactus_test_definitions/client/procedures/ALL-27.yaml +144 -0
  51. cactus_test_definitions/client/procedures/ALL-28.yaml +274 -0
  52. cactus_test_definitions/client/procedures/ALL-29.yaml +87 -0
  53. cactus_test_definitions/client/procedures/ALL-30.yaml +188 -0
  54. cactus_test_definitions/client/procedures/BES-01.yaml +136 -0
  55. cactus_test_definitions/client/procedures/BES-02.yaml +137 -0
  56. cactus_test_definitions/client/procedures/BES-03.yaml +135 -0
  57. cactus_test_definitions/client/procedures/BES-04.yaml +228 -0
  58. cactus_test_definitions/client/procedures/DRA-01.yaml +54 -0
  59. cactus_test_definitions/client/procedures/DRA-02.yaml +64 -0
  60. cactus_test_definitions/client/procedures/DRD-01.yaml +667 -0
  61. cactus_test_definitions/client/procedures/DRL-01.yaml +327 -0
  62. cactus_test_definitions/client/procedures/GEN-01.yaml +73 -0
  63. cactus_test_definitions/client/procedures/GEN-02.yaml +72 -0
  64. cactus_test_definitions/client/procedures/GEN-03.yaml +160 -0
  65. cactus_test_definitions/client/procedures/GEN-04.yaml +161 -0
  66. cactus_test_definitions/client/procedures/GEN-05.yaml +89 -0
  67. cactus_test_definitions/client/procedures/GEN-06.yaml +90 -0
  68. cactus_test_definitions/client/procedures/GEN-07.yaml +145 -0
  69. cactus_test_definitions/client/procedures/GEN-08.yaml +145 -0
  70. cactus_test_definitions/client/procedures/GEN-09.yaml +117 -0
  71. cactus_test_definitions/client/procedures/GEN-10.yaml +737 -0
  72. cactus_test_definitions/client/procedures/GEN-11.yaml +376 -0
  73. cactus_test_definitions/client/procedures/GEN-12.yaml +376 -0
  74. cactus_test_definitions/client/procedures/GEN-13.yaml +70 -0
  75. cactus_test_definitions/client/procedures/LOA-01.yaml +73 -0
  76. cactus_test_definitions/client/procedures/LOA-02.yaml +73 -0
  77. cactus_test_definitions/client/procedures/LOA-03.yaml +160 -0
  78. cactus_test_definitions/client/procedures/LOA-04.yaml +161 -0
  79. cactus_test_definitions/client/procedures/LOA-05.yaml +85 -0
  80. cactus_test_definitions/client/procedures/LOA-06.yaml +85 -0
  81. cactus_test_definitions/client/procedures/LOA-07.yaml +145 -0
  82. cactus_test_definitions/client/procedures/LOA-08.yaml +145 -0
  83. cactus_test_definitions/client/procedures/LOA-09.yaml +117 -0
  84. cactus_test_definitions/client/procedures/LOA-10.yaml +739 -0
  85. cactus_test_definitions/client/procedures/LOA-11.yaml +376 -0
  86. cactus_test_definitions/client/procedures/LOA-12.yaml +376 -0
  87. cactus_test_definitions/client/procedures/LOA-13.yaml +71 -0
  88. cactus_test_definitions/client/procedures/MUL-01.yaml +92 -0
  89. cactus_test_definitions/client/procedures/MUL-02.yaml +80 -0
  90. cactus_test_definitions/client/procedures/MUL-03.yaml +78 -0
  91. cactus_test_definitions/client/procedures/OPT-1-IN-BAND.yaml +115 -0
  92. cactus_test_definitions/client/procedures/OPT-1-OUT-OF-BAND.yaml +101 -0
  93. cactus_test_definitions/client/procedures/test-procedures.yaml +75 -0
  94. cactus_test_definitions/client/test_procedures.py +296 -0
  95. cactus_test_definitions/csipaus.py +81 -0
  96. cactus_test_definitions/errors.py +15 -0
  97. cactus_test_definitions/parameters.py +149 -0
  98. cactus_test_definitions/py.typed +0 -0
  99. cactus_test_definitions/schema.py +22 -0
  100. cactus_test_definitions/server/README.md +170 -0
  101. cactus_test_definitions/server/__pycache__/actions.cpython-312.pyc +0 -0
  102. cactus_test_definitions/server/__pycache__/checks.cpython-312.pyc +0 -0
  103. cactus_test_definitions/server/__pycache__/test_procedures.cpython-312-pytest-8.3.5.pyc +0 -0
  104. cactus_test_definitions/server/actions.py +139 -0
  105. cactus_test_definitions/server/checks.py +117 -0
  106. cactus_test_definitions/server/procedures/S-ALL-01.yaml +42 -0
  107. cactus_test_definitions/server/procedures/S-ALL-02.yaml +65 -0
  108. cactus_test_definitions/server/procedures/S-ALL-03.yaml +65 -0
  109. cactus_test_definitions/server/procedures/S-ALL-04.yaml +137 -0
  110. cactus_test_definitions/server/procedures/S-ALL-05.yaml +111 -0
  111. cactus_test_definitions/server/procedures/S-OPT-01.yaml +42 -0
  112. cactus_test_definitions/server/procedures/S-OPT-02.yaml +40 -0
  113. cactus_test_definitions/server/procedures/S-OPT-03.yaml +44 -0
  114. cactus_test_definitions/server/procedures/S-OPT-04.yaml +32 -0
  115. cactus_test_definitions/server/procedures/test-procedures.yaml +14 -0
  116. cactus_test_definitions/server/test_procedures.py +183 -0
  117. cactus_test_definitions/variable_expressions.py +419 -0
  118. cactus_test_definitions-1.0.0.dist-info/METADATA +288 -0
  119. cactus_test_definitions-1.0.0.dist-info/RECORD +135 -0
  120. cactus_test_definitions-1.0.0.dist-info/WHEEL +5 -0
  121. cactus_test_definitions-1.0.0.dist-info/licenses/LICENSE.txt +22 -0
  122. cactus_test_definitions-1.0.0.dist-info/top_level.txt +2 -0
  123. tests/__init__.py +0 -0
  124. tests/unit/__init__.py +0 -0
  125. tests/unit/client/__init__.py +0 -0
  126. tests/unit/client/test_actions.py +72 -0
  127. tests/unit/client/test_checks.py +47 -0
  128. tests/unit/client/test_config.py +61 -0
  129. tests/unit/client/test_events.py +36 -0
  130. tests/unit/client/test_test_procedures.py +150 -0
  131. tests/unit/server/__init__.py +0 -0
  132. tests/unit/server/test_test_procedures.py +86 -0
  133. tests/unit/test_csipaus.py +49 -0
  134. tests/unit/test_parameters.py +197 -0
  135. tests/unit/test_variable_expressions.py +402 -0
@@ -0,0 +1,115 @@
1
+ Description: Connection Point Registration (In Band EndDevice Registration)
2
+ Category: Registration
3
+ Classes:
4
+ - C
5
+
6
+ TargetVersions:
7
+ - v1.2
8
+ - v1.3-beta/storage
9
+
10
+ Criteria:
11
+ checks:
12
+ - type: all-steps-complete
13
+ parameters: {}
14
+ - type: der-capability-contents
15
+ parameters: {}
16
+ - type: der-settings-contents
17
+ parameters: {}
18
+ - type: der-status-contents
19
+ parameters: {}
20
+ - type: end-device-contents
21
+ parameters:
22
+ has_connection_point_id: true
23
+
24
+ Preconditions:
25
+ immediate_start: true
26
+ init_actions:
27
+ - type: set-comms-rate
28
+ parameters:
29
+ dcap_poll_seconds: 60
30
+ edev_list_poll_seconds: 60
31
+ fsa_list_poll_seconds: 60
32
+ der_list_poll_seconds: 60
33
+ derp_list_poll_seconds: 60
34
+ mup_post_seconds: 60
35
+
36
+ Steps:
37
+ GET-DCAP:
38
+ event:
39
+ type: GET-request-received
40
+ parameters:
41
+ endpoint: /dcap
42
+ actions:
43
+ - type: enable-steps
44
+ parameters:
45
+ steps:
46
+ - GET-EDEV
47
+ - GET-TM
48
+ - type: remove-steps
49
+ parameters:
50
+ steps:
51
+ - GET-DCAP
52
+
53
+ GET-EDEV:
54
+ event:
55
+ type: GET-request-received
56
+ parameters:
57
+ endpoint: /edev
58
+ actions:
59
+ - type: enable-steps
60
+ parameters:
61
+ steps:
62
+ - POST-EDEV
63
+ - type: remove-steps
64
+ parameters:
65
+ steps:
66
+ - GET-EDEV
67
+
68
+ GET-TM:
69
+ event:
70
+ type: GET-request-received
71
+ parameters:
72
+ endpoint: /tm
73
+ actions:
74
+ - type: remove-steps
75
+ parameters:
76
+ steps:
77
+ - GET-TM
78
+
79
+ POST-EDEV:
80
+ event:
81
+ type: POST-request-received
82
+ parameters:
83
+ endpoint: /edev
84
+ actions:
85
+ - type: enable-steps
86
+ parameters:
87
+ steps:
88
+ - GET-DER
89
+ - PUT-CP
90
+ - type: remove-steps
91
+ parameters:
92
+ steps:
93
+ - POST-EDEV
94
+
95
+ GET-DER:
96
+ event:
97
+ type: GET-request-received
98
+ parameters:
99
+ endpoint: /edev/1/der
100
+ actions:
101
+ - type: remove-steps
102
+ parameters:
103
+ steps:
104
+ - GET-DER
105
+
106
+ PUT-CP:
107
+ event:
108
+ type: PUT-request-received
109
+ parameters:
110
+ endpoint: /edev/1/cp
111
+ actions:
112
+ - type: remove-steps
113
+ parameters:
114
+ steps:
115
+ - PUT-CP
@@ -0,0 +1,101 @@
1
+ Description: Connection Point Registration (Out of Band EndDevice Registration)
2
+ Category: Registration
3
+ Classes:
4
+ - C
5
+
6
+ TargetVersions:
7
+ - v1.2
8
+ - v1.3-beta/storage
9
+
10
+ Preconditions:
11
+ immediate_start: true
12
+ init_actions:
13
+ - type: set-comms-rate
14
+ parameters:
15
+ dcap_poll_seconds: 60
16
+ edev_list_poll_seconds: 60
17
+ fsa_list_poll_seconds: 60
18
+ der_list_poll_seconds: 60
19
+ derp_list_poll_seconds: 60
20
+ mup_post_seconds: 60
21
+ actions:
22
+ - type: register-end-device
23
+ parameters:
24
+ registration_pin: 11111 # With checksum is 111115
25
+ aggregator_lfdi: 3E4F45AB31EDFE5B67E343E5E4562E3100000000 # Trailing PEN digits set to 0
26
+ aggregator_sfdi: 16726121139
27
+
28
+ Criteria:
29
+ checks:
30
+ - type: all-steps-complete
31
+ parameters: {}
32
+ - type: end-device-contents
33
+ parameters:
34
+ has_connection_point_id: true
35
+
36
+ Steps:
37
+ GET-DCAP:
38
+ instructions:
39
+ - "An EndDevice has already been registered (out of band) with PIN 111115"
40
+ - "[Aggregator Client Only] LFDI: 3E4F45AB31EDFE5B67E343E5E4562E31XXXXXXXX (The X values will match your client PEN)"
41
+ - "[Aggregator Client Only] SFDI: 16726121139"
42
+ event:
43
+ type: GET-request-received
44
+ parameters:
45
+ endpoint: /dcap
46
+ actions:
47
+ - type: enable-steps
48
+ parameters:
49
+ steps:
50
+ - GET-EDEV-LIST
51
+ - GET-TM
52
+ - GET-DER
53
+ - PUT-CP
54
+ - type: remove-steps
55
+ parameters:
56
+ steps:
57
+ - GET-DCAP
58
+
59
+ GET-EDEV-LIST:
60
+ event:
61
+ type: GET-request-received
62
+ parameters:
63
+ endpoint: /edev
64
+ actions:
65
+ - type: remove-steps
66
+ parameters:
67
+ steps:
68
+ - GET-EDEV-LIST
69
+
70
+ GET-TM:
71
+ event:
72
+ type: GET-request-received
73
+ parameters:
74
+ endpoint: /tm
75
+ actions:
76
+ - type: remove-steps
77
+ parameters:
78
+ steps:
79
+ - GET-TM
80
+
81
+ GET-DER:
82
+ event:
83
+ type: GET-request-received
84
+ parameters:
85
+ endpoint: /edev/1/der
86
+ actions:
87
+ - type: remove-steps
88
+ parameters:
89
+ steps:
90
+ - GET-DER
91
+
92
+ PUT-CP:
93
+ event:
94
+ type: PUT-request-received
95
+ parameters:
96
+ endpoint: /edev/1/cp
97
+ actions:
98
+ - type: remove-steps
99
+ parameters:
100
+ steps:
101
+ - PUT-CP
@@ -0,0 +1,75 @@
1
+ ---
2
+ Description: CSIP-AUS Client Test Procedures
3
+ Version: 0.1
4
+ TestProcedures:
5
+ ALL-01: !include ALL-01.yaml
6
+ ALL-02: !include ALL-02.yaml
7
+ ALL-03: !include ALL-03.yaml
8
+ ALL-03-REJ: !include ALL-03-REJ.yaml
9
+ ALL-04: !include ALL-04.yaml
10
+ ALL-05: !include ALL-05.yaml
11
+ ALL-06: !include ALL-06.yaml
12
+ ALL-07: !include ALL-07.yaml
13
+ ALL-08: !include ALL-08.yaml
14
+ ALL-09: !include ALL-09.yaml
15
+ ALL-10: !include ALL-10.yaml
16
+ ALL-11: !include ALL-11.yaml
17
+ ALL-12: !include ALL-12.yaml
18
+ ALL-13: !include ALL-13.yaml
19
+ ALL-14: !include ALL-14.yaml
20
+ ALL-15: !include ALL-15.yaml
21
+ ALL-16: !include ALL-16.yaml
22
+ ALL-17: !include ALL-17.yaml
23
+ ALL-18: !include ALL-18.yaml
24
+ ALL-19: !include ALL-19.yaml
25
+ ALL-20: !include ALL-20.yaml
26
+ ALL-21: !include ALL-21.yaml
27
+ ALL-22: !include ALL-22.yaml
28
+ ALL-23: !include ALL-23.yaml
29
+ ALL-24: !include ALL-24.yaml
30
+ ALL-25: !include ALL-25.yaml
31
+ ALL-26: !include ALL-26.yaml
32
+ ALL-27: !include ALL-27.yaml
33
+ ALL-28: !include ALL-28.yaml
34
+ ALL-29: !include ALL-29.yaml
35
+ ALL-30: !include ALL-30.yaml
36
+ DRA-01: !include DRA-01.yaml
37
+ DRA-02: !include DRA-02.yaml
38
+ DRD-01: !include DRD-01.yaml
39
+ DRL-01: !include DRL-01.yaml
40
+ GEN-01: !include GEN-01.yaml
41
+ GEN-02: !include GEN-02.yaml
42
+ GEN-03: !include GEN-03.yaml
43
+ GEN-04: !include GEN-04.yaml
44
+ GEN-05: !include GEN-05.yaml
45
+ GEN-06: !include GEN-06.yaml
46
+ GEN-07: !include GEN-07.yaml
47
+ GEN-08: !include GEN-08.yaml
48
+ GEN-09: !include GEN-09.yaml
49
+ GEN-10: !include GEN-10.yaml
50
+ GEN-11: !include GEN-11.yaml
51
+ GEN-12: !include GEN-12.yaml
52
+ GEN-13: !include GEN-13.yaml
53
+ LOA-01: !include LOA-01.yaml
54
+ LOA-02: !include LOA-02.yaml
55
+ LOA-03: !include LOA-03.yaml
56
+ LOA-04: !include LOA-04.yaml
57
+ LOA-05: !include LOA-05.yaml
58
+ LOA-06: !include LOA-06.yaml
59
+ LOA-07: !include LOA-07.yaml
60
+ LOA-08: !include LOA-08.yaml
61
+ LOA-09: !include LOA-09.yaml
62
+ LOA-10: !include LOA-10.yaml
63
+ LOA-11: !include LOA-11.yaml
64
+ LOA-12: !include LOA-12.yaml
65
+ LOA-13: !include LOA-13.yaml
66
+ MUL-01: !include MUL-01.yaml
67
+ MUL-02: !include MUL-02.yaml
68
+ MUL-03: !include MUL-03.yaml
69
+ OPT-1-IN-BAND: !include OPT-1-IN-BAND.yaml
70
+ OPT-1-OUT-OF-BAND: !include OPT-1-OUT-OF-BAND.yaml
71
+ BES-01: !include BES-01.yaml
72
+ BES-02: !include BES-02.yaml
73
+ BES-03: !include BES-03.yaml
74
+ BES-04: !include BES-04.yaml
75
+
@@ -0,0 +1,296 @@
1
+ from dataclasses import dataclass
2
+ from enum import StrEnum
3
+ from importlib import resources
4
+ from pathlib import Path
5
+ from typing import Iterable
6
+
7
+ import yaml
8
+ import yaml_include
9
+ from cactus_test_definitions.client.actions import Action, validate_action_parameters
10
+ from cactus_test_definitions.client.checks import Check, validate_check_parameters
11
+ from cactus_test_definitions.client.events import Event, validate_event_parameters
12
+ from cactus_test_definitions.csipaus import CSIPAusVersion
13
+ from cactus_test_definitions.errors import TestProcedureDefinitionError
14
+ from cactus_test_definitions.schema import UniqueKeyLoader
15
+ from dataclass_wizard import YAMLWizard
16
+
17
+
18
+ class TestProcedureId(StrEnum):
19
+ """The set of all available test ID's
20
+
21
+ This should be kept in sync with the current set of client test procedures loaded from the procedures directory"""
22
+
23
+ __test__ = False # Prevent pytest from picking up this class
24
+ ALL_01 = "ALL-01"
25
+ ALL_02 = "ALL-02"
26
+ ALL_03 = "ALL-03"
27
+ ALL_03_REJ = "ALL-03-REJ"
28
+ ALL_04 = "ALL-04"
29
+ ALL_05 = "ALL-05"
30
+ ALL_06 = "ALL-06"
31
+ ALL_07 = "ALL-07"
32
+ ALL_08 = "ALL-08"
33
+ ALL_09 = "ALL-09"
34
+ ALL_10 = "ALL-10"
35
+ ALL_11 = "ALL-11"
36
+ ALL_12 = "ALL-12"
37
+ ALL_13 = "ALL-13"
38
+ ALL_14 = "ALL-14"
39
+ ALL_15 = "ALL-15"
40
+ ALL_16 = "ALL-16"
41
+ ALL_17 = "ALL-17"
42
+ ALL_18 = "ALL-18"
43
+ ALL_19 = "ALL-19"
44
+ ALL_20 = "ALL-20"
45
+ ALL_21 = "ALL-21"
46
+ ALL_22 = "ALL-22"
47
+ ALL_23 = "ALL-23"
48
+ ALL_24 = "ALL-24"
49
+ ALL_25 = "ALL-25"
50
+ ALL_26 = "ALL-26"
51
+ ALL_27 = "ALL-27"
52
+ ALL_28 = "ALL-28"
53
+ ALL_29 = "ALL-29"
54
+ ALL_30 = "ALL-30"
55
+ DRA_01 = "DRA-01"
56
+ DRA_02 = "DRA-02"
57
+ DRD_01 = "DRD-01"
58
+ DRL_01 = "DRL-01"
59
+ GEN_01 = "GEN-01"
60
+ GEN_02 = "GEN-02"
61
+ GEN_03 = "GEN-03"
62
+ GEN_04 = "GEN-04"
63
+ GEN_05 = "GEN-05"
64
+ GEN_06 = "GEN-06"
65
+ GEN_07 = "GEN-07"
66
+ GEN_08 = "GEN-08"
67
+ GEN_09 = "GEN-09"
68
+ GEN_10 = "GEN-10"
69
+ GEN_11 = "GEN-11"
70
+ GEN_12 = "GEN-12"
71
+ GEN_13 = "GEN-13"
72
+ LOA_01 = "LOA-01"
73
+ LOA_02 = "LOA-02"
74
+ LOA_03 = "LOA-03"
75
+ LOA_04 = "LOA-04"
76
+ LOA_05 = "LOA-05"
77
+ LOA_06 = "LOA-06"
78
+ LOA_07 = "LOA-07"
79
+ LOA_08 = "LOA-08"
80
+ LOA_09 = "LOA-09"
81
+ LOA_10 = "LOA-10"
82
+ LOA_11 = "LOA-11"
83
+ LOA_12 = "LOA-12"
84
+ LOA_13 = "LOA-13"
85
+ MUL_01 = "MUL-01"
86
+ MUL_02 = "MUL-02"
87
+ MUL_03 = "MUL-03"
88
+ OPT_1_IN_BAND = "OPT-1-IN-BAND"
89
+ OPT_1_OUT_OF_BAND = "OPT-1-OUT-OF-BAND"
90
+
91
+ # Storage extension
92
+ BES_01 = "BES-01"
93
+ BES_02 = "BES-02"
94
+ BES_03 = "BES-03"
95
+ BES_04 = "BES-04"
96
+
97
+
98
+ @dataclass
99
+ class Step:
100
+ """A step is a part of the test procedure that waits for some form of event before running a set of actions.
101
+
102
+ It's common for a step to activate other "steps" so that the state of the active test procedure can "evolve" in
103
+ response to client behaviour
104
+
105
+ Instructions are out-of-band operations that need performing during the step
106
+ e.g. disconnect DER from grid, disable power consumption etc.
107
+ """
108
+
109
+ event: Event # The event to act as a trigger
110
+ actions: list[Action] # The actions to execute when the trigger is met
111
+ instructions: list[str] | None = None
112
+
113
+
114
+ @dataclass
115
+ class Preconditions:
116
+ """Preconditions are run during the "initialization" state that precedes the start of a test. They typically
117
+ allow for the setup of the test.
118
+
119
+ Checks are also included to prevent a client from starting a test before they have correctly met preconditions
120
+
121
+ Instructions are out-of-band operations that need performing at the start of the test procedure
122
+ e.g. attach a load etc.
123
+
124
+ If immediate_start is set to True - the "initialization" step will be progressed through immediately so that the
125
+ client has no opportunity to interact with the server in this state. Any actions will still be executed. Do NOT
126
+ utilise immediate_start with precondition checks.
127
+ """
128
+
129
+ init_actions: list[Action] | None = None # To be executed as the runner starts (before anything can occur)
130
+ immediate_start: bool = False # If True - a test execution will have NO "pre-start" phase.
131
+ actions: list[Action] | None = None # To be executed as the test case "starts" (usually on request of client)
132
+ checks: list[Check] | None = None # Will prevent move from "init" state to "started" state of a test if any fail
133
+ instructions: list[str] | None = None
134
+
135
+
136
+ @dataclass
137
+ class Criteria:
138
+ """Criteria represent the final pass/fail analysis run after a TestProcedure completion. They can consider both
139
+ the final state of the test system as well as the interactions that happened while it was running"""
140
+
141
+ checks: list[Check] | None = None # These should be run at test procedure finalization to determine pass/fail
142
+
143
+
144
+ @dataclass
145
+ class TestProcedure:
146
+ """Top level object for collecting everything relevant to a single TestProcedure"""
147
+
148
+ __test__ = False # Prevent pytest from picking up this class
149
+ description: str # Metadata from test definitions
150
+ category: str # Metadata from test definitions
151
+ classes: list[str] # Metadata from test definitions
152
+ target_versions: list[CSIPAusVersion] # What version(s) of csip-aus is this test targeting?
153
+ steps: dict[str, Step]
154
+ preconditions: Preconditions | None = None # These execute during "init" and setup the test for a valid start state
155
+ criteria: Criteria | None = None # How will success/failure of this procedure be determined?
156
+
157
+
158
+ @dataclass
159
+ class TestProcedures(YAMLWizard):
160
+ """Represents a collection of CSIP-AUS client test procedure descriptions/specifications
161
+
162
+ By sub-classing the YAMLWizard mixin, we get access to the class method `from_yaml`
163
+ which we can use to create an instances of `TestProcedures`.
164
+ """
165
+
166
+ __test__ = False # Prevent pytest from picking up this class
167
+
168
+ description: str
169
+ version: str
170
+ test_procedures: dict[str, TestProcedure]
171
+
172
+ def _do_action_validate(self, procedure: TestProcedure, procedure_name: str, location: str, action: Action):
173
+ """Handles the full validation of an action's definition for a parent procedure.
174
+
175
+ procedure: The parent TestProcedure for action
176
+ procedure_name: The name of procedure (used for labelling errors)
177
+ location: Where in procedure can you find action? (used for labelling errors)
178
+ action: The action to validate
179
+
180
+ raises TestProcedureDefinitionError on failure
181
+ """
182
+ validate_action_parameters(procedure_name, location, action)
183
+
184
+ # Provide additional "action specific" validation
185
+ match action.type:
186
+ case "enable-steps" | "remove-steps":
187
+ for step_name in action.parameters["steps"]:
188
+ if step_name not in procedure.steps.keys():
189
+ raise TestProcedureDefinitionError(
190
+ f"{procedure_name}.{location}. Refers to unknown step '{step_name}'."
191
+ )
192
+
193
+ def _validate_actions(self):
194
+ """Validate actions of test procedure steps / preconditions
195
+
196
+ Ensure,
197
+ - action has the correct parameters
198
+ - if parameters refer to steps then those steps are defined for the test procedure
199
+ """
200
+
201
+ for test_procedure_name, test_procedure in self.test_procedures.items():
202
+ # Validate actions in the preconditions
203
+ if test_procedure.preconditions:
204
+ if test_procedure.preconditions.actions:
205
+ for action in test_procedure.preconditions.actions:
206
+ self._do_action_validate(test_procedure, test_procedure_name, "Precondition", action)
207
+
208
+ if test_procedure.preconditions.init_actions:
209
+ for action in test_procedure.preconditions.init_actions:
210
+ self._do_action_validate(test_procedure, test_procedure_name, "Precondition", action)
211
+
212
+ # Validate actions that exist on steps
213
+ for step_name, step in test_procedure.steps.items():
214
+ for action in step.actions:
215
+ self._do_action_validate(test_procedure, test_procedure_name, step_name, action)
216
+
217
+ def _validate_checks(self):
218
+ """Validate checks of test procedures
219
+
220
+ Ensure,
221
+ - check has the correct parameters
222
+ """
223
+
224
+ for test_procedure_name, test_procedure in self.test_procedures.items():
225
+ if test_procedure.criteria and test_procedure.criteria.checks:
226
+ for check in test_procedure.criteria.checks:
227
+ validate_check_parameters(test_procedure_name, check)
228
+
229
+ def _validate_events(self):
230
+ """Validate events of test procedure steps
231
+
232
+ Ensure,
233
+ - event has the correct parameters
234
+ """
235
+
236
+ for test_procedure_name, test_procedure in self.test_procedures.items():
237
+ for step_name, step in test_procedure.steps.items():
238
+ validate_event_parameters(test_procedure_name, step_name, step.event)
239
+
240
+ def validate(self):
241
+ self._validate_actions()
242
+ self._validate_checks()
243
+ self._validate_events()
244
+
245
+
246
+ class TestProcedureConfig:
247
+ __test__ = False # Prevent pytest from picking up this class
248
+
249
+ @staticmethod
250
+ def from_yamlfile(path: Path, skip_validation: bool = False) -> TestProcedures:
251
+ """Converts a yaml file given by 'path' into a 'TestProcedures' instance.
252
+
253
+ Supports parts of the TestProcedures instance being described by external
254
+ YAML files. These are referenced in the parent yaml file using the `!include` directive.
255
+
256
+ skip_validation: If True, the test_procedures.validate() call will not be made
257
+
258
+ Example:
259
+
260
+ Description: CSIP-AUS Client Test Procedures
261
+ Version: 0.1
262
+ TestProcedures:
263
+ ALL-01: !include ALL-01.yaml
264
+ """
265
+ with open(path, "r") as f:
266
+ yaml_contents = f.read()
267
+
268
+ # Modifies the pyyaml's load method to support references to external yaml files
269
+ # through the `!include` directive.
270
+ yaml.add_constructor(
271
+ "!include", constructor=yaml_include.Constructor(base_dir=path.parent), Loader=UniqueKeyLoader
272
+ )
273
+
274
+ # ...because we are using YAMLWizard we need to supply a decoder and a Loader to
275
+ # use this modified version.
276
+ test_procedures: TestProcedures = TestProcedures.from_yaml(
277
+ yaml_contents,
278
+ decoder=yaml.load, # type: ignore
279
+ Loader=UniqueKeyLoader,
280
+ )
281
+
282
+ if not skip_validation:
283
+ test_procedures.validate()
284
+
285
+ return test_procedures
286
+
287
+ @staticmethod
288
+ def from_resource() -> TestProcedures:
289
+ yaml_resource = resources.files("cactus_test_definitions.client.procedures") / "test-procedures.yaml"
290
+ with resources.as_file(yaml_resource) as yaml_file:
291
+ return TestProcedureConfig.from_yamlfile(path=yaml_file)
292
+
293
+ @staticmethod
294
+ def available_tests() -> Iterable[str]:
295
+ test_procedures: TestProcedures = TestProcedureConfig.from_resource()
296
+ return test_procedures.test_procedures.keys()
@@ -0,0 +1,81 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class CSIPAusVersion(StrEnum):
5
+ """The various version identifiers for CSIP-Aus. Used for distinguishing what tests are compatible with what
6
+ released versions CSIP-Aus."""
7
+
8
+ RELEASE_1_2 = "v1.2"
9
+ BETA_1_3_STORAGE = "v1.3-beta/storage"
10
+
11
+
12
+ class CSIPAusResource(StrEnum):
13
+ """Labels for each resource type that the server/client tests might reference. This is not designed to be
14
+ an exhaustive list of all SEP2 / CSIP-Aus models - only the entities that might have tests applied to them."""
15
+
16
+ DeviceCapability = "DeviceCapability"
17
+
18
+ Time = "Time"
19
+
20
+ MirrorUsagePointList = "MirrorUsagePointList"
21
+ MirrorUsagePoint = "MirrorUsagePoint"
22
+
23
+ EndDeviceList = "EndDeviceList"
24
+ EndDevice = "EndDevice"
25
+ ConnectionPoint = "ConnectionPoint"
26
+ Registration = "Registration"
27
+
28
+ FunctionSetAssignmentsList = "FunctionSetAssignmentsList"
29
+ FunctionSetAssignments = "FunctionSetAssignments"
30
+
31
+ DERProgramList = "DERProgramList"
32
+ DERProgram = "DERProgram"
33
+
34
+ DERControlList = "DERControlList"
35
+ DERControl = "DERControl"
36
+
37
+ DefaultDERControl = "DefaultDERControl"
38
+
39
+ DERList = "DERList"
40
+ DER = "DER"
41
+ DERCapability = "DERCapability"
42
+ DERSettings = "DERSettings"
43
+ DERStatus = "DERStatus"
44
+
45
+ SubscriptionList = "SubscriptionList"
46
+ Subscription = "Subscription"
47
+
48
+
49
+ class CSIPAusReadingLocation(StrEnum):
50
+ Site = "Site" # The reading is measured at the site's connection point
51
+ Device = "Device" # The reading is measured at the actual device (behind the meter)
52
+
53
+
54
+ class CSIPAusReadingType(StrEnum):
55
+ """A non exhaustive set of CSIPAus reading types / role flags that can be specified in tests"""
56
+
57
+ ActivePowerAverage = "ActivePowerAverage"
58
+ ActivePowerInstantaneous = "ActivePowerInstantaneous"
59
+ ActivePowerMaximum = "ActivePowerMaximum"
60
+ ActivePowerMinimum = "ActivePowerMinimum"
61
+
62
+ ReactivePowerAverage = "ReactivePowerAverage"
63
+ ReactivePowerInstantaneous = "ReactivePowerInstantaneous"
64
+ ReactivePowerMaximum = "ReactivePowerMaximum"
65
+ ReactivePowerMinimum = "ReactivePowerMinimum"
66
+
67
+ FrequencyAverage = "FrequencyAverage"
68
+ FrequencyInstantaneous = "FrequencyInstantaneous"
69
+ FrequencyMaximum = "FrequencyMaximum"
70
+ FrequencyMinimum = "FrequencyMinimum"
71
+
72
+ VoltageSinglePhaseAverage = "VoltageSinglePhaseAverage"
73
+ VoltageSinglePhaseInstantaneous = "VoltageSinglePhaseInstantaneous"
74
+ VoltageSinglePhaseMaximum = "VoltageSinglePhaseMaximum"
75
+ VoltageSinglePhaseMinimum = "VoltageSinglePhaseMinimum"
76
+
77
+
78
+ def is_list_resource(resource: CSIPAusResource) -> bool:
79
+ """Returns true if the specified resource is classified as a list resource (i.e. it supports list query params) and
80
+ will return an entity with list attributes (eg 'all')"""
81
+ return resource.name.endswith("List") # This is a really simple method but it should work
@@ -0,0 +1,15 @@
1
+ class TestProcedureDefinitionError(Exception):
2
+ __test__ = False # Prevent pytest from picking up this class
3
+
4
+
5
+ class UnresolvableVariableError(Exception):
6
+ """Raised whenever a NamedVariable cannot be resolved at test execution time (eg: database doesn't have the
7
+ requisite information)"""
8
+
9
+ pass
10
+
11
+
12
+ class UnparseableVariableExpressionError(Exception):
13
+ """Raised whenever a raw string cannot parse to a NamedVariable/Expression"""
14
+
15
+ pass