nonnative 2.19.0 → 2.19.1

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: e83e6a409c77b42f73d52473d360f136255a62f5227bb08b770d129082ccd69b
4
- data.tar.gz: f2cb0c6bf4b4bcfa7a9ab95851735b987b16ab180aa4ff9278e334e473863aca
3
+ metadata.gz: '08e1e5b760ed902c52e55ef0694bddeb1e36580891ab9a778767a04ea02b1d9c'
4
+ data.tar.gz: d632a3b8047ebada176e3db071caada192b87d8c255d6beb0e14a1010874103f
5
5
  SHA512:
6
- metadata.gz: e282a3e79b1319d47154ffac90b305ef5344eb78d9f960e30b3d6a851303f1b736b2f0456e24816a8459db9b5368f4e90d10777fd385e26da3748ac7a894f29f
7
- data.tar.gz: 10b38f3e4b0d3d279add988ae32af3c60990715b1fa0c96e94efa6adad29b6f86868b243d2d000e0005815c1c80c4c28a79889a105ef0cf265555b80e4b60b39
6
+ metadata.gz: bfeba487e42d817e967c0a1cfe0814e5fc75c4d360399dcbd0caaf6ddef83c11efb8a4aff8ffe58ee6566be138b3b85e146e5ffe44dc431e734cf22544956019
7
+ data.tar.gz: 268c3d360f3d23b18a69317cbe656b06d24b8f94799c245108e94e5e269ac852c000d74d3427168fd2ad5b2c56ea24a3bb21e1507c77d9e4cce713fac4b57a3b
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:3.8
6
+ - image: alexfalkowski/ruby:3.9
7
7
  working_directory: ~/nonnative
8
8
  steps:
9
9
  - checkout:
@@ -58,7 +58,7 @@ jobs:
58
58
  resource_class: arm.large
59
59
  wait-all:
60
60
  docker:
61
- - image: alexfalkowski/ruby:3.8
61
+ - image: alexfalkowski/ruby:3.9
62
62
  steps:
63
63
  - run: echo "all applicable jobs finished"
64
64
  resource_class: arm.large
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nonnative (2.19.0)
4
+ nonnative (2.19.1)
5
5
  concurrent-ruby (>= 1, < 2)
6
6
  config (>= 5, < 6)
7
7
  cucumber (>= 7, < 12)
data/README.md CHANGED
@@ -37,7 +37,7 @@ gem install nonnative
37
37
 
38
38
  ## Usage
39
39
 
40
- Nonnative is configured via {#Nonnative.configure} (programmatic) or `config.load_file(...)` (YAML).
40
+ Nonnative is configured via `Nonnative.configure` (programmatic) or `config.load_file(...)` (YAML).
41
41
  YAML configuration is loaded as data only: ERB is not evaluated and arbitrary Ruby objects are not
42
42
  deserialized.
43
43
 
@@ -50,11 +50,14 @@ High-level configuration fields:
50
50
  - `servers`: in-process Ruby servers started in threads.
51
51
  - `services`: external dependencies (proxy-only; no process/thread started by Nonnative).
52
52
 
53
- Runner fields (process/server/service):
53
+ Common runner fields:
54
+ - `name`: runner name used for lookup.
55
+ - `host`/`port`: client-facing address. `host` defaults to `127.0.0.1`. For processes and servers, this address is also used for readiness/shutdown port checks. When a `fault_injection` proxy is enabled, this is the endpoint your tests/clients should hit.
56
+
57
+ Process/server fields:
54
58
  - `timeout`: max time (seconds) for readiness/shutdown port checks.
55
59
  - `wait`: small sleep (seconds) between lifecycle steps.
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.
57
- - `log`: per-runner log file (used by process output redirection or server implementations).
60
+ - `log`: per-runner log file used by process output redirection or server implementations.
58
61
 
59
62
  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
63
 
@@ -95,7 +98,7 @@ A process is some sort of command that you would run locally.
95
98
  Commands can be strings or argv arrays. String commands preserve legacy shell semantics, while argv arrays
96
99
  avoid shell interpretation and are preferred for new configuration.
97
100
 
98
- Setup it up programmatically:
101
+ Set it up programmatically:
99
102
 
100
103
  ```ruby
101
104
  require 'nonnative'
@@ -121,7 +124,7 @@ Nonnative.configure do |config|
121
124
 
122
125
  config.process do |p|
123
126
  p.name = 'start_2'
124
- p.command = -> { 'features/support/bin/start 12_322' }
127
+ p.command = -> { ['features/support/bin/start', '12_322'] }
125
128
  p.timeout = 0.5
126
129
  p.wait = 0.1
127
130
  p.port = 12_322
@@ -130,7 +133,7 @@ Nonnative.configure do |config|
130
133
  end
131
134
  ```
132
135
 
133
- Setup it up through configuration:
136
+ Set it up through configuration:
134
137
 
135
138
  ```yaml
136
139
  version: "1.0"
@@ -152,7 +155,9 @@ processes:
152
155
  TEST: true
153
156
  -
154
157
  name: start_2
155
- command: features/support/bin/start 12_322
158
+ command:
159
+ - features/support/bin/start
160
+ - "12_322"
156
161
  timeout: 5
157
162
  wait: 1
158
163
  port: 12322
@@ -211,7 +216,7 @@ module Nonnative
211
216
  end
212
217
  ```
213
218
 
214
- Setup it up programmatically:
219
+ Set it up programmatically:
215
220
 
216
221
  ```ruby
217
222
  require 'nonnative'
@@ -224,7 +229,7 @@ Nonnative.configure do |config|
224
229
 
225
230
  config.server do |s|
226
231
  s.name = 'server_1'
227
- s.klass = Nonnative::EchoServer
232
+ s.klass = Nonnative::TCPServer
228
233
  s.timeout = 1
229
234
  s.port = 12_323
230
235
  s.log = 'server_1.log'
@@ -232,7 +237,7 @@ Nonnative.configure do |config|
232
237
 
233
238
  config.server do |s|
234
239
  s.name = 'server_2'
235
- s.klass = Nonnative::EchoServer
240
+ s.klass = Nonnative::TCPServer
236
241
  s.timeout = 1
237
242
  s.port = 12_324
238
243
  s.log = 'server_2.log'
@@ -240,7 +245,7 @@ Nonnative.configure do |config|
240
245
  end
241
246
  ```
242
247
 
243
- Setup it up through configuration:
248
+ Set it up through configuration:
244
249
 
245
250
  ```yaml
246
251
  version: "1.0"
@@ -250,13 +255,13 @@ log: nonnative.log
250
255
  servers:
251
256
  -
252
257
  name: server_1
253
- class: Nonnative::EchoServer
258
+ class: Nonnative::TCPServer
254
259
  timeout: 1
255
260
  port: 12323
256
261
  log: server_1.log
257
262
  -
258
263
  name: server_2
259
- class: Nonnative::EchoServer
264
+ class: Nonnative::TCPServer
260
265
  timeout: 1
261
266
  port: 12324
262
267
  log: server_2.log
@@ -294,7 +299,7 @@ module Nonnative
294
299
  end
295
300
  ```
296
301
 
297
- Setup it up programmatically:
302
+ Set it up programmatically:
298
303
 
299
304
  ```ruby
300
305
  require 'nonnative'
@@ -315,7 +320,7 @@ Nonnative.configure do |config|
315
320
  end
316
321
  ```
317
322
 
318
- Setup it up through configuration:
323
+ Set it up through configuration:
319
324
 
320
325
  ```yaml
321
326
  version: "1.0"
@@ -359,7 +364,7 @@ module Nonnative
359
364
  end
360
365
  ```
361
366
 
362
- Setup it up programmatically:
367
+ Set it up programmatically:
363
368
 
364
369
  ```ruby
365
370
  require 'nonnative'
@@ -380,7 +385,7 @@ Nonnative.configure do |config|
380
385
  end
381
386
  ```
382
387
 
383
- Setup it up through configuration:
388
+ Set it up through configuration:
384
389
 
385
390
  ```yaml
386
391
  version: "1.0"
@@ -428,7 +433,7 @@ module Nonnative
428
433
  end
429
434
  ```
430
435
 
431
- Setup it up programmatically:
436
+ Set it up programmatically:
432
437
 
433
438
  ```ruby
434
439
  require 'nonnative'
@@ -449,7 +454,7 @@ Nonnative.configure do |config|
449
454
  end
450
455
  ```
451
456
 
452
- Setup it up through configuration:
457
+ Set it up through configuration:
453
458
 
454
459
  ```yaml
455
460
  version: "1.0"
@@ -711,7 +716,7 @@ Clients connect to the runner `host`/`port`, while the proxy forwards traffic to
711
716
 
712
717
  ###### Fault Injection Processes
713
718
 
714
- Setup it up programmatically:
719
+ Set it up programmatically:
715
720
 
716
721
  ```ruby
717
722
  name = 'name of process in configuration'
@@ -730,7 +735,7 @@ Then I should reset the proxy for process 'process_1'
730
735
 
731
736
  ###### Fault Injection Servers
732
737
 
733
- Setup it up programmatically:
738
+ Set it up programmatically:
734
739
 
735
740
  ```ruby
736
741
  name = 'name of server in configuration'
@@ -749,7 +754,7 @@ Then I should reset the proxy for server 'server_1'
749
754
 
750
755
  ###### Fault Injection Services
751
756
 
752
- Setup it up programmatically:
757
+ Set it up programmatically:
753
758
 
754
759
  ```ruby
755
760
  name = 'name of service in configuration'
@@ -768,11 +773,26 @@ Then I should reset the proxy for service 'service_1'
768
773
 
769
774
  ### Go
770
775
 
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.
776
+ As we love using Go as a language for services we have added support to start binaries with defined parameters.
777
+
778
+ Programmatic Go binaries can be configured as normal argv process commands:
779
+
780
+ ```ruby
781
+ Nonnative.configure do |config|
782
+ config.process do |p|
783
+ p.name = 'go'
784
+ p.command = -> { ['your_binary', 'sub_command', '--config', 'config.yaml'] }
785
+ p.port = 12_345
786
+ end
787
+ end
788
+ ```
789
+
790
+ YAML `go:` configuration is for Go test binaries compiled with `go test -c`. It builds argv entries in this order: executable, optional `-test.*` profiling/trace/coverage flags, command, then parameters. Parameter strings are parsed into argv words with shell-style quoting, but the argv entries are executed without shell interpretation.
772
791
 
773
792
  To get this to work you will need to create a `main_test.go` file with these contents:
774
793
 
775
794
  ```go
795
+ //go:build features
776
796
  // +build features
777
797
 
778
798
  package main
@@ -780,7 +800,7 @@ package main
780
800
  import "testing"
781
801
 
782
802
  func TestFeatures(t *testing.T) {
783
- main()
803
+ main()
784
804
  }
785
805
  ```
786
806
 
@@ -790,19 +810,7 @@ Then to compile this binary you will need to do the following:
790
810
  go test -mod vendor -c -tags features -covermode=count -o your_binary -coverpkg=./... github.com/your_location
791
811
  ```
792
812
 
793
- Setup it up programmatically as an argv process command:
794
-
795
- ```ruby
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
803
- ```
804
-
805
- Setup it up through configuration:
813
+ Set it up through configuration:
806
814
 
807
815
  ```yaml
808
816
  version: "1.0"
@@ -818,7 +826,7 @@ processes:
818
826
  executable: your_binary
819
827
  command: sub_command
820
828
  parameters:
821
- - --config config.yaml
829
+ - "-i file:.config/server.yml"
822
830
  timeout: 5
823
831
  port: 8000
824
832
  log: go.log
@@ -19,6 +19,8 @@ module Nonnative
19
19
  #
20
20
  # If `tools` is `nil` or empty, all tools (`prof`, `trace`, `cover`) are enabled.
21
21
  #
22
+ # Parameter strings are parsed into argv words using shell-style quoting, then executed without a shell.
23
+ #
22
24
  # @example
23
25
  # cmd = Nonnative::GoCommand.new(%w[prof cover], './svc.test', 'reports')
24
26
  # cmd.executable_args('serve', '--config', 'config.yaml')
@@ -40,16 +42,20 @@ module Nonnative
40
42
  # A short random suffix is appended to output filenames to reduce collisions across runs.
41
43
  #
42
44
  # @param cmd [String] command/sub-command argument passed to the Go test binary
43
- # @param params [Array<String>] additional parameters passed after `cmd`
45
+ # @param params [Array<String>] additional parameter strings passed after `cmd`
44
46
  # @return [Array<String>] argv entries to execute
45
47
  def executable_args(cmd, *params)
46
- [exec, *flags(cmd), cmd, *params.flatten.compact.map(&:to_s)]
48
+ [exec, *flags(cmd), cmd, *parameter_args(params)]
47
49
  end
48
50
 
49
51
  private
50
52
 
51
53
  attr_reader :tools, :exec, :output
52
54
 
55
+ def parameter_args(params)
56
+ params.flatten.compact.flat_map { |p| Shellwords.split(p.to_s) }
57
+ end
58
+
53
59
  def flags(cmd)
54
60
  suffix = SecureRandom.alphanumeric(4)
55
61
  m = File.basename(exec, File.extname(exec))
@@ -4,5 +4,5 @@ module Nonnative
4
4
  # The current gem version.
5
5
  #
6
6
  # @return [String]
7
- VERSION = '2.19.0'
7
+ VERSION = '2.19.1'
8
8
  end
data/lib/nonnative.rb CHANGED
@@ -46,6 +46,7 @@ require 'timeout'
46
46
  require 'yaml'
47
47
  require 'open3'
48
48
  require 'securerandom'
49
+ require 'shellwords'
49
50
 
50
51
  require 'grpc'
51
52
  require 'sinatra'
@@ -161,7 +162,7 @@ module Nonnative
161
162
  # @param output [String] directory where outputs should be written
162
163
  # @param exec [String] the test binary (or wrapper) to execute
163
164
  # @param cmd [String] the command argument passed to the test binary
164
- # @param params [Array<String>] extra parameters for the command
165
+ # @param params [Array<String>] extra parameter strings for the command
165
166
  # @return [Array<String>] executable argv entries
166
167
  def go_executable_args(tools, output, exec, cmd, *params)
167
168
  Nonnative::GoCommand.new(tools, exec, output).executable_args(cmd, *params)
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.19.0
4
+ version: 2.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alejandro Falkowski