rsmp-validator 0.1.0

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.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/config/cross_rs4s.yaml +55 -0
  3. data/config/gem_supervisor.yaml +56 -0
  4. data/config/gem_tlc.yaml +56 -0
  5. data/config/gem_tlc_secrets.yaml +3 -0
  6. data/config/kapsch_etx.yaml +54 -0
  7. data/config/lightmotion_satellite.yaml +56 -0
  8. data/config/secrets.yaml +3 -0
  9. data/config/secrets_example.yaml +6 -0
  10. data/config/semaforica_cartesio.yaml +56 -0
  11. data/config/simulator/node_log.yaml +17 -0
  12. data/config/simulator/supervisor.yaml +11 -0
  13. data/config/simulator/tlc.yaml +56 -0
  14. data/config/sus.rb +13 -0
  15. data/config/swarco_itc3.yaml +55 -0
  16. data/config/tecsen_tmacs_supervisor.yaml +57 -0
  17. data/config/validator.rb +37 -0
  18. data/config/validator.yaml +5 -0
  19. data/config/validator_example.yaml +23 -0
  20. data/config/validator_log.yaml +19 -0
  21. data/exe/rsmp-validator +121 -0
  22. data/lib/doc_gen/parser.rb +276 -0
  23. data/lib/doc_gen/renderer.rb +153 -0
  24. data/lib/rsmp/validator/async_context.rb +15 -0
  25. data/lib/rsmp/validator/auto_node.rb +82 -0
  26. data/lib/rsmp/validator/auto_site.rb +30 -0
  27. data/lib/rsmp/validator/auto_supervisor.rb +23 -0
  28. data/lib/rsmp/validator/config_normalizer.rb +103 -0
  29. data/lib/rsmp/validator/configuration/loader.rb +79 -0
  30. data/lib/rsmp/validator/configuration/secrets.rb +54 -0
  31. data/lib/rsmp/validator/configuration/validation.rb +115 -0
  32. data/lib/rsmp/validator/configuration.rb +129 -0
  33. data/lib/rsmp/validator/helpers/alarms.rb +66 -0
  34. data/lib/rsmp/validator/helpers/clock.rb +16 -0
  35. data/lib/rsmp/validator/helpers/connection.rb +73 -0
  36. data/lib/rsmp/validator/helpers/handshake.rb +110 -0
  37. data/lib/rsmp/validator/helpers/input.rb +42 -0
  38. data/lib/rsmp/validator/helpers/security.rb +26 -0
  39. data/lib/rsmp/validator/helpers/signal_plans.rb +37 -0
  40. data/lib/rsmp/validator/helpers/signal_priority.rb +130 -0
  41. data/lib/rsmp/validator/helpers/startup.rb +157 -0
  42. data/lib/rsmp/validator/helpers/status.rb +22 -0
  43. data/lib/rsmp/validator/lifecycle.rb +99 -0
  44. data/lib/rsmp/validator/log.rb +11 -0
  45. data/lib/rsmp/validator/mode_detection.rb +84 -0
  46. data/lib/rsmp/validator/options/site_test_options.rb +58 -0
  47. data/lib/rsmp/validator/options/supervisor_test_options.rb +51 -0
  48. data/lib/rsmp/validator/site_tester.rb +113 -0
  49. data/lib/rsmp/validator/supervisor_tester.rb +76 -0
  50. data/lib/rsmp/validator/tester.rb +101 -0
  51. data/lib/rsmp/validator/version.rb +5 -0
  52. data/lib/rsmp/validator/version_filter.rb +44 -0
  53. data/lib/rsmp/validator.rb +50 -0
  54. data/schemas/site_test.json +36 -0
  55. data/schemas/supervisor_test.json +28 -0
  56. data/test/site/core/aggregated_status_spec.rb +43 -0
  57. data/test/site/core/connect_spec.rb +104 -0
  58. data/test/site/core/core_spec.rb +9 -0
  59. data/test/site/core/disconnect_spec.rb +54 -0
  60. data/test/site/site_spec.rb +5 -0
  61. data/test/site/tlc/alarm_spec.rb +134 -0
  62. data/test/site/tlc/clock_spec.rb +252 -0
  63. data/test/site/tlc/detector_logics_spec.rb +76 -0
  64. data/test/site/tlc/emergency_routes_spec.rb +106 -0
  65. data/test/site/tlc/input_spec.rb +102 -0
  66. data/test/site/tlc/invalid_command_spec.rb +103 -0
  67. data/test/site/tlc/invalid_status_spec.rb +70 -0
  68. data/test/site/tlc/modes_spec.rb +260 -0
  69. data/test/site/tlc/output_spec.rb +58 -0
  70. data/test/site/tlc/signal_groups_spec.rb +96 -0
  71. data/test/site/tlc/signal_plans_spec.rb +287 -0
  72. data/test/site/tlc/signal_priority_spec.rb +144 -0
  73. data/test/site/tlc/subscribe_spec.rb +71 -0
  74. data/test/site/tlc/system_spec.rb +76 -0
  75. data/test/site/tlc/tlc_spec.rb +7 -0
  76. data/test/site/tlc/traffic_data_spec.rb +151 -0
  77. data/test/site/tlc/traffic_situations_spec.rb +50 -0
  78. data/test/supervisor/aggregated_status_spec.rb +18 -0
  79. data/test/supervisor/connect_spec.rb +219 -0
  80. data/test/supervisor/supervisor_spec.rb +11 -0
  81. metadata +190 -0
@@ -0,0 +1,58 @@
1
+ describe 'Site::Tlc::Output' do
2
+ # Tests related to outputs.
3
+
4
+ # Verify that output status can be read with S0004, extended output status
5
+ # 1. Given the site is connected
6
+ # 2. When we subscribe to S0004
7
+ # 3. We should receive a status updated
8
+ # 4. And the outputstatus attribute should be a digit string
9
+ it 'is read with S0004 with extended output status' do
10
+ with_site(:connected, sxl: ['>=1.0.7', '<1.2']) do |site_proxy|
11
+ site_proxy.request_status_and_collect(
12
+ { S0004: %i[outputstatus extendedoutputstatus] },
13
+ within: RSMP::Validator.get_config('timeouts', 'status_response')
14
+ ).ok!
15
+ end
16
+ end
17
+
18
+ # Verify that output status can be read with S0004
19
+ # 1. Given the site is connected
20
+ # 2. When we subscribe to S0004
21
+ # 3. We should receive a status updated
22
+ # 4. And the outputstatus attribute should be a digit string
23
+ it 'is read with S0004' do
24
+ with_site(:connected, sxl: ['>=1.2']) do |site_proxy|
25
+ site_proxy.request_status_and_collect({ S0004: [:outputstatus] },
26
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
27
+ end
28
+ end
29
+
30
+ # Verify that forced output status can be read with S0030
31
+ # 1. Given the site is connected
32
+ # 2. Request status
33
+ # 3. Expect status response before timeout
34
+ it 'forcing is read with S0030' do
35
+ with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
36
+ site_proxy.request_status_and_collect({ S0030: [:status] },
37
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
38
+ end
39
+ end
40
+
41
+ # Verify that output can be forced with M0020
42
+ # 1. Given the site is connected
43
+ # 2. When we force output with M0020
44
+ # 3. Wait for status = true
45
+ it 'forcing is set with M0020' do
46
+ with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
47
+ outputs = RSMP::Validator.get_config('items', 'outputs')
48
+ skip('No outputs configured') if outputs.nil? || outputs.empty?
49
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
50
+ outputs.each do |output|
51
+ site_proxy.tlc.force_output(output: output, status: 'True', value: 'True', within: timeout)
52
+ site_proxy.tlc.force_output(output: output, status: 'True', value: 'False', within: timeout)
53
+ ensure
54
+ site_proxy.tlc.force_output(output: output, status: 'False', value: 'True', within: timeout)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,96 @@
1
+ describe 'Site::Tlc::SignalGroups' do
2
+ include RSMP::Validator::Helpers::Startup
3
+
4
+ # Validate that a signal group can be ordered to green using the M0010 command.
5
+ #
6
+ # 1. Verify connection
7
+ # 2. Send control command to start signalgrup, set_signal_start= true, include security_code
8
+ # 3. Wait for status = true
9
+ it 'is ordered to green with M0010' do
10
+ with_site(:connected, sxl: '>=1.0.8') do |site_proxy|
11
+ component = RSMP::Validator.get_config('components', 'signal_group').keys[0]
12
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
13
+ site_proxy.tlc.order_signal_start(component, within: timeout)
14
+ end
15
+ end
16
+
17
+ # 1. Verify connection
18
+ # 2. Send control command to stop signalgrup, set_signal_start= false, include security_code
19
+ # 3. Wait for status = true
20
+ it 'is ordered to red with M0011' do
21
+ with_site(:connected, sxl: '>=1.0.8') do |site_proxy|
22
+ component = RSMP::Validator.get_config('components', 'signal_group').keys[0]
23
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
24
+ site_proxy.tlc.order_signal_stop(component, within: timeout)
25
+ end
26
+ end
27
+
28
+ # Verify that signal group status can be read with S0001.
29
+ #
30
+ # 1. Given the site_proxy is connected
31
+ # 2. Request status
32
+ # 3. Expect status response before timeout
33
+ it 'state is read with S0001' do
34
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
35
+ site_proxy.request_status_and_collect(
36
+ { S0001: %i[signalgroupstatus cyclecounter basecyclecounter stage] },
37
+ within: RSMP::Validator.get_config('timeouts', 'status_response')
38
+ ).ok!
39
+ end
40
+ end
41
+
42
+ # Verify that time-of-green/time-of-red can be read with S0025.
43
+ #
44
+ # 1. Given the site_proxy is connected
45
+ # 2. Request status
46
+ # 3. Expect status response before timeout
47
+ it 'red/green predictions is read with S0025' do
48
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
49
+ component = RSMP::Validator.get_config('components', 'signal_group').keys.first
50
+ site_proxy.request_status_and_collect(
51
+ { S0025: %i[
52
+ minToGEstimate
53
+ maxToGEstimate
54
+ likelyToGEstimate
55
+ ToGConfidence
56
+ minToREstimate
57
+ maxToREstimate
58
+ likelyToREstimate
59
+ ] },
60
+ component: component,
61
+ within: RSMP::Validator.get_config('timeouts', 'status_response')
62
+ ).ok!
63
+ end
64
+ end
65
+
66
+ # Verify status S0017 number of signal groups
67
+ #
68
+ # 1. Given the site_proxy is connected
69
+ # 2. Request status
70
+ # 3. Expect status response before timeout
71
+ it 'list size is read with S0017' do
72
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
73
+ site_proxy.request_status_and_collect({ S0017: [:number] },
74
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
75
+ end
76
+ end
77
+
78
+ # Verify that we can activate normal control after yellow flash mode is turned off
79
+ #
80
+ # 1. Given the site_proxy is connected and in yellow flash mode
81
+ # 2. When we activate normal control
82
+ # 3. All signal groups should go through e, f and g
83
+ it 'follow startup sequence after yellow flash' do
84
+ skip 'requires sxl >= 1.0.7' unless RSMP::Validator.sxl_matches?('>=1.0.7')
85
+ with_site(:connected) do |site_proxy|
86
+ verify_startup_sequence(site_proxy) do
87
+ timeout = RSMP::Validator.get_config('timeouts', 'yellow_flash')
88
+ site_proxy.tlc.set_functional_position('YellowFlash', within: timeout)
89
+ command_timeout = RSMP::Validator.get_config('timeouts', 'command_response')
90
+ site_proxy.tlc.set_functional_position('NormalControl', within: command_timeout)
91
+ end
92
+ command_timeout ||= RSMP::Validator.get_config('timeouts', 'command_response')
93
+ site_proxy.tlc.set_functional_position('NormalControl', within: command_timeout)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,287 @@
1
+ describe 'Site::Tlc::SignalPlans' do
2
+ include RSMP::Validator::Helpers::SignalPlans
3
+
4
+ # Verify status S0014 current time plan
5
+ #
6
+ # 1. Given the site_proxy is connected
7
+ # 2. When we request the status
8
+ # 3. We should receive a status response before timeout
9
+ it 'currently active is read with S0014' do
10
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
11
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
12
+ { S0014: %i[status source] }
13
+ else
14
+ { S0014: [:status] }
15
+ end
16
+ site_proxy.request_status_and_collect(status_list,
17
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
18
+ end
19
+ end
20
+
21
+ # Verify that we change time plan (signal program)
22
+ # We try switching all programs configured
23
+ #
24
+ # 1. Given the site_proxy is connected
25
+ # 2. And there is a RSMP::Validator.get_config('validator') with a time plan
26
+ # 3. When we send the command
27
+ # 3. We should receive a confirmative command response before timeout
28
+ it 'currently active is set with M0002' do
29
+ skip 'requires sxl >= 1.0.7' unless RSMP::Validator.sxl_matches?('>=1.0.7')
30
+ plans = RSMP::Validator.get_config('items', 'plans')
31
+ skip('No time plans configured') if plans.nil? || plans.empty?
32
+ with_site(:connected) do |site_proxy|
33
+ RSMP::Validator.get_config('secrets', 'security_codes', 2)
34
+ plans.each do |plan|
35
+ command_timeout = RSMP::Validator.get_config('timeouts', 'command')
36
+ status_timeout = RSMP::Validator.get_config('timeouts', 'status_response')
37
+ site_proxy.tlc.set_timeplan(plan, within: command_timeout)
38
+
39
+ s0014_fields = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
40
+ { S0014: %i[status source] }
41
+ else
42
+ { S0014: [:status] }
43
+ end
44
+ collector = site_proxy.request_status_and_collect(
45
+ s0014_fields,
46
+ within: status_timeout
47
+ )
48
+ collector.ok!
49
+ ss = collector.messages.last.attributes['sS']
50
+ expect(ss.find { |i| i['n'] == 'status' }&.fetch('s').to_i).to eq(plan)
51
+ end
52
+ end
53
+ end
54
+
55
+ # Verify status S0018 number of time plans
56
+ # Deprecated from 1.2, use S0022 instead.
57
+ #
58
+ # 1. Given the site_proxy is connected
59
+ # 2. When we request the status
60
+ # 3. We should receive a status response before timeout
61
+ it 'list size is read with S0018' do
62
+ with_site(:connected, sxl: ['>=1.0.7', '<1.2']) do |site_proxy|
63
+ site_proxy.request_status_and_collect({ S0018: [:number] },
64
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
65
+ end
66
+ end
67
+
68
+ # Verify status S0022 list of time plans
69
+ #
70
+ # 1. Given the site_proxy is connected
71
+ # 2. When we request the status
72
+ # 3. We should receive a status response before timeout
73
+ it 'list is read with S0022' do
74
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
75
+ site_proxy.request_status_and_collect({ S0022: [:status] },
76
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
77
+ end
78
+ end
79
+
80
+ # Verify status S0026 week time table
81
+ #
82
+ # 1. Given the site_proxy is connected
83
+ # 2. When we request the status
84
+ # 3. We should receive a status response before timeout
85
+ it 'week table is read with S0026' do
86
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
87
+ site_proxy.request_status_and_collect({ S0026: [:status] },
88
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
89
+ end
90
+ end
91
+
92
+ # Verify that we can set week table with M0016
93
+ #
94
+ # 1. Given the site_proxy is connected
95
+ # 2. When we send the command
96
+ # 3. We should receive a confirmative command response before timeout
97
+ it 'week table is set with M0016' do
98
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
99
+ status = '0-1,6-2'
100
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
101
+ site_proxy.tlc.set_week_table(status, within: timeout)
102
+ end
103
+ end
104
+
105
+ # Verify status S0027 time tables
106
+ #
107
+ # 1. Given the site_proxy is connected
108
+ # 2. When we request the status
109
+ # 3. We should receive a status response before timeout
110
+ it 'day table is read with S0027' do
111
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
112
+ site_proxy.request_status_and_collect({ S0027: [:status] },
113
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
114
+ end
115
+ end
116
+
117
+ # Verify that we can set day table with M0017
118
+ #
119
+ # 1. Given the site_proxy is connected
120
+ # 2. When we send the command
121
+ # 3. We should receive a confirmative command response before timeout
122
+ it 'day table is set with M0017' do
123
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
124
+ status = '12-1-12-59,1-0-23-12'
125
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
126
+ site_proxy.tlc.set_day_table(status, within: timeout)
127
+ end
128
+ end
129
+
130
+ # Verify status S0097 version of traffic program
131
+ #
132
+ # 1. Given the site_proxy is connected
133
+ # 2. When we request the status
134
+ # 3. We should receive a status response before timeout
135
+ it 'version is read with S0097' do
136
+ with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
137
+ site_proxy.request_status_and_collect({ S0097: %i[timestamp checksum] },
138
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
139
+ end
140
+ end
141
+
142
+ #
143
+ # Verify status S0098 configuration of traffic parameters
144
+ #
145
+ # 1. Given the site_proxy is connected
146
+ # 2. When we request the status
147
+ # 3. We should receive a status response before timeout
148
+ it 'config is read with S0098' do
149
+ with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
150
+ timeout = RSMP::Validator.get_config('timeouts', 'status_response')
151
+ collector = site_proxy.request_status_and_collect(
152
+ { S0098: %i[timestamp config version] },
153
+ within: timeout
154
+ )
155
+ collector.ok!
156
+ ss = collector.messages.last.attributes['sS']
157
+ values = ss.to_h { |i| [i['n'], i['s']] }
158
+
159
+ assert(!values['timestamp'].empty?, 'expected timestamp to not be empty')
160
+ assert(!values['config'].empty?, 'expected config to not be empty')
161
+ assert(!values['version'].empty?, 'expected version to not be empty')
162
+ end
163
+ end
164
+
165
+ # Verify status S0023 command table
166
+ #
167
+ # 1. Given the site_proxy is connected
168
+ # 2. When we request the status
169
+ # 3. We should receive a status response before timeout
170
+ it 'dynamic bands are read with S0023' do
171
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
172
+ site_proxy.request_status_and_collect({ S0023: [:status] },
173
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
174
+ end
175
+ end
176
+
177
+ # Verify that dynamic bands can the set with M0014
178
+ #
179
+ # 1. Given the site_proxy is connected
180
+ # 2. When we send the command
181
+ # 3. We should receive a confirmative command response before timeout
182
+ it 'dynamic bands are set with M0014' do
183
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
184
+ plan = RSMP::Validator.get_config('items', 'plans').first
185
+ status = '1-12'
186
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
187
+ site_proxy.tlc.set_dynamic_bands(plan: plan, status: status, within: timeout)
188
+ end
189
+ end
190
+
191
+ # Verify that dynamic bands can be read and changed
192
+ #
193
+ # 1. Given the site_proxy is connected
194
+ # 2. And we read dynamic band
195
+ # 3. When we set dynamic band to 2x previous value
196
+ # 4. Then reading dynamic bands should confirm the change
197
+ # 5. Finally when we revert dynamic band to previous value
198
+ # 6. Then reading dynamic bands should confirm the reversion
199
+
200
+ it 'dynamic bands values can be changed and read back' do
201
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
202
+ plan = RSMP::Validator.get_config('items', 'plans').first
203
+ band = 3
204
+
205
+ value = site_proxy.tlc.read_dynamic_band(plan: plan, band: band) || 0
206
+ expect(value).to be_a(Integer)
207
+
208
+ new_value = value + 1
209
+
210
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
211
+ site_proxy.tlc.set_dynamic_bands(plan: plan, status: "#{band}-#{new_value}", within: timeout)
212
+ expect(site_proxy.tlc.read_dynamic_band(plan: plan, band: band)).to eq(new_value)
213
+
214
+ site_proxy.tlc.set_dynamic_bands(plan: plan, status: "#{band}-#{value}", within: timeout)
215
+ expect(site_proxy.tlc.read_dynamic_band(plan: plan, band: band)).to eq(value)
216
+ end
217
+ end
218
+
219
+ # Verify command M0023 timeout of dynamic bands
220
+ #
221
+ # 1. Given the site_proxy is connected
222
+ # 2. When we send command to set timeout
223
+ # 3. Then we should get a confirmation
224
+ # 2. When we send command to disable timeout
225
+ # 3. Then we should get a confirmation
226
+ it 'timeout for dynamic bands is set with M0023' do
227
+ with_site(:connected, sxl: '>=1.1') do |site_proxy|
228
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
229
+ status = 10
230
+ site_proxy.tlc.set_dynamic_bands_timeout(status, within: timeout)
231
+ status = 0
232
+ site_proxy.tlc.set_dynamic_bands_timeout(status, within: timeout)
233
+ end
234
+ end
235
+
236
+ # Verify status S0024 offset time
237
+ #
238
+ # 1. Given the site_proxy is connected
239
+ # 2. Request status
240
+ # 3. Expect status response before timeout
241
+ it 'offset is read with S0024' do
242
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
243
+ site_proxy.request_status_and_collect({ S0024: [:status] },
244
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
245
+ end
246
+ end
247
+
248
+ # 1. Verify connection
249
+ # 2. Send control command to set dynamic_bands
250
+ # 3. Wait for status = true
251
+ it 'offset is set with M0015' do
252
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
253
+ plan = RSMP::Validator.get_config('items', 'plans').first
254
+ offset = 99
255
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
256
+ site_proxy.tlc.set_offset(plan: plan, offset: offset, within: timeout)
257
+ end
258
+ end
259
+
260
+ # Verify status S0028 cycle time
261
+ #
262
+ # 1. Given the site_proxy is connected
263
+ # 2. When we request the status
264
+ # 3. We should receive a status response before timeout
265
+ it 'cycle time is read with S0028' do
266
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
267
+ site_proxy.request_status_and_collect({ S0028: [:status] },
268
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
269
+ end
270
+ end
271
+
272
+ # Verify that cycle time can be changed with M0018
273
+ #
274
+ # 1. Given the site_proxy is connected
275
+ # 2. And we read cycle times
276
+ # 3. When we extend cycle time of curent plan with 5s
277
+ # 4. Then reading the cycle time should confirm the change
278
+ # 5. Finally when we revert cycle time to previous value
279
+ # 6. Then reading cycle time should confirm the reversion
280
+ it 'cycle time is set with M0018' do
281
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
282
+ with_cycle_time_extended(site_proxy) do
283
+ log 'Cycle time extension confirmed'
284
+ end
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,144 @@
1
+ describe 'Site::Tlc::SignalPriority' do
2
+ include RSMP::Validator::Helpers::Status
3
+
4
+ # Signal requests require core >= 3.2 because they uses the Array data type.
5
+
6
+ # Validate that a signal priority can be requested.
7
+ #
8
+ # 1. Given the site_proxy is connected
9
+ # 2. When we send a signal priority request
10
+ # 3. Then we should receive an acknowledgement
11
+ it 'can be requested with M0022' do
12
+ with_site(:connected, core: '>=3.2', sxl: '>=1.1') do |site_proxy|
13
+ signal_group = RSMP::Validator.get_config('components', 'signal_group').keys.first
14
+ command_list = RSMP::CommandList.new(:M0022, :requestPriority,
15
+ requestId: SecureRandom.uuid[0..3],
16
+ signalGroupId: signal_group,
17
+ type: 'new',
18
+ level: 7,
19
+ eta: 10,
20
+ vehicleType: 'car').to_a
21
+ log "Request signal priority for signal group #{signal_group}"
22
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
23
+ site_proxy.send_command_and_collect(command_list, within: timeout).ok!
24
+ end
25
+ end
26
+
27
+ # Validate that signal priority status can be requested.
28
+ #
29
+ # 1. Given the site_proxy is connected
30
+ # 2. When we request signal priority status
31
+ # 3. Then we should receive a status update
32
+ it 'status can be fetched with S0033' do
33
+ with_site(:connected, core: '>=3.2', sxl: '>=1.1') do |site_proxy|
34
+ site_proxy.request_status_and_collect({ S0033: [:status] },
35
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
36
+ end
37
+ end
38
+
39
+ # Validate that we can subscribe signal priority status
40
+ #
41
+ # 1. Given the site_proxy is connected
42
+ # 2. And we subscribe to signal priority status updates
43
+ # 4. Then we should receive an acknowledgement
44
+ # 5. And we should reive a status updates
45
+ it 'status can be subscribed to with S0033' do
46
+ with_site(:connected, core: '>=3.2', sxl: '>=1.1') do |site_proxy|
47
+ status_list = [{ 'sCI' => 'S0033', 'n' => 'status', 'uRt' => '0' }]
48
+ status_list.map! { |item| item.merge!('sOc' => true) } if site_proxy.tlc.use_soc?
49
+ wait_for_status(site_proxy, 'signal priority status', status_list)
50
+ end
51
+ end
52
+
53
+ # Validate that a signal priority completes when we cancel it.
54
+ #
55
+ # 1. Given the site_proxy is connected
56
+ # 2. And we subscribe to signal priority status
57
+ # 3. When we send a signal priority request
58
+ # 4. Then the request state should become 'received'
59
+ # 5. Then the request state should become 'activated'
60
+ # 6. When we cancel the request
61
+ # 7. Then the state should become 'completed'
62
+
63
+ it 'becomes completed when cancelled' do
64
+ with_site(:connected, core: '>=3.2', sxl: '>=1.1') do |site_proxy|
65
+ timeout = RSMP::Validator.get_config('timeouts', 'priority_completion')
66
+ component = RSMP::Validator.get_config('main_component')
67
+ signal_group_id = RSMP::Validator.get_config('components', 'signal_group').keys.first
68
+ prio = RSMP::Validator::Helpers::SignalPriority::RequestHelper.new(
69
+ site_proxy,
70
+ component: component,
71
+ signal_group_id: signal_group_id,
72
+ timeout: timeout,
73
+ task: Async::Task.current
74
+ )
75
+
76
+ prio.run do
77
+ log 'Before: Send unrelated signal priority request.'
78
+ prio.request_unrelated
79
+
80
+ log 'Send signal priority request, wait for reception.'
81
+ prio.request
82
+
83
+ log 'After: Send unrelated signal priority request.'
84
+ prio.request_unrelated
85
+
86
+ prio.expect :received
87
+ log 'Signal priority request was received, wait for activation.'
88
+
89
+ prio.expect :activated
90
+ log 'Signal priority request was activated, now cancel it and wait for completion.'
91
+
92
+ prio.cancel
93
+ prio.expect :completed
94
+ log 'Signal priority request was completed.'
95
+ end
96
+ end
97
+ end
98
+
99
+ # Validate that a signal priority times out if not cancelled.
100
+ #
101
+ # 1. Given the site_proxy is connected
102
+ # 2. And we subscribe to signal priority status
103
+ # 3. When we send a signal priority request
104
+ # 4. Then the request state should become 'received'
105
+ # 5. Then the request state should become 'activated'
106
+ # 6. When we do not cancel the request
107
+ # 7. Then the state should become 'stale'
108
+
109
+ it 'becomes stale if not cancelled' do
110
+ with_site(:connected, core: '>=3.2', sxl: '>=1.1') do |site_proxy|
111
+ timeout = RSMP::Validator.get_config('timeouts', 'priority_completion')
112
+ component = RSMP::Validator.get_config('main_component')
113
+ signal_group_id = RSMP::Validator.get_config('components', 'signal_group').keys.first
114
+ prio = RSMP::Validator::Helpers::SignalPriority::RequestHelper.new(
115
+ site_proxy,
116
+ component: component,
117
+ signal_group_id: signal_group_id,
118
+ timeout: timeout,
119
+ task: Async::Task.current
120
+ )
121
+
122
+ prio.run do
123
+ log 'Before: Send unrelated signal priority request.'
124
+ prio.request_unrelated
125
+
126
+ log 'Send signal priority request, wait for reception.'
127
+ prio.request
128
+
129
+ log 'After: Send unrelated signal priority request.'
130
+ prio.request_unrelated
131
+
132
+ prio.expect :received
133
+ log 'Signal priority request was received, wait for activation.'
134
+
135
+ prio.expect :activated
136
+ log 'Signal priority request was activated, wait for it to become stale.'
137
+
138
+ # don't cancel request, it should then become stale by itself
139
+ prio.expect :stale
140
+ log 'Signal priority request became stale.'
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,71 @@
1
+ describe 'Site::Tlc::Subscribe' do
2
+ # Check that we can *subscribe* to status messages.
3
+ # The test subscribes to S0001 (signal group status), because
4
+ # it will usually change once per second, but otherwise the choice
5
+ # is arbitrary as we simply want to check that
6
+ # the subscription mechanism works.
7
+ #
8
+ # 1. subscribe
9
+ # 1. check that we receive a status update with a predefined time
10
+ # 1. unsubscribe
11
+
12
+ it 'can be turned on and off for S0001' do
13
+ with_site(:connected) do |site_proxy|
14
+ log 'Subscribe to status and wait for update'
15
+ component = RSMP::Validator.get_config('main_component')
16
+
17
+ status_list = [{ 'sCI' => 'S0001', 'n' => 'signalgroupstatus', 'uRt' => '1' }]
18
+ status_list.map! { |item| item.merge!('sOc' => true) } if site_proxy.tlc.use_soc?
19
+
20
+ site_proxy.subscribe_to_status_and_collect(status_list,
21
+ component: component,
22
+ within: RSMP::Validator.get_config('timeouts', 'status_update')).ok!
23
+ ensure
24
+ unsubscribe_list = status_list.map { |item| item.slice('sCI', 'n') }
25
+ site_proxy.unsubscribe_to_status unsubscribe_list, component: component
26
+ end
27
+ end
28
+
29
+ # Check that we can change the update rate interval while status subscription is active.
30
+ # The test subscribes to S0001 'cyclecounter' attribute with an initial update rate of 60s,
31
+ # then changes the update rate to 1s and verifies the new rate is in effect.
32
+ #
33
+ # 1. Subscribe to S0001 'cyclecounter' with update rate 60s
34
+ # 2. Verify that subscription succeeds
35
+ # 3. Send the same subscription again with update rate 1s
36
+ # 4. Verify that the new update rate is in effect by checking next update is received within 2s
37
+
38
+ it 'can change interval during active subscription' do
39
+ with_site(:connected) do |site_proxy|
40
+ component = RSMP::Validator.get_config('main_component')
41
+
42
+ # Step 1: Subscribe with 60s update rate (no need to wait for updates with long interval)
43
+ log 'Subscribe to S0001 cyclecounter with 60s update rate'
44
+ initial_status_list = [{ 'sCI' => 'S0001', 'n' => 'cyclecounter', 'uRt' => '60' }]
45
+ initial_status_list.map! { |item| item.merge!('sOc' => true) } if site_proxy.tlc.use_soc?
46
+
47
+ # Subscribe but don't wait for updates (since 60s is too long)
48
+ site_proxy.subscribe_to_status initial_status_list, component: component
49
+ log 'Initial subscription with 60s update rate successful'
50
+
51
+ # Step 3: Change update rate to 1s by re-subscribing and verify we get update within 2s
52
+ log 'Change update rate to 1s by re-subscribing and verify update within 2s'
53
+ updated_status_list = [{ 'sCI' => 'S0001', 'n' => 'cyclecounter', 'uRt' => '1' }]
54
+ updated_status_list.map! { |item| item.merge!('sOc' => true) } if site_proxy.tlc.use_soc?
55
+
56
+ # This should collect at least one status update within 2s if the 1s rate is working
57
+ collector = site_proxy.subscribe_to_status_and_collect(updated_status_list,
58
+ component: component,
59
+ within: 2).ok!
60
+
61
+ assert(!collector.nil?, 'Expected subscribe_to_status_and_collect to return a collector')
62
+ assert(!collector.messages.empty?,
63
+ 'Expected to receive status update within 2s with new 1s update rate')
64
+ log 'Successfully received status update within 2s, confirming 1s update rate is active'
65
+ ensure
66
+ # Clean up subscription
67
+ unsubscribe_list = [{ 'sCI' => 'S0001', 'n' => 'cyclecounter' }]
68
+ site_proxy.unsubscribe_to_status unsubscribe_list, component: component
69
+ end
70
+ end
71
+ end