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.
- checksums.yaml +7 -0
- data/config/cross_rs4s.yaml +55 -0
- data/config/gem_supervisor.yaml +56 -0
- data/config/gem_tlc.yaml +56 -0
- data/config/gem_tlc_secrets.yaml +3 -0
- data/config/kapsch_etx.yaml +54 -0
- data/config/lightmotion_satellite.yaml +56 -0
- data/config/secrets.yaml +3 -0
- data/config/secrets_example.yaml +6 -0
- data/config/semaforica_cartesio.yaml +56 -0
- data/config/simulator/node_log.yaml +17 -0
- data/config/simulator/supervisor.yaml +11 -0
- data/config/simulator/tlc.yaml +56 -0
- data/config/sus.rb +13 -0
- data/config/swarco_itc3.yaml +55 -0
- data/config/tecsen_tmacs_supervisor.yaml +57 -0
- data/config/validator.rb +37 -0
- data/config/validator.yaml +5 -0
- data/config/validator_example.yaml +23 -0
- data/config/validator_log.yaml +19 -0
- data/exe/rsmp-validator +121 -0
- data/lib/doc_gen/parser.rb +276 -0
- data/lib/doc_gen/renderer.rb +153 -0
- data/lib/rsmp/validator/async_context.rb +15 -0
- data/lib/rsmp/validator/auto_node.rb +82 -0
- data/lib/rsmp/validator/auto_site.rb +30 -0
- data/lib/rsmp/validator/auto_supervisor.rb +23 -0
- data/lib/rsmp/validator/config_normalizer.rb +103 -0
- data/lib/rsmp/validator/configuration/loader.rb +79 -0
- data/lib/rsmp/validator/configuration/secrets.rb +54 -0
- data/lib/rsmp/validator/configuration/validation.rb +115 -0
- data/lib/rsmp/validator/configuration.rb +129 -0
- data/lib/rsmp/validator/helpers/alarms.rb +66 -0
- data/lib/rsmp/validator/helpers/clock.rb +16 -0
- data/lib/rsmp/validator/helpers/connection.rb +73 -0
- data/lib/rsmp/validator/helpers/handshake.rb +110 -0
- data/lib/rsmp/validator/helpers/input.rb +42 -0
- data/lib/rsmp/validator/helpers/security.rb +26 -0
- data/lib/rsmp/validator/helpers/signal_plans.rb +37 -0
- data/lib/rsmp/validator/helpers/signal_priority.rb +130 -0
- data/lib/rsmp/validator/helpers/startup.rb +157 -0
- data/lib/rsmp/validator/helpers/status.rb +22 -0
- data/lib/rsmp/validator/lifecycle.rb +99 -0
- data/lib/rsmp/validator/log.rb +11 -0
- data/lib/rsmp/validator/mode_detection.rb +84 -0
- data/lib/rsmp/validator/options/site_test_options.rb +58 -0
- data/lib/rsmp/validator/options/supervisor_test_options.rb +51 -0
- data/lib/rsmp/validator/site_tester.rb +113 -0
- data/lib/rsmp/validator/supervisor_tester.rb +76 -0
- data/lib/rsmp/validator/tester.rb +101 -0
- data/lib/rsmp/validator/version.rb +5 -0
- data/lib/rsmp/validator/version_filter.rb +44 -0
- data/lib/rsmp/validator.rb +50 -0
- data/schemas/site_test.json +36 -0
- data/schemas/supervisor_test.json +28 -0
- data/test/site/core/aggregated_status_spec.rb +43 -0
- data/test/site/core/connect_spec.rb +104 -0
- data/test/site/core/core_spec.rb +9 -0
- data/test/site/core/disconnect_spec.rb +54 -0
- data/test/site/site_spec.rb +5 -0
- data/test/site/tlc/alarm_spec.rb +134 -0
- data/test/site/tlc/clock_spec.rb +252 -0
- data/test/site/tlc/detector_logics_spec.rb +76 -0
- data/test/site/tlc/emergency_routes_spec.rb +106 -0
- data/test/site/tlc/input_spec.rb +102 -0
- data/test/site/tlc/invalid_command_spec.rb +103 -0
- data/test/site/tlc/invalid_status_spec.rb +70 -0
- data/test/site/tlc/modes_spec.rb +260 -0
- data/test/site/tlc/output_spec.rb +58 -0
- data/test/site/tlc/signal_groups_spec.rb +96 -0
- data/test/site/tlc/signal_plans_spec.rb +287 -0
- data/test/site/tlc/signal_priority_spec.rb +144 -0
- data/test/site/tlc/subscribe_spec.rb +71 -0
- data/test/site/tlc/system_spec.rb +76 -0
- data/test/site/tlc/tlc_spec.rb +7 -0
- data/test/site/tlc/traffic_data_spec.rb +151 -0
- data/test/site/tlc/traffic_situations_spec.rb +50 -0
- data/test/supervisor/aggregated_status_spec.rb +18 -0
- data/test/supervisor/connect_spec.rb +219 -0
- data/test/supervisor/supervisor_spec.rb +11 -0
- 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
|