rsmp-validator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/config/cross_rs4s.yaml +55 -0
  3. data/config/gem_supervisor.yaml +56 -0
  4. data/config/gem_tlc.yaml +56 -0
  5. data/config/gem_tlc_secrets.yaml +3 -0
  6. data/config/kapsch_etx.yaml +54 -0
  7. data/config/lightmotion_satellite.yaml +56 -0
  8. data/config/secrets.yaml +3 -0
  9. data/config/secrets_example.yaml +6 -0
  10. data/config/semaforica_cartesio.yaml +56 -0
  11. data/config/simulator/node_log.yaml +17 -0
  12. data/config/simulator/supervisor.yaml +11 -0
  13. data/config/simulator/tlc.yaml +56 -0
  14. data/config/sus.rb +13 -0
  15. data/config/swarco_itc3.yaml +55 -0
  16. data/config/tecsen_tmacs_supervisor.yaml +57 -0
  17. data/config/validator.rb +37 -0
  18. data/config/validator.yaml +5 -0
  19. data/config/validator_example.yaml +23 -0
  20. data/config/validator_log.yaml +19 -0
  21. data/exe/rsmp-validator +121 -0
  22. data/lib/doc_gen/parser.rb +276 -0
  23. data/lib/doc_gen/renderer.rb +153 -0
  24. data/lib/rsmp/validator/async_context.rb +15 -0
  25. data/lib/rsmp/validator/auto_node.rb +82 -0
  26. data/lib/rsmp/validator/auto_site.rb +30 -0
  27. data/lib/rsmp/validator/auto_supervisor.rb +23 -0
  28. data/lib/rsmp/validator/config_normalizer.rb +103 -0
  29. data/lib/rsmp/validator/configuration/loader.rb +79 -0
  30. data/lib/rsmp/validator/configuration/secrets.rb +54 -0
  31. data/lib/rsmp/validator/configuration/validation.rb +115 -0
  32. data/lib/rsmp/validator/configuration.rb +129 -0
  33. data/lib/rsmp/validator/helpers/alarms.rb +66 -0
  34. data/lib/rsmp/validator/helpers/clock.rb +16 -0
  35. data/lib/rsmp/validator/helpers/connection.rb +73 -0
  36. data/lib/rsmp/validator/helpers/handshake.rb +110 -0
  37. data/lib/rsmp/validator/helpers/input.rb +42 -0
  38. data/lib/rsmp/validator/helpers/security.rb +26 -0
  39. data/lib/rsmp/validator/helpers/signal_plans.rb +37 -0
  40. data/lib/rsmp/validator/helpers/signal_priority.rb +130 -0
  41. data/lib/rsmp/validator/helpers/startup.rb +157 -0
  42. data/lib/rsmp/validator/helpers/status.rb +22 -0
  43. data/lib/rsmp/validator/lifecycle.rb +99 -0
  44. data/lib/rsmp/validator/log.rb +11 -0
  45. data/lib/rsmp/validator/mode_detection.rb +84 -0
  46. data/lib/rsmp/validator/options/site_test_options.rb +58 -0
  47. data/lib/rsmp/validator/options/supervisor_test_options.rb +51 -0
  48. data/lib/rsmp/validator/site_tester.rb +113 -0
  49. data/lib/rsmp/validator/supervisor_tester.rb +76 -0
  50. data/lib/rsmp/validator/tester.rb +101 -0
  51. data/lib/rsmp/validator/version.rb +5 -0
  52. data/lib/rsmp/validator/version_filter.rb +44 -0
  53. data/lib/rsmp/validator.rb +50 -0
  54. data/schemas/site_test.json +36 -0
  55. data/schemas/supervisor_test.json +28 -0
  56. data/test/site/core/aggregated_status_spec.rb +43 -0
  57. data/test/site/core/connect_spec.rb +104 -0
  58. data/test/site/core/core_spec.rb +9 -0
  59. data/test/site/core/disconnect_spec.rb +54 -0
  60. data/test/site/site_spec.rb +5 -0
  61. data/test/site/tlc/alarm_spec.rb +134 -0
  62. data/test/site/tlc/clock_spec.rb +252 -0
  63. data/test/site/tlc/detector_logics_spec.rb +76 -0
  64. data/test/site/tlc/emergency_routes_spec.rb +106 -0
  65. data/test/site/tlc/input_spec.rb +102 -0
  66. data/test/site/tlc/invalid_command_spec.rb +103 -0
  67. data/test/site/tlc/invalid_status_spec.rb +70 -0
  68. data/test/site/tlc/modes_spec.rb +260 -0
  69. data/test/site/tlc/output_spec.rb +58 -0
  70. data/test/site/tlc/signal_groups_spec.rb +96 -0
  71. data/test/site/tlc/signal_plans_spec.rb +287 -0
  72. data/test/site/tlc/signal_priority_spec.rb +144 -0
  73. data/test/site/tlc/subscribe_spec.rb +71 -0
  74. data/test/site/tlc/system_spec.rb +76 -0
  75. data/test/site/tlc/tlc_spec.rb +7 -0
  76. data/test/site/tlc/traffic_data_spec.rb +151 -0
  77. data/test/site/tlc/traffic_situations_spec.rb +50 -0
  78. data/test/supervisor/aggregated_status_spec.rb +18 -0
  79. data/test/supervisor/connect_spec.rb +219 -0
  80. data/test/supervisor/supervisor_spec.rb +11 -0
  81. metadata +190 -0
@@ -0,0 +1,84 @@
1
+ module RSMP
2
+ module Validator
3
+ # Methods for detecting test mode and building the appropriate tester and auto node.
4
+ module ModeDetection
5
+ # Print an error message and exit.
6
+ def abort_with_error(error)
7
+ warn "Error: #{error}".colorize(:red)
8
+ exit 1
9
+ end
10
+
11
+ # Initial connectivity check to verify we can connect to the site/supervisor being tested.
12
+ def check_connection
13
+ log "Initial #{mode} connection check"
14
+ if mode == :site
15
+ SiteTester.instance.connected { nil }
16
+ elsif mode == :supervisor
17
+ SupervisorTester.instance.connected { nil }
18
+ end
19
+ end
20
+
21
+ # Set whether we are testing a site or a supervisor.
22
+ def select_mode(mode)
23
+ if self.mode
24
+ abort_with_error 'Cannot run tests in both test/site/ and test/supervisor/' if self.mode != mode
25
+ return
26
+ end
27
+
28
+ case mode
29
+ when :site, :supervisor
30
+ self.mode = mode
31
+ else
32
+ abort_with_error "Unknown test mode: #{mode}"
33
+ end
34
+ end
35
+
36
+ # Determine mode from test file paths.
37
+ def determine_mode(sus_config)
38
+ paths = sus_config.paths.any? ? sus_config.paths : sus_config.test_paths
39
+ site_dir = File.expand_path('test/site', sus_config.root)
40
+ supervisor_dir = File.expand_path('test/supervisor', sus_config.root)
41
+
42
+ paths.each do |path_str|
43
+ expanded = File.expand_path(path_str, sus_config.root)
44
+ inferred = infer_mode_from_path(expanded, site_dir, supervisor_dir)
45
+ select_mode inferred if inferred
46
+ end
47
+
48
+ abort_with_error 'Could not determine test mode (site or supervisor) from test paths' unless mode
49
+ end
50
+
51
+ # Determine the test mode from a single expanded path.
52
+ def infer_mode_from_path(path, site_dir, supervisor_dir)
53
+ return :site if path == site_dir || path.start_with?("#{site_dir}/")
54
+ return :supervisor if path == supervisor_dir || path.start_with?("#{supervisor_dir}/")
55
+
56
+ nil
57
+ end
58
+
59
+ # Build the tester instance.
60
+ def build_tester
61
+ if mode == :site
62
+ SiteTester.instance = SiteTester.new
63
+ elsif mode == :supervisor
64
+ SupervisorTester.instance = SupervisorTester.new
65
+ else
66
+ abort_with_error "Unknown test mode: #{mode}"
67
+ end
68
+ end
69
+
70
+ # Build the auto node (local site or supervisor to be tested).
71
+ def build_auto_node
72
+ return unless auto_node_config
73
+
74
+ if mode == :site
75
+ self.auto_node = AutoSite.new
76
+ elsif mode == :supervisor
77
+ self.auto_node = AutoSupervisor.new
78
+ else
79
+ abort_with_error "Unknown test mode: #{mode}"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,58 @@
1
+ require 'rsmp'
2
+
3
+ module RSMP
4
+ module Validator
5
+ module SiteTest
6
+ # Configuration options for site testing.
7
+ class Options < RSMP::Options
8
+ def schema_file
9
+ 'site_test.json'
10
+ end
11
+
12
+ def schema_path
13
+ File.expand_path("../../../schemas/#{schema_file}", __dir__)
14
+ end
15
+
16
+ private
17
+
18
+ def apply_defaults(options)
19
+ return options unless options.is_a?(Hash)
20
+
21
+ local_supervisor = options['local_supervisor']
22
+ return options unless local_supervisor.is_a?(Hash)
23
+
24
+ local_supervisor['sites'] ||= {}
25
+ local_supervisor['sites']['default'] =
26
+ merge_default_defaults(options, local_supervisor.dig('sites', 'default'))
27
+ local_supervisor = RSMP::Supervisor::Options.new(local_supervisor).to_h
28
+ options.merge('local_supervisor' => local_supervisor)
29
+ end
30
+
31
+ def merge_default_defaults(options, default)
32
+ merged_default = default.is_a?(Hash) ? default.dup : {}
33
+
34
+ site_defaults.each do |key|
35
+ value = options[key]
36
+ next if value.nil? || merged_default.key?(key)
37
+
38
+ merged_default[key] = value
39
+ end
40
+
41
+ merged_default
42
+ end
43
+
44
+ def site_defaults
45
+ %w[
46
+ sxls
47
+ core_version
48
+ rsmp_versions
49
+ intervals
50
+ timeouts
51
+ components
52
+ skip_validation
53
+ ]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,51 @@
1
+ require 'rsmp'
2
+
3
+ module RSMP
4
+ module Validator
5
+ module SupervisorTest
6
+ # Configuration options for supervisor testing.
7
+ class Options < RSMP::Options
8
+ def schema_file
9
+ 'supervisor_test.json'
10
+ end
11
+
12
+ def schema_path
13
+ File.expand_path("../../../schemas/#{schema_file}", __dir__)
14
+ end
15
+
16
+ private
17
+
18
+ def apply_defaults(options)
19
+ return options unless options.is_a?(Hash)
20
+
21
+ local_site = options['local_site']
22
+ return options unless local_site.is_a?(Hash)
23
+
24
+ %w[
25
+ sxls
26
+ core_version
27
+ rsmp_versions
28
+ intervals
29
+ timeouts
30
+ components
31
+ skip_validation
32
+ ].each do |key|
33
+ value = options[key]
34
+ next if value.nil? || local_site.key?(key)
35
+
36
+ local_site[key] = value
37
+ end
38
+
39
+ site_options_class = if local_site['type'] == 'tlc'
40
+ RSMP::TLC::TrafficControllerSite::Options
41
+ else
42
+ RSMP::Site::Options
43
+ end
44
+ local_site = site_options_class.new(local_site).to_h
45
+
46
+ options.merge('local_site' => local_site)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,113 @@
1
+ module RSMP
2
+ module Validator
3
+ # Helper class for testing RSMP sites.
4
+ # Runs a local RSMP supervisor inside an Async reactor.
5
+ # Only one site is expected to connect to the supervisor.
6
+ class SiteTester < RSMP::Validator::Tester
7
+ class << self
8
+ attr_accessor :instance
9
+
10
+ def connected(options = {}, &)
11
+ instance.connected(options, &)
12
+ end
13
+
14
+ def reconnected(options = {}, &)
15
+ instance.reconnected(options, &)
16
+ end
17
+
18
+ def disconnected(&)
19
+ instance.disconnected(&)
20
+ end
21
+
22
+ def isolated(options = {}, &)
23
+ instance.isolated(options, &)
24
+ end
25
+
26
+ def stop
27
+ instance.stop
28
+ end
29
+ end
30
+
31
+ def parse_config
32
+ setup_supervisor_config
33
+ validate_timeouts
34
+ end
35
+
36
+ def setup_supervisor_config
37
+ @supervisor_config = config['local_supervisor']
38
+ raise "config 'local_supervisor' is missing" unless @supervisor_config
39
+
40
+ @supervisor_config['max_sites'] ||= 1
41
+ @supervisor_config['sites'] ||= {}
42
+ @supervisor_config['sites']['default'] ||= {}
43
+ apply_security_codes
44
+ end
45
+
46
+ def apply_security_codes
47
+ security_codes = config.dig('secrets', 'security_codes')
48
+ return unless security_codes && !@supervisor_config['sites']['default']['security_codes']
49
+
50
+ @supervisor_config['sites']['default']['security_codes'] = security_codes
51
+ end
52
+
53
+ def validate_timeouts
54
+ %w[
55
+ connect
56
+ ready
57
+ status_response
58
+ status_update
59
+ subscribe
60
+ command
61
+ command_response
62
+ alarm
63
+ disconnect
64
+ ].each do |key|
65
+ raise "config 'timeouts/#{key}' is missing" unless config['timeouts'][key]
66
+ end
67
+ end
68
+
69
+ def build_node(options)
70
+ logger = create_supervisor_logger(@supervisor_config)
71
+ supervisor_settings = ConfigNormalizer.normalize_supervisor_settings(@supervisor_config.deep_merge(options))
72
+
73
+ RSMP::Supervisor.new(
74
+ supervisor_settings: supervisor_settings,
75
+ logger: logger,
76
+ collect: options['collect']
77
+ )
78
+ end
79
+
80
+ def wait_for_connection
81
+ @proxy = @node.proxies.first
82
+ return if @proxy
83
+
84
+ log 'Waiting for site to connect'
85
+ @proxy = @node.wait_for_site(:any, timeout: config['timeouts']['connect'])
86
+ rescue RSMP::TimeoutError
87
+ raise RSMP::ConnectionError, "Site did not connect within #{config['timeouts']['connect']}s"
88
+ end
89
+
90
+ def wait_for_handshake
91
+ return if @proxy.ready?
92
+
93
+ log 'Waiting for handshake to complete'
94
+ @proxy.wait_for_state :ready, timeout: config['timeouts']['ready']
95
+ log 'Ready'
96
+ return if @initial_unsubscribe_done
97
+
98
+ @proxy.unsubscribe_from_all component: RSMP::Validator.get_config('main_component')
99
+ @initial_unsubscribe_done = true
100
+ end
101
+
102
+ def create_supervisor_logger(supervisor_config)
103
+ log_settings = supervisor_config.is_a?(Hash) ? supervisor_config['log'] : nil
104
+ logger_settings = RSMP::Validator.node_log_settings.merge('prefix' => '[SUPERVISOR]')
105
+ return RSMP::Logger.new(logger_settings) unless log_settings && !log_settings.empty?
106
+
107
+ logger_settings.merge!(log_settings)
108
+ logger_settings.delete('stream') if log_settings['path']
109
+ RSMP::Logger.new(logger_settings)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,76 @@
1
+ require 'rsmp'
2
+ require 'singleton'
3
+ require 'colorize'
4
+
5
+ module RSMP
6
+ module Validator
7
+ # Helper class for testing RSMP supervisors.
8
+ # Runs a local RSMP site inside an Async reactor.
9
+ class SupervisorTester < RSMP::Validator::Tester
10
+ class << self
11
+ attr_accessor :instance
12
+
13
+ def connected(options = {}, &)
14
+ instance.connected(options, &)
15
+ end
16
+
17
+ def reconnected(options = {}, &)
18
+ instance.reconnected(options, &)
19
+ end
20
+
21
+ def disconnected(&)
22
+ instance.disconnected(&)
23
+ end
24
+
25
+ def isolated(options = {}, &)
26
+ instance.isolated(options, &)
27
+ end
28
+ end
29
+
30
+ def parse_config
31
+ @site_config = config['local_site']
32
+ raise "config 'local_site' is missing" unless @site_config
33
+ end
34
+
35
+ def build_node(options)
36
+ klass = case @site_config['type']
37
+ when 'tlc'
38
+ RSMP::TLC::TrafficControllerSite
39
+ else
40
+ RSMP::Site
41
+ end
42
+ site_settings = ConfigNormalizer.normalize_site_settings(@site_config.deep_merge(options))
43
+ logger = create_site_logger(@site_config)
44
+ @site = klass.new(
45
+ site_settings: site_settings,
46
+ logger: logger,
47
+ collect: options['collect']
48
+ )
49
+ end
50
+
51
+ def wait_for_connection
52
+ log 'Waiting for connection to supervisor'
53
+ @proxy = @node.find_supervisor :any
54
+ @proxy.wait_for_state %i[connected ready], timeout: config['timeouts']['connect']
55
+ rescue RSMP::TimeoutError
56
+ raise RSMP::ConnectionError, "Could not connect to supervisor within #{config['timeouts']['connect']}s"
57
+ end
58
+
59
+ def wait_for_handshake
60
+ @proxy.wait_for_state :ready, timeout: config['timeouts']['ready']
61
+ rescue RSMP::TimeoutError
62
+ raise RSMP::ConnectionError, "Handshake didn't complete within #{config['timeouts']['ready']}s"
63
+ end
64
+
65
+ def create_site_logger(site_config)
66
+ log_settings = site_config.is_a?(Hash) ? site_config['log'] : nil
67
+ logger_settings = RSMP::Validator.node_log_settings.merge('prefix' => '[TLC] ')
68
+ return RSMP::Logger.new(logger_settings) unless log_settings && !log_settings.empty?
69
+
70
+ logger_settings.merge!(log_settings)
71
+ logger_settings.delete('stream') if log_settings['path']
72
+ RSMP::Logger.new(logger_settings)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,101 @@
1
+ require 'rsmp'
2
+ require 'colorize'
3
+
4
+ module RSMP
5
+ module Validator
6
+ # Base class for testing either a site or a supervisor.
7
+ # Handles running the corresponding local site/supervisor inside an Async reactor.
8
+ class Tester
9
+ include RSMP::Validator::Log
10
+
11
+ def self.sentinel_errors
12
+ @sentinel_errors ||= []
13
+ end
14
+
15
+ def config
16
+ RSMP::Validator.config
17
+ end
18
+
19
+ # Ensures that the site is connected.
20
+ # If the site is already connected, the block will be called immediately.
21
+ # Otherwise waits until the site is connected before calling the block.
22
+ def connected(options = {})
23
+ start options, 'Connecting'
24
+ wait_for_proxy
25
+ yield Async::Task.current, @node, @proxy
26
+ end
27
+
28
+ # Disconnects the site if connected, then waits until the site is connected
29
+ # before calling the block.
30
+ def reconnected(options = {})
31
+ stop 'Reconnecting'
32
+ start options
33
+ wait_for_proxy
34
+ yield Async::Task.current, @node, @proxy
35
+ end
36
+
37
+ # Like connected, except that the connection is closed after the test.
38
+ def isolated(options = {})
39
+ stop 'Isolating'
40
+ start options, 'Connecting'
41
+ wait_for_proxy
42
+ yield Async::Task.current, @node, @proxy
43
+ stop 'Isolating'
44
+ end
45
+
46
+ # Disconnects the site if connected before calling the block.
47
+ def disconnected
48
+ stop 'Disconnecting'
49
+ yield Async::Task.current
50
+ end
51
+
52
+ # Stop the rsmp supervisor
53
+ def stop(why = nil)
54
+ if @node
55
+ log why if why
56
+ @node.ignore_errors RSMP::DisconnectError do
57
+ @node.stop
58
+ end
59
+ end
60
+ @node = nil
61
+ @proxy = nil
62
+ end
63
+
64
+ private
65
+
66
+ def initialize
67
+ parse_config
68
+ end
69
+
70
+ # Start the tester node inside an async task that will persist between tests.
71
+ def start(options = {}, _why = nil)
72
+ return if @node
73
+
74
+ RSMP::Validator.reactor.async do |task|
75
+ task.annotate 'node runner'
76
+
77
+ @node = build_node options
78
+
79
+ RSMP::Validator.reactor.async do |sentinel|
80
+ sentinel.annotate 'sentinel'
81
+ while @node
82
+ e = @node.error_queue.dequeue
83
+ log "Sentinel warning: #{e.class}: #{e}"
84
+ self.class.sentinel_errors << e
85
+ end
86
+ end
87
+
88
+ @node.start
89
+ end
90
+ end
91
+
92
+ # Wait until communication has been established, and handshake completed.
93
+ def wait_for_proxy
94
+ wait_for_connection
95
+ wait_for_handshake
96
+ end
97
+
98
+ def parse_config; end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module RSMP
2
+ module Validator
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ module RSMP
2
+ # Main module for RSMP Validator functionality.
3
+ module Validator
4
+ # Helpers for filtering tests by RSMP core and SXL version.
5
+ module VersionFilter
6
+ # Check if the configured SXL version satisfies the given requirement.
7
+ # @param requirement [String] Gem::Requirement-compatible string, e.g. ">= 1.0.7"
8
+ def self.sxl_matches?(requirement, name: nil)
9
+ sxl = configured_sxl(name)
10
+ version_satisfies?(requirement, sxl && sxl['version'])
11
+ end
12
+
13
+ # Check if the configured core version satisfies the given requirement.
14
+ # @param requirement [String] Gem::Requirement-compatible string, e.g. ">= 3.2"
15
+ def self.core_matches?(requirement)
16
+ version_satisfies?(requirement, RSMP::Validator.config['core_version'])
17
+ end
18
+
19
+ # Helper that does the version comparison.
20
+ def self.version_satisfies?(requirement, version_str)
21
+ return false unless version_str
22
+
23
+ version = Gem::Version.new(version_str)
24
+ Gem::Requirement.new(requirement).satisfied_by?(version)
25
+ end
26
+
27
+ def self.configured_sxl(name = nil)
28
+ sxls = RSMP::Validator.config['sxls'] || []
29
+ return sxls.first unless name
30
+
31
+ sxls.find { |sxl| sxl['name'] == name.to_s }
32
+ end
33
+ end
34
+
35
+ # Convenience module methods delegating to VersionFilter
36
+ def self.sxl_matches?(requirement, name: nil)
37
+ VersionFilter.sxl_matches?(requirement, name: name)
38
+ end
39
+
40
+ def self.core_matches?(requirement)
41
+ VersionFilter.core_matches?(requirement)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,50 @@
1
+ require 'rsmp'
2
+ require 'colorize'
3
+ require_relative 'validator/version'
4
+ require_relative 'validator/log'
5
+ require_relative 'validator/options/site_test_options'
6
+ require_relative 'validator/options/supervisor_test_options'
7
+ require_relative 'validator/config_normalizer'
8
+ require_relative 'validator/configuration'
9
+ require_relative 'validator/version_filter'
10
+ require_relative 'validator/lifecycle'
11
+ require_relative 'validator/mode_detection'
12
+ require_relative 'validator/tester'
13
+ require_relative 'validator/site_tester'
14
+ require_relative 'validator/supervisor_tester'
15
+ require_relative 'validator/auto_node'
16
+ require_relative 'validator/auto_site'
17
+ require_relative 'validator/auto_supervisor'
18
+ require_relative 'validator/async_context'
19
+ require_relative 'validator/helpers/connection'
20
+ require_relative 'validator/helpers/status'
21
+ require_relative 'validator/helpers/input'
22
+ require_relative 'validator/helpers/clock'
23
+ require_relative 'validator/helpers/security'
24
+ require_relative 'validator/helpers/signal_plans'
25
+ require_relative 'validator/helpers/alarms'
26
+ require_relative 'validator/helpers/startup'
27
+ require_relative 'validator/helpers/handshake'
28
+ require_relative 'validator/helpers/signal_priority'
29
+
30
+ module RSMP
31
+ # Main module for RSMP Validator functionality.
32
+ # Handles configuration, logging, and coordination between sus and the RSMP gem.
33
+ module Validator
34
+ extend Configuration
35
+ extend Lifecycle
36
+ extend ModeDetection
37
+
38
+ class << self
39
+ include RSMP::Logging
40
+
41
+ attr_accessor :config, :config_log_settings, :mode, :logger, :auto_node_config,
42
+ :auto_node_log_settings, :auto_node, :node_log_settings
43
+ end
44
+
45
+ # Get the global Async reactor used for RSMP communication
46
+ def self.reactor
47
+ @reactor
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "site_test.json",
4
+ "type": "object",
5
+ "properties": {
6
+ "local_supervisor": {
7
+ "type": "object",
8
+ "properties": {
9
+ "log": { "type": "object" }
10
+ },
11
+ "additionalProperties": true
12
+ },
13
+ "core_version": { "type": "string" },
14
+ "sxls": {
15
+ "type": "object",
16
+ "propertyNames": { "not": { "const": "core" } },
17
+ "additionalProperties": { "type": "string" }
18
+ },
19
+ "rsmp_versions": {
20
+ "oneOf": [
21
+ { "type": "string" },
22
+ { "type": "array", "items": { "type": "string" } }
23
+ ]
24
+ },
25
+ "timeouts": { "type": "object" },
26
+ "components": { "type": "object" },
27
+ "items": { "type": "object" },
28
+ "startup_sequence": { "type": ["string", "null"] },
29
+ "skip_validation": { "type": "array", "items": { "type": "string" } },
30
+ "secrets": { "type": "object" },
31
+ "alarm_triggers": { "type": "object" },
32
+ "log": { "type": "object" }
33
+ },
34
+ "required": ["local_supervisor"],
35
+ "additionalProperties": true
36
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "supervisor_test.json",
4
+ "type": "object",
5
+ "properties": {
6
+ "local_site": {
7
+ "type": "object",
8
+ "properties": {
9
+ "log": { "type": "object" }
10
+ },
11
+ "additionalProperties": true
12
+ },
13
+ "core_version": { "type": "string" },
14
+ "sxls": {
15
+ "type": "object",
16
+ "propertyNames": { "not": { "const": "core" } },
17
+ "additionalProperties": { "type": "string" }
18
+ },
19
+ "timeouts": { "type": "object" },
20
+ "components": { "type": "object" },
21
+ "items": { "type": "object" },
22
+ "skip_validation": { "type": "array", "items": { "type": "string" } },
23
+ "secrets": { "type": "object" },
24
+ "log": { "type": "object" }
25
+ },
26
+ "required": ["local_site"],
27
+ "additionalProperties": true
28
+ }