cem_win_spec 0.1.7 → 0.1.9
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/Gemfile.lock +23 -16
- data/exe/cem-win-spec +1 -0
- data/lib/cem_win_spec/logging.rb +1 -1
- data/lib/cem_win_spec/test_runner.rb +11 -14
- data/lib/cem_win_spec/version.rb +1 -1
- data/lib/cem_win_spec/win_exec/cmd/base_cmd.rb +14 -5
- data/lib/cem_win_spec/win_exec/cmd/local_cmd.rb +9 -6
- data/lib/cem_win_spec/win_exec/cmd/winrm_cmd.rb +11 -3
- data/lib/cem_win_spec/win_exec/factory.rb +3 -3
- data/lib/cem_win_spec.rb +46 -9
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b5689dd8fae43d58612457473f06c19baa7e798443f6393c87dda2c84b1a2f4
|
4
|
+
data.tar.gz: 1535bc2325b68cdb08475020b79e1d1d96df40803800e13c5b273cf6e63778f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d58a1f16b67591c42c7566cb102023ab07f5706d0638fc5b2d89cdc4bf1c4d89101779faec8dd864b220b2edd663bd1004e721d5f91db0616af98557ab962ff9
|
7
|
+
data.tar.gz: cafa3f69e03a737e06f840afd92abe2cc8c95d7f83cb8bfa5c043b2656ab59bec868c84467c3da6ee060451bd0515cfe4fc57c8fb21a73c7c15807fb3edc690f
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cem_win_spec (0.1.
|
4
|
+
cem_win_spec (0.1.9)
|
5
5
|
parallel_tests (~> 3.4)
|
6
6
|
puppet_forge (~> 4.1)
|
7
7
|
winrm (~> 2.3)
|
@@ -11,17 +11,20 @@ GEM
|
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
13
|
ast (2.4.2)
|
14
|
-
|
15
|
-
|
14
|
+
base64 (0.2.0)
|
15
|
+
bigdecimal (3.1.8)
|
16
|
+
builder (3.3.0)
|
16
17
|
coderay (1.1.3)
|
17
18
|
diff-lcs (1.5.0)
|
18
|
-
erubi (1.
|
19
|
-
faraday (2.
|
20
|
-
faraday-net_http (>= 2.0, < 3.
|
19
|
+
erubi (1.13.0)
|
20
|
+
faraday (2.12.1)
|
21
|
+
faraday-net_http (>= 2.0, < 3.5)
|
22
|
+
json
|
23
|
+
logger
|
21
24
|
faraday-follow_redirects (0.3.0)
|
22
25
|
faraday (>= 1, < 3)
|
23
|
-
faraday-net_http (3.
|
24
|
-
net-http
|
26
|
+
faraday-net_http (3.4.0)
|
27
|
+
net-http (>= 0.5.0)
|
25
28
|
ffi (1.16.3)
|
26
29
|
gssapi (1.3.1)
|
27
30
|
ffi (>= 1.0.1)
|
@@ -29,16 +32,18 @@ GEM
|
|
29
32
|
builder (>= 2.1.2)
|
30
33
|
rexml (~> 3.0)
|
31
34
|
httpclient (2.8.3)
|
35
|
+
json (2.8.2)
|
32
36
|
little-plugger (1.1.4)
|
33
|
-
|
37
|
+
logger (1.7.0)
|
38
|
+
logging (2.4.0)
|
34
39
|
little-plugger (~> 1.1)
|
35
40
|
multi_json (~> 1.14)
|
36
41
|
method_source (1.0.0)
|
37
|
-
minitar (0.
|
42
|
+
minitar (0.12.1)
|
38
43
|
multi_json (1.15.0)
|
39
|
-
net-http (0.
|
44
|
+
net-http (0.5.0)
|
40
45
|
uri
|
41
|
-
nori (2.7.
|
46
|
+
nori (2.7.1)
|
42
47
|
bigdecimal
|
43
48
|
parallel (1.22.1)
|
44
49
|
parallel_tests (3.13.0)
|
@@ -82,19 +87,21 @@ GEM
|
|
82
87
|
rubocop-ast (1.24.1)
|
83
88
|
parser (>= 3.1.1.0)
|
84
89
|
ruby-progressbar (1.11.0)
|
85
|
-
rubyntlm (0.6.
|
90
|
+
rubyntlm (0.6.5)
|
91
|
+
base64
|
86
92
|
rubyzip (2.3.2)
|
87
93
|
semantic_puppet (1.1.0)
|
88
94
|
unicode-display_width (2.1.0)
|
89
|
-
uri (0.
|
90
|
-
winrm (2.3.
|
95
|
+
uri (1.0.2)
|
96
|
+
winrm (2.3.9)
|
91
97
|
builder (>= 2.1.2)
|
92
98
|
erubi (~> 1.8)
|
93
99
|
gssapi (~> 1.2)
|
94
100
|
gyoku (~> 1.0)
|
95
101
|
httpclient (~> 2.2, >= 2.2.0.2)
|
96
102
|
logging (>= 1.6.1, < 3.0)
|
97
|
-
nori (~> 2.0)
|
103
|
+
nori (~> 2.0, >= 2.7.1)
|
104
|
+
rexml (~> 3.0)
|
98
105
|
rubyntlm (~> 0.6.0, >= 0.6.3)
|
99
106
|
winrm-fs (1.3.5)
|
100
107
|
erubi (~> 1.8)
|
data/exe/cem-win-spec
CHANGED
data/lib/cem_win_spec/logging.rb
CHANGED
@@ -98,13 +98,17 @@ module CemWinSpec
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
def clean_up(
|
102
|
-
@clean_up ||= new_command('Cleanup') do
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
101
|
+
def clean_up(**opts)
|
102
|
+
@clean_up ||= new_command('Cleanup', **opts) do
|
103
|
+
remote_run(
|
104
|
+
[
|
105
|
+
"Get-ChildItem -Path #{remote_working_dir} -Force -Recurse | Remove-Item -Force -Recurse",
|
106
|
+
"Remove-Item #{remote_working_dir} -Force",
|
107
|
+
],
|
108
|
+
ruby_cmd: false,
|
109
|
+
add_envs: false,
|
110
|
+
chdir: false,
|
111
|
+
)
|
108
112
|
end
|
109
113
|
end
|
110
114
|
|
@@ -142,12 +146,5 @@ module CemWinSpec
|
|
142
146
|
end
|
143
147
|
end
|
144
148
|
end
|
145
|
-
|
146
|
-
def cleanup_cmd(working_dir)
|
147
|
-
<<~EOS
|
148
|
-
Get-ChildItem #{working_dir} -Recurse | Remove-Item -Force
|
149
|
-
Remove-Item -Force #{working_dir}
|
150
|
-
EOS
|
151
|
-
end
|
152
149
|
end
|
153
150
|
end
|
data/lib/cem_win_spec/version.rb
CHANGED
@@ -49,6 +49,7 @@ module CemWinSpec
|
|
49
49
|
|
50
50
|
value['PUPPET_GEM_VERSION'] = "~> #{puppet_version}" if puppet_version
|
51
51
|
value['FACTER_GEM_VERSION'] = 'https://github.com/puppetlabs/facter#main' if puppet_version
|
52
|
+
value.delete('password') if value.key?('password')
|
52
53
|
@env_vars = value
|
53
54
|
end
|
54
55
|
|
@@ -69,18 +70,26 @@ module CemWinSpec
|
|
69
70
|
PUPPET_VER_TO_RUBY_VER[puppet_version.split('.')[0]]
|
70
71
|
end
|
71
72
|
|
72
|
-
|
73
|
+
# Formats the command to be run
|
74
|
+
# @param cmd [String, Array[String]] the command to be run
|
75
|
+
# @param ruby_cmd [Boolean] Whether the command is a ruby command and should be ran
|
76
|
+
# in a ruby context. If false, the command will not set up the Uru ruby environment.
|
77
|
+
# @param add_envs [Boolean] Whether to add the environment variables to the command
|
78
|
+
# @param chdir [Boolean] Whether to change the working directory to the working dir
|
79
|
+
# @return [String] the formatted command
|
80
|
+
def command(cmd, ruby_cmd: true, add_envs: true, chdir: true, **_kwargs)
|
81
|
+
cmd = cmd.join(COMMAND_SEPARATOR) if cmd.is_a?(Array)
|
73
82
|
cmd = [cmd]
|
74
|
-
cmd.unshift(change_ruby_version_cmd) if ruby_version # executes third
|
75
|
-
env_vars.each { |k, v| cmd.unshift(set_env_var_cmd(k, v)) } if env_vars.any? # executes second
|
76
|
-
cmd.unshift(change_working_dir_cmd(working_dir)) if working_dir # executes first
|
83
|
+
cmd.unshift(change_ruby_version_cmd) if ruby_cmd && ruby_version # executes third
|
84
|
+
env_vars.each { |k, v| cmd.unshift(set_env_var_cmd(k, v)) } if add_envs && env_vars.any? # executes second
|
85
|
+
cmd.unshift(change_working_dir_cmd(working_dir)) if chdir && working_dir # executes first
|
77
86
|
cmd.join(COMMAND_SEPARATOR)
|
78
87
|
end
|
79
88
|
|
80
89
|
private
|
81
90
|
|
82
91
|
def log_command(cmd)
|
83
|
-
cmd =
|
92
|
+
cmd.gsub!(/\$env:password = "\w+"/, '$env:password = [REDACTED]')
|
84
93
|
logger.debug "Executing command:\n#{cmd.split(%r{\n|\r\n|;\s*}).map { |c| " #> #{c}" }.join("\n")}"
|
85
94
|
end
|
86
95
|
|
@@ -35,9 +35,10 @@ module CemWinSpec
|
|
35
35
|
# This is useful for running commands that should not block the current process
|
36
36
|
# and that you don't need stdout/stderr from.
|
37
37
|
# @param cmd [String] The command to execute
|
38
|
-
def bg_run(cmd, *_args, **
|
38
|
+
def bg_run(cmd, *_args, **kwargs)
|
39
|
+
cmd = command(cmd, **kwargs)
|
39
40
|
log_command(cmd)
|
40
|
-
Process.detach(spawn(
|
41
|
+
Process.detach(spawn())
|
41
42
|
end
|
42
43
|
|
43
44
|
# Execute a command in a new thread. This works by creating a new thread in a thread group
|
@@ -48,20 +49,22 @@ module CemWinSpec
|
|
48
49
|
# Process::Status object.
|
49
50
|
# @param cmd [String] The command to execute
|
50
51
|
# @return [Array] An array of [:threaded, cmd]
|
51
|
-
def thread_run(cmd, *_args, **
|
52
|
+
def thread_run(cmd, *_args, **kwargs)
|
52
53
|
@ran_in_thread = true
|
53
54
|
th = Thread.new do
|
55
|
+
cmd = command(cmd, **kwargs)
|
54
56
|
log_command(cmd)
|
55
|
-
so, se, st = Open3.capture3(
|
57
|
+
so, se, st = Open3.capture3(cmd)
|
56
58
|
@thread_results[cmd] = [so, se, st]
|
57
59
|
end
|
58
60
|
thread_group.add th
|
59
61
|
:threaded
|
60
62
|
end
|
61
63
|
|
62
|
-
def run(cmd, *_args, **
|
64
|
+
def run(cmd, *_args, **kwargs)
|
65
|
+
cmd = command(cmd, **kwargs)
|
63
66
|
log_command(cmd)
|
64
|
-
Open3.capture3(
|
67
|
+
Open3.capture3(cmd)
|
65
68
|
end
|
66
69
|
|
67
70
|
private
|
@@ -21,14 +21,22 @@ module CemWinSpec
|
|
21
21
|
@available
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
# Run a command over WinRM
|
25
|
+
# @param cmd [String] The command to run
|
26
|
+
# @param kwargs [Hash] Additional options for the command
|
27
|
+
# These following options are available:
|
28
|
+
# - :ruby_cmd [Boolean] Whether the command is a ruby command and should be ran
|
29
|
+
# in a ruby context. If false, the command will not set up the Uru ruby environment.
|
30
|
+
# - :add_envs [Boolean] Whether to add the environment variables to the command
|
31
|
+
# - :chdir [Boolean] Whether to change the working directory to the working dir
|
32
|
+
def run(cmd, *_args, **kwargs)
|
33
|
+
cmd = command(cmd, **kwargs)
|
26
34
|
log_command(cmd)
|
27
35
|
shell = nil
|
28
36
|
output = nil
|
29
37
|
begin
|
30
38
|
shell = conn.shell(:powershell)
|
31
|
-
output = shell.run(
|
39
|
+
output = shell.run(cmd) do |stdout, stderr|
|
32
40
|
logger << stdout if stdout
|
33
41
|
logger << stderr if stderr
|
34
42
|
end
|
@@ -35,12 +35,12 @@ module CemWinSpec
|
|
35
35
|
# @return [Exec] An Exec object
|
36
36
|
def build(title, merge: true, user: nil, pass: nil, working_dir: nil, **opts, &block)
|
37
37
|
logger.debug "Building Wexec object for #{title}"
|
38
|
-
build_conn_opts(merge: merge, user: user, pass: pass,
|
38
|
+
build_conn_opts(merge: merge, user: user, pass: pass, **@init_opts.merge(opts))
|
39
39
|
logger.debug 'Created ConnectionOpts'
|
40
40
|
wexec = Exec.new
|
41
41
|
wexec.add_title title
|
42
42
|
wexec.add_local_cmd @current_local_cmd
|
43
|
-
wexec.add_remote_cmd get_remote_cmd(working_dir, **@
|
43
|
+
wexec.add_remote_cmd get_remote_cmd(working_dir, **@current_conn_opts.to_h)
|
44
44
|
wexec.add_iap_tunnel @iap_tunnel
|
45
45
|
wexec.add_ma_builder @ma_builder
|
46
46
|
wexec.add_rspec_test_cmds @rspec_test_cmds
|
@@ -68,7 +68,7 @@ module CemWinSpec
|
|
68
68
|
@current_conn_opts = ConnectionOpts.new(new_host: 'localhost', new_port: @iap_tunnel.port, user: user, pass: pass, **opts)
|
69
69
|
return @current_conn_opts
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
if need_new_conn_opts?(new_host: 'localhost', new_port: @iap_tunnel.port, user: user, pass: pass, **opts)
|
73
73
|
if merge
|
74
74
|
logger.debug 'Merging ConnectionOpts with new options'
|
data/lib/cem_win_spec.rb
CHANGED
@@ -8,16 +8,24 @@ module CemWinSpec
|
|
8
8
|
include CemWinSpec::Logging
|
9
9
|
end
|
10
10
|
|
11
|
+
def self.exit_code
|
12
|
+
@exit_code ||= 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.exit_code=(value)
|
16
|
+
@exit_code = value
|
17
|
+
end
|
18
|
+
|
11
19
|
def self.signal_handler(runner)
|
12
20
|
Signal.trap('INT') do
|
13
|
-
puts 'Caught
|
14
|
-
runner
|
21
|
+
puts 'Caught SIGINT, killing tunnel and exiting'
|
22
|
+
runner&.iap_tunnel&.stop(wait: false, log: false)
|
15
23
|
exit 1
|
16
24
|
end
|
17
25
|
Signal.trap('TERM') do
|
18
|
-
puts 'Caught
|
19
|
-
runner
|
20
|
-
exit
|
26
|
+
puts 'Caught SIGTERM, killing tunnel and exiting'
|
27
|
+
runner&.iap_tunnel&.stop(wait: false, log: false)
|
28
|
+
exit!
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
@@ -38,6 +46,7 @@ module CemWinSpec
|
|
38
46
|
logger.debug "Created TestRunner: #{runner}"
|
39
47
|
signal_handler(runner)
|
40
48
|
logger.debug 'Set up signal handler'
|
49
|
+
working_dir = nil
|
41
50
|
begin
|
42
51
|
sre_out = setup_remote_environment(runner)
|
43
52
|
working_dir = sre_out.stdout.chomp
|
@@ -49,8 +58,12 @@ module CemWinSpec
|
|
49
58
|
case operation
|
50
59
|
when :spec
|
51
60
|
run_spec(runner, module_dir, **options)
|
61
|
+
# We set this to 0 if the tests pass because this can be set to 1 earlier by commands that fail and retry.
|
62
|
+
self.exit_code = 0
|
52
63
|
when :clean_fixture_cache
|
53
64
|
clean_fixture_cache(runner, module_dir, **options)
|
65
|
+
# We set this to 0 if the tests pass because this can be set to 1 earlier by commands that fail and retry.
|
66
|
+
self.exit_code = 0
|
54
67
|
else
|
55
68
|
raise ArgumentError, "Unknown operation: #{operation}"
|
56
69
|
end
|
@@ -67,15 +80,24 @@ module CemWinSpec
|
|
67
80
|
handle_run_error(e)
|
68
81
|
end
|
69
82
|
ensure
|
70
|
-
|
71
|
-
|
83
|
+
if working_dir
|
84
|
+
begin
|
85
|
+
logger.info "Cleaning up working directory #{working_dir}"
|
86
|
+
clean_up(runner, working_dir, **options)
|
87
|
+
logger.debug 'Finished cleaning up working directory'
|
88
|
+
rescue StandardError => e
|
89
|
+
handle_run_error(e)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
runner&.iap_tunnel&.stop(log: false)
|
93
|
+
logger.info 'Finished running cem-win-spec'
|
72
94
|
end
|
73
95
|
end
|
74
96
|
|
75
97
|
def self.handle_run_error(err)
|
76
98
|
logger.fatal "Error: #{err.message}"
|
77
99
|
logger.debug err.backtrace.join("\n")
|
78
|
-
|
100
|
+
self.exit_code = 1
|
79
101
|
end
|
80
102
|
|
81
103
|
def self.retry_spec_on_error(runner, module_dir, **options)
|
@@ -126,6 +148,21 @@ module CemWinSpec
|
|
126
148
|
reuse_tunnel: false,
|
127
149
|
**opts).run
|
128
150
|
end
|
151
|
+
if output.stderr&.include?('Tests Failed')
|
152
|
+
logger.error 'Tests failed'
|
153
|
+
self.exit_code = 1
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Clean up the remote working directory
|
158
|
+
# @param options [Hash] Options for the test runner
|
159
|
+
def self.clean_up(runner, working_dir, **opts)
|
160
|
+
validate_output do
|
161
|
+
runner.clean_up(operation_timeout: 300,
|
162
|
+
receive_timeout: 310,
|
163
|
+
working_dir: working_dir,
|
164
|
+
**opts).run
|
165
|
+
end
|
129
166
|
end
|
130
167
|
|
131
168
|
# Clean the remote fixture cache
|
@@ -164,7 +201,7 @@ module CemWinSpec
|
|
164
201
|
end
|
165
202
|
|
166
203
|
unless output.send(validation_method)
|
167
|
-
raise CemWinSpecValidationError, "Output validation \"#{validation_method}\" failed
|
204
|
+
raise CemWinSpecValidationError, "Output validation \"#{validation_method}\" failed:\n#{output}"
|
168
205
|
end
|
169
206
|
output
|
170
207
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cem_win_spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heston Snodgrass
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: winrm
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
142
|
+
rubygems_version: 3.5.18
|
143
143
|
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: Write a short summary, because RubyGems requires one.
|