rsmp-validator 0.1.0 → 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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/config/cross_rs4s.yaml +6 -0
  3. data/config/gem_supervisor.yaml +6 -0
  4. data/config/gem_tlc.yaml +6 -0
  5. data/config/kapsch_etx.yaml +13 -6
  6. data/config/lightmotion_satellite.yaml +8 -2
  7. data/config/semaforica_cartesio.yaml +8 -2
  8. data/config/sus.rb +1 -1
  9. data/config/swarco_itc3.yaml +8 -2
  10. data/config/tecsen_tmacs_supervisor.yaml +6 -0
  11. data/exe/rsmp-validator +2 -118
  12. data/lib/rsmp/validator/async_context.rb +4 -3
  13. data/lib/rsmp/validator/auto_node.rb +5 -15
  14. data/lib/rsmp/validator/cli/config_cli.rb +32 -0
  15. data/lib/rsmp/validator/cli/entrypoint.rb +40 -0
  16. data/lib/rsmp/validator/cli/run_options.rb +87 -0
  17. data/lib/rsmp/validator/cli/runner.rb +119 -0
  18. data/lib/rsmp/validator/cli/tee_io.rb +30 -0
  19. data/lib/rsmp/validator/cli/validator_overrides.rb +28 -0
  20. data/lib/rsmp/validator/compliance/config_metadata.rb +31 -0
  21. data/lib/rsmp/validator/compliance/config_sxls.rb +24 -0
  22. data/lib/rsmp/validator/compliance/report.rb +70 -0
  23. data/lib/rsmp/validator/compliance/report_failure.rb +45 -0
  24. data/lib/rsmp/validator/compliance/report_metadata.rb +101 -0
  25. data/lib/rsmp/validator/config_check.rb +72 -0
  26. data/lib/rsmp/validator/configuration/loader.rb +6 -0
  27. data/lib/rsmp/validator/configuration/sxls_override.rb +33 -0
  28. data/lib/rsmp/validator/configuration/validation.rb +1 -35
  29. data/lib/rsmp/validator/configuration/version_normalization.rb +56 -0
  30. data/lib/rsmp/validator/configuration.rb +25 -22
  31. data/lib/rsmp/validator/helpers/alarms.rb +1 -1
  32. data/lib/rsmp/validator/helpers/clock.rb +2 -2
  33. data/lib/rsmp/validator/helpers/connection.rb +18 -8
  34. data/lib/rsmp/validator/helpers/handshake.rb +5 -8
  35. data/lib/rsmp/validator/helpers/input.rb +3 -3
  36. data/lib/rsmp/validator/helpers/security.rb +1 -1
  37. data/lib/rsmp/validator/helpers/signal_plans.rb +5 -5
  38. data/lib/rsmp/validator/helpers/signal_priority.rb +8 -11
  39. data/lib/rsmp/validator/helpers/startup.rb +6 -20
  40. data/lib/rsmp/validator/helpers/status.rb +1 -1
  41. data/lib/rsmp/validator/lifecycle.rb +11 -4
  42. data/lib/rsmp/validator/options/site_test_options.rb +21 -1
  43. data/lib/rsmp/validator/options/supervisor_test_options.rb +50 -13
  44. data/lib/rsmp/validator/site_tester.rb +15 -6
  45. data/lib/rsmp/validator/supervisor_tester.rb +11 -5
  46. data/lib/rsmp/validator/tester.rb +25 -29
  47. data/lib/rsmp/validator/version.rb +1 -1
  48. data/lib/rsmp/validator/version_filter.rb +1 -1
  49. data/lib/rsmp/validator.rb +5 -1
  50. data/schemas/site_test.json +0 -6
  51. data/test/site/core/aggregated_status_spec.rb +5 -7
  52. data/test/site/core/connect_spec.rb +5 -5
  53. data/test/site/core/disconnect_spec.rb +10 -19
  54. data/test/site/core/message_buffer_spec.rb +114 -0
  55. data/test/site/tlc/alarm_spec.rb +7 -7
  56. data/test/site/tlc/clock_spec.rb +26 -26
  57. data/test/site/tlc/detector_logics_spec.rb +6 -6
  58. data/test/site/tlc/emergency_routes_spec.rb +16 -16
  59. data/test/site/tlc/input_spec.rb +10 -10
  60. data/test/site/tlc/invalid_command_spec.rb +24 -20
  61. data/test/site/tlc/invalid_status_spec.rb +25 -20
  62. data/test/site/tlc/modes_spec.rb +53 -37
  63. data/test/site/tlc/output_spec.rb +8 -8
  64. data/test/site/tlc/signal_groups_spec.rb +8 -8
  65. data/test/site/tlc/signal_plans_spec.rb +32 -34
  66. data/test/site/tlc/signal_priority_spec.rb +10 -12
  67. data/test/site/tlc/subscribe_spec.rb +9 -9
  68. data/test/site/tlc/system_spec.rb +12 -10
  69. data/test/site/tlc/traffic_data_spec.rb +27 -16
  70. data/test/site/tlc/traffic_situations_spec.rb +5 -5
  71. data/test/supervisor/connect_spec.rb +9 -12
  72. metadata +35 -6
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module RSMP
6
+ module Validator
7
+ module Compliance
8
+ # Reads stable compliance target metadata from a validator YAML config file.
9
+ class ConfigMetadata
10
+ def initialize(path)
11
+ @path = path
12
+ end
13
+
14
+ def target
15
+ return {} unless @path && File.exist?(@path)
16
+
17
+ metadata = YAML.safe_load_file(@path, aliases: true)['compliance']
18
+ metadata.is_a?(Hash) ? stringify(metadata) : {}
19
+ rescue Psych::Exception
20
+ {}
21
+ end
22
+
23
+ private
24
+
25
+ def stringify(hash)
26
+ hash.transform_keys(&:to_s).transform_values { |value| value.is_a?(Hash) ? stringify(value) : value }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSMP
4
+ module Validator
5
+ module Compliance
6
+ # Formats resolved validator SXL config for compliance reports.
7
+ class ConfigSxls
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def to_h
13
+ Array(@config && @config['sxls']).each_with_object({}) do |sxl, memo|
14
+ next unless sxl.is_a?(Hash)
15
+
16
+ name = sxl['name']
17
+ version = sxl['version']
18
+ memo[name.to_s] = version.to_s if name && version
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'json'
5
+ require 'time'
6
+ require_relative 'report_failure'
7
+ require_relative 'report_metadata'
8
+
9
+ module RSMP
10
+ module Validator
11
+ module Compliance
12
+ # Builds the machine-readable compliance report emitted by rsmp-validator.
13
+ class Report
14
+ COMPLIANCE_SCHEMA_VERSION = 1
15
+
16
+ def initialize(assertions:, env: ENV, args: ARGV, generated_at: Time.now.utc, **options)
17
+ @assertions = assertions
18
+ @args = args
19
+ @generated_at = generated_at
20
+ @metadata = ReportMetadata.new(
21
+ env: env,
22
+ config: options[:config],
23
+ config_path: options[:config_path],
24
+ log_path: options[:log_path],
25
+ report_json_path: options[:report_json_path]
26
+ )
27
+ end
28
+
29
+ def self.write(path, **options)
30
+ report = new(**options).to_h
31
+ FileUtils.mkdir_p(File.dirname(path))
32
+ File.write(path, "#{JSON.pretty_generate(report)}\n")
33
+ report
34
+ end
35
+
36
+ def to_h
37
+ {
38
+ 'schema_version' => COMPLIANCE_SCHEMA_VERSION,
39
+ 'generated_at' => @generated_at.iso8601,
40
+ 'target' => @metadata.target,
41
+ 'workflow' => @metadata.workflow,
42
+ 'run' => @metadata.run,
43
+ 'matrix' => @metadata.matrix,
44
+ 'summary' => summary,
45
+ 'failures' => failures
46
+ }
47
+ end
48
+
49
+ private
50
+
51
+ def summary
52
+ {
53
+ 'status' => @assertions.passed? ? 'passed' : 'failed',
54
+ 'passed' => @assertions.passed?,
55
+ 'test_count' => @assertions.total,
56
+ 'passed_count' => @assertions.passed.size,
57
+ 'failed_count' => @assertions.failed.size,
58
+ 'errored_count' => @assertions.errored.size,
59
+ 'skipped_count' => @assertions.skipped.size,
60
+ 'assertion_count' => @assertions.count
61
+ }
62
+ end
63
+
64
+ def failures
65
+ @assertions.each_failure.map { |failure| ReportFailure.new(failure).to_h }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSMP
4
+ module Validator
5
+ module Compliance
6
+ # Converts a failed Sus assertion/error into compact JSON-friendly data.
7
+ class ReportFailure
8
+ ANSI_ESCAPE = /\e\[[0-9;]*m/
9
+
10
+ def initialize(failure)
11
+ @failure = failure
12
+ end
13
+
14
+ def to_h
15
+ message = failure_message
16
+ {
17
+ 'id' => failure_id,
18
+ 'message' => clean_text(message[:text]),
19
+ 'location' => message[:location],
20
+ 'type' => @failure.class.name
21
+ }.compact
22
+ end
23
+
24
+ private
25
+
26
+ def failure_message
27
+ @failure.message
28
+ rescue StandardError => e
29
+ { text: e.message, location: failure_id }
30
+ end
31
+
32
+ def failure_id
33
+ identity = @failure.respond_to?(:identity) ? @failure.identity : nil
34
+ identity&.to_s
35
+ end
36
+
37
+ def clean_text(text)
38
+ return nil unless text
39
+
40
+ text.to_s.gsub(ANSI_ESCAPE, '').strip
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'config_metadata'
4
+ require_relative 'config_sxls'
5
+
6
+ module RSMP
7
+ module Validator
8
+ module Compliance
9
+ # Builds static and runtime metadata for a compliance report.
10
+ class ReportMetadata
11
+ def initialize(env:, config: nil, config_path: nil, log_path: nil, report_json_path: nil)
12
+ @env = env
13
+ @config = config
14
+ @config_path = config_path
15
+ @log_path = log_path
16
+ @report_json_path = report_json_path
17
+ end
18
+
19
+ def target
20
+ ConfigMetadata.new(config_path).target.merge(env_target_metadata)
21
+ end
22
+
23
+ def workflow
24
+ env_hash(
25
+ 'name' => 'GITHUB_WORKFLOW',
26
+ 'file' => 'COMPLIANCE_WORKFLOW_FILE',
27
+ 'event' => 'GITHUB_EVENT_NAME',
28
+ 'ref' => 'GITHUB_REF',
29
+ 'sha' => 'GITHUB_SHA'
30
+ ).merge(workflow_file_from_ref)
31
+ end
32
+
33
+ def run
34
+ {
35
+ 'id' => integer_env('GITHUB_RUN_ID'),
36
+ 'number' => integer_env('GITHUB_RUN_NUMBER'),
37
+ 'attempt' => integer_env('GITHUB_RUN_ATTEMPT'),
38
+ 'url' => run_url,
39
+ 'log_artifact' => env_value('COMPLIANCE_LOG_ARTIFACT') || @log_path,
40
+ 'report_artifact' => env_value('COMPLIANCE_REPORT_ARTIFACT') || @report_json_path
41
+ }.compact
42
+ end
43
+
44
+ def matrix
45
+ values = {
46
+ 'core' => config_value('core_version'),
47
+ 'os' => env_value('RUNNER_OS')
48
+ }.compact
49
+ sxls = ConfigSxls.new(@config).to_h
50
+ values['sxls'] = sxls unless sxls.empty?
51
+ values
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :config_path
57
+
58
+ def env_target_metadata
59
+ env_hash(
60
+ 'id' => 'COMPLIANCE_TARGET_ID',
61
+ 'kind' => 'COMPLIANCE_TARGET_KIND',
62
+ 'name' => 'COMPLIANCE_TARGET_NAME',
63
+ 'product_url' => 'COMPLIANCE_PRODUCT_URL'
64
+ )
65
+ end
66
+
67
+ def workflow_file_from_ref
68
+ workflow_ref = env_value('GITHUB_WORKFLOW_REF')
69
+ match = workflow_ref&.match(%r{/(\.github/workflows/[^@]+)@})
70
+ match ? { 'file' => File.basename(match[1]) } : {}
71
+ end
72
+
73
+ def env_hash(mapping)
74
+ mapping.transform_values { |name| env_value(name) }.compact
75
+ end
76
+
77
+ def config_value(name)
78
+ @config[name] if @config.is_a?(Hash)
79
+ end
80
+
81
+ def integer_env(name)
82
+ value = env_value(name)
83
+ value&.to_i
84
+ end
85
+
86
+ def env_value(name)
87
+ value = @env[name]
88
+ value unless value.nil? || value == ''
89
+ end
90
+
91
+ def run_url
92
+ repository = env_value('GITHUB_REPOSITORY')
93
+ run_id = env_value('GITHUB_RUN_ID')
94
+ return nil unless repository && run_id
95
+
96
+ "https://github.com/#{repository}/actions/runs/#{run_id}"
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,72 @@
1
+ require 'yaml'
2
+
3
+ module RSMP
4
+ module Validator
5
+ # Validates rsmp-validator config files and their embedded RSMP node config.
6
+ class ConfigCheck
7
+ Result = Struct.new(:path, :mode, :options, keyword_init: true)
8
+
9
+ class << self
10
+ def check_file(path, mode: 'auto')
11
+ raw = load_file(path)
12
+ resolved_mode = resolve_mode(mode, raw)
13
+ options = options_class_for(resolved_mode).new(config_settings(raw), log_settings: raw['log'])
14
+
15
+ Result.new(path: path, mode: resolved_mode, options: options)
16
+ end
17
+
18
+ private
19
+
20
+ def load_file(path)
21
+ ensure_config_file!(path)
22
+
23
+ raw = YAML.load_file(path)
24
+ raise RSMP::ConfigurationError, "Config #{path} must be a hash" unless raw.is_a?(Hash) || raw.nil?
25
+
26
+ raw || {}
27
+ rescue Psych::SyntaxError => e
28
+ raise RSMP::ConfigurationError, "Cannot read config file #{path}: #{e}"
29
+ end
30
+
31
+ def ensure_config_file!(path)
32
+ raise RSMP::ConfigurationError, 'not found' unless File.exist?(path)
33
+ raise RSMP::ConfigurationError, 'is not a file' unless File.file?(path)
34
+ raise RSMP::ConfigurationError, 'must be a YAML file (.yml or .yaml)' unless yaml_file?(path)
35
+ end
36
+
37
+ def yaml_file?(path)
38
+ %w[.yml .yaml].include?(File.extname(path).downcase)
39
+ end
40
+
41
+ def config_settings(raw)
42
+ settings = raw.dup
43
+ settings.delete('log')
44
+ settings
45
+ end
46
+
47
+ def resolve_mode(mode, raw)
48
+ mode = mode.to_s
49
+ return mode if %w[site supervisor].include?(mode)
50
+ raise RSMP::ConfigurationError, "Unknown config mode #{mode.inspect}" unless mode == 'auto'
51
+
52
+ return 'site' if raw.key?('local_supervisor')
53
+ return 'supervisor' if raw.key?('local_site')
54
+
55
+ raise RSMP::ConfigurationError,
56
+ 'Cannot infer validator config mode; use --mode site or --mode supervisor'
57
+ end
58
+
59
+ def options_class_for(mode)
60
+ case mode
61
+ when 'site'
62
+ RSMP::Validator::SiteTest::Options
63
+ when 'supervisor'
64
+ RSMP::Validator::SupervisorTest::Options
65
+ else
66
+ raise RSMP::ConfigurationError, "Unknown config mode #{mode.inspect}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -27,6 +27,12 @@ module RSMP
27
27
 
28
28
  def ensure_config_exists!(path, missing_message)
29
29
  abort_with_error missing_message unless File.exist?(path)
30
+ abort_with_error "Config #{path} is not a file" unless File.file?(path)
31
+ abort_with_error "Config #{path} must be a YAML file (.yml or .yaml)" unless yaml_file?(path)
32
+ end
33
+
34
+ def yaml_file?(path)
35
+ %w[.yml .yaml].include?(File.extname(path).downcase)
30
36
  end
31
37
 
32
38
  def validate_config_hash!(raw, path)
@@ -0,0 +1,33 @@
1
+ module RSMP
2
+ module Validator
3
+ module Configuration
4
+ # Parses CLI SXL overrides.
5
+ module SxlsOverride
6
+ def apply_auto_node_overrides!(raw_config)
7
+ apply_auto_node_sxls_override!(raw_config) if sxls_override
8
+ end
9
+
10
+ def apply_auto_node_sxls_override!(raw_config)
11
+ sxls = parse_sxls(sxls_override)
12
+ if mode == :supervisor
13
+ raw_config['sites'] ||= {}
14
+ raw_config['sites']['default'] ||= {}
15
+ raw_config['sites']['default']['sxls'] = sxls
16
+ else
17
+ raw_config['sxls'] = sxls
18
+ end
19
+ end
20
+
21
+ def parse_sxls(value)
22
+ value.split(',').each_with_object({}) do |item, memo|
23
+ parts = item.split(':')
24
+ abort_with_error "Invalid --sxls item #{item.inspect}, expected name:version" unless parts.length == 2
25
+
26
+ name, version = parts
27
+ memo[name] = version
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,7 +1,7 @@
1
1
  module RSMP
2
2
  module Validator
3
3
  module Configuration
4
- # Private helpers for validating and normalizing configuration values.
4
+ # Private helpers for validating configuration values.
5
5
  module Validation
6
6
  private
7
7
 
@@ -75,40 +75,6 @@ module RSMP
75
75
  timeouts = config['timeouts']
76
76
  abort_with_error "Error: config 'timeouts' settings is missing or empty" if timeouts.nil? || timeouts == {}
77
77
  end
78
-
79
- def normalize_core_version!
80
- core_version = ENV['CORE_VERSION'] || config['core_version'] || RSMP::Schema.latest_core_version
81
- core_version = RSMP::Schema.latest_core_version if core_version == 'latest'
82
-
83
- known_versions = RSMP::Schema.core_versions
84
- normalized = normalized_core_version(core_version, known_versions)
85
- return config['core_version'] = normalized.to_s if normalized
86
-
87
- abort_with_error "Unknown core version #{core_version}, must be one of [#{known_versions.join(', ')}]."
88
- end
89
-
90
- def normalized_core_version(core_version, known_versions)
91
- known_versions.map { |v| Gem::Version.new(v) }.sort.reverse.detect do |v|
92
- Gem::Requirement.new(core_version).satisfied_by?(v)
93
- end
94
- end
95
-
96
- def normalize_sxls!
97
- sxls = config['sxls']
98
- if sxls.nil?
99
- config['sxls'] = [{ 'name' => 'tlc', 'version' => RSMP::Schema.latest_version(:tlc) }]
100
- return
101
- end
102
-
103
- sxls.each do |sxl|
104
- name = sxl['name']
105
- abort_with_error 'SXL name cannot be core.' if name.to_s == 'core'
106
-
107
- RSMP::Schema.find_schema! name, sxl['version'], lenient: true
108
- rescue RSMP::Schema::UnknownSchemaError => e
109
- abort_with_error "Unknown SXL #{name} #{sxl['version']}: #{e}"
110
- end
111
- end
112
78
  end
113
79
  end
114
80
  end
@@ -0,0 +1,56 @@
1
+ module RSMP
2
+ module Validator
3
+ module Configuration
4
+ # Canonicalizes the versions used by filters and compliance metadata.
5
+ # Embedded RSMP nodes retain configured legacy spellings for wire
6
+ # compatibility; the rsmp gem normalizes them only for schema lookup.
7
+ module VersionNormalization
8
+ private
9
+
10
+ def normalize_core_version!
11
+ core_version = config['core_version'] || RSMP::Schema.latest_core_version
12
+ config['core_version'] = canonical_core_version(core_version)
13
+ end
14
+
15
+ def canonical_core_version(core_version)
16
+ core_version = RSMP::Schema.latest_core_version if core_version == 'latest'
17
+
18
+ known_versions = RSMP::Schema.core_versions
19
+ normalized = normalized_core_version(core_version, known_versions)
20
+ return normalized.to_s if normalized
21
+
22
+ abort_with_error "Unknown core version #{core_version}, must be one of [#{known_versions.join(', ')}]."
23
+ end
24
+
25
+ def normalized_core_version(core_version, known_versions)
26
+ known_versions.map { |v| Gem::Version.new(v) }.sort.reverse.detect do |v|
27
+ Gem::Requirement.new(core_version).satisfied_by?(v)
28
+ end
29
+ end
30
+
31
+ def normalize_sxls!
32
+ sxls = config['sxls']
33
+ if sxls.nil?
34
+ config['sxls'] = [{ 'name' => 'tlc', 'version' => RSMP::Schema.latest_version(:tlc) }]
35
+ return
36
+ end
37
+
38
+ sxls.each do |sxl|
39
+ name = sxl['name']
40
+ abort_with_error 'SXL name cannot be core.' if name.to_s == 'core'
41
+
42
+ sxl['version'] = canonical_sxl_version(name, sxl['version'])
43
+ end
44
+ end
45
+
46
+ def canonical_sxl_version(name, version)
47
+ normalized = RSMP::Schema.sanitize_version(version.to_s)
48
+ RSMP::Schema.find_schema! name, normalized
49
+ normalized
50
+ rescue RSMP::Schema::UnknownSchemaError => e
51
+ abort_with_error "Unknown SXL #{name} #{version}: #{e}"
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,7 +1,9 @@
1
1
  require 'yaml'
2
2
  require_relative 'configuration/loader'
3
3
  require_relative 'configuration/validation'
4
+ require_relative 'configuration/version_normalization'
4
5
  require_relative 'configuration/secrets'
6
+ require_relative 'configuration/sxls_override'
5
7
 
6
8
  module RSMP
7
9
  module Validator
@@ -9,7 +11,9 @@ module RSMP
9
11
  module Configuration
10
12
  include Loader
11
13
  include Validation
14
+ include VersionNormalization
12
15
  include Secrets
16
+ include SxlsOverride
13
17
 
14
18
  def load_tester_config
15
19
  config_path = get_config_path
@@ -19,15 +23,15 @@ module RSMP
19
23
  missing_message: "#{mode.capitalize} config file #{config_path} is missing"
20
24
  )
21
25
 
22
- apply_env_overrides!(raw_config)
26
+ apply_cli_overrides!(raw_config)
23
27
  options = build_tester_options(raw_config, config_path)
24
28
  apply_loaded_config(options)
25
29
  validate_and_finalize_config!(config_path)
26
30
  end
27
31
 
28
- def apply_env_overrides!(raw_config)
29
- raw_config['core_version'] = ENV['CORE_VERSION'] if ENV['CORE_VERSION']
30
- raw_config['sxls'] = parse_sxls(ENV['SXLS']) if ENV['SXLS']
32
+ def apply_cli_overrides!(raw_config)
33
+ raw_config['core_version'] = core_version_override if core_version_override
34
+ raw_config['sxls'] = parse_sxls(sxls_override) if sxls_override
31
35
  end
32
36
 
33
37
  def validate_and_finalize_config!(config_path)
@@ -49,7 +53,7 @@ module RSMP
49
53
  using_message: '',
50
54
  missing_message: "Auto #{mode} config file #{path} is missing"
51
55
  )
52
- raw_config['sxls'] = parse_sxls(ENV['SXLS']) if ENV['SXLS']
56
+ apply_auto_node_overrides!(raw_config)
53
57
  options_class = auto_node_options_class_for(raw_config)
54
58
  options = build_options_from_raw(raw_config, path, options_class)
55
59
  self.auto_node_config = options.to_h
@@ -58,17 +62,17 @@ module RSMP
58
62
 
59
63
  def get_config_path(local: false)
60
64
  mode_name = mode.to_s
61
- config_path = get_config_path_from_env(mode_name) || get_config_path_from_validator_yaml(mode_name)
65
+ config_path = config_path_option(mode_name) || get_config_path_from_validator_yaml(mode_name)
62
66
  abort_with_error "#{mode_name.capitalize} config path not set" unless config_path && config_path != ''
63
67
 
64
68
  config_path = File.expand_path(config_path) if local
69
+ self.config_path = config_path
65
70
  config_path
66
71
  end
67
72
 
68
73
  def auto_node_config_path
69
- env_key = mode == :site ? 'AUTO_SITE_CONFIG' : 'AUTO_SUPERVISOR_CONFIG'
70
- env_path = ENV.fetch(env_key, nil)
71
- return env_path if env_path && !env_path.empty?
74
+ option_path = auto_config_path_option(mode.to_s)
75
+ return option_path if option_path && !option_path.empty?
72
76
 
73
77
  ref_path = 'config/validator.yaml'
74
78
  return nil unless File.exist? ref_path
@@ -98,9 +102,18 @@ module RSMP
98
102
 
99
103
  private
100
104
 
101
- def get_config_path_from_env(mode_name)
102
- key = "#{mode_name.upcase}_CONFIG"
103
- ENV.fetch(key, nil)
105
+ def config_path_option(mode_name)
106
+ case mode_name
107
+ when 'site' then site_config_path
108
+ when 'supervisor' then supervisor_config_path
109
+ end
110
+ end
111
+
112
+ def auto_config_path_option(mode_name)
113
+ case mode_name
114
+ when 'site' then auto_site_config_path
115
+ when 'supervisor' then auto_supervisor_config_path
116
+ end
104
117
  end
105
118
 
106
119
  def get_config_path_from_validator_yaml(mode_name)
@@ -114,16 +127,6 @@ module RSMP
114
127
  def warning(message)
115
128
  log "Warning: #{message}", level: :warning
116
129
  end
117
-
118
- def parse_sxls(value)
119
- value.split(',').each_with_object({}) do |item, memo|
120
- parts = item.split(':')
121
- abort_with_error "Invalid SXLS item #{item.inspect}, expected name:version" unless parts.length == 2
122
-
123
- name, version = parts
124
- memo[name] = version
125
- end
126
- end
127
130
  end
128
131
  end
129
132
  end
@@ -40,7 +40,7 @@ module RSMP
40
40
  end
41
41
 
42
42
  def build_alarm_matchers(site_proxy)
43
- if RSMP::Proxy.version_meets_requirement? site_proxy.core_version, '>=3.2'
43
+ if RSMP::Proxy.version_meets_requirement? site_proxy.core_version, '>=3.2.0'
44
44
  [/Issue/, /Active/, /inActive/]
45
45
  else
46
46
  [/issue/i, /active/i, /inactive/i]
@@ -4,11 +4,11 @@ module RSMP
4
4
  # Helper methods for testing RSMP clock functionality.
5
5
  module Clock
6
6
  def with_clock_set(site_proxy, clock, within:)
7
- site_proxy.tlc.set_clock(clock, within:)
7
+ site_proxy.tlc.set_clock!(clock, within:)
8
8
  site_proxy.clear_alarm_timestamps
9
9
  yield
10
10
  ensure
11
- site_proxy.tlc.set_clock(Time.now.utc, within:)
11
+ site_proxy.tlc.set_clock!(Time.now.utc, within:)
12
12
  end
13
13
  end
14
14
  end