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,106 @@
1
+ describe 'Site::Tlc::EmergencyRoutes' do
2
+ include RSMP::Validator::Helpers::Status
3
+
4
+ # Verify that current emergency route can be read with S0006.
5
+ # Depreciated from 1.2, use S0035 instead.
6
+ # 1. Given the site_proxy is connected.
7
+ # 2. When we request S0006.
8
+ # 3. Then we should receive a status response.
9
+ it 'emergency route is read with S0006' do
10
+ with_site(:connected, sxl: ['>=1.0.7', '<1.2']) do |site_proxy|
11
+ site_proxy.request_status_and_collect({ S0006: %i[status emergencystage] },
12
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
13
+ end
14
+ end
15
+
16
+ # Verify that current emergency routes can be read with S0035.
17
+ # Requires core >= 3.2 since it uses the array data type.
18
+ # 1. Given the site_proxy is connected.
19
+ # 2. When we request S0035.
20
+ # 3. Then we should receive a status response.
21
+ it 'emergency route is read with S0035' do
22
+ skip 'requires core >= 3.2' unless RSMP::Validator.core_matches?('>=3.2')
23
+ with_site(:connected, sxl: '>=1.2') do |site_proxy|
24
+ site_proxy.request_status_and_collect({ S0035: [:emergencyroutes] },
25
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
26
+ end
27
+ end
28
+
29
+ # Verify that emergency routes can be activated with M0005.
30
+ # S0006 should reflect the last route enabled/disabled.
31
+ # 1. Given the site_proxy is connected.
32
+ # 2. When we send M0005 to set emergency route.
33
+ # 3. Then we should get a command responds confirming the change.
34
+ it 'can be activated with M0005 and read with S0006' do
35
+ skip 'requires sxl >= 1.0.7, < 1.2' unless RSMP::Validator.sxl_matches?(['>=1.0.7', '<1.2'])
36
+ emergency_routes = RSMP::Validator.get_config('items', 'emergency_routes')
37
+ skip('No emergency routes configured') if emergency_routes.nil? || emergency_routes.empty?
38
+
39
+ def set_emergency_states(site_proxy, emergency_routes, state)
40
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
41
+ emergency_routes.each do |emergency_route|
42
+ site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: state, within: timeout)
43
+ end
44
+ wait_for_status(site_proxy, "emergency route #{emergency_routes.last} to be enabled",
45
+ [
46
+ { 'sCI' => 'S0006', 'n' => 'status', 's' => (state ? 'True' : 'False') },
47
+ { 'sCI' => 'S0006', 'n' => 'emergencystage',
48
+ 's' => (state ? emergency_routes.last.to_s : '0') }
49
+ ])
50
+ end
51
+
52
+ with_site(:connected) do |site_proxy|
53
+ set_emergency_states(site_proxy, emergency_routes, false)
54
+ begin
55
+ set_emergency_states(site_proxy, emergency_routes, true)
56
+ ensure
57
+ set_emergency_states(site_proxy, emergency_routes, false)
58
+ end
59
+ end
60
+ end
61
+
62
+ # Verify that emergency routes can be activated with M0005.
63
+ # S0035 should show all active routes.
64
+ # 1. Given the site_proxy is connected.
65
+ # 2. When we send M0005 to set emergency route.
66
+ # 3. Then we should get a command responds confirming the change.
67
+ # 4. When we request the current emergency routes with S035.
68
+ # 5. Then we should receive the list of active routes.
69
+
70
+ it 'emergency routes can be activated with M0005 and read with S0035' do
71
+ skip 'requires core >= 3.2' unless RSMP::Validator.core_matches?('>=3.2')
72
+ skip 'requires sxl >= 1.2' unless RSMP::Validator.sxl_matches?('>=1.2')
73
+
74
+ emergency_routes = RSMP::Validator.get_config('items', 'emergency_routes')
75
+ skip('No emergency routes configured') if emergency_routes.nil? || emergency_routes.empty?
76
+
77
+ def enable_routes(site_proxy, emergency_routes)
78
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
79
+ emergency_routes.each do |emergency_route|
80
+ site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: true, within: timeout)
81
+ end
82
+ routes = emergency_routes.map { |i| { 'id' => i.to_s } }
83
+ wait_for_status(site_proxy, "emergency routes #{emergency_routes} to be enabled",
84
+ [{ 'sCI' => 'S0035', 'n' => 'emergencyroutes', 's' => routes }])
85
+ end
86
+
87
+ def disable_routes(site_proxy, emergency_routes, within:)
88
+ emergency_routes.each do |emergency_route|
89
+ site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: false, within:)
90
+ end
91
+ routes = []
92
+ wait_for_status(site_proxy, 'all emergency routes to be disabled',
93
+ [{ 'sCI' => 'S0035', 'n' => 'emergencyroutes', 's' => routes }])
94
+ end
95
+
96
+ with_site(:connected) do |site_proxy|
97
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
98
+ disable_routes(site_proxy, emergency_routes, within: timeout)
99
+ begin
100
+ enable_routes(site_proxy, emergency_routes)
101
+ ensure
102
+ disable_routes(site_proxy, emergency_routes, within: timeout)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,102 @@
1
+ describe 'Site::Tlc::Input' do
2
+ include RSMP::Validator::Helpers::Input
3
+
4
+ # Tests related to inputs and outputs.
5
+
6
+ # Verify that we can read input status with S0003, extendedinputstatus attribute
7
+ # 1. Given the site is connected
8
+ # 2. When we read input with S0029
9
+ # 3. Then we should receive a valid response
10
+ it 'is read with S0003 with extended input status' do
11
+ with_site(:connected, sxl: '<1.2') do |site_proxy|
12
+ site_proxy.request_status_and_collect(
13
+ { S0003: %i[inputstatus extendedinputstatus] },
14
+ within: RSMP::Validator.get_config('timeouts', 'status_response')
15
+ ).ok!
16
+ end
17
+ end
18
+
19
+ # Verify that we can read input status with S0003
20
+ # 1. Given the site is connected
21
+ # 2. When we read input with S0029
22
+ # 3. Then we should receive a valid response
23
+ it 'is read with S0003' do
24
+ with_site(:connected, sxl: '>=1.2') do |site_proxy|
25
+ site_proxy.request_status_and_collect({ S0003: [:inputstatus] },
26
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
27
+ end
28
+ end
29
+
30
+ # Verify that we can read forced input status with S0029
31
+ # 1. Given the site is connected
32
+ # 2. When we read input with S0029
33
+ # 3. Then we should receive a valid response
34
+ it 'forcing is read with S0029' do
35
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
36
+ site_proxy.request_status_and_collect({ S0029: [:status] },
37
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
38
+ end
39
+ end
40
+
41
+ # Verify that we can force input with M0019
42
+ # 1. Given the site is connected
43
+ # 2. And the input is forced off
44
+ # 2. When we force the input on
45
+ # 3. Then S0003 should show the input on
46
+
47
+ it 'forcing is set with M0019' do
48
+ with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
49
+ inputs = RSMP::Validator.get_config('items', 'inputs')
50
+ skip('No inputs configured') if inputs.nil? || inputs.empty?
51
+ inputs.each do |input|
52
+ timeout = RSMP::Validator.get_config('timeouts', 'command')
53
+ site_proxy.tlc.force_input(input: input, status: 'True', value: 'False', within: timeout)
54
+ site_proxy.tlc.force_input(input: input, status: 'True', value: 'True', within: timeout)
55
+ ensure
56
+ site_proxy.tlc.force_input(input: input, status: 'False', value: 'True', within: timeout)
57
+ end
58
+ end
59
+ end
60
+
61
+ # Verify that we can activate input with M0006
62
+ # 1. Given the site is connected
63
+ # 2. When we activate input with M0006
64
+ # 3. Then S0003 should show the input is active
65
+ # 4. When we deactivate input with M0006
66
+ # 5. Then S0003 should show the input is inactive
67
+
68
+ it 'is activated with M0006' do
69
+ inputs = RSMP::Validator.get_config('items', 'inputs')
70
+ skip('No inputs configured') if inputs.nil? || inputs.empty?
71
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
72
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
73
+ inputs.each { |input| switch_input(site_proxy, input, within: timeout) }
74
+ end
75
+ end
76
+
77
+ # Verify that we can acticate/deactivate a series of inputs with M0013
78
+ # 1. Given the site is connected
79
+ # 2. Send control command to set a serie of input
80
+ # 3. Wait for status = true
81
+ it 'series is activated with M0013' do
82
+ with_site(:connected, sxl: '>=1.0.8') do |site_proxy|
83
+ inputs = RSMP::Validator.get_config('items', 'inputs')
84
+ skip('No inputs configured') if inputs.nil? || inputs.empty?
85
+ status = '1,3,12;5,5,10'
86
+ timeout = RSMP::Validator.get_config('timeouts', 'command')
87
+ site_proxy.tlc.set_inputs(status, within: timeout)
88
+ end
89
+ end
90
+
91
+ # Verify that input sensitivity can be set with M0021
92
+ # 1. Given the site is connected
93
+ # 2. When we set sensitivity with M0021
94
+ # 3. Then we receive a confirmation
95
+ it 'sensitivity is set with M0021' do
96
+ with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
97
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
98
+ status = '1-50'
99
+ site_proxy.tlc.set_trigger_level(status, within: timeout)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,103 @@
1
+ describe 'Site::Tlc::InvalidCommand' do
2
+ # Verify that site_proxy reponds with age=undefined when receiving
3
+ # a command with an unknown component id
4
+ #
5
+ # 1. Given the site_proxy is connected
6
+ # 2. When we send a command with an unknown component id
7
+ # 3. Then the site_proxy should return a command response with age=undefined
8
+
9
+ it 'returns a command response with age=undefined if compoent id is unknown' do
10
+ with_site(:connected, core: '>=3.1.3') do |site_proxy|
11
+ log 'Sending M0001'
12
+ command_list = RSMP::CommandList.new(:M0001, :setValue,
13
+ securityCode: RSMP::Validator.get_config('secrets', 'security_codes', 2),
14
+ status: 'NormalControl',
15
+ timeout: 0,
16
+ intersection: 0).to_a
17
+ result = site_proxy.send_command_and_collect(
18
+ command_list,
19
+ component: 'bad',
20
+ within: RSMP::Validator.get_config('timeouts', 'command_response'),
21
+ validate: false # disable validation of outgoing message
22
+ )
23
+ expect(result).to be_a(RSMP::Collector)
24
+ expect(result.status).to eq(:ok)
25
+ response = result.messages.first
26
+ expect(response).to be_a(RSMP::CommandResponse)
27
+ rvs = response.attributes['rvs']
28
+ expect(rvs).to be_a(Array)
29
+ rvs.each do |rv|
30
+ age = rv['age']
31
+ expect(age).to eq('undefined')
32
+ end
33
+ end
34
+ end
35
+
36
+ # Verify that site_proxy returns NotAck when receiving an unknown command
37
+ #
38
+ # 1. Given the site_proxy is connected
39
+ # 2. When we send a non-existing M0000 command
40
+ # 3. Then the site_proxy should return NotAck
41
+
42
+ it 'returns NotAck if command code id is unknown' do
43
+ with_site(:connected) do |site_proxy|
44
+ log 'Sending non-existing command M0000'
45
+ command_list = RSMP::CommandList.new(:M0000, :bad, {}).to_a
46
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
47
+
48
+ collector = site_proxy.send_command_and_collect(command_list,
49
+ within: timeout,
50
+ validate: false) # disable schema validation of outgoing message
51
+ expect(collector.status).to eq(:cancelled)
52
+ expect(collector.error).to be_a(RSMP::MessageRejected)
53
+ end
54
+ end
55
+
56
+ # Verify that site_proxy returns NotAck when receiving a command
57
+ # with a mising command attribute
58
+ #
59
+ # 1. Given the site_proxy is connected
60
+ # 2. When we send an M0001 command with 'status' missing
61
+ # 3. Then the site_proxy return NotAck
62
+
63
+ it 'returns NotAck if attribute is missing' do
64
+ with_site(:connected) do |site_proxy|
65
+ log "Sending M0001 with 'status' attribute missing"
66
+ command_list = RSMP::CommandList.new(:M0001, :setValue,
67
+ securityCode: '1111',
68
+ intersection: '0',
69
+ timeout: '0').to_a
70
+ # intentionally not setting 'status'
71
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
72
+ collector = site_proxy.send_command_and_collect(command_list,
73
+ within: timeout,
74
+ validate: false) # disable validation of outgoing message
75
+ expect(collector.status).to eq(:cancelled)
76
+ expect(collector.error).to be_a(RSMP::MessageRejected)
77
+ end
78
+ end
79
+
80
+ # Verify that site_proxy returns NotAck when receiving a command
81
+ # with an unknown command name
82
+ #
83
+ # 1. Given the site_proxy is connected
84
+ # 2. When we send an M0001 command with 'bad' as command name
85
+ # 3. Then the site_proxy should return NotAck
86
+
87
+ it 'returns NotAck if command name is bad' do
88
+ with_site(:connected) do |site_proxy|
89
+ log 'Sending M0001'
90
+ # for M0001, cO should be :setValue, here we use the incorrect :bad
91
+ command_list = RSMP::CommandList.new(:M0001, :bad,
92
+ securityCode: '1111',
93
+ intersection: '0',
94
+ timeout: '0').to_a
95
+ timeout = RSMP::Validator.get_config('timeouts', 'command_response')
96
+ collector = site_proxy.send_command_and_collect(command_list,
97
+ within: timeout,
98
+ validate: false) # disable validation of outgoing message
99
+ expect(collector.status).to eq(:cancelled)
100
+ expect(collector.error).to be_a(RSMP::MessageRejected)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,70 @@
1
+ describe 'Site::Tlc::InvalidStatus' do
2
+ # Verify that site_proxy reponds with q=undefined when receiving a
3
+ # status request with an unknown component id.
4
+ #
5
+ # 1. Given the site_proxy is connected
6
+ # 2. When we send a status request with an unknown component id
7
+ # 3. Then the site_proxy should return a status response with q=undefined
8
+
9
+ it 'return a command response with age=undefined when component id is unknown' do
10
+ with_site(:connected, core: '>=3.1.3') do |site_proxy|
11
+ log 'Sending M0001 with bad component id'
12
+ collector = site_proxy.request_status_and_collect(
13
+ { S0001: [:signalgroupstatus] },
14
+ component: 'bad',
15
+ within: RSMP::Validator.get_config('timeouts', 'status_response'),
16
+ validate: false
17
+ )
18
+ collector.ok!
19
+ expect(collector.status).to eq(:ok)
20
+ response = collector.messages.first
21
+ expect(response).to be_a(RSMP::StatusResponse)
22
+ ss = response.attributes['sS']
23
+ expect(ss).to be_a(Array)
24
+ ss.each do |s|
25
+ q = s['q']
26
+ expect(q).to eq('undefined')
27
+ end
28
+ end
29
+ end
30
+
31
+ # Verify that site_proxy returns NotAck when receiving
32
+ # a request for an unknown status
33
+ #
34
+ # 1. Given the site_proxy is connected
35
+ # 2. When we send a non-existing S000 status request
36
+ # 3. Then the site_proxy should return NotAck
37
+ it 'returns NotAck when status code is unknown' do
38
+ with_site(:connected) do |site_proxy|
39
+ log 'Requesting non-existing status S0000'
40
+ expect do
41
+ site_proxy.request_status_and_collect(
42
+ { S0000: [:status] },
43
+ component: RSMP::Validator.get_config('main_component'),
44
+ within: RSMP::Validator.get_config('timeouts', 'status_response'),
45
+ validate: false
46
+ ).ok!
47
+ end.to raise_exception(RSMP::MessageRejected)
48
+ end
49
+ end
50
+
51
+ # Verify that site_proxy returns NotAck when receiving
52
+ # a request for an unknown status
53
+ #
54
+ # 1. Given the site_proxy is connected
55
+ # 2. When we send an S0001 request with the stauts name 'bad'
56
+ # 3. Then the site_proxy should return NotAck
57
+ it 'returns NotAck when status name is unknown' do
58
+ with_site(:connected) do |site_proxy|
59
+ log 'Requesting S0001 with non-existing status name'
60
+ expect do
61
+ site_proxy.request_status_and_collect(
62
+ { S0001: [:bad] },
63
+ component: RSMP::Validator.get_config('main_component'),
64
+ within: RSMP::Validator.get_config('timeouts', 'status_response'),
65
+ validate: false
66
+ ).ok!
67
+ end.to raise_exception(RSMP::MessageRejected)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,260 @@
1
+ describe 'Site::Tlc::Modes' do
2
+ include RSMP::Validator::Helpers::Startup
3
+
4
+ # Verify status S0020 control mode
5
+ #
6
+ # 1. Given the site_proxy is connected
7
+ # 2. Request status
8
+ # 3. Expect status response before timeout
9
+ it 'control mode is read with S0020' do
10
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
11
+ site_proxy.request_status_and_collect({ S0020: %i[controlmode intersection] },
12
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
13
+ end
14
+ end
15
+
16
+ # Verify status S0005 traffic controller starting
17
+ #
18
+ # 1. Given the site_proxy is connected
19
+ # 2. Request status
20
+ # 3. Expect status response before timeout
21
+ it 'startup status is read with S0005' do
22
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
23
+ site_proxy.request_status_and_collect({ S0005: [:status] },
24
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
25
+ end
26
+ end
27
+
28
+ # Verify status S0005 traffic controller starting by intersection
29
+ # statusByIntersection requires core >= 3.2, since it uses the array data type.
30
+ #
31
+ # 1. Given the site_proxy is connected
32
+ # 2. Request status
33
+ # 3. Expect status response before timeout
34
+ it 'startup status is read with S0005 by intersection' do
35
+ skip 'requires core >= 3.2' unless RSMP::Validator.core_matches?('>=3.2')
36
+ with_site(:connected, sxl: '>=1.2') do |site_proxy|
37
+ site_proxy.request_status_and_collect({ S0005: [:statusByIntersection] },
38
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
39
+ end
40
+ end
41
+
42
+ # Verify status S0007 controller switched on (dark mode=off)
43
+ #
44
+ # 1. Given the site_proxy is connected
45
+ # 2. Request status
46
+ # 3. Expect status response before timeout
47
+ it 'switched on is read with S0007' do
48
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
49
+ site_proxy.request_status_and_collect({ S0007: %i[status intersection] },
50
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
51
+ end
52
+ end
53
+
54
+ # Verify status S0007 controller switched on, source attribute
55
+ #
56
+ # 1. Given the site_proxy is connected
57
+ # 2. Request status
58
+ # 3. Expect status response before timeout
59
+ it 'switched on is read with S0007 with source' do
60
+ with_site(:connected, sxl: '>=1.1') do |site_proxy|
61
+ site_proxy.request_status_and_collect({ S0007: %i[status intersection source] },
62
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
63
+ end
64
+ end
65
+
66
+ # Verify status S0008 manual control
67
+ #
68
+ # 1. Given the site_proxy is connected
69
+ # 2. Request status
70
+ # 3. Expect status response before timeout
71
+ it 'manual control is read with S0008' do
72
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
73
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
74
+ { S0008: %i[status intersection source] }
75
+ else
76
+ { S0008: %i[status intersection] }
77
+ end
78
+ site_proxy.request_status_and_collect(status_list,
79
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
80
+ end
81
+ end
82
+
83
+ # Verify status S0009 fixed time control
84
+ #
85
+ # 1. Given the site_proxy is connected
86
+ # 2. Request status
87
+ # 3. Expect status response before timeout
88
+ it 'fixed time control is read with S0009' do
89
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
90
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
91
+ { S0009: %i[status intersection source] }
92
+ else
93
+ { S0009: %i[status intersection] }
94
+ end
95
+ site_proxy.request_status_and_collect(status_list,
96
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
97
+ end
98
+ end
99
+
100
+ # Verify command M0007 fixed time control
101
+ #
102
+ # 1. Verify connection
103
+ # 2. Send command to switch to fixed time = true
104
+ # 3. Wait for status = true
105
+ # 4. Send command to switch to fixed time = false
106
+ # 5. Wait for status = false
107
+ it 'fixed time control can be activated with M0007' do
108
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
109
+ timeout = RSMP::Validator.get_config('timeouts', 'command')
110
+ site_proxy.tlc.set_fixed_time('True', within: timeout)
111
+ site_proxy.tlc.set_fixed_time('False', within: timeout)
112
+ end
113
+ end
114
+
115
+ # Verify status S0010 isolated control
116
+ #
117
+ # 1. Given the site_proxy is connected
118
+ # 2. Request status
119
+ # 3. Expect status response before timeout
120
+ it 'isolated control is read with S0010' do
121
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
122
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
123
+ { S0010: %i[status intersection source] }
124
+ else
125
+ { S0010: %i[status intersection] }
126
+ end
127
+ site_proxy.request_status_and_collect(status_list,
128
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
129
+ end
130
+ end
131
+
132
+ # Verify status S0032 coordinated control
133
+ #
134
+ # 1. Given the site_proxy is connected
135
+ # 2. Request status
136
+ # 3. Expect status response before timeout
137
+ it 'coordinated control is read with S0032' do
138
+ with_site(:connected, sxl: '>=1.1') do |site_proxy|
139
+ site_proxy.request_status_and_collect({ S0032: %i[status intersection source] },
140
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
141
+ end
142
+ end
143
+
144
+ # Verify status S0011 yellow flash
145
+ #
146
+ # 1. Given the site_proxy is connected
147
+ # 2. Request status
148
+ # 3. Expect status response before timeout
149
+ it 'yellow flash can be read with S0011' do
150
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
151
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
152
+ { S0011: %i[status intersection source] }
153
+ else
154
+ { S0011: %i[status intersection] }
155
+ end
156
+ site_proxy.request_status_and_collect(status_list,
157
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
158
+ end
159
+ end
160
+
161
+ # Verify that we can activate yellow flash
162
+ #
163
+ # 1. Given the site_proxy is connected
164
+ # 2. Send the control command to switch to Yellow flash
165
+ # 3. Wait for status Yellow flash
166
+ # 4. Send command to switch to normal control
167
+ # 5. Wait for status "Yellow flash" = false, "Controller starting"= false, "Controller on"= true"
168
+ it 'yellow flash can be activated with M0001' do
169
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
170
+ yellow_flash_timeout = RSMP::Validator.get_config('timeouts', 'yellow_flash')
171
+ startup_timeout = RSMP::Validator.get_config('timeouts', 'startup_sequence')
172
+ site_proxy.tlc.set_functional_position('YellowFlash', within: yellow_flash_timeout)
173
+ site_proxy.tlc.set_functional_position('NormalControl', within: startup_timeout)
174
+ end
175
+ end
176
+
177
+ # Verify that we can yellow flash causes all groups to go to state 'c'
178
+ #
179
+ # 1. Given the site_proxy is connected
180
+ # 2. Send the control command to switch to Yellow flash
181
+ # 3. Wait for all groups to go to group 'c'
182
+ # 4. Send command to switch to normal control
183
+ # 5. Wait for all groups to switch do something else that 'c'
184
+ it 'yellow flash affects all signal groups' do
185
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
186
+ timeout = RSMP::Validator.get_config('timeouts', 'yellow_flash')
187
+
188
+ site_proxy.tlc.set_functional_position('YellowFlash', within: timeout)
189
+ site_proxy.tlc.wait_for_groups 'c', timeout: timeout # c means yellow flash
190
+
191
+ startup_timeout = RSMP::Validator.get_config('timeouts', 'startup_sequence')
192
+ site_proxy.tlc.set_functional_position('NormalControl', within: startup_timeout)
193
+ site_proxy.tlc.wait_for_groups '[^c]', timeout: timeout # not c, ie. not yellow flash
194
+ end
195
+ end
196
+
197
+ # Verify status S0012 all red
198
+ #
199
+ # 1. Given the site_proxy is connected
200
+ # 2. Request status
201
+ # 3. Expect status response before timeout
202
+ it 'all red can be read with S0012' do
203
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
204
+ status_list = if RSMP::Proxy.version_meets_requirement?(site_proxy.sxl_version, '>=1.1')
205
+ { S0012: %i[status intersection source] }
206
+ else
207
+ { S0012: %i[status intersection] }
208
+ end
209
+ site_proxy.request_status_and_collect(status_list,
210
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
211
+ end
212
+ end
213
+
214
+ # Verify status S0013 police key
215
+ #
216
+ # 1. Given the site_proxy is connected
217
+ # 2. Request status
218
+ # 3. Expect status response before timeout
219
+ it 'police key can be read with S0013' do
220
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
221
+ site_proxy.request_status_and_collect({ S0013: [:status] },
222
+ within: RSMP::Validator.get_config('timeouts', 'status_response')).ok!
223
+ end
224
+ end
225
+
226
+ # Verify that we can activate dark mode
227
+ #
228
+ # 1. Given the site_proxy is connected
229
+ # 2. Send the control command to switch todarkmode
230
+ # 3. Wait for status"Controller on" = false
231
+ # 4. Send command to switch to normal control
232
+ # 5. Wait for status "Yellow flash" = false, "Controller starting"= false, "Controller on"= true"
233
+ it 'dark mode can be activated with M0001' do
234
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
235
+ timeout = RSMP::Validator.get_config('timeouts', 'functional_position')
236
+ startup_timeout = RSMP::Validator.get_config('timeouts', 'startup_sequence')
237
+ site_proxy.tlc.set_functional_position('Dark', within: timeout)
238
+ site_proxy.tlc.set_functional_position('NormalControl', within: startup_timeout)
239
+ end
240
+ end
241
+
242
+ # Verify that we can activate yellow flash and after 1 minute goes back to NormalControl
243
+ #
244
+ # 1. Given the site_proxy is connected
245
+ # 2. Send the control command to switch to Normal Control, and wait for this
246
+ # 2. Send the control command to switch to Yellow flash
247
+ # 3. Wait for status Yellow flash
248
+ # 5. Wait for automatic revert to Normal Control
249
+ it 'can use yellow flash with a timeout of one minute' do
250
+ with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
251
+ startup_timeout = RSMP::Validator.get_config('timeouts', 'startup_sequence')
252
+ site_proxy.tlc.set_functional_position('NormalControl', within: startup_timeout)
253
+ minutes = 1
254
+ timeout = RSMP::Validator.get_config('timeouts', 'yellow_flash')
255
+ site_proxy.tlc.set_functional_position('YellowFlash', timeout_minutes: minutes, within: timeout)
256
+ fp_timeout = RSMP::Validator.get_config('timeouts', 'functional_position')
257
+ wait_normal_control(site_proxy, timeout: (minutes * 60) + fp_timeout)
258
+ end
259
+ end
260
+ end