Skip to content

Commit

Permalink
(SDK-312) Add option --parallel to pdk test unit
Browse files Browse the repository at this point in the history
  • Loading branch information
austb committed Jul 14, 2017
1 parent d379920 commit ff054ae
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 6 deletions.
3 changes: 3 additions & 0 deletions lib/pdk/cli/exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def execute!
stdout: @stdout.read,
stderr: @stderr.read,
exit_code: @process.exit_code,
duration: @duration,
}

return process_data
Expand All @@ -162,6 +163,7 @@ def execute!
def run_process!
command_string = argv.join(' ')
PDK.logger.debug(_("Executing '%{command}'") % { command: command_string })
start_time = Time.now
begin
@process.start
rescue ChildProcess::LaunchError => e
Expand All @@ -178,6 +180,7 @@ def run_process!
# Wait indfinitely if no timeout set.
@process.wait
end
@duration = Time.now - start_time
end
end

Expand Down
1 change: 1 addition & 0 deletions lib/pdk/cli/test/unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module PDK::CLI
summary _('Run unit tests.')

flag nil, :list, _('list all available unit tests and their descriptions')
flag nil, :parallel, _('run unit tests in parallel'), hidden: true

option nil, :tests, _('a comma-separated list of tests to run'), argument: :required, default: '' do |values|
PDK::CLI::Util::OptionValidator.comma_separated_list?(values)
Expand Down
60 changes: 54 additions & 6 deletions lib/pdk/tests/unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
module PDK
module Test
class Unit
def self.cmd(_tests)
def self.cmd(_tests, opts = {})
# TODO: test selection
[File.join(PDK::Util.module_root, 'bin', 'rake'), 'spec']
if opts.key?(:parallel)
[File.join(PDK::Util.module_root, 'bin', 'rake'), 'parallel']
else
[File.join(PDK::Util.module_root, 'bin', 'rake'), 'spec']
end
end

def self.invoke(report, options = {})
Expand All @@ -17,7 +21,7 @@ def self.invoke(report, options = {})

tests = options.fetch(:tests)

cmd_argv = cmd(tests)
cmd_argv = cmd(tests, options)
cmd_argv.unshift('ruby') if Gem.win_platform?

command = PDK::CLI::Exec::Command.new(*cmd_argv).tap do |c|
Expand All @@ -33,17 +37,24 @@ def self.invoke(report, options = {})
# TODO: cleanup rspec and/or beaker output
# Iterate through possible JSON documents until we find one that is valid.
json_result = nil
json_result = [] if options.key?(:parallel)

result[:stdout].scan(%r{\{(?:[^{}]|(?:\g<0>))*\}}x) do |str|
begin
json_result = JSON.parse(str)
break
if options.key?(:parallel)
json_result.push(JSON.parse(str))
else
json_result = JSON.parse(str)
break
end
rescue JSON::ParserError
next
end
end

raise PDK::CLI::FatalError, _('Unit test output did not contain a valid JSON result: %{output}') % { output: result[:stdout] } unless json_result
raise PDK::CLI::FatalError, _('Unit test output did not contain a valid JSON result: %{output}') % { output: result[:stdout] } if json_result.nil? || json_result.empty?

json_result = merge_json_results(json_result, result[:duration]) if options.key?(:parallel)

parse_output(report, json_result)

Expand Down Expand Up @@ -99,6 +110,43 @@ def self.parse_output(report, json_data)
}
end

def self.merge_json_results(json_data, duration)
merged_json_result = {}

# Merge messages
message_set = Set.new
json_data.each do |json|
next unless json['messages']
message_set |= json['messages']
end
merged_json_result['messages'] = message_set.to_a

# Merge examples
all_examples = []
json_data.each do |json|
next unless json['examples']
all_examples.concat json['examples']
end
merged_json_result['examples'] = all_examples

# Merge summaries
summary_hash = {
'duration' => duration,
'example_count' => 0,
'failure_count' => 0,
'pending_count' => 0,
}
json_data.each do |json|
next unless json['summary']
summary_hash['example_count'] += json['summary']['example_count']
summary_hash['failure_count'] += json['summary']['failure_count']
summary_hash['pending_count'] += json['summary']['pending_count']
end
merged_json_result['summary'] = summary_hash

merged_json_result
end

# @return array of { :id, :full_description }
def self.list
PDK::Util::Bundler.ensure_bundle!
Expand Down
44 changes: 44 additions & 0 deletions spec/pdk/test/unit_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'spec_helper'
require 'pdk/tests/unit'

describe PDK::Test::Unit do
describe 'merging json results' do
let(:duration) { 55 }
let(:results) do
[{ 'messages' => ['message 1', 'message 2'],
'examples' => %w[example example example],
'summary' => {
'example_count' => 40,
'failure_count' => 7,
'pending_count' => 12,
'duration' => 30,
} },
{
'messages' => ['message 2', 'message 3'],
'examples' => %w[example example example],
'summary' => {
'example_count' => 30,
'failure_count' => 4,
'pending_count' => 6,
'duration' => 40,
},
}]
end

it 'successfully combines information' do
json_result = described_class.merge_json_results(results, duration)

expect(json_result['messages'].count).to eq(3)
expect(json_result['examples'].count).to eq(6)
expect(json_result['summary']['example_count']).to eq(70)
expect(json_result['summary']['failure_count']).to eq(11)
expect(json_result['summary']['pending_count']).to eq(18)
end

it 'assigns given duration to the result' do
json_result = described_class.merge_json_results(results, duration)

expect(json_result['summary']['duration']).to eq(duration)
end
end
end

0 comments on commit ff054ae

Please sign in to comment.