1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
# frozen_string_literal: true
require 'rspec/core'
require 'rspec/expectations'
module QA
module Specs
class Runner < Scenario::Template
attr_accessor :tty, :tags, :options
RegexMismatchError = Class.new(StandardError)
DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze
DEFAULT_STD_ARGS = [$stderr, $stdout].freeze
def initialize
@tty = false
@tags = []
@options = []
end
def paths_from_knapsack
allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator
QA::Runtime::Logger.info '==== Knapsack specs to execute ====='
QA::Runtime::Logger.info 'Report specs:'
QA::Runtime::Logger.info allocator.report_node_tests.join(', ')
QA::Runtime::Logger.info 'Leftover specs:'
QA::Runtime::Logger.info allocator.leftover_node_tests.join(', ')
['--', allocator.node_tests]
end
def rspec_tags
tags_for_rspec = []
if tags.any?
tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }
else
tags_for_rspec.push(%w[--tag ~orchestrated --tag ~transient]) unless (%w[-t --tag] & options).any?
end
tags_for_rspec.push(%w[--tag ~geo]) unless QA::Runtime::Env.geo_environment?
tags_for_rspec.push(%w[--tag ~skip_signup_disabled]) if QA::Runtime::Env.signup_disabled?
tags_for_rspec.push(%w[--tag ~smoke --tag ~reliable]) if QA::Runtime::Env.skip_smoke_reliable?
tags_for_rspec.push(%w[--tag ~skip_live_env]) if QA::Specs::Helpers::ContextSelector.dot_com?
QA::Runtime::Env.supported_features.each_key do |key|
tags_for_rspec.push(%W[--tag ~requires_#{key}]) unless QA::Runtime::Env.can_test? key
end
tags_for_rspec
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/CyclomaticComplexity
def perform
args = []
args.push('--tty') if tty
args.push(rspec_tags)
args.push(options)
if Runtime::Env.knapsack?
args.push(paths_from_knapsack)
else
args.push(DEFAULT_TEST_PATH_ARGS) unless options.any? { |opt| opt =~ %r{/features/} }
end
Runtime::Scenario.define(:large_setup?, args.flatten.include?('can_use_large_setup'))
if Runtime::Scenario.attributes[:parallel]
ParallelRunner.run(args.flatten)
elsif Runtime::Scenario.attributes[:loop]
LoopRunner.run(args.flatten)
elsif Runtime::Scenario.attributes[:count_examples_only]
args.unshift('--dry-run')
out = StringIO.new
RSpec::Core::Runner.run(args.flatten, $stderr, out).tap do |status|
abort if status.nonzero?
end
begin
total_examples = out.string.match(/(\d+) examples?,/)[1]
rescue StandardError
raise RegexMismatchError, 'Rspec output did not match regex'
end
filename = build_filename
File.open(filename, 'w') { |f| f.write(total_examples) } if total_examples.to_i > 0
$stdout.puts "Total examples in #{Runtime::Scenario.klass}: #{total_examples}#{total_examples.to_i > 0 ? ". Saved to file: #{filename}" : ''}"
elsif Runtime::Scenario.attributes[:test_metadata_only]
args.unshift('--dry-run')
output_file = Pathname.new(File.join(Runtime::Path.qa_root, 'tmp', 'test-metadata.json'))
RSpec.configure do |config|
config.add_formatter(QA::Support::JsonFormatter, output_file)
config.fail_if_no_examples = true
end
RSpec::Core::Runner.run(args.flatten, $stderr, $stdout) do |status|
abort if status.nonzero?
end
$stdout.puts "Saved to file: #{output_file}"
else
RSpec::Core::Runner.run(args.flatten, *DEFAULT_STD_ARGS).tap do |status|
abort if status.nonzero?
end
end
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/CyclomaticComplexity
private
def build_filename
filename = Runtime::Scenario.klass.split('::').last(3).join('_').downcase
tags = []
options.reduce do |before, after|
tags << after if %w[--tag -t].include?(before)
after
end
tags = tags.compact.join('_')
filename.concat("_#{tags}") unless tags.empty?
filename.concat('.txt')
FileUtils.mkdir_p('no_of_examples')
File.join('no_of_examples', filename)
end
end
end
end
|