rsmp-validator 0.1.1 → 0.3.2
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 +4 -4
- data/config/cross_rs4s.yaml +6 -0
- data/config/gem_supervisor.yaml +6 -0
- data/config/gem_tlc.yaml +6 -0
- data/config/kapsch_etx.yaml +13 -6
- data/config/lightmotion_satellite.yaml +8 -2
- data/config/semaforica_cartesio.yaml +8 -2
- data/config/sus.rb +1 -1
- data/config/swarco_itc3.yaml +8 -2
- data/config/tecsen_tmacs_supervisor.yaml +6 -0
- data/exe/rsmp-validator +2 -117
- data/lib/rsmp/validator/async_context.rb +4 -3
- data/lib/rsmp/validator/auto_node.rb +5 -15
- data/lib/rsmp/validator/cli/config_cli.rb +32 -0
- data/lib/rsmp/validator/cli/entrypoint.rb +40 -0
- data/lib/rsmp/validator/cli/run_options.rb +87 -0
- data/lib/rsmp/validator/cli/runner.rb +119 -0
- data/lib/rsmp/validator/cli/tee_io.rb +30 -0
- data/lib/rsmp/validator/cli/validator_overrides.rb +28 -0
- data/lib/rsmp/validator/compliance/config_metadata.rb +31 -0
- data/lib/rsmp/validator/compliance/config_sxls.rb +24 -0
- data/lib/rsmp/validator/compliance/report.rb +70 -0
- data/lib/rsmp/validator/compliance/report_failure.rb +45 -0
- data/lib/rsmp/validator/compliance/report_metadata.rb +101 -0
- data/lib/rsmp/validator/config_check.rb +72 -0
- data/lib/rsmp/validator/configuration/loader.rb +6 -0
- data/lib/rsmp/validator/configuration/sxls_override.rb +33 -0
- data/lib/rsmp/validator/configuration/validation.rb +1 -35
- data/lib/rsmp/validator/configuration/version_normalization.rb +56 -0
- data/lib/rsmp/validator/configuration.rb +25 -22
- data/lib/rsmp/validator/helpers/alarms.rb +1 -1
- data/lib/rsmp/validator/helpers/clock.rb +2 -2
- data/lib/rsmp/validator/helpers/connection.rb +18 -8
- data/lib/rsmp/validator/helpers/handshake.rb +5 -8
- data/lib/rsmp/validator/helpers/input.rb +3 -3
- data/lib/rsmp/validator/helpers/security.rb +1 -1
- data/lib/rsmp/validator/helpers/signal_plans.rb +5 -5
- data/lib/rsmp/validator/helpers/signal_priority.rb +8 -11
- data/lib/rsmp/validator/helpers/startup.rb +6 -20
- data/lib/rsmp/validator/helpers/status.rb +1 -1
- data/lib/rsmp/validator/lifecycle.rb +11 -4
- data/lib/rsmp/validator/options/site_test_options.rb +21 -1
- data/lib/rsmp/validator/options/supervisor_test_options.rb +50 -13
- data/lib/rsmp/validator/site_tester.rb +15 -6
- data/lib/rsmp/validator/supervisor_tester.rb +11 -5
- data/lib/rsmp/validator/tester.rb +25 -29
- data/lib/rsmp/validator/version.rb +1 -1
- data/lib/rsmp/validator/version_filter.rb +1 -1
- data/lib/rsmp/validator.rb +5 -1
- data/schemas/site_test.json +0 -6
- data/test/site/core/aggregated_status_spec.rb +5 -7
- data/test/site/core/connect_spec.rb +5 -5
- data/test/site/core/disconnect_spec.rb +10 -19
- data/test/site/core/message_buffer_spec.rb +114 -0
- data/test/site/tlc/alarm_spec.rb +7 -7
- data/test/site/tlc/clock_spec.rb +26 -26
- data/test/site/tlc/detector_logics_spec.rb +6 -6
- data/test/site/tlc/emergency_routes_spec.rb +16 -16
- data/test/site/tlc/input_spec.rb +10 -10
- data/test/site/tlc/invalid_command_spec.rb +24 -20
- data/test/site/tlc/invalid_status_spec.rb +25 -20
- data/test/site/tlc/modes_spec.rb +53 -37
- data/test/site/tlc/output_spec.rb +8 -8
- data/test/site/tlc/signal_groups_spec.rb +8 -8
- data/test/site/tlc/signal_plans_spec.rb +32 -34
- data/test/site/tlc/signal_priority_spec.rb +10 -12
- data/test/site/tlc/subscribe_spec.rb +9 -9
- data/test/site/tlc/system_spec.rb +12 -10
- data/test/site/tlc/traffic_data_spec.rb +27 -16
- data/test/site/tlc/traffic_situations_spec.rb +5 -5
- data/test/supervisor/connect_spec.rb +9 -12
- metadata +35 -6
data/lib/rsmp/validator.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative 'validator/version'
|
|
|
4
4
|
require_relative 'validator/log'
|
|
5
5
|
require_relative 'validator/options/site_test_options'
|
|
6
6
|
require_relative 'validator/options/supervisor_test_options'
|
|
7
|
+
require_relative 'validator/config_check'
|
|
7
8
|
require_relative 'validator/config_normalizer'
|
|
8
9
|
require_relative 'validator/configuration'
|
|
9
10
|
require_relative 'validator/version_filter'
|
|
@@ -39,7 +40,10 @@ module RSMP
|
|
|
39
40
|
include RSMP::Logging
|
|
40
41
|
|
|
41
42
|
attr_accessor :config, :config_log_settings, :mode, :logger, :auto_node_config,
|
|
42
|
-
:auto_node_log_settings, :auto_node, :node_log_settings
|
|
43
|
+
:auto_node_log_settings, :auto_node, :node_log_settings,
|
|
44
|
+
:core_version_override, :sxls_override, :site_config_path,
|
|
45
|
+
:supervisor_config_path, :auto_site_config_path,
|
|
46
|
+
:auto_supervisor_config_path, :config_path
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
# Get the global Async reactor used for RSMP communication
|
data/schemas/site_test.json
CHANGED
|
@@ -16,12 +16,6 @@
|
|
|
16
16
|
"propertyNames": { "not": { "const": "core" } },
|
|
17
17
|
"additionalProperties": { "type": "string" }
|
|
18
18
|
},
|
|
19
|
-
"rsmp_versions": {
|
|
20
|
-
"oneOf": [
|
|
21
|
-
{ "type": "string" },
|
|
22
|
-
{ "type": "array", "items": { "type": "string" } }
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
19
|
"timeouts": { "type": "object" },
|
|
26
20
|
"components": { "type": "object" },
|
|
27
21
|
"items": { "type": "object" },
|
|
@@ -11,18 +11,18 @@ describe 'Site::Core' do
|
|
|
11
11
|
site_proxy.request_aggregated_status_and_collect(
|
|
12
12
|
RSMP::Validator.get_config('main_component'),
|
|
13
13
|
within: RSMP::Validator.get_config('timeouts', 'status_response')
|
|
14
|
-
).
|
|
14
|
+
).value!
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
# Verify that aggregated status uses null for unused attributes, from SXL 1.1
|
|
19
|
-
# For SXL versions before 1.1 empty strings "" is also allowed.
|
|
18
|
+
# Verify that aggregated status uses null for unused attributes, from SXL 1.1.0
|
|
19
|
+
# For SXL versions before 1.1.0 empty strings "" is also allowed.
|
|
20
20
|
#
|
|
21
21
|
# 1. Given the is reconnected
|
|
22
22
|
# 2. When we receive an aggregated status
|
|
23
23
|
# 3. Then fP and fS should be null
|
|
24
24
|
it 'uses null for functional position/state' do
|
|
25
|
-
with_site(:isolated, sxl: '>=1.1',
|
|
25
|
+
with_site(:isolated, sxl: '>=1.1.0',
|
|
26
26
|
'collect' => {
|
|
27
27
|
filter: RSMP::Filter.new(type: 'AggregatedStatus'),
|
|
28
28
|
timeout: RSMP::Validator.get_config('timeouts', 'ready'),
|
|
@@ -30,9 +30,7 @@ describe 'Site::Core' do
|
|
|
30
30
|
ingoing: true
|
|
31
31
|
}) do |site_proxy|
|
|
32
32
|
collector = site_proxy.collector
|
|
33
|
-
collector.
|
|
34
|
-
collector.wait!
|
|
35
|
-
aggregated_status = site_proxy.collector.messages.first
|
|
33
|
+
aggregated_status = collector.wait!.first
|
|
36
34
|
|
|
37
35
|
expect(aggregated_status).to be_a(RSMP::AggregatedStatus)
|
|
38
36
|
expect(aggregated_status.attribute('fP')).to be_nil
|
|
@@ -57,15 +57,15 @@ describe 'Site::Core' do
|
|
|
57
57
|
check_sequence '3.1.5'
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
# Verify the connection sequence when using rsmp core 3.2
|
|
60
|
+
# Verify the connection sequence when using rsmp core 3.2.0
|
|
61
61
|
#
|
|
62
|
-
# 1. Given the site is connected and using core 3.2
|
|
62
|
+
# 1. Given the site is connected and using core 3.2.0
|
|
63
63
|
# 2. When handshake messages are sent and received
|
|
64
64
|
# 3. Then the handshake messages should be in the specified sequence corresponding to version 3.1.5
|
|
65
65
|
# 4. And the connection sequence should be complete
|
|
66
|
-
it 'is correct for rsmp version 3.2' do
|
|
67
|
-
skip 'requires core == 3.2' unless RSMP::Validator.core_matches?('3.2')
|
|
68
|
-
check_sequence '3.2'
|
|
66
|
+
it 'is correct for rsmp version 3.2.0' do
|
|
67
|
+
skip 'requires core == 3.2.0' unless RSMP::Validator.core_matches?('3.2.0')
|
|
68
|
+
check_sequence '3.2.0'
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# Verify the connection sequence when using rsmp core 3.2.1
|
|
@@ -14,19 +14,15 @@ describe 'Site::Core' do
|
|
|
14
14
|
it 'is closed if watchdogs are not acknowledged' do
|
|
15
15
|
with_site(:isolated, sxl: '>=1.0.7') do |site_proxy|
|
|
16
16
|
timeout = RSMP::Validator.get_config('timeouts', 'disconnect')
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
super
|
|
24
|
-
end
|
|
17
|
+
log 'Disabling watchdog acknowledgements, site should disconnect'
|
|
18
|
+
def site_proxy.acknowledge(original)
|
|
19
|
+
if original.is_a? RSMP::Watchdog
|
|
20
|
+
log 'Not acknowledgning watchdog', message: original
|
|
21
|
+
else
|
|
22
|
+
super
|
|
25
23
|
end
|
|
26
|
-
site_proxy.wait_for_state :disconnected, timeout: timeout
|
|
27
24
|
end
|
|
28
|
-
|
|
29
|
-
raise "Site did not disconnect within #{timeout}s"
|
|
25
|
+
site_proxy.wait_for_state!(:disconnected, timeout: timeout)
|
|
30
26
|
end
|
|
31
27
|
end
|
|
32
28
|
|
|
@@ -37,16 +33,11 @@ describe 'Site::Core' do
|
|
|
37
33
|
with_site(:isolated, sxl: '>=1.0.7') do |site_proxy|
|
|
38
34
|
timeout = RSMP::Validator.get_config('timeouts', 'disconnect')
|
|
39
35
|
|
|
40
|
-
wait_task = Async::Task.current.async do
|
|
41
|
-
site_proxy.wait_for_state :disconnected, timeout: timeout
|
|
42
|
-
raise RSMP::DisconnectError
|
|
43
|
-
rescue RSMP::TimeoutError
|
|
44
|
-
# ok, no disconnect happened
|
|
45
|
-
end
|
|
46
|
-
|
|
47
36
|
log 'Stop sending watchdogs, site should not disconnect'
|
|
48
37
|
site_proxy.with_watchdog_disabled do
|
|
49
|
-
|
|
38
|
+
result = site_proxy.wait_for_state :disconnected, timeout: timeout
|
|
39
|
+
assert(result.failure? && result.failure.code == :timeout,
|
|
40
|
+
"Site disconnected unexpectedly: #{result.inspect}")
|
|
50
41
|
end
|
|
51
42
|
end
|
|
52
43
|
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
describe 'Site::Core' do
|
|
2
|
+
describe 'Message Buffer' do
|
|
3
|
+
def buffered_status_list(site_proxy)
|
|
4
|
+
status_list = [{ 'sCI' => 'S0001', 'n' => 'signalgroupstatus', 'uRt' => '1' }]
|
|
5
|
+
status_list.map! { |item| item.merge('sOc' => true) } if site_proxy.tlc.use_soc?
|
|
6
|
+
status_list
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def buffered_status_timeout
|
|
10
|
+
RSMP::Validator.get_config('timeouts', 'ready') +
|
|
11
|
+
RSMP::Validator.get_config('timeouts', 'status_update') + 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def subscribe_buffered_status(component)
|
|
15
|
+
with_site(:connected, core: '>=3.1.4') do |site_proxy|
|
|
16
|
+
status_list = buffered_status_list(site_proxy)
|
|
17
|
+
site_proxy.subscribe_to_status_and_collect(
|
|
18
|
+
status_list,
|
|
19
|
+
component: component,
|
|
20
|
+
within: RSMP::Validator.get_config('timeouts', 'status_update')
|
|
21
|
+
).value!
|
|
22
|
+
status_list
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def simulate_status_buffer_disruption
|
|
27
|
+
RSMP::Validator::SiteTester.instance.stop 'Simulating communication disruption'
|
|
28
|
+
Async::Task.current.sleep 1.5
|
|
29
|
+
Time.now.utc
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def collect_status_after_reconnect(component, status_list)
|
|
33
|
+
with_site(:connected,
|
|
34
|
+
core: '>=3.1.4',
|
|
35
|
+
'collect' => {
|
|
36
|
+
filter: RSMP::Filter.new(type: 'StatusUpdate',
|
|
37
|
+
component: component,
|
|
38
|
+
ingoing: true,
|
|
39
|
+
outgoing: false),
|
|
40
|
+
timeout: buffered_status_timeout,
|
|
41
|
+
num: 1,
|
|
42
|
+
ingoing: true
|
|
43
|
+
}) do |site_proxy|
|
|
44
|
+
collector = site_proxy.collector
|
|
45
|
+
messages = collector.wait!
|
|
46
|
+
update = messages.first
|
|
47
|
+
|
|
48
|
+
unsubscribe_list = status_list.map { |item| item.slice('sCI', 'n') }
|
|
49
|
+
site_proxy.unsubscribe_to_status! unsubscribe_list, component: component
|
|
50
|
+
update
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def collect_buffered_status_after_disruption
|
|
55
|
+
collect_buffered_status_after_disruption_with_timing[:update]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def collect_buffered_status_after_disruption_with_timing
|
|
59
|
+
component = RSMP::Validator.get_config('main_component')
|
|
60
|
+
status_list = subscribe_buffered_status component
|
|
61
|
+
reconnect_started_at = simulate_status_buffer_disruption
|
|
62
|
+
update = collect_status_after_reconnect component, status_list
|
|
63
|
+
{ update: update, reconnect_started_at: reconnect_started_at }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Verify that a site sends buffered status messages after communication is restored.
|
|
67
|
+
#
|
|
68
|
+
# 1. Given the site is connected and a status subscription is active
|
|
69
|
+
# 2. When communication is disrupted long enough for a status update to be due
|
|
70
|
+
# 3. And communication is restored
|
|
71
|
+
# 4. Then the site should send the buffered status update
|
|
72
|
+
it 'sends buffered status messages after communication is restored' do
|
|
73
|
+
skip 'requires core >= 3.1.4' unless RSMP::Validator.core_matches?('>=3.1.4')
|
|
74
|
+
|
|
75
|
+
update = collect_buffered_status_after_disruption
|
|
76
|
+
|
|
77
|
+
expect(update).to be_a(RSMP::StatusUpdate)
|
|
78
|
+
assert(!update.attributes['sS'].empty?, 'expected buffered status update to include status values')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Verify that buffered status messages use quality "old" for core versions
|
|
82
|
+
# where the core spec requires it.
|
|
83
|
+
#
|
|
84
|
+
# 1. Given the site is connected using core 3.2.0 or later
|
|
85
|
+
# 2. And a status subscription is active
|
|
86
|
+
# 3. When communication is disrupted and later restored
|
|
87
|
+
# 4. Then buffered status values should have q=old
|
|
88
|
+
it 'marks buffered status values as old for rsmp 3.2.0 and later' do
|
|
89
|
+
skip 'requires core >= 3.2.0' unless RSMP::Validator.core_matches?('>=3.2.0')
|
|
90
|
+
|
|
91
|
+
update = collect_buffered_status_after_disruption
|
|
92
|
+
|
|
93
|
+
expect(update.attributes['sS'].map { |status| status['q'] }.uniq).to be == ['old']
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Verify that buffered status timestamps reflect when the status data was
|
|
97
|
+
# generated, not when the buffered message was sent after reconnect.
|
|
98
|
+
#
|
|
99
|
+
# 1. Given the site is connected and a status subscription is active
|
|
100
|
+
# 2. When communication is disrupted long enough for a status update to be due
|
|
101
|
+
# 3. And communication is restored
|
|
102
|
+
# 4. Then the buffered status timestamp should be older than the reconnect
|
|
103
|
+
it 'preserves buffered status timestamps from before reconnect' do
|
|
104
|
+
skip 'requires core >= 3.1.4' unless RSMP::Validator.core_matches?('>=3.1.4')
|
|
105
|
+
|
|
106
|
+
result = collect_buffered_status_after_disruption_with_timing
|
|
107
|
+
status_time = Time.parse(result[:update].attributes['sTs'])
|
|
108
|
+
|
|
109
|
+
assert(status_time < result[:reconnect_started_at],
|
|
110
|
+
"expected buffered status timestamp #{status_time} to be before reconnect " \
|
|
111
|
+
"#{result[:reconnect_started_at]}")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/test/site/tlc/alarm_spec.rb
CHANGED
|
@@ -86,7 +86,7 @@ describe 'Site::Tlc::Alarm' do
|
|
|
86
86
|
timeout: timeout).collect!
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
site_proxy.send_message RSMP::AlarmAcknowledge.new(
|
|
89
|
+
site_proxy.send_message! RSMP::AlarmAcknowledge.new(
|
|
90
90
|
'cId' => component_id,
|
|
91
91
|
'aTs' => site_proxy.clock.to_s,
|
|
92
92
|
'aCId' => alarm_code_id
|
|
@@ -113,21 +113,21 @@ describe 'Site::Tlc::Alarm' do
|
|
|
113
113
|
_, component_id = find_alarm_programming(alarm_code_id)
|
|
114
114
|
|
|
115
115
|
# first resume alarm to make sure something happens when we suspend
|
|
116
|
-
site_proxy.resume_alarm
|
|
116
|
+
site_proxy.resume_alarm!(c_id: component_id, a_c_id: alarm_code_id, collect: false)
|
|
117
117
|
|
|
118
118
|
begin
|
|
119
119
|
# suspend alarm
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
exchange = site_proxy.suspend_alarm!(c_id: component_id, a_c_id: alarm_code_id, collect: true)
|
|
121
|
+
response = exchange.messages.first
|
|
122
122
|
expect(response).to be_a(RSMP::AlarmSuspended)
|
|
123
123
|
|
|
124
124
|
# resume alarm
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
exchange = site_proxy.resume_alarm!(c_id: component_id, a_c_id: alarm_code_id, collect: true)
|
|
126
|
+
response = exchange.messages.first
|
|
127
127
|
expect(response).to be_a(RSMP::AlarmResumed)
|
|
128
128
|
ensure
|
|
129
129
|
# always end with resuming alarm
|
|
130
|
-
site_proxy.resume_alarm
|
|
130
|
+
site_proxy.resume_alarm!(c_id: component_id, a_c_id: alarm_code_id, collect: false)
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
end
|
data/test/site/tlc/clock_spec.rb
CHANGED
|
@@ -19,7 +19,7 @@ describe 'Site::Tlc::Clock' do
|
|
|
19
19
|
it 'can be read with S0096' do
|
|
20
20
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
21
21
|
site_proxy.request_status_and_collect({ S0096: %i[year month day hour minute second] },
|
|
22
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
22
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ describe 'Site::Tlc::Clock' do
|
|
|
31
31
|
it 'can be set with M0104' do
|
|
32
32
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
33
33
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
34
|
-
site_proxy.tlc.set_clock(clock, within: timeout)
|
|
34
|
+
site_proxy.tlc.set_clock!(clock, within: timeout)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -56,20 +56,19 @@ describe 'Site::Tlc::Clock' do
|
|
|
56
56
|
second
|
|
57
57
|
] }
|
|
58
58
|
timeout = RSMP::Validator.get_config('timeouts', 'status_update')
|
|
59
|
-
|
|
59
|
+
exchange = site_proxy.request_status_and_collect(
|
|
60
60
|
status_list,
|
|
61
61
|
within: timeout
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
status = status_list.keys.first.to_s
|
|
62
|
+
).value!
|
|
63
|
+
values = exchange.reached.to_h { |item| [item['n'], item['s']] }
|
|
65
64
|
|
|
66
65
|
received = Time.new(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
values.fetch('year'),
|
|
67
|
+
values.fetch('month'),
|
|
68
|
+
values.fetch('day'),
|
|
69
|
+
values.fetch('hour'),
|
|
70
|
+
values.fetch('minute'),
|
|
71
|
+
values.fetch('second'),
|
|
73
72
|
'UTC'
|
|
74
73
|
)
|
|
75
74
|
|
|
@@ -106,12 +105,11 @@ describe 'Site::Tlc::Clock' do
|
|
|
106
105
|
] }
|
|
107
106
|
|
|
108
107
|
timeout = RSMP::Validator.get_config('timeouts', 'status_response')
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
collector.ok!
|
|
108
|
+
exchange = site_proxy.request_status_and_collect(status_list,
|
|
109
|
+
within: timeout).value!
|
|
112
110
|
|
|
113
111
|
max_diff = RSMP::Validator.get_config('timeouts', 'command_response') + timeout
|
|
114
|
-
diff = Time.parse(
|
|
112
|
+
diff = Time.parse(exchange.messages.first.attributes['sTs']) - clock
|
|
115
113
|
diff = diff.round
|
|
116
114
|
assert(diff.abs <= max_diff,
|
|
117
115
|
"Timestamp of S0096 is off by #{diff}s, should be within #{max_diff}s")
|
|
@@ -135,9 +133,9 @@ describe 'Site::Tlc::Clock' do
|
|
|
135
133
|
with_clock_set site_proxy, clock, within: RSMP::Validator.get_config('timeouts', 'command_response') do
|
|
136
134
|
component = RSMP::Validator.get_config('main_component')
|
|
137
135
|
timeout = RSMP::Validator.get_config('timeouts', 'status_response')
|
|
138
|
-
|
|
136
|
+
exchange = site_proxy.request_aggregated_status_and_collect(component, within: timeout).value!
|
|
139
137
|
max_diff = RSMP::Validator.get_config('timeouts', 'command_response') + timeout
|
|
140
|
-
diff = Time.parse(
|
|
138
|
+
diff = Time.parse(exchange.messages.first.attributes['aSTS']) - clock
|
|
141
139
|
diff = diff.round
|
|
142
140
|
assert(diff.abs <= max_diff,
|
|
143
141
|
"Timestamp of aggregated status is off by #{diff}s, should be within #{max_diff}s")
|
|
@@ -158,10 +156,9 @@ describe 'Site::Tlc::Clock' do
|
|
|
158
156
|
site_proxy.with_watchdog_disabled do # avoid time synchronization by disabling watchdogs
|
|
159
157
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
160
158
|
with_clock_set site_proxy, clock, within: timeout do
|
|
161
|
-
|
|
162
|
-
collector = result[:collector]
|
|
159
|
+
exchange = site_proxy.tlc.set_functional_position!('NormalControl', within: timeout)
|
|
163
160
|
max_diff = timeout * 2
|
|
164
|
-
diff = Time.parse(
|
|
161
|
+
diff = Time.parse(exchange.messages.first.attributes['cTS']) - clock
|
|
165
162
|
diff = diff.round
|
|
166
163
|
assert(diff.abs <= max_diff,
|
|
167
164
|
"Timestamp of command response is off by #{diff}s, should be within #{max_diff}s")
|
|
@@ -182,10 +179,9 @@ describe 'Site::Tlc::Clock' do
|
|
|
182
179
|
site_proxy.with_watchdog_disabled do # avoid time synchronization by disabling watchdogs
|
|
183
180
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
184
181
|
with_clock_set site_proxy, clock, within: timeout do
|
|
185
|
-
|
|
186
|
-
collector = result[:collector]
|
|
182
|
+
exchange = site_proxy.tlc.set_functional_position!('NormalControl', within: timeout)
|
|
187
183
|
max_diff = timeout
|
|
188
|
-
diff = Time.parse(
|
|
184
|
+
diff = Time.parse(exchange.messages.first.attributes['cTS']) - clock
|
|
189
185
|
diff = diff.round
|
|
190
186
|
assert(diff.abs <= max_diff,
|
|
191
187
|
"Timestamp of command response is off by #{diff}s, should be within #{max_diff}s")
|
|
@@ -236,8 +232,12 @@ describe 'Site::Tlc::Clock' do
|
|
|
236
232
|
with_clock_set site_proxy, clock, within: RSMP::Validator.get_config('timeouts', 'command_response') do
|
|
237
233
|
log 'Checking watchdog timestamp'
|
|
238
234
|
watchdog_timeout = RSMP::Validator.get_config('timeouts', 'watchdog')
|
|
239
|
-
collector = RSMP::Collector.new(
|
|
240
|
-
|
|
235
|
+
collector = RSMP::Collector.new(
|
|
236
|
+
site_proxy,
|
|
237
|
+
filter: RSMP::Filter.new(type: 'Watchdog'),
|
|
238
|
+
num: 1,
|
|
239
|
+
timeout: watchdog_timeout
|
|
240
|
+
)
|
|
241
241
|
collector.collect!
|
|
242
242
|
max_diff = RSMP::Validator.get_config('timeouts', 'command_response') +
|
|
243
243
|
RSMP::Validator.get_config('timeouts', 'status_response')
|
|
@@ -10,7 +10,7 @@ describe 'Site::Tlc::DetectorLogics' do
|
|
|
10
10
|
it 'list size is read with S0016' do
|
|
11
11
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
12
12
|
site_proxy.request_status_and_collect({ S0016: [:number] },
|
|
13
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
13
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ describe 'Site::Tlc::DetectorLogics' do
|
|
|
22
22
|
it 'status is read with S0002' do
|
|
23
23
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
24
24
|
site_proxy.request_status_and_collect({ S0002: [:detectorlogicstatus] },
|
|
25
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
25
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -34,7 +34,7 @@ describe 'Site::Tlc::DetectorLogics' do
|
|
|
34
34
|
it 'forcing is read with S0021' do
|
|
35
35
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
36
36
|
site_proxy.request_status_and_collect({ S0021: [:detectorlogics] },
|
|
37
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
37
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -45,14 +45,14 @@ describe 'Site::Tlc::DetectorLogics' do
|
|
|
45
45
|
with_site(:connected, sxl: '>=1.0.7') do |site_proxy|
|
|
46
46
|
RSMP::Validator.get_config('components', 'detector_logic').keys.each_with_index do |component, indx|
|
|
47
47
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
48
|
-
site_proxy.tlc.force_detector_logic(component, status: 'True', mode: 'True', within: timeout)
|
|
48
|
+
site_proxy.tlc.force_detector_logic!(component, status: 'True', mode: 'True', within: timeout)
|
|
49
49
|
wait_for_status(
|
|
50
50
|
site_proxy,
|
|
51
51
|
"detector logic #{component} to be True",
|
|
52
52
|
[{ 'sCI' => 'S0002', 'n' => 'detectorlogicstatus', 's' => /^.{#{indx}}1/ }]
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
-
site_proxy.tlc.force_detector_logic(component, status: 'True', mode: 'False', within: timeout)
|
|
55
|
+
site_proxy.tlc.force_detector_logic!(component, status: 'True', mode: 'False', within: timeout)
|
|
56
56
|
wait_for_status(
|
|
57
57
|
site_proxy,
|
|
58
58
|
"detector logic #{component} to be False",
|
|
@@ -70,7 +70,7 @@ describe 'Site::Tlc::DetectorLogics' do
|
|
|
70
70
|
it 'sensitivity is read with S0031' do
|
|
71
71
|
with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
|
|
72
72
|
site_proxy.request_status_and_collect({ S0031: [:status] },
|
|
73
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
73
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
74
74
|
end
|
|
75
75
|
end
|
|
76
76
|
end
|
|
@@ -2,27 +2,27 @@ describe 'Site::Tlc::EmergencyRoutes' do
|
|
|
2
2
|
include RSMP::Validator::Helpers::Status
|
|
3
3
|
|
|
4
4
|
# Verify that current emergency route can be read with S0006.
|
|
5
|
-
#
|
|
5
|
+
# Deprecated from 1.2.0, use S0035 instead.
|
|
6
6
|
# 1. Given the site_proxy is connected.
|
|
7
7
|
# 2. When we request S0006.
|
|
8
8
|
# 3. Then we should receive a status response.
|
|
9
9
|
it 'emergency route is read with S0006' do
|
|
10
|
-
with_site(:connected, sxl: ['>=1.0.7', '<1.2']) do |site_proxy|
|
|
10
|
+
with_site(:connected, sxl: ['>=1.0.7', '<1.2.0']) do |site_proxy|
|
|
11
11
|
site_proxy.request_status_and_collect({ S0006: %i[status emergencystage] },
|
|
12
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
12
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# Verify that current emergency routes can be read with S0035.
|
|
17
|
-
# Requires core >= 3.2 since it uses the array data type.
|
|
17
|
+
# Requires core >= 3.2.0 since it uses the array data type.
|
|
18
18
|
# 1. Given the site_proxy is connected.
|
|
19
19
|
# 2. When we request S0035.
|
|
20
20
|
# 3. Then we should receive a status response.
|
|
21
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|
|
|
22
|
+
skip 'requires core >= 3.2.0' unless RSMP::Validator.core_matches?('>=3.2.0')
|
|
23
|
+
with_site(:connected, sxl: '>=1.2.0') do |site_proxy|
|
|
24
24
|
site_proxy.request_status_and_collect({ S0035: [:emergencyroutes] },
|
|
25
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
25
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -32,20 +32,20 @@ describe 'Site::Tlc::EmergencyRoutes' do
|
|
|
32
32
|
# 2. When we send M0005 to set emergency route.
|
|
33
33
|
# 3. Then we should get a command responds confirming the change.
|
|
34
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'])
|
|
35
|
+
skip 'requires sxl >= 1.0.7, < 1.2.0' unless RSMP::Validator.sxl_matches?(['>=1.0.7', '<1.2.0'])
|
|
36
36
|
emergency_routes = RSMP::Validator.get_config('items', 'emergency_routes')
|
|
37
37
|
skip('No emergency routes configured') if emergency_routes.nil? || emergency_routes.empty?
|
|
38
38
|
|
|
39
39
|
def set_emergency_states(site_proxy, emergency_routes, state)
|
|
40
40
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
41
41
|
emergency_routes.each do |emergency_route|
|
|
42
|
-
site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: state, within: timeout)
|
|
42
|
+
site_proxy.tlc.set_emergency_route!(route: emergency_route.to_s, active: state, within: timeout)
|
|
43
43
|
end
|
|
44
44
|
wait_for_status(site_proxy, "emergency route #{emergency_routes.last} to be enabled",
|
|
45
45
|
[
|
|
46
|
-
{ 'sCI' => 'S0006', 'n' => 'status', 's' =>
|
|
46
|
+
{ 'sCI' => 'S0006', 'n' => 'status', 's' => state },
|
|
47
47
|
{ 'sCI' => 'S0006', 'n' => 'emergencystage',
|
|
48
|
-
's' => (state ? emergency_routes.last.
|
|
48
|
+
's' => (state ? emergency_routes.last.to_i : 0) }
|
|
49
49
|
])
|
|
50
50
|
end
|
|
51
51
|
|
|
@@ -68,8 +68,8 @@ describe 'Site::Tlc::EmergencyRoutes' do
|
|
|
68
68
|
# 5. Then we should receive the list of active routes.
|
|
69
69
|
|
|
70
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')
|
|
71
|
+
skip 'requires core >= 3.2.0' unless RSMP::Validator.core_matches?('>=3.2.0')
|
|
72
|
+
skip 'requires sxl >= 1.2.0' unless RSMP::Validator.sxl_matches?('>=1.2.0')
|
|
73
73
|
|
|
74
74
|
emergency_routes = RSMP::Validator.get_config('items', 'emergency_routes')
|
|
75
75
|
skip('No emergency routes configured') if emergency_routes.nil? || emergency_routes.empty?
|
|
@@ -77,16 +77,16 @@ describe 'Site::Tlc::EmergencyRoutes' do
|
|
|
77
77
|
def enable_routes(site_proxy, emergency_routes)
|
|
78
78
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
79
79
|
emergency_routes.each do |emergency_route|
|
|
80
|
-
site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: true, within: timeout)
|
|
80
|
+
site_proxy.tlc.set_emergency_route!(route: emergency_route.to_s, active: true, within: timeout)
|
|
81
81
|
end
|
|
82
|
-
routes = emergency_routes.map { |i| { 'id' => i.
|
|
82
|
+
routes = emergency_routes.map { |i| { 'id' => i.to_i } }
|
|
83
83
|
wait_for_status(site_proxy, "emergency routes #{emergency_routes} to be enabled",
|
|
84
84
|
[{ 'sCI' => 'S0035', 'n' => 'emergencyroutes', 's' => routes }])
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def disable_routes(site_proxy, emergency_routes, within:)
|
|
88
88
|
emergency_routes.each do |emergency_route|
|
|
89
|
-
site_proxy.tlc.set_emergency_route(route: emergency_route.to_s, active: false, within:)
|
|
89
|
+
site_proxy.tlc.set_emergency_route!(route: emergency_route.to_s, active: false, within:)
|
|
90
90
|
end
|
|
91
91
|
routes = []
|
|
92
92
|
wait_for_status(site_proxy, 'all emergency routes to be disabled',
|
data/test/site/tlc/input_spec.rb
CHANGED
|
@@ -8,11 +8,11 @@ describe 'Site::Tlc::Input' do
|
|
|
8
8
|
# 2. When we read input with S0029
|
|
9
9
|
# 3. Then we should receive a valid response
|
|
10
10
|
it 'is read with S0003 with extended input status' do
|
|
11
|
-
with_site(:connected, sxl: '<1.2') do |site_proxy|
|
|
11
|
+
with_site(:connected, sxl: '<1.2.0') do |site_proxy|
|
|
12
12
|
site_proxy.request_status_and_collect(
|
|
13
13
|
{ S0003: %i[inputstatus extendedinputstatus] },
|
|
14
14
|
within: RSMP::Validator.get_config('timeouts', 'status_response')
|
|
15
|
-
).
|
|
15
|
+
).value!
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -21,9 +21,9 @@ describe 'Site::Tlc::Input' do
|
|
|
21
21
|
# 2. When we read input with S0029
|
|
22
22
|
# 3. Then we should receive a valid response
|
|
23
23
|
it 'is read with S0003' do
|
|
24
|
-
with_site(:connected, sxl: '>=1.2') do |site_proxy|
|
|
24
|
+
with_site(:connected, sxl: '>=1.2.0') do |site_proxy|
|
|
25
25
|
site_proxy.request_status_and_collect({ S0003: [:inputstatus] },
|
|
26
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
26
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -34,7 +34,7 @@ describe 'Site::Tlc::Input' do
|
|
|
34
34
|
it 'forcing is read with S0029' do
|
|
35
35
|
with_site(:connected, sxl: '>=1.0.13') do |site_proxy|
|
|
36
36
|
site_proxy.request_status_and_collect({ S0029: [:status] },
|
|
37
|
-
within: RSMP::Validator.get_config('timeouts', 'status_response')).
|
|
37
|
+
within: RSMP::Validator.get_config('timeouts', 'status_response')).value!
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -50,10 +50,10 @@ describe 'Site::Tlc::Input' do
|
|
|
50
50
|
skip('No inputs configured') if inputs.nil? || inputs.empty?
|
|
51
51
|
inputs.each do |input|
|
|
52
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)
|
|
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
55
|
ensure
|
|
56
|
-
site_proxy.tlc.force_input(input: input, status: 'False', value: 'True', within: timeout)
|
|
56
|
+
site_proxy.tlc.force_input!(input: input, status: 'False', value: 'True', within: timeout)
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -84,7 +84,7 @@ describe 'Site::Tlc::Input' do
|
|
|
84
84
|
skip('No inputs configured') if inputs.nil? || inputs.empty?
|
|
85
85
|
status = '1,3,12;5,5,10'
|
|
86
86
|
timeout = RSMP::Validator.get_config('timeouts', 'command')
|
|
87
|
-
site_proxy.tlc.set_inputs(status, within: timeout)
|
|
87
|
+
site_proxy.tlc.set_inputs!(status, within: timeout)
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
|
|
@@ -96,7 +96,7 @@ describe 'Site::Tlc::Input' do
|
|
|
96
96
|
with_site(:connected, sxl: '>=1.0.15') do |site_proxy|
|
|
97
97
|
timeout = RSMP::Validator.get_config('timeouts', 'command_response')
|
|
98
98
|
status = '1-50'
|
|
99
|
-
site_proxy.tlc.set_trigger_level(status, within: timeout)
|
|
99
|
+
site_proxy.tlc.set_trigger_level!(status, within: timeout)
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
102
|
end
|