cem_win_spec 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +56 -11
- data/exe/cem-win-spec +11 -5
- data/lib/cem_win_spec/fixture_cache.rb +35 -12
- data/lib/cem_win_spec/logging.rb +4 -1
- data/lib/cem_win_spec/rake_tasks.rb +105 -117
- data/lib/cem_win_spec/test_runner.rb +8 -2
- data/lib/cem_win_spec/version.rb +1 -1
- data/lib/cem_win_spec/win_exec/local_exec.rb +1 -1
- data/lib/cem_win_spec/win_exec.rb +1 -1
- data/lib/cem_win_spec.rb +62 -32
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdb91d3bd9c4220238d0712938226a34f036c4313370f0ac70b818402d67051d
|
4
|
+
data.tar.gz: 6e1b4a03b910513b5d4e985f5643394834f0ff38e7af9c03ffebe24a179d1f61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d36cc7f04c91d80fd494caecbe1ee33b39a71d3cde95cf71f4381ba12c232f0f4ed02b91886a89a9e4d2253d1b8ca9bc58bb8348e69d8eda97c7e5d5da22399c
|
7
|
+
data.tar.gz: c3fc479c502495358843257577391242f7c7003abee9fcb73e7dfa2e456adcd9bbbd448b864b9df347096d519c6ca4ca9ce6c9a7be71582acca448710bb88807
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# CemWinSpec
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
cem_win_spec is a gem that provides CLI for running CEM RSpec test on a remote Windows machine.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -16,18 +14,65 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
16
14
|
|
17
15
|
## Usage
|
18
16
|
|
19
|
-
|
17
|
+
CemWinSpec requires that you have [gcloud](https://cloud.google.com/sdk/gcloud) installed and configured to connect to the GCP instance that you want to run the tests on.
|
18
|
+
|
19
|
+
The gem provides a CLI that can be used to run CEM RSpec tests on a remote Windows machine. The CLI help menu can be viewed by running:
|
20
|
+
|
21
|
+
$ cem-win-spec --help
|
22
|
+
Usage: cem-win-spec [options]
|
23
|
+
-v, --version Print version and exit
|
24
|
+
-o, --operation [OPERATION] Operation to perform (spec, clean_fixture_cache)
|
25
|
+
-q, --quiet Suppress output
|
26
|
+
-d, --debug Enable debug output on the console
|
27
|
+
-l, --log-level [LEVEL] Set log level (debug, info, warn, error, fatal)
|
28
|
+
-L, --log-file [FILE] Log output to file
|
29
|
+
-f, --log-format [FORMAT] Set log format(file, text, json, github_action
|
30
|
+
-h, --help Print this help
|
31
|
+
|
32
|
+
The `operation` option can be used to specify the operation to perform. The CLI supports the following operations:
|
33
|
+
|
34
|
+
spec - Run the RSpec tests on the remote Windows machine (default)
|
35
|
+
clean_fixture_cache - Clean the RSpec fixture cache on the remote Windows machine
|
36
|
+
|
37
|
+
The `quiet` option can be used to suppress all console output. This option can be used in conjunction with the `log-file` option to suppress console output and only log to a file.
|
38
|
+
|
39
|
+
The `debug` option only affects the console output and does not affect the log file output.
|
40
|
+
|
41
|
+
The `log-level` option can be used to set the log level for the log file output. The default log level is `debug`.
|
42
|
+
|
43
|
+
The `log-file` option can be used to set the log file path. If this is not set, no log file will be created.
|
44
|
+
|
45
|
+
The `log-format` option can be used to set the log format. The default log format is `text` for the console and `file` for the log file. The `github_action` format is designed to be used with GitHub Actions. Setting this affects both the console and log file output.
|
46
|
+
|
47
|
+
### Configuration
|
48
|
+
|
49
|
+
CemWinSpec takes it's configuration from environment variables. The following environment variables are required:
|
50
|
+
|
51
|
+
- `GCP_INSTANCE_NAME` - The name of the GCP Windows instance to run the tests on
|
52
|
+
- `WINRM_USERNAME` - The username to use when connecting to the GCP instance
|
53
|
+
- `WINRM_PASSWORD` - The password to use when connecting to the GCP instance
|
54
|
+
|
55
|
+
The following environment variables may be required if they cannot be determined from gcloud:
|
56
|
+
|
57
|
+
- `GCP_PROJECT_ID` - The GCP project ID that the instance is in
|
58
|
+
- `GCP_ZONE` - The GCP zone that the instance is in
|
59
|
+
|
60
|
+
The following environment variables are optional:
|
20
61
|
|
21
|
-
|
62
|
+
- `CEM_WIN_SPEC_PATTERN` - The pattern to use when running the tests. Defaults to `spec/{classes,defines,functions,unit}/**/*_spec.rb`
|
63
|
+
- `CEM_WIN_SPEC_FAIL_FAST` - If set to true, the tests will stop running after the first failure. Defaults to `false`
|
64
|
+
- `CEM_WIN_SPEC_TRACE` - If set to true, Rake will output a full backtrace for any halting errors. Defaults to `false`
|
65
|
+
- `CEM_WIN_SPEC_FORMAT` - The RSpec output format to use when running the tests. Defaults to `progress`
|
22
66
|
|
23
|
-
|
67
|
+
The following environment variables have an effect, but should not be set manually:
|
24
68
|
|
25
|
-
|
69
|
+
- `CI` - If set, the tests will run in CI mode which changes the logging output to be more suitable for GitHub Actions
|
70
|
+
- `GITHUB_ACTIONS` - If set, the tests will run in CI mode which changes the logging output to be more suitable for GitHub Actions
|
26
71
|
|
27
|
-
|
72
|
+
### Adding to module Rakefile
|
28
73
|
|
29
|
-
|
74
|
+
The following line must be added to the `Rakefile` in the CEM Windows repository:
|
30
75
|
|
31
|
-
|
76
|
+
require 'cem_win_spec/rake_tasks' if Bundler.rubygems.find_name('cem_win_spec').any?
|
32
77
|
|
33
|
-
The
|
78
|
+
This will add the `cem_win_spec` task namespace to the Rakefile, along with the tasks `run`, `prep`, and `parallel_spec`. The tasks are used by `cem_win_spec` to run the tests on the remote Windows machine and should not be used directly.
|
data/exe/cem-win-spec
CHANGED
@@ -18,6 +18,15 @@ parser = OptionParser.new do |opts|
|
|
18
18
|
exit 0
|
19
19
|
end
|
20
20
|
|
21
|
+
opts.on('-o', '--operation [OPERATION]', 'Operation to perform (spec, clean_fixture_cache)') do |operation|
|
22
|
+
unless %w[spec clean_fixture_cache].include?(operation)
|
23
|
+
warn "Unknown operation: #{operation}"
|
24
|
+
puts opts
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
options[:operation] = operation.to_sym
|
28
|
+
end
|
29
|
+
|
21
30
|
opts.on('-q', '--quiet', 'Suppress output') do
|
22
31
|
options[:quiet] = true
|
23
32
|
end
|
@@ -26,10 +35,6 @@ parser = OptionParser.new do |opts|
|
|
26
35
|
options[:debug] = true
|
27
36
|
end
|
28
37
|
|
29
|
-
opts.on('-V', '--verbose', 'Enable verbose output on the console') do
|
30
|
-
options[:verbose] = true
|
31
|
-
end
|
32
|
-
|
33
38
|
opts.on('-l', '--log-level [LEVEL]', 'Set log level (debug, info, warn, error, fatal)') do |level|
|
34
39
|
options[:log_level] = level
|
35
40
|
end
|
@@ -49,4 +54,5 @@ parser = OptionParser.new do |opts|
|
|
49
54
|
end
|
50
55
|
parser.parse!
|
51
56
|
|
52
|
-
|
57
|
+
operation = options[:operation] || :spec
|
58
|
+
CemWinSpec.run(operation, options)
|
@@ -13,30 +13,32 @@ module CemWinSpec
|
|
13
13
|
# Puppet modules between test runs instead of downloading them each time.
|
14
14
|
# The cache works by creating a YAML file that maps module names and
|
15
15
|
class FixtureCache
|
16
|
+
CACHE_DIR = 'C:/cem_win_spec'
|
16
17
|
CACHE_MANIFEST = 'cache_manifest.yaml'
|
17
18
|
|
19
|
+
def self.clean!
|
20
|
+
::FileUtils.rm_rf(CACHE_DIR) if File.directory?(CACHE_DIR)
|
21
|
+
puts "Deleted fixture cache #{CACHE_DIR}"
|
22
|
+
end
|
23
|
+
|
18
24
|
attr_reader :cache_dir, :cache_entries
|
19
25
|
|
20
|
-
def initialize
|
26
|
+
def initialize
|
21
27
|
raise 'FixtureCache must be ran on Windows' unless Gem.win_platform?
|
22
28
|
|
23
|
-
@cache_dir =
|
29
|
+
@cache_dir = CACHE_DIR
|
24
30
|
@cache_entries = setup_and_load_cache
|
31
|
+
@entries_digest = Digest::SHA256.hexdigest(@cache_entries.to_s)
|
25
32
|
@dependencies = dependencies_from_metadata
|
26
33
|
setup!
|
27
34
|
end
|
28
35
|
|
29
|
-
def copy_fixtures_to(fixtures_dir)
|
30
|
-
@cache_entries.each do |_, path|
|
31
|
-
FileUtils.cp_r(path, fixtures_dir)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
36
|
def setup!
|
38
37
|
@dependencies.each do |name, data|
|
39
|
-
|
38
|
+
if cached?(data[:checksum])
|
39
|
+
puts "Using cached #{name} #{data[:version]}"
|
40
|
+
next
|
41
|
+
end
|
40
42
|
|
41
43
|
puts "Downloading #{name} #{data[:version]}..."
|
42
44
|
download_and_cache(name, data[:release_slug], data[:checksum])
|
@@ -45,6 +47,21 @@ module CemWinSpec
|
|
45
47
|
save_cache_entries
|
46
48
|
end
|
47
49
|
|
50
|
+
def copy_fixtures_to(fixtures_dir, make_fixtures_dir: true)
|
51
|
+
::FileUtils.mkdir_p(fixtures_dir) if make_fixtures_dir
|
52
|
+
raise "Directory #{fixtures_dir} does not exist" unless File.directory?(fixtures_dir)
|
53
|
+
|
54
|
+
@cache_entries.each do |_, path|
|
55
|
+
::FileUtils.cp_r(path, fixtures_dir)
|
56
|
+
interim_mod_path = File.join(fixtures_dir, File.basename(path))
|
57
|
+
final_mod_path = File.join(fixtures_dir, File.basename(path).split('-').last)
|
58
|
+
::FileUtils.mv(interim_mod_path, final_mod_path)
|
59
|
+
puts "Copied #{File.basename(path)} to #{final_mod_path}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
48
65
|
def dependencies_from_metadata
|
49
66
|
raise "File metadata.json not found in current directory #{Dir.pwd}" unless File.exist?('metadata.json')
|
50
67
|
|
@@ -93,7 +110,9 @@ module CemWinSpec
|
|
93
110
|
unless File.exist?(manifest)
|
94
111
|
puts "Creating cache manifest #{manifest}..."
|
95
112
|
File.write(manifest, {}.to_yaml)
|
113
|
+
`attrib -s -h -r #{cache_dir.gsub('/', '\\')}\\*.* /s`
|
96
114
|
end
|
115
|
+
puts "Loading cache manifest #{manifest}..."
|
97
116
|
YAML.load_file(manifest)
|
98
117
|
end
|
99
118
|
|
@@ -101,7 +120,7 @@ module CemWinSpec
|
|
101
120
|
cache_entries.key?(checksum)
|
102
121
|
end
|
103
122
|
|
104
|
-
def download_and_cache(release_slug, checksum)
|
123
|
+
def download_and_cache(name, release_slug, checksum)
|
105
124
|
release = PuppetForge::Release.find(release_slug)
|
106
125
|
module_cache_dir = File.join(cache_dir, checksum)
|
107
126
|
::FileUtils.mkdir_p(File.join(cache_dir, checksum))
|
@@ -112,10 +131,14 @@ module CemWinSpec
|
|
112
131
|
File.join(module_cache_dir, name),
|
113
132
|
File.join(module_cache_dir, 'temp'))
|
114
133
|
cache_entries[checksum] = File.join(module_cache_dir, name)
|
134
|
+
puts "Downloaded #{release_slug} to #{File.join(module_cache_dir, name)}"
|
115
135
|
end
|
116
136
|
|
117
137
|
def save_cache_entries
|
138
|
+
return if @entries_digest == Digest::SHA256.hexdigest(cache_entries.to_s)
|
139
|
+
|
118
140
|
File.write(manifest, cache_entries.to_yaml)
|
141
|
+
puts "Saved cache manifest #{manifest}"
|
119
142
|
end
|
120
143
|
end
|
121
144
|
end
|
data/lib/cem_win_spec/logging.rb
CHANGED
@@ -76,7 +76,10 @@ module CemWinSpec
|
|
76
76
|
# create a new one.
|
77
77
|
# @return [Logger]
|
78
78
|
def logger
|
79
|
-
|
79
|
+
unless @logger
|
80
|
+
warn 'Logger not set up! Setting up default logger.'
|
81
|
+
log_setup!
|
82
|
+
end
|
80
83
|
|
81
84
|
@logger
|
82
85
|
end
|
@@ -1,138 +1,126 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'fileutils'
|
3
4
|
require 'rake'
|
4
|
-
require 'rake/file_list'
|
5
|
-
require 'rake/tasklib'
|
6
5
|
require 'parallel_tests'
|
7
|
-
|
8
|
-
|
9
|
-
# Provides custom rake tasks to run tests on a remote Windows host.
|
10
|
-
# Add the following to your Rakefile to use:
|
11
|
-
# require 'cem_win_spec/rake_tasks'
|
12
|
-
# CemWinSpecRakeTasks::All.new
|
13
|
-
module CemWinSpecRakeTasks
|
14
|
-
# Class for defining all custom rake tasks
|
15
|
-
class All
|
16
|
-
def initialize(**opts)
|
17
|
-
@namespace = opts[:namespace] || :cem_win_spec
|
18
|
-
@data_dir = opts[:data_dir]
|
19
|
-
@hiera_conf = opts[:hiera_conf]
|
20
|
-
@pattern = opts[:pattern]
|
21
|
-
@fail_fast = opts[:fail_fast]
|
22
|
-
@format = opts[:format]
|
23
|
-
define_tasks
|
24
|
-
end
|
6
|
+
require 'cem_win_spec/fixture_cache'
|
25
7
|
|
26
|
-
|
8
|
+
def cem_win_spec_work_dir
|
9
|
+
w_dir = Dir.pwd
|
10
|
+
unless File.exist?(File.join(w_dir, 'metadata.json'))
|
11
|
+
raise "Current working directory is not a module root directory! dir: #{dir}"
|
12
|
+
end
|
13
|
+
w_dir
|
14
|
+
end
|
27
15
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
16
|
+
def cem_win_spec_dir
|
17
|
+
s_dir = File.join(cem_win_spec_work_dir, 'spec')
|
18
|
+
unless File.directory?(s_dir)
|
19
|
+
raise "Spec directory '#{s_dir}' does not exist!"
|
20
|
+
end
|
21
|
+
s_dir
|
22
|
+
end
|
32
23
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
24
|
+
def cem_win_spec_fixtures_dir
|
25
|
+
f_dir = File.join(cem_win_spec_dir, 'fixtures')
|
26
|
+
::FileUtils.mkdir_p(f_dir) unless File.directory?(f_dir)
|
27
|
+
f_dir
|
28
|
+
end
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
30
|
+
def cem_win_spec_base_path_in_fixtures(path)
|
31
|
+
base = File.basename(path)
|
32
|
+
File.join(cem_win_spec_fixtures_dir, base)
|
33
|
+
end
|
34
|
+
|
35
|
+
def cem_win_spec_data_dir
|
36
|
+
d_dir = File.join(cem_win_spec_work_dir, 'data')
|
37
|
+
unless File.directory?(d_dir)
|
38
|
+
raise "Data directory '#{d_dir}' does not exist!"
|
47
39
|
end
|
40
|
+
d_dir
|
41
|
+
end
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
def cem_win_spec_hiera_conf
|
44
|
+
h_file = File.join(cem_win_spec_work_dir, 'hiera.yaml')
|
45
|
+
unless File.file?(h_file)
|
46
|
+
raise "Hiera config file '#{h_file}' does not exist!"
|
47
|
+
end
|
48
|
+
h_file
|
49
|
+
end
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
@hiera_conf = 'hiera.yaml'
|
57
|
-
end
|
51
|
+
def cem_win_spec_pattern
|
52
|
+
ENV['CEM_WIN_SPEC_PATTERN'] || 'spec/{classes,defines,functions,unit}/**/*_spec.rb'
|
53
|
+
end
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if Gem.win_platform?
|
64
|
-
prep_data
|
65
|
-
prep_modules
|
66
|
-
else
|
67
|
-
puts 'Not on Windows, skipping prep'
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
55
|
+
def cem_win_spec_fail_fast
|
56
|
+
ff_var = ENV['CEM_WIN_SPEC_FAIL_FAST'] || 'false'
|
57
|
+
(ff_var).match?(/^(true|t|yes|y|1)$/i)
|
58
|
+
end
|
74
59
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
60
|
+
def cem_win_spec_trace
|
61
|
+
t_var = ENV['CEM_WIN_SPEC_TRACE'] || 'false'
|
62
|
+
(t_var).match?(/^(true|t|yes|y|1)$/i)
|
63
|
+
end
|
79
64
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
if File.directory?(data_fix)
|
84
|
-
puts "Removing old #{data_fix} directory..."
|
85
|
-
::FileUtils.remove_entry_secure(data_fix)
|
86
|
-
end
|
87
|
-
puts "Copying Hiera data to #{data_fix}..."
|
88
|
-
::FileUtils.cp_r(data_dir, data_fix)
|
89
|
-
unless Dir.glob("#{data_fix}/**/*").map { |f| f.delete_prefix('spec/fixtures/') } == Dir.glob("#{data_dir}/**/*")
|
90
|
-
raise 'Spec data copy failed!'
|
91
|
-
end
|
92
|
-
hiera_fix = fixtures(hiera_conf)
|
93
|
-
puts "Copying Hiera config to #{hiera_fix}..."
|
94
|
-
::FileUtils.cp(hiera_conf, hiera_fix)
|
95
|
-
unless File.exist?(hiera_fix)
|
96
|
-
raise 'Hiera config copy failed!'
|
97
|
-
end
|
98
|
-
puts 'Spec data prepared successfully'
|
99
|
-
end
|
65
|
+
def cem_win_spec_format
|
66
|
+
ENV['CEM_WIN_SPEC_FORMAT'] || 'progress'
|
67
|
+
end
|
100
68
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
cache = CemWinSpec::FixtureCache.new
|
105
|
-
cache.copy_fixtures_to(mod_fix)
|
106
|
-
end
|
107
|
-
end
|
69
|
+
def cem_win_spec_dir_basenames(dir)
|
70
|
+
Dir.glob("#{dir}/**/*").map { |f| File.basename(f) }
|
71
|
+
end
|
108
72
|
|
109
|
-
|
110
|
-
|
111
|
-
|
73
|
+
namespace 'cem_win_spec' do
|
74
|
+
desc 'Run prep and parallel spec tests'
|
75
|
+
task :parallel_spec do
|
76
|
+
Rake::Task['cem_win_spec:prep'].invoke
|
77
|
+
Rake::Task['cem_win_spec:parallel_spec_standalone'].invoke
|
78
|
+
end
|
112
79
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
80
|
+
desc 'Prepare spec data and fixtures'
|
81
|
+
task :prep do
|
82
|
+
puts 'Preparing spec data...'
|
83
|
+
data_fix = cem_win_spec_base_path_in_fixtures(cem_win_spec_data_dir)
|
84
|
+
if File.directory?(data_fix)
|
85
|
+
puts "Removing old #{data_fix} directory..."
|
86
|
+
::FileUtils.remove_entry_secure(data_fix)
|
118
87
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
pargs.concat(rspec_args)
|
130
|
-
pargs << '--'
|
131
|
-
puts "Running tests on Windows host with pattern #{pattern} and args #{pargs}..."
|
132
|
-
pargs.concat(spec_files)
|
133
|
-
ParallelTests::CLI.new.run(pargs)
|
134
|
-
end
|
135
|
-
end
|
88
|
+
puts "Copying Hiera data to #{data_fix}..."
|
89
|
+
::FileUtils.cp_r(cem_win_spec_data_dir, data_fix)
|
90
|
+
unless cem_win_spec_dir_basenames(data_fix) == cem_win_spec_dir_basenames(cem_win_spec_data_dir)
|
91
|
+
raise 'Spec data copy failed!'
|
92
|
+
end
|
93
|
+
hiera_fix = cem_win_spec_base_path_in_fixtures(cem_win_spec_hiera_conf)
|
94
|
+
puts "Copying Hiera config to #{hiera_fix}..."
|
95
|
+
::FileUtils.cp(cem_win_spec_hiera_conf, hiera_fix)
|
96
|
+
unless File.exist?(hiera_fix)
|
97
|
+
raise 'Hiera config copy failed!'
|
136
98
|
end
|
99
|
+
puts 'Spec data prepared successfully'
|
100
|
+
puts 'Preparing module fixtures...'
|
101
|
+
mod_fix = cem_win_spec_base_path_in_fixtures('modules')
|
102
|
+
cache = CemWinSpec::FixtureCache.new
|
103
|
+
cache.copy_fixtures_to(mod_fix)
|
104
|
+
puts 'Module fixtures prepared successfully'
|
105
|
+
end
|
106
|
+
|
107
|
+
desc 'Run RSpec tests on Windows host'
|
108
|
+
task :parallel_spec_standalone do
|
109
|
+
spec_files = Rake::FileList[cem_win_spec_pattern]
|
110
|
+
pargs = ['--type', 'rspec']
|
111
|
+
pargs << '--trace' if cem_win_spec_trace
|
112
|
+
rspec_args = ['--']
|
113
|
+
rspec_args << '--fail-fast' if cem_win_spec_fail_fast
|
114
|
+
rspec_args.concat(['--format', cem_win_spec_format])
|
115
|
+
pargs.concat(rspec_args)
|
116
|
+
pargs << '--'
|
117
|
+
puts "Running tests on Windows host with pattern #{cem_win_spec_pattern} and args #{pargs}..."
|
118
|
+
pargs.concat(spec_files)
|
119
|
+
ParallelTests::CLI.new.run(pargs)
|
120
|
+
end
|
121
|
+
|
122
|
+
desc 'Clean fixture cache'
|
123
|
+
task :clean_fixture_cache do
|
124
|
+
CemWinSpec::FixtureCache.clean!
|
137
125
|
end
|
138
126
|
end
|
@@ -83,7 +83,7 @@ module CemWinSpec
|
|
83
83
|
|
84
84
|
def rspec_prep(**opts)
|
85
85
|
@rspec_prep ||= new_command('Prepare rspec tests', **opts) do
|
86
|
-
remote_exec('bundle exec rake cem_win_spec:prep')
|
86
|
+
remote_exec('bundle exec rake cem_win_spec:prep --trace')
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -95,7 +95,7 @@ module CemWinSpec
|
|
95
95
|
|
96
96
|
def rspec_tests_parallel(**opts)
|
97
97
|
@rspec_tests_parallel ||= new_command('Run rspec tests in parallel', **opts) do
|
98
|
-
remote_exec('bundle exec rake cem_win_spec:
|
98
|
+
remote_exec('bundle exec rake cem_win_spec:parallel_spec')
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -109,6 +109,12 @@ module CemWinSpec
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
+
def clean_fixture_cache(**opts)
|
113
|
+
@clean_cache ||= new_command('Clean fixture cache', **opts) do
|
114
|
+
remote_exec('bundle exec rake cem_win_spec:clean_fixture_cache')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
112
118
|
private
|
113
119
|
|
114
120
|
def title_sym(title)
|
data/lib/cem_win_spec/version.rb
CHANGED
data/lib/cem_win_spec.rb
CHANGED
@@ -22,58 +22,88 @@ module CemWinSpec
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
25
|
+
# Run cem_win_spec operations
|
26
26
|
# @param options [Hash] Options for the test runner
|
27
27
|
# @option options [Boolean] :quiet (false) Whether to suppress output
|
28
28
|
# @option options [Boolean] :debug (false) Whether to enable debug output
|
29
|
-
# @option options [Boolean] :verbose (false) Whether to enable verbose output
|
30
29
|
# @option options [String] :log_level (nil) Explicitly set the log level
|
31
30
|
# @option options [String] :log_file (nil) Log output to file
|
32
31
|
# @option options [String] :log_format (nil) Set log format(text, json, github_action)
|
33
|
-
def self.
|
32
|
+
def self.run(operation = :spec, options = {})
|
34
33
|
raise 'Must be ran from the root of the project' unless File.exist?('Gemfile')
|
35
34
|
|
36
35
|
log_setup!(options)
|
37
|
-
logger.info 'Running
|
36
|
+
logger.info 'Running cem-win-spec...'
|
38
37
|
logger.debug "Options: #{options}"
|
39
38
|
runner = TestRunner.new
|
40
39
|
logger.debug "Created TestRunner: #{runner}"
|
41
40
|
signal_handler(runner)
|
42
41
|
logger.debug 'Set up signal handler'
|
43
|
-
exitcode = 99
|
44
42
|
spinner = TTY::Spinner.new(format: :classic, interval: 1, hide_cursor: true, clear: true)
|
45
43
|
begin
|
46
|
-
runner
|
47
|
-
runner
|
48
|
-
|
49
|
-
working_dir = working_dir_out&.stdout.chomp
|
50
|
-
logger.debug "Working dir: #{working_dir}"
|
51
|
-
module_dir = runner.upload_module(working_dir: working_dir).run&.stdout.chomp
|
44
|
+
sre_out = setup_remote_environment(runner, spinner)
|
45
|
+
check_output!(sre_out, runner)
|
46
|
+
module_dir = sre_out.stdout.chomp
|
52
47
|
logger.debug "Module dir: #{module_dir}"
|
53
|
-
runner
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# We currently don't have any local commands being run
|
66
|
-
# but we may in the future. If we do, we'll need to
|
67
|
-
# call local_threaded_results on the TestRunner
|
68
|
-
# runner.local_threaded_results
|
69
|
-
exitcode = spec_out&.exitcode
|
70
|
-
logger.info "Completed tests with exit code: #{exitcode}"
|
48
|
+
srr_out = setup_remote_ruby(runner, module_dir, spinner)
|
49
|
+
check_output!(srr_out, runner)
|
50
|
+
case operation
|
51
|
+
when :spec
|
52
|
+
spec_out = run_spec(runner, module_dir, spinner)
|
53
|
+
check_output!(spec_out, runner)
|
54
|
+
when :clean_fixture_cache
|
55
|
+
clean_fixture_cache_out = clean_fixture_cache(runner, module_dir, spinner)
|
56
|
+
check_output!(clean_fixture_cache_out, runner)
|
57
|
+
else
|
58
|
+
raise ArgumentError, "Unknown operation: #{operation}"
|
59
|
+
end
|
71
60
|
rescue StandardError => e
|
72
61
|
logger.fatal "Error: #{e.message}"
|
73
62
|
logger.debug e.backtrace.join("\n")
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.setup_remote_environment(runner, spinner)
|
68
|
+
runner.enable_long_paths.run
|
69
|
+
runner.enable_symlinks.run
|
70
|
+
runner.enable_symlinks.run
|
71
|
+
working_dir_out = runner.create_working_dir.run
|
72
|
+
working_dir = working_dir_out.stdout.chomp
|
73
|
+
logger.debug "Working dir: #{working_dir}"
|
74
|
+
runner.upload_module(working_dir: working_dir).run
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.setup_remote_ruby(runner, module_dir, spinner)
|
78
|
+
runner.setup_ruby(operation_timeout: 300,
|
79
|
+
receive_timeout: 310,
|
80
|
+
working_dir: module_dir,
|
81
|
+
reuse_tunnel: false,
|
82
|
+
spinner: spinner).run
|
83
|
+
end
|
84
|
+
|
85
|
+
# Runs RSpec tests
|
86
|
+
def self.run_spec(runner, module_dir, spinner)
|
87
|
+
#runner.rspec_prep(working_dir: module_dir, reuse_tunnel: false, spinner: spinner).run
|
88
|
+
runner.rspec_tests_parallel(operation_timeout: 300,
|
89
|
+
receive_timeout: 310,
|
90
|
+
working_dir: module_dir,
|
91
|
+
ignore_exitcode: true,
|
92
|
+
reuse_tunnel: false,
|
93
|
+
spinner: spinner).run
|
94
|
+
end
|
95
|
+
|
96
|
+
# Clean the remote fixture cache
|
97
|
+
# @param options [Hash] Options for the test runner
|
98
|
+
def self.clean_fixture_cache(runner, module_dir, spinner)
|
99
|
+
runner.clean_fixture_cache(working_dir: module_dir, spinner: spinner).run
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.check_output!(output, runner = nil)
|
103
|
+
unless output.success?
|
104
|
+
runner&.iap_tunnel&.stop(wait: false, log: false)
|
105
|
+
logger.fatal "Command failed with exit code #{output.exitcode}"
|
106
|
+
exit output.exitcode
|
77
107
|
end
|
78
108
|
end
|
79
109
|
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.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heston Snodgrass
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: winrm
|