nonnative 2.15.1 → 2.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df0fc1bbc0cd9de5368098691bb6c4b812029d70a3d8df236b587874b96e9baf
4
- data.tar.gz: 431042c13689b0dec97b2064c130a1b104a167fafecda20f6e90aff2e9c22190
3
+ metadata.gz: e83e6a409c77b42f73d52473d360f136255a62f5227bb08b770d129082ccd69b
4
+ data.tar.gz: f2cb0c6bf4b4bcfa7a9ab95851735b987b16ab180aa4ff9278e334e473863aca
5
5
  SHA512:
6
- metadata.gz: 5dd146af474ac19e1173b38701a75383dd5650e6a182b529c20d2290c44a037072025eee23cc0f6bd06326fc91690d6da83ff746be5cac443609703d5da59075
7
- data.tar.gz: 7d7dcbebffa532f5dfe93b4c80ff563d4b0bd5c329a092fc69fcbe1930cd8dac1f191cc04a9ff2dd0de15447b3f446ea134bd9708993e20e7bac780c41122d99
6
+ metadata.gz: e282a3e79b1319d47154ffac90b305ef5344eb78d9f960e30b3d6a851303f1b736b2f0456e24816a8459db9b5368f4e90d10777fd385e26da3748ac7a894f29f
7
+ data.tar.gz: 10b38f3e4b0d3d279add988ae32af3c60990715b1fa0c96e94efa6adad29b6f86868b243d2d000e0005815c1c80c4c28a79889a105ef0cf265555b80e4b60b39
data/.circleci/config.yml CHANGED
@@ -3,7 +3,7 @@ version: 2.1
3
3
  jobs:
4
4
  build:
5
5
  docker:
6
- - image: alexfalkowski/ruby:2.15
6
+ - image: alexfalkowski/ruby:3.8
7
7
  working_directory: ~/nonnative
8
8
  steps:
9
9
  - checkout:
@@ -35,7 +35,7 @@ jobs:
35
35
  resource_class: arm.large
36
36
  sync:
37
37
  docker:
38
- - image: alexfalkowski/release:7.16
38
+ - image: alexfalkowski/release:8.8
39
39
  working_directory: ~/nonnative
40
40
  steps:
41
41
  - checkout:
@@ -46,7 +46,7 @@ jobs:
46
46
  resource_class: arm.large
47
47
  version:
48
48
  docker:
49
- - image: alexfalkowski/release:7.16
49
+ - image: alexfalkowski/release:8.8
50
50
  working_directory: ~/nonnative
51
51
  steps:
52
52
  - checkout:
@@ -58,7 +58,7 @@ jobs:
58
58
  resource_class: arm.large
59
59
  wait-all:
60
60
  docker:
61
- - image: alexfalkowski/ruby:2.15
61
+ - image: alexfalkowski/ruby:3.8
62
62
  steps:
63
63
  - run: echo "all applicable jobs finished"
64
64
  resource_class: arm.large
data/AGENTS.md CHANGED
@@ -1,13 +1,16 @@
1
1
  # AGENTS.md
2
2
 
3
+ ## Shared skills
4
+
5
+ This repository uses the shared skills from `bin/skills/`. Read
6
+ `bin/AGENTS.md` for the canonical shared skill list and use the smallest
7
+ matching skill for the task.
8
+
3
9
  `nonnative` is a Ruby gem for end-to-end testing systems implemented in other
4
10
  languages. It starts processes, in-process servers, and proxy-only services,
5
11
  waits on TCP readiness/shutdown, and can place fault-injection proxies in front
6
12
  of dependencies.
7
13
 
8
- Use `./bin/skills/coding-standards` for shared coding, review, testing,
9
- documentation, and PR conventions. This file only adds repo-specific context.
10
-
11
14
  ## Map And Commands
12
15
 
13
16
  - Library: `lib/nonnative/**/*.rb`
@@ -76,6 +79,9 @@ Fault-injection states: `none`, `close_all`, `delay`, `invalid_data`.
76
79
 
77
80
  Config rules:
78
81
 
82
+ - YAML config is loaded as data only via `Nonnative::ConfigurationFile`; ERB is not evaluated and arbitrary Ruby object tags are rejected
83
+ - Runner `host` and nested `proxy.host` default to `127.0.0.1`; use explicit `0.0.0.0` only when external access is intended
84
+ - Process `command` can be a legacy shell string or an argv array; prefer argv arrays for new config, and `go:` config builds argv internally
79
85
  - YAML services belong under `services:`, not `processes:`
80
86
  - There is no top-level `config.wait`; `wait` is per runner
81
87
  - Programmatic service config uses `config.service do |s| ... end`, so use `s.host` / `s.port`
@@ -104,4 +110,4 @@ Limitations:
104
110
  - Process lifecycle: `lib/nonnative/process.rb`
105
111
  - Proxies: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
106
112
  - Cucumber: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
107
- - Config loading: `lib/nonnative/configuration.rb`, `lib/nonnative/configuration_runner.rb`, `lib/nonnative/configuration_proxy.rb`
113
+ - Config loading: `lib/nonnative/configuration.rb`, `lib/nonnative/configuration_file.rb`, `lib/nonnative/configuration_runner.rb`, `lib/nonnative/configuration_proxy.rb`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nonnative (2.15.1)
4
+ nonnative (2.19.0)
5
5
  concurrent-ruby (>= 1, < 2)
6
6
  config (>= 5, < 6)
7
7
  cucumber (>= 7, < 12)
@@ -206,4 +206,4 @@ DEPENDENCIES
206
206
  simplecov-cobertura
207
207
 
208
208
  BUNDLED WITH
209
- 4.0.10
209
+ 4.0.11
data/README.md CHANGED
@@ -38,6 +38,8 @@ gem install nonnative
38
38
  ## Usage
39
39
 
40
40
  Nonnative is configured via {#Nonnative.configure} (programmatic) or `config.load_file(...)` (YAML).
41
+ YAML configuration is loaded as data only: ERB is not evaluated and arbitrary Ruby objects are not
42
+ deserialized.
41
43
 
42
44
  High-level configuration fields:
43
45
  - `version`: configuration version (example: `"1.0"`).
@@ -51,10 +53,12 @@ High-level configuration fields:
51
53
  Runner fields (process/server/service):
52
54
  - `timeout`: max time (seconds) for readiness/shutdown port checks.
53
55
  - `wait`: small sleep (seconds) between lifecycle steps.
54
- - `host`/`port`: client-facing address used for readiness/shutdown port checks. When a `fault_injection` proxy is enabled, this is the endpoint your tests/clients should hit.
56
+ - `host`/`port`: client-facing address used for readiness/shutdown port checks. `host` defaults to `127.0.0.1`. When a `fault_injection` proxy is enabled, this is the endpoint your tests/clients should hit.
55
57
  - `log`: per-runner log file (used by process output redirection or server implementations).
56
58
 
57
- For `fault_injection`, the nested `proxy.host`/`proxy.port` describe the upstream target behind the proxy. In-process server implementations typically bind there via `proxy.host` / `proxy.port`.
59
+ For `fault_injection`, the nested `proxy.host`/`proxy.port` describe the upstream target behind the proxy. Nested `proxy.host` also defaults to `127.0.0.1`. In-process server implementations typically bind there via `proxy.host` / `proxy.port`.
60
+
61
+ Nonnative readiness and shutdown checks are TCP-only. Configure ports that are dedicated to the test run; if another process is already listening on the same `host`/`port`, results are undefined.
58
62
 
59
63
  ### Lifecycle strategies (Cucumber integration)
60
64
 
@@ -88,6 +92,8 @@ This calls `Nonnative.start` immediately and registers an `at_exit` stop.
88
92
  ### Processes
89
93
 
90
94
  A process is some sort of command that you would run locally.
95
+ Commands can be strings or argv arrays. String commands preserve legacy shell semantics, while argv arrays
96
+ avoid shell interpretation and are preferred for new configuration.
91
97
 
92
98
  Setup it up programmatically:
93
99
 
@@ -102,7 +108,7 @@ Nonnative.configure do |config|
102
108
 
103
109
  config.process do |p|
104
110
  p.name = 'start_1'
105
- p.command = -> { 'features/support/bin/start 12_321' }
111
+ p.command = -> { ['features/support/bin/start', '12_321'] }
106
112
  p.timeout = 5
107
113
  p.wait = 0.1
108
114
  p.port = 12_321
@@ -134,7 +140,9 @@ log: nonnative.log
134
140
  processes:
135
141
  -
136
142
  name: start_1
137
- command: features/support/bin/start 12_321
143
+ command:
144
+ - features/support/bin/start
145
+ - "12_321"
138
146
  timeout: 5
139
147
  wait: 1
140
148
  port: 12321
@@ -760,7 +768,7 @@ Then I should reset the proxy for service 'service_1'
760
768
 
761
769
  ### Go
762
770
 
763
- As we love using go as a language for services we have added support to start binaries with defined parameters. This expects that you build your services in the format of `command sub_command --params`
771
+ As we love using go as a language for services we have added support to start binaries with defined parameters. This expects that you build your services in the format of `command sub_command --params`. YAML `go:` configuration is executed as argv entries, without shell interpretation.
764
772
 
765
773
  To get this to work you will need to create a `main_test.go` file with these contents:
766
774
 
@@ -782,12 +790,16 @@ Then to compile this binary you will need to do the following:
782
790
  go test -mod vendor -c -tags features -covermode=count -o your_binary -coverpkg=./... github.com/your_location
783
791
  ```
784
792
 
785
- Setup it up programmatically:
793
+ Setup it up programmatically as an argv process command:
786
794
 
787
795
  ```ruby
788
- tools = %w[prof trace cover]
789
-
790
- Nonnative.go_executable(tools, 'reports', 'your_binary', 'sub_command', '--config config.yaml')
796
+ Nonnative.configure do |config|
797
+ config.process do |p|
798
+ p.name = 'go'
799
+ p.command = -> { ['your_binary', 'sub_command', '--config', 'config.yaml'] }
800
+ p.port = 12_345
801
+ end
802
+ end
791
803
  ```
792
804
 
793
805
  Setup it up through configuration:
@@ -52,13 +52,14 @@ module Nonnative
52
52
 
53
53
  # Loads a configuration file and appends its runners to this instance.
54
54
  #
55
- # The file is loaded using the `config` gem via {Nonnative.configurations}. Top-level attributes are
56
- # copied onto this object, and runner sections are transformed into configuration runner objects.
55
+ # The file is loaded using safe YAML parsing. ERB is not evaluated,
56
+ # arbitrary object deserialization is not allowed, top-level attributes are copied onto this object,
57
+ # and runner sections are transformed into configuration runner objects.
57
58
  #
58
59
  # @param path [String] path to a configuration file (typically YAML)
59
60
  # @return [void]
60
61
  def load_file(path)
61
- cfg = Nonnative.configurations(path)
62
+ cfg = Nonnative::ConfigurationFile.load(path)
62
63
 
63
64
  self.version = cfg.version
64
65
  self.name = cfg.name
@@ -140,7 +141,7 @@ module Nonnative
140
141
  params = go.parameters || []
141
142
  tools = go.tools || []
142
143
 
143
- -> { Nonnative.go_executable(tools, go.output, go.executable, go.command, *params) }
144
+ -> { Nonnative.go_executable_args(tools, go.output, go.executable, go.command, *params) }
144
145
  else
145
146
  -> { process.command }
146
147
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nonnative
4
+ # Safely loads a YAML configuration file into the Config::Options shape used by Nonnative.
5
+ class ConfigurationFile
6
+ class << self
7
+ # Loads a file into a Config::Options instance.
8
+ #
9
+ # YAML files are parsed as data only: ERB is not evaluated and arbitrary object deserialization is not allowed.
10
+ #
11
+ # @param path [String] file path
12
+ # @return [Config::Options]
13
+ def load(path)
14
+ Config::Options.new.tap do |config|
15
+ config.add_source!(safe_load_yaml(path))
16
+ config.load!
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def safe_load_yaml(path)
23
+ contents = File.read(path)
24
+ config = YAML.safe_load(contents, aliases: true) || {}
25
+ return config if config.is_a?(Hash)
26
+
27
+ raise ArgumentError, "Configuration file '#{path}' must contain a YAML mapping"
28
+ rescue Psych::SyntaxError => e
29
+ raise ArgumentError, "YAML syntax error occurred while parsing #{path}: #{e.message}"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -11,11 +11,21 @@ module Nonnative
11
11
  # @see Nonnative::Configuration
12
12
  # @see Nonnative::Process
13
13
  class ConfigurationProcess < ConfigurationRunner
14
- # @return [Proc] a callable that returns the command string to execute (e.g. `-> { "./bin/api" }`)
14
+ # @return [Proc] a callable that returns the command to execute
15
+ # as a shell string or argv array
16
+ # (e.g. `-> { "./bin/api" }` or `-> { ["./bin/api", "--port", "8080"] }`)
17
+ attr_accessor :command
18
+
15
19
  # @return [String, nil] signal name to use for stopping (defaults to `"INT"` when not set)
20
+ attr_accessor :signal
21
+
16
22
  # @return [Numeric] readiness timeout (seconds) used when waiting for the port to open/close
23
+ attr_accessor :timeout
24
+
17
25
  # @return [String] log file path to append process stdout/stderr to
26
+ attr_accessor :log
27
+
18
28
  # @return [Hash, nil] environment variables to pass to the spawned process
19
- attr_accessor :command, :signal, :timeout, :log, :environment
29
+ attr_accessor :environment
20
30
  end
21
31
  end
@@ -15,7 +15,7 @@ module Nonnative
15
15
  # @see Nonnative.proxies
16
16
  class ConfigurationProxy
17
17
  # @return [String] proxy kind name (for example `"none"` or `"fault_injection"`)
18
- # @return [String] upstream host used by proxy implementations (defaults to `"0.0.0.0"`)
18
+ # @return [String] upstream host used by proxy implementations (defaults to `"127.0.0.1"`)
19
19
  # @return [Integer] upstream port used by proxy implementations (defaults to `0`)
20
20
  # @return [String, nil] path to proxy log file (implementation-dependent)
21
21
  # @return [Numeric] wait interval (seconds) after proxy state changes (defaults to `0.1`)
@@ -27,7 +27,7 @@ module Nonnative
27
27
  #
28
28
  # Defaults:
29
29
  # - `kind`: `"none"`
30
- # - `host`: `"0.0.0.0"`
30
+ # - `host`: `"127.0.0.1"`
31
31
  # - `port`: `0`
32
32
  # - `wait`: `0.1`
33
33
  # - `options`: `{}`
@@ -35,7 +35,7 @@ module Nonnative
35
35
  # @return [void]
36
36
  def initialize
37
37
  self.kind = 'none'
38
- self.host = '0.0.0.0'
38
+ self.host = '127.0.0.1'
39
39
  self.port = 0
40
40
  self.wait = 0.1
41
41
  self.options = {}
@@ -14,7 +14,7 @@ module Nonnative
14
14
  # @see Nonnative::ConfigurationService
15
15
  class ConfigurationRunner
16
16
  # @return [String, nil] runner name used for lookup (for example via `pool.process_by_name`)
17
- # @return [String] host to bind/connect to (defaults to `"0.0.0.0"`)
17
+ # @return [String] host to bind/connect to (defaults to `"127.0.0.1"`)
18
18
  # @return [Integer] port to bind/connect to
19
19
  # @return [Numeric] wait interval (seconds) used by runners between lifecycle steps
20
20
  attr_accessor :name, :host, :port, :wait
@@ -30,14 +30,14 @@ module Nonnative
30
30
  # Creates a runner configuration with defaults.
31
31
  #
32
32
  # Defaults:
33
- # - `host`: `"0.0.0.0"`
33
+ # - `host`: `"127.0.0.1"`
34
34
  # - `port`: `0`
35
35
  # - `wait`: `0.1`
36
36
  # - `proxy`: a new {Nonnative::ConfigurationProxy} with its own defaults
37
37
  #
38
38
  # @return [void]
39
39
  def initialize
40
- self.host = '0.0.0.0'
40
+ self.host = '127.0.0.1'
41
41
  self.port = 0
42
42
  self.wait = 0.1
43
43
 
@@ -88,6 +88,8 @@ module Nonnative
88
88
  end
89
89
 
90
90
  module LifecycleSteps
91
+ SERVICE_UNAVAILABLE = 'Service Unavailable'
92
+
91
93
  def install_state_steps
92
94
  install_start_step
93
95
  install_attempt_start_step
@@ -125,7 +127,11 @@ module Nonnative
125
127
 
126
128
  Then('I should see {string} as unhealthy') do |service|
127
129
  wait_for { Nonnative.observability.health(opts).code }.to eq(503)
128
- wait_for { Nonnative.observability.health(opts).body }.to include(service)
130
+ wait_for { Nonnative.observability.health(opts).body }.to satisfy do |body|
131
+ body = body.to_s.strip
132
+
133
+ body == SERVICE_UNAVAILABLE || body.include?(service)
134
+ end
129
135
  end
130
136
  end
131
137
 
@@ -134,7 +140,11 @@ module Nonnative
134
140
 
135
141
  Then('I should see {string} as healthy') do |service|
136
142
  wait_for { Nonnative.observability.health(opts).code }.to eq(200)
137
- wait_for { Nonnative.observability.health(opts).body }.to_not include(service)
143
+ wait_for { Nonnative.observability.health(opts).body }.to satisfy do |body|
144
+ body = body.to_s.strip
145
+
146
+ body != SERVICE_UNAVAILABLE && !body.include?(service)
147
+ end
138
148
  end
139
149
  end
140
150
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nonnative
4
- # Builds command lines for running a Go test binary with optional profiling/trace/coverage flags.
4
+ # Builds commands for running a Go test binary with optional profiling/trace/coverage flags.
5
5
  #
6
- # This helper is used by {Nonnative.go_executable} and by YAML configuration when a process has a
7
- # `go:` section (see {Nonnative::Configuration}).
6
+ # This helper is used by YAML configuration when a process has a `go:` section
7
+ # (see {Nonnative::Configuration}).
8
8
  #
9
9
  # The generated flags use Go's `testing` package flags (e.g. `-test.cpuprofile=...`), so this
10
10
  # is intended to run a binary compiled from `go test -c`.
@@ -21,10 +21,10 @@ module Nonnative
21
21
  #
22
22
  # @example
23
23
  # cmd = Nonnative::GoCommand.new(%w[prof cover], './svc.test', 'reports')
24
- # cmd.executable('serve', '--config', 'config.yaml')
25
- # # => "./svc.test -test.cpuprofile=... -test.coverprofile=... serve --config config.yaml"
24
+ # cmd.executable_args('serve', '--config', 'config.yaml')
25
+ # # => ["./svc.test", "-test.cpuprofile=...", "-test.coverprofile=...", "serve", "--config", "config.yaml"]
26
26
  #
27
- # @see Nonnative.go_executable
27
+ # @see Nonnative.go_executable_args
28
28
  class GoCommand
29
29
  # @param tools [Array<String>, nil] tool names to enable (see class docs)
30
30
  # @param exec [String] path to the compiled Go test binary
@@ -35,16 +35,15 @@ module Nonnative
35
35
  @output = output
36
36
  end
37
37
 
38
- # Returns an executable command string including enabled `-test.*` flags.
38
+ # Returns an executable argv array including enabled `-test.*` flags.
39
39
  #
40
40
  # A short random suffix is appended to output filenames to reduce collisions across runs.
41
41
  #
42
42
  # @param cmd [String] command/sub-command argument passed to the Go test binary
43
43
  # @param params [Array<String>] additional parameters passed after `cmd`
44
- # @return [String] the full command to execute
45
- def executable(cmd, *params)
46
- params = params.join(' ')
47
- "#{exec} #{flags(cmd).join(' ')} #{cmd} #{params}".strip
44
+ # @return [Array<String>] argv entries to execute
45
+ def executable_args(cmd, *params)
46
+ [exec, *flags(cmd), cmd, *params.flatten.compact.map(&:to_s)]
48
47
  end
49
48
 
50
49
  private
@@ -89,10 +89,10 @@ module Nonnative
89
89
  environment[k] = ENV.fetch(k, nil) || environment[k]
90
90
  end
91
91
 
92
- command = service.command.call
92
+ command = Array(service.command.call)
93
93
 
94
- spawn(environment, command, %i[out err] => [service.log, 'a']).tap do |pid|
95
- Nonnative.logger.info "started '#{command}' with pid '#{pid}'"
94
+ spawn(environment, *command, %i[out err] => [service.log, 'a']).tap do |pid|
95
+ Nonnative.logger.info "started '#{command.join(' ')}' with pid '#{pid}'"
96
96
  end
97
97
  end
98
98
 
@@ -4,5 +4,5 @@ module Nonnative
4
4
  # The current gem version.
5
5
  #
6
6
  # @return [String]
7
- VERSION = '2.15.1'
7
+ VERSION = '2.19.0'
8
8
  end
data/lib/nonnative.rb CHANGED
@@ -67,6 +67,7 @@ require 'nonnative/stop_error'
67
67
  require 'nonnative/not_found_error'
68
68
  require 'nonnative/timeout'
69
69
  require 'nonnative/port'
70
+ require 'nonnative/configuration_file'
70
71
  require 'nonnative/configuration'
71
72
  require 'nonnative/configuration_runner'
72
73
  require 'nonnative/configuration_process'
@@ -113,16 +114,6 @@ module Nonnative
113
114
  # @return [Nonnative::Pool, nil] the pool instance, or `nil` if not started yet
114
115
  attr_accessor :pool
115
116
 
116
- # Loads one or more configuration files using the `config` gem.
117
- #
118
- # This is primarily used by {Nonnative::Configuration#load_file}, but is public for advanced cases.
119
- #
120
- # @param files [Array<String>] paths to configuration files
121
- # @return [Config::Options] the loaded configuration object
122
- def configurations(*files)
123
- Config.load_files(files)
124
- end
125
-
126
117
  # Returns the current configuration (memoized).
127
118
  #
128
119
  # @return [Nonnative::Configuration]
@@ -162,7 +153,7 @@ module Nonnative
162
153
  File.readlines(path).select { |l| predicate.call(l) }
163
154
  end
164
155
 
165
- # Builds a Go test executable command line with optional profiling/trace/coverage flags.
156
+ # Builds a Go test executable argv array with optional profiling/trace/coverage flags.
166
157
  #
167
158
  # This is used when process configuration specifies a `go` section.
168
159
  #
@@ -171,9 +162,9 @@ module Nonnative
171
162
  # @param exec [String] the test binary (or wrapper) to execute
172
163
  # @param cmd [String] the command argument passed to the test binary
173
164
  # @param params [Array<String>] extra parameters for the command
174
- # @return [String] executable command string
175
- def go_executable(tools, output, exec, cmd, *params)
176
- Nonnative::GoCommand.new(tools, exec, output).executable(cmd, params)
165
+ # @return [Array<String>] executable argv entries
166
+ def go_executable_args(tools, output, exec, cmd, *params)
167
+ Nonnative::GoCommand.new(tools, exec, output).executable_args(cmd, *params)
177
168
  end
178
169
 
179
170
  # Returns an HTTP client for common health/readiness endpoints.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nonnative
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.15.1
4
+ version: 2.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Falkowski
@@ -288,6 +288,7 @@ files:
288
288
  - lib/nonnative.rb
289
289
  - lib/nonnative/close_all_socket_pair.rb
290
290
  - lib/nonnative/configuration.rb
291
+ - lib/nonnative/configuration_file.rb
291
292
  - lib/nonnative/configuration_process.rb
292
293
  - lib/nonnative/configuration_proxy.rb
293
294
  - lib/nonnative/configuration_runner.rb
@@ -345,7 +346,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
345
346
  - !ruby/object:Gem::Version
346
347
  version: '0'
347
348
  requirements: []
348
- rubygems_version: 4.0.10
349
+ rubygems_version: 4.0.11
349
350
  specification_version: 4
350
351
  summary: Allows you to keep using the power of ruby to test other systems
351
352
  test_files: []