nonnative 2.16.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 +4 -4
- data/.circleci/config.yml +2 -2
- data/AGENTS.md +4 -1
- data/Gemfile.lock +1 -1
- data/README.md +56 -38
- data/lib/nonnative/configuration.rb +5 -4
- data/lib/nonnative/configuration_file.rb +33 -0
- data/lib/nonnative/configuration_process.rb +12 -2
- data/lib/nonnative/configuration_proxy.rb +3 -3
- data/lib/nonnative/configuration_runner.rb +3 -3
- data/lib/nonnative/go_command.rb +17 -12
- data/lib/nonnative/process.rb +3 -3
- data/lib/nonnative/version.rb +1 -1
- data/lib/nonnative.rb +7 -15
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08e1e5b760ed902c52e55ef0694bddeb1e36580891ab9a778767a04ea02b1d9c'
|
|
4
|
+
data.tar.gz: d632a3b8047ebada176e3db071caada192b87d8c255d6beb0e14a1010874103f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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.
|
|
61
|
+
- image: alexfalkowski/ruby:3.9
|
|
62
62
|
steps:
|
|
63
63
|
- run: echo "all applicable jobs finished"
|
|
64
64
|
resource_class: arm.large
|
data/AGENTS.md
CHANGED
|
@@ -79,6 +79,9 @@ Fault-injection states: `none`, `close_all`, `delay`, `invalid_data`.
|
|
|
79
79
|
|
|
80
80
|
Config rules:
|
|
81
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
|
|
82
85
|
- YAML services belong under `services:`, not `processes:`
|
|
83
86
|
- There is no top-level `config.wait`; `wait` is per runner
|
|
84
87
|
- Programmatic service config uses `config.service do |s| ... end`, so use `s.host` / `s.port`
|
|
@@ -107,4 +110,4 @@ Limitations:
|
|
|
107
110
|
- Process lifecycle: `lib/nonnative/process.rb`
|
|
108
111
|
- Proxies: `lib/nonnative/fault_injection_proxy.rb`, `lib/nonnative/socket_pair_factory.rb`
|
|
109
112
|
- Cucumber: `lib/nonnative/cucumber.rb`, `lib/nonnative/startup.rb`, `features/support/env.rb`
|
|
110
|
-
- 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
data/README.md
CHANGED
|
@@ -37,7 +37,9 @@ gem install nonnative
|
|
|
37
37
|
|
|
38
38
|
## Usage
|
|
39
39
|
|
|
40
|
-
Nonnative is configured via
|
|
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"`).
|
|
@@ -48,13 +50,16 @@ High-level configuration fields:
|
|
|
48
50
|
- `servers`: in-process Ruby servers started in threads.
|
|
49
51
|
- `services`: external dependencies (proxy-only; no process/thread started by Nonnative).
|
|
50
52
|
|
|
51
|
-
|
|
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:
|
|
52
58
|
- `timeout`: max time (seconds) for readiness/shutdown port checks.
|
|
53
59
|
- `wait`: small sleep (seconds) between lifecycle steps.
|
|
54
|
-
- `
|
|
55
|
-
- `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.
|
|
56
61
|
|
|
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`.
|
|
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`.
|
|
58
63
|
|
|
59
64
|
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.
|
|
60
65
|
|
|
@@ -90,8 +95,10 @@ This calls `Nonnative.start` immediately and registers an `at_exit` stop.
|
|
|
90
95
|
### Processes
|
|
91
96
|
|
|
92
97
|
A process is some sort of command that you would run locally.
|
|
98
|
+
Commands can be strings or argv arrays. String commands preserve legacy shell semantics, while argv arrays
|
|
99
|
+
avoid shell interpretation and are preferred for new configuration.
|
|
93
100
|
|
|
94
|
-
|
|
101
|
+
Set it up programmatically:
|
|
95
102
|
|
|
96
103
|
```ruby
|
|
97
104
|
require 'nonnative'
|
|
@@ -104,7 +111,7 @@ Nonnative.configure do |config|
|
|
|
104
111
|
|
|
105
112
|
config.process do |p|
|
|
106
113
|
p.name = 'start_1'
|
|
107
|
-
p.command = -> { 'features/support/bin/start 12_321' }
|
|
114
|
+
p.command = -> { ['features/support/bin/start', '12_321'] }
|
|
108
115
|
p.timeout = 5
|
|
109
116
|
p.wait = 0.1
|
|
110
117
|
p.port = 12_321
|
|
@@ -117,7 +124,7 @@ Nonnative.configure do |config|
|
|
|
117
124
|
|
|
118
125
|
config.process do |p|
|
|
119
126
|
p.name = 'start_2'
|
|
120
|
-
p.command = -> { 'features/support/bin/start 12_322' }
|
|
127
|
+
p.command = -> { ['features/support/bin/start', '12_322'] }
|
|
121
128
|
p.timeout = 0.5
|
|
122
129
|
p.wait = 0.1
|
|
123
130
|
p.port = 12_322
|
|
@@ -126,7 +133,7 @@ Nonnative.configure do |config|
|
|
|
126
133
|
end
|
|
127
134
|
```
|
|
128
135
|
|
|
129
|
-
|
|
136
|
+
Set it up through configuration:
|
|
130
137
|
|
|
131
138
|
```yaml
|
|
132
139
|
version: "1.0"
|
|
@@ -136,7 +143,9 @@ log: nonnative.log
|
|
|
136
143
|
processes:
|
|
137
144
|
-
|
|
138
145
|
name: start_1
|
|
139
|
-
command:
|
|
146
|
+
command:
|
|
147
|
+
- features/support/bin/start
|
|
148
|
+
- "12_321"
|
|
140
149
|
timeout: 5
|
|
141
150
|
wait: 1
|
|
142
151
|
port: 12321
|
|
@@ -146,7 +155,9 @@ processes:
|
|
|
146
155
|
TEST: true
|
|
147
156
|
-
|
|
148
157
|
name: start_2
|
|
149
|
-
command:
|
|
158
|
+
command:
|
|
159
|
+
- features/support/bin/start
|
|
160
|
+
- "12_322"
|
|
150
161
|
timeout: 5
|
|
151
162
|
wait: 1
|
|
152
163
|
port: 12322
|
|
@@ -205,7 +216,7 @@ module Nonnative
|
|
|
205
216
|
end
|
|
206
217
|
```
|
|
207
218
|
|
|
208
|
-
|
|
219
|
+
Set it up programmatically:
|
|
209
220
|
|
|
210
221
|
```ruby
|
|
211
222
|
require 'nonnative'
|
|
@@ -218,7 +229,7 @@ Nonnative.configure do |config|
|
|
|
218
229
|
|
|
219
230
|
config.server do |s|
|
|
220
231
|
s.name = 'server_1'
|
|
221
|
-
s.klass = Nonnative::
|
|
232
|
+
s.klass = Nonnative::TCPServer
|
|
222
233
|
s.timeout = 1
|
|
223
234
|
s.port = 12_323
|
|
224
235
|
s.log = 'server_1.log'
|
|
@@ -226,7 +237,7 @@ Nonnative.configure do |config|
|
|
|
226
237
|
|
|
227
238
|
config.server do |s|
|
|
228
239
|
s.name = 'server_2'
|
|
229
|
-
s.klass = Nonnative::
|
|
240
|
+
s.klass = Nonnative::TCPServer
|
|
230
241
|
s.timeout = 1
|
|
231
242
|
s.port = 12_324
|
|
232
243
|
s.log = 'server_2.log'
|
|
@@ -234,7 +245,7 @@ Nonnative.configure do |config|
|
|
|
234
245
|
end
|
|
235
246
|
```
|
|
236
247
|
|
|
237
|
-
|
|
248
|
+
Set it up through configuration:
|
|
238
249
|
|
|
239
250
|
```yaml
|
|
240
251
|
version: "1.0"
|
|
@@ -244,13 +255,13 @@ log: nonnative.log
|
|
|
244
255
|
servers:
|
|
245
256
|
-
|
|
246
257
|
name: server_1
|
|
247
|
-
class: Nonnative::
|
|
258
|
+
class: Nonnative::TCPServer
|
|
248
259
|
timeout: 1
|
|
249
260
|
port: 12323
|
|
250
261
|
log: server_1.log
|
|
251
262
|
-
|
|
252
263
|
name: server_2
|
|
253
|
-
class: Nonnative::
|
|
264
|
+
class: Nonnative::TCPServer
|
|
254
265
|
timeout: 1
|
|
255
266
|
port: 12324
|
|
256
267
|
log: server_2.log
|
|
@@ -288,7 +299,7 @@ module Nonnative
|
|
|
288
299
|
end
|
|
289
300
|
```
|
|
290
301
|
|
|
291
|
-
|
|
302
|
+
Set it up programmatically:
|
|
292
303
|
|
|
293
304
|
```ruby
|
|
294
305
|
require 'nonnative'
|
|
@@ -309,7 +320,7 @@ Nonnative.configure do |config|
|
|
|
309
320
|
end
|
|
310
321
|
```
|
|
311
322
|
|
|
312
|
-
|
|
323
|
+
Set it up through configuration:
|
|
313
324
|
|
|
314
325
|
```yaml
|
|
315
326
|
version: "1.0"
|
|
@@ -353,7 +364,7 @@ module Nonnative
|
|
|
353
364
|
end
|
|
354
365
|
```
|
|
355
366
|
|
|
356
|
-
|
|
367
|
+
Set it up programmatically:
|
|
357
368
|
|
|
358
369
|
```ruby
|
|
359
370
|
require 'nonnative'
|
|
@@ -374,7 +385,7 @@ Nonnative.configure do |config|
|
|
|
374
385
|
end
|
|
375
386
|
```
|
|
376
387
|
|
|
377
|
-
|
|
388
|
+
Set it up through configuration:
|
|
378
389
|
|
|
379
390
|
```yaml
|
|
380
391
|
version: "1.0"
|
|
@@ -422,7 +433,7 @@ module Nonnative
|
|
|
422
433
|
end
|
|
423
434
|
```
|
|
424
435
|
|
|
425
|
-
|
|
436
|
+
Set it up programmatically:
|
|
426
437
|
|
|
427
438
|
```ruby
|
|
428
439
|
require 'nonnative'
|
|
@@ -443,7 +454,7 @@ Nonnative.configure do |config|
|
|
|
443
454
|
end
|
|
444
455
|
```
|
|
445
456
|
|
|
446
|
-
|
|
457
|
+
Set it up through configuration:
|
|
447
458
|
|
|
448
459
|
```yaml
|
|
449
460
|
version: "1.0"
|
|
@@ -705,7 +716,7 @@ Clients connect to the runner `host`/`port`, while the proxy forwards traffic to
|
|
|
705
716
|
|
|
706
717
|
###### Fault Injection Processes
|
|
707
718
|
|
|
708
|
-
|
|
719
|
+
Set it up programmatically:
|
|
709
720
|
|
|
710
721
|
```ruby
|
|
711
722
|
name = 'name of process in configuration'
|
|
@@ -724,7 +735,7 @@ Then I should reset the proxy for process 'process_1'
|
|
|
724
735
|
|
|
725
736
|
###### Fault Injection Servers
|
|
726
737
|
|
|
727
|
-
|
|
738
|
+
Set it up programmatically:
|
|
728
739
|
|
|
729
740
|
```ruby
|
|
730
741
|
name = 'name of server in configuration'
|
|
@@ -743,7 +754,7 @@ Then I should reset the proxy for server 'server_1'
|
|
|
743
754
|
|
|
744
755
|
###### Fault Injection Services
|
|
745
756
|
|
|
746
|
-
|
|
757
|
+
Set it up programmatically:
|
|
747
758
|
|
|
748
759
|
```ruby
|
|
749
760
|
name = 'name of service in configuration'
|
|
@@ -762,11 +773,26 @@ Then I should reset the proxy for service 'service_1'
|
|
|
762
773
|
|
|
763
774
|
### Go
|
|
764
775
|
|
|
765
|
-
As we love using
|
|
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.
|
|
766
791
|
|
|
767
792
|
To get this to work you will need to create a `main_test.go` file with these contents:
|
|
768
793
|
|
|
769
794
|
```go
|
|
795
|
+
//go:build features
|
|
770
796
|
// +build features
|
|
771
797
|
|
|
772
798
|
package main
|
|
@@ -774,7 +800,7 @@ package main
|
|
|
774
800
|
import "testing"
|
|
775
801
|
|
|
776
802
|
func TestFeatures(t *testing.T) {
|
|
777
|
-
|
|
803
|
+
main()
|
|
778
804
|
}
|
|
779
805
|
```
|
|
780
806
|
|
|
@@ -784,15 +810,7 @@ Then to compile this binary you will need to do the following:
|
|
|
784
810
|
go test -mod vendor -c -tags features -covermode=count -o your_binary -coverpkg=./... github.com/your_location
|
|
785
811
|
```
|
|
786
812
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
```ruby
|
|
790
|
-
tools = %w[prof trace cover]
|
|
791
|
-
|
|
792
|
-
Nonnative.go_executable(tools, 'reports', 'your_binary', 'sub_command', '--config config.yaml')
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
Setup it up through configuration:
|
|
813
|
+
Set it up through configuration:
|
|
796
814
|
|
|
797
815
|
```yaml
|
|
798
816
|
version: "1.0"
|
|
@@ -808,7 +826,7 @@ processes:
|
|
|
808
826
|
executable: your_binary
|
|
809
827
|
command: sub_command
|
|
810
828
|
parameters:
|
|
811
|
-
-
|
|
829
|
+
- "-i file:.config/server.yml"
|
|
812
830
|
timeout: 5
|
|
813
831
|
port: 8000
|
|
814
832
|
log: go.log
|
|
@@ -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
|
|
56
|
-
#
|
|
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.
|
|
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.
|
|
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
|
|
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 :
|
|
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 `"
|
|
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`: `"
|
|
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 = '
|
|
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 `"
|
|
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`: `"
|
|
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 = '
|
|
40
|
+
self.host = '127.0.0.1'
|
|
41
41
|
self.port = 0
|
|
42
42
|
self.wait = 0.1
|
|
43
43
|
|
data/lib/nonnative/go_command.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Nonnative
|
|
4
|
-
# Builds
|
|
4
|
+
# Builds commands for running a Go test binary with optional profiling/trace/coverage flags.
|
|
5
5
|
#
|
|
6
|
-
# This helper is used by
|
|
7
|
-
#
|
|
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`.
|
|
@@ -19,12 +19,14 @@ 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
|
-
# cmd.
|
|
25
|
-
# # => "./svc.test -test.cpuprofile=... -test.coverprofile=... serve --config config.yaml"
|
|
26
|
+
# cmd.executable_args('serve', '--config', 'config.yaml')
|
|
27
|
+
# # => ["./svc.test", "-test.cpuprofile=...", "-test.coverprofile=...", "serve", "--config", "config.yaml"]
|
|
26
28
|
#
|
|
27
|
-
# @see Nonnative.
|
|
29
|
+
# @see Nonnative.go_executable_args
|
|
28
30
|
class GoCommand
|
|
29
31
|
# @param tools [Array<String>, nil] tool names to enable (see class docs)
|
|
30
32
|
# @param exec [String] path to the compiled Go test binary
|
|
@@ -35,22 +37,25 @@ module Nonnative
|
|
|
35
37
|
@output = output
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
# Returns an executable
|
|
40
|
+
# Returns an executable argv array including enabled `-test.*` flags.
|
|
39
41
|
#
|
|
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
|
|
44
|
-
# @return [String]
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
"#{exec} #{flags(cmd).join(' ')} #{cmd} #{params}".strip
|
|
45
|
+
# @param params [Array<String>] additional parameter strings passed after `cmd`
|
|
46
|
+
# @return [Array<String>] argv entries to execute
|
|
47
|
+
def executable_args(cmd, *params)
|
|
48
|
+
[exec, *flags(cmd), cmd, *parameter_args(params)]
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
private
|
|
51
52
|
|
|
52
53
|
attr_reader :tools, :exec, :output
|
|
53
54
|
|
|
55
|
+
def parameter_args(params)
|
|
56
|
+
params.flatten.compact.flat_map { |p| Shellwords.split(p.to_s) }
|
|
57
|
+
end
|
|
58
|
+
|
|
54
59
|
def flags(cmd)
|
|
55
60
|
suffix = SecureRandom.alphanumeric(4)
|
|
56
61
|
m = File.basename(exec, File.extname(exec))
|
data/lib/nonnative/process.rb
CHANGED
|
@@ -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
|
|
data/lib/nonnative/version.rb
CHANGED
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'
|
|
@@ -67,6 +68,7 @@ require 'nonnative/stop_error'
|
|
|
67
68
|
require 'nonnative/not_found_error'
|
|
68
69
|
require 'nonnative/timeout'
|
|
69
70
|
require 'nonnative/port'
|
|
71
|
+
require 'nonnative/configuration_file'
|
|
70
72
|
require 'nonnative/configuration'
|
|
71
73
|
require 'nonnative/configuration_runner'
|
|
72
74
|
require 'nonnative/configuration_process'
|
|
@@ -113,16 +115,6 @@ module Nonnative
|
|
|
113
115
|
# @return [Nonnative::Pool, nil] the pool instance, or `nil` if not started yet
|
|
114
116
|
attr_accessor :pool
|
|
115
117
|
|
|
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
118
|
# Returns the current configuration (memoized).
|
|
127
119
|
#
|
|
128
120
|
# @return [Nonnative::Configuration]
|
|
@@ -162,7 +154,7 @@ module Nonnative
|
|
|
162
154
|
File.readlines(path).select { |l| predicate.call(l) }
|
|
163
155
|
end
|
|
164
156
|
|
|
165
|
-
# Builds a Go test executable
|
|
157
|
+
# Builds a Go test executable argv array with optional profiling/trace/coverage flags.
|
|
166
158
|
#
|
|
167
159
|
# This is used when process configuration specifies a `go` section.
|
|
168
160
|
#
|
|
@@ -170,10 +162,10 @@ module Nonnative
|
|
|
170
162
|
# @param output [String] directory where outputs should be written
|
|
171
163
|
# @param exec [String] the test binary (or wrapper) to execute
|
|
172
164
|
# @param cmd [String] the command argument passed to the test binary
|
|
173
|
-
# @param params [Array<String>] extra
|
|
174
|
-
# @return [String] executable
|
|
175
|
-
def
|
|
176
|
-
Nonnative::GoCommand.new(tools, exec, output).
|
|
165
|
+
# @param params [Array<String>] extra parameter strings for the command
|
|
166
|
+
# @return [Array<String>] executable argv entries
|
|
167
|
+
def go_executable_args(tools, output, exec, cmd, *params)
|
|
168
|
+
Nonnative::GoCommand.new(tools, exec, output).executable_args(cmd, *params)
|
|
177
169
|
end
|
|
178
170
|
|
|
179
171
|
# 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.
|
|
4
|
+
version: 2.19.1
|
|
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
|