cem_win_spec 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f80bb9bd51e4ad8a8d005504e107a6c7761a4f8c63da2fe2df69f84e1afb1b4
4
- data.tar.gz: 6eb10d5243db33711faa2b8f21914e05f3ce16cc6514ae6add15159f03c53266
3
+ metadata.gz: 000454f69f3ea2722dcd11ec105a5ebe617301d076a2c1772cb530d8275e0f11
4
+ data.tar.gz: 1d2635cc5f330baa755482c5738901e2e79aeabd585200db5ee0ef218cd9decf
5
5
  SHA512:
6
- metadata.gz: 3203c1ce68eb0c392c3968b82cf80066023545b1a4522d415b1f199538bdfd7cef34c4b2e4c8bd154ddec5e95fe5fe1f5b88652aeac81f2650f8a1b27bf3a8f4
7
- data.tar.gz: 8ef99fac173500c73992db6f059a704674f862bf17563a3f3aff05507eb01e715a829ea822bf6c1f3845bdae9640f90f8d178247c57ad28eb402250fc8046b48
6
+ metadata.gz: d8d28e53eeb77001c89b81a9140be2783278c528fa1dc92aef59b7154cd0174fba47b534d346977135e9465115b74981d9bfdd04eb35952a612e80dea71657a4
7
+ data.tar.gz: 0d4b7117383ab02ee03c0d8f19f75be611a3e678dd973140844f9316d651db7bc0263ed0f4354fda64893b498a344128adb6e44dcb999030bef66445dc4cd0f9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cem_win_spec (0.1.7)
4
+ cem_win_spec (0.1.8)
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
- bigdecimal (3.1.6)
15
- builder (3.2.4)
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.12.0)
19
- faraday (2.9.0)
20
- faraday-net_http (>= 2.0, < 3.2)
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.1.0)
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
- logging (2.3.1)
37
+ logger (1.6.5)
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.9)
42
+ minitar (0.12.1)
38
43
  multi_json (1.15.0)
39
- net-http (0.4.1)
44
+ net-http (0.5.0)
40
45
  uri
41
- nori (2.7.0)
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.3)
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.13.0)
90
- winrm (2.3.6)
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
@@ -77,3 +77,4 @@ parser.parse!
77
77
 
78
78
  operation = options[:operation] || :spec
79
79
  CemWinSpec.run(operation, options)
80
+ exit CemWinSpec.exit_code
@@ -98,13 +98,17 @@ module CemWinSpec
98
98
  end
99
99
  end
100
100
 
101
- def clean_up(working_dir)
102
- @clean_up ||= new_command('Cleanup') do |working_dir|
103
- if remote_available?
104
- remote_run(cleanup_cmd, working_dir, quiet: true)
105
- else
106
- logger.warn 'Cleanup not available'
107
- end
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CemWinSpec
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.8"
5
5
  end
@@ -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
- def command(cmd)
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 = command(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, **_kwargs)
38
+ def bg_run(cmd, *_args, **kwargs)
39
+ cmd = command(cmd, **kwargs)
39
40
  log_command(cmd)
40
- Process.detach(spawn(command(cmd)))
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, **_kwargs)
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(command(cmd))
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, **_kwargs)
64
+ def run(cmd, *_args, **kwargs)
65
+ cmd = command(cmd, **kwargs)
63
66
  log_command(cmd)
64
- Open3.capture3(command(cmd))
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
- def run(cmd, *_args, **_kwargs)
25
- cmd = cmd.join('; ') if cmd.is_a?(Array)
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(command(cmd)) do |stdout, stderr|
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, **opts)
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, **@init_opts.merge(opts))
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 interrupt, killing tunnel and exiting'
14
- runner.iap_tunnel.stop(wait: false, log: false)
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 interrupt, killing tunnel and exiting'
19
- runner.iap_tunnel.stop(wait: false, log: false)
20
- exit 1
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
@@ -67,15 +76,24 @@ module CemWinSpec
67
76
  handle_run_error(e)
68
77
  end
69
78
  ensure
70
- runner&.clean_up(working_dir) if working_dir
71
- runner&.iap_tunnel&.stop(wait: false, log: false)
79
+ if working_dir
80
+ begin
81
+ logger.info "Cleaning up working directory #{working_dir}"
82
+ clean_up(runner, working_dir, **options)
83
+ logger.debug 'Finished cleaning up working directory'
84
+ rescue StandardError => e
85
+ handle_run_error(e)
86
+ end
87
+ end
88
+ runner&.iap_tunnel&.stop(log: false)
89
+ logger.info 'Finished running cem-win-spec'
72
90
  end
73
91
  end
74
92
 
75
93
  def self.handle_run_error(err)
76
94
  logger.fatal "Error: #{err.message}"
77
95
  logger.debug err.backtrace.join("\n")
78
- exit 1
96
+ self.exit_code = 1
79
97
  end
80
98
 
81
99
  def self.retry_spec_on_error(runner, module_dir, **options)
@@ -126,6 +144,21 @@ module CemWinSpec
126
144
  reuse_tunnel: false,
127
145
  **opts).run
128
146
  end
147
+ if output.stderr&.include?('Tests Failed')
148
+ logger.error 'Tests failed'
149
+ self.exit_code = 1
150
+ end
151
+ end
152
+
153
+ # Clean up the remote working directory
154
+ # @param options [Hash] Options for the test runner
155
+ def self.clean_up(runner, working_dir, **opts)
156
+ validate_output do
157
+ runner.clean_up(operation_timeout: 300,
158
+ receive_timeout: 310,
159
+ working_dir: working_dir,
160
+ **opts).run
161
+ end
129
162
  end
130
163
 
131
164
  # Clean the remote fixture cache
@@ -164,7 +197,7 @@ module CemWinSpec
164
197
  end
165
198
 
166
199
  unless output.send(validation_method)
167
- raise CemWinSpecValidationError, "Output validation \"#{validation_method}\" failed: #{output}"
200
+ raise CemWinSpecValidationError, "Output validation \"#{validation_method}\" failed:\n#{output}"
168
201
  end
169
202
  output
170
203
  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.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Heston Snodgrass
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-29 00:00:00.000000000 Z
11
+ date: 2025-02-20 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.4.22
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.