diff --git a/.gitignore b/.gitignore index 8dde7f7..15b11e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ Gemfile.lock config/report_portal.yaml +rp_launch_id.tmp diff --git a/lib/report_portal/cucumber/formatter.rb b/lib/report_portal/cucumber/formatter.rb index 8c4d13b..efede67 100644 --- a/lib/report_portal/cucumber/formatter.rb +++ b/lib/report_portal/cucumber/formatter.rb @@ -36,7 +36,7 @@ def report end def setup_message_processing - return if use_same_thread_for_reporting? + return if ReportPortal::Settings.instance.formatter_modes.use_same_thread_for_reporting? @queue = Queue.new @thread = Thread.new do @@ -49,7 +49,7 @@ def setup_message_processing end def finish_message_processing - return if use_same_thread_for_reporting? + return if ReportPortal::Settings.instance.formatter_modes.use_same_thread_for_reporting? sleep 0.03 while !@queue.empty? || @queue.num_waiting.zero? # TODO: how to interrupt launch if the user aborted execution @thread.kill @@ -57,16 +57,12 @@ def finish_message_processing def process_message(report_method_name, *method_args) args = [report_method_name, *method_args, ReportPortal.now] - if use_same_thread_for_reporting? + if ReportPortal::Settings.instance.formatter_modes.use_same_thread_for_reporting? report.public_send(*args) else @queue.push(args) end end - - def use_same_thread_for_reporting? - ReportPortal::Settings.instance.formatter_modes.include?('use_same_thread_for_reporting') - end end end end diff --git a/lib/report_portal/cucumber/report.rb b/lib/report_portal/cucumber/report.rb index f331c2e..10b7d18 100644 --- a/lib/report_portal/cucumber/report.rb +++ b/lib/report_portal/cucumber/report.rb @@ -14,10 +14,6 @@ def parallel? false end - def attach_to_launch? - ReportPortal::Settings.instance.formatter_modes.include?('attach_to_launch') - end - def initialize @last_used_time = 0 @root_node = Tree::TreeNode.new('') @@ -25,20 +21,12 @@ def initialize start_launch end - def start_launch(desired_time = ReportPortal.now) - if attach_to_launch? - ReportPortal.launch_id = - if ReportPortal::Settings.instance.launch_id - ReportPortal::Settings.instance.launch_id - else - file_path = ReportPortal::Settings.instance.file_with_launch_id || (Pathname(Dir.tmpdir) + 'rp_launch_id.tmp') - File.read(file_path) - end - $stdout.puts "Attaching to launch #{ReportPortal.launch_id}" + def start_launch + if ReportPortal::Settings.instance.attach_to_launch? + ReportPortal.launch_id = ReportPortal::Settings.get_launch_id else - description = ReportPortal::Settings.instance.description - description ||= ARGV.map { |arg| arg.gsub(/rp_uuid=.+/, 'rp_uuid=[FILTERED]') }.join(' ') - ReportPortal.start_launch(description, time_to_send(desired_time)) + cmd_args = ARGV.map { |arg| arg.include?('rp_uuid=') ? 'rp_uuid=[FILTERED]' : arg }.join(' ') + ReportPortal.start_launch(cmd_args) end end @@ -119,7 +107,7 @@ def test_step_finished(event, desired_time = ReportPortal.now) def test_run_finished(_event, desired_time = ReportPortal.now) end_feature(desired_time) unless @parent_item_node.is_root? - unless attach_to_launch? + unless ReportPortal::Settings.instance.attach_to_launch? close_all_children_of(@root_node) # Folder items are closed here as they can't be closed after finishing a feature time_to_send = time_to_send(desired_time) ReportPortal.finish_launch(time_to_send) diff --git a/lib/report_portal/rspec/formatter.rb b/lib/report_portal/rspec/formatter.rb index 1d287b7..e674d81 100644 --- a/lib/report_portal/rspec/formatter.rb +++ b/lib/report_portal/rspec/formatter.rb @@ -18,13 +18,18 @@ class Formatter def initialize(_output) ENV['REPORT_PORTAL_USED'] = 'true' + @root_node = Tree::TreeNode.new(SecureRandom.hex) + @parent_item_node = @root_node + @last_used_time = 0 end def start(_start_notification) - cmd_args = ARGV.map { |arg| arg.include?('rp_uuid=') ? 'rp_uuid=[FILTERED]' : arg }.join(' ') - ReportPortal.start_launch(cmd_args) - @root_node = Tree::TreeNode.new(SecureRandom.hex) - @current_group_node = @root_node + if ReportPortal::Settings.instance.attach_to_launch? + ReportPortal.launch_id = ReportPortal::Settings.get_launch_id + else + cmd_args = ARGV.map { |arg| arg.include?('rp_uuid=') ? 'rp_uuid=[FILTERED]' : arg }.join(' ') + ReportPortal.start_launch(cmd_args) + end end def example_group_started(group_notification) @@ -44,16 +49,16 @@ def example_group_started(group_notification) if group_node.nil? p "Group node is nil for item #{item.inspect}" else - @current_group_node << group_node unless @current_group_node.nil? # make @current_group_node parent of group_node - @current_group_node = group_node + @parent_item_node << group_node unless @parent_item_node.nil? # make @current_group_node parent of group_node + @parent_item_node = group_node group_node.content.id = ReportPortal.start_item(group_node) end end def example_group_finished(_group_notification) - unless @current_group_node.nil? - ReportPortal.finish_item(@current_group_node.content) - @current_group_node = @current_group_node.parent + unless @parent_item_node.nil? + ReportPortal.finish_item(@parent_item_node.content) + @parent_item_node = @parent_item_node.parent end end @@ -74,7 +79,7 @@ def example_started(notification) if example_node.nil? p "Example node is nil for scenario #{ReportPortal.current_scenario.inspect}" else - @current_group_node << example_node + @parent_item_node << example_node example_node.content.id = ReportPortal.start_item(example_node) end end @@ -104,8 +109,34 @@ def message(notification) end end - def stop(_notification) - ReportPortal.finish_launch + def example_finished(desired_time) + ReportPortal.finish_item(@parent_item_node.content, nil, time_to_send(desired_time)) + end + + def close_all_children_of(root_node) + root_node.postordered_each do |node| + if !node.is_root? && !node.content.closed + ReportPortal.finish_item(node.content) + end + end + end + + def stop(_notification, desired_time = ReportPortal.now) + example_finished(desired_time) unless @parent_item_node.is_root? + + unless ReportPortal::Settings.instance.attach_to_launch? + close_all_children_of(@root_node) # Folder items are closed here as they can't be closed after finishing a feature + time_to_send = time_to_send(desired_time) + ReportPortal.finish_launch(time_to_send) + end + end + + def time_to_send(desired_time) + time_to_send = desired_time + if time_to_send <= @last_used_time + time_to_send = @last_used_time + 1 + end + @last_used_time = time_to_send end end end diff --git a/lib/report_portal/settings.rb b/lib/report_portal/settings.rb index 3eabe34..d8533ac 100644 --- a/lib/report_portal/settings.rb +++ b/lib/report_portal/settings.rb @@ -1,18 +1,14 @@ require 'yaml' require 'singleton' + module ReportPortal class Settings include Singleton def initialize - filename = ENV.fetch('rp_config') do - glob = Dir.glob('{,.config/,config/}report{,-,_}portal{.yml,.yaml}') - p "Multiple configuration files found for ReportPortal. Using the first one: #{glob.first}" if glob.size > 1 - glob.first - end - - @properties = filename.nil? ? {} : YAML.load_file(filename) + @filename = get_settings_file + @properties = @filename.nil? ? {} : YAML.load_file(@filename) keys = { 'uuid' => true, 'endpoint' => true, @@ -48,6 +44,27 @@ def formatter_modes setting('formatter_modes') || [] end + def use_same_thread_for_reporting? + formatter_modes.include?('use_same_thread_for_reporting') + end + + def attach_to_launch? + formatter_modes.include?('attach_to_launch') + end + + def get_launch_id + begin + if ReportPortal::Settings.instance.launch_id + ReportPortal::Settings.instance.launch_id + else + file_path = ReportPortal::Settings.instance.file_with_launch_id || (Pathname(Dir.pwd) + 'rp_launch_id.tmp') + File.read(file_path) + end + rescue ArgumentError + raise "ReportPortal: Define environment variable 'launch_id' or 'file_with_launch_id' " + end + end + private def setting(key) @@ -59,6 +76,14 @@ def setting(key) @properties[key] end + def get_settings_file + ENV.fetch('rp_config') do + glob = Dir.glob('{,.config/,config/}report{,-,_}portal{.yml,.yaml}') + p "Multiple configuration files found for ReportPortal. Using the first one: #{glob.first}" if glob.size > 1 + glob.first + end + end + def env_variable_name(key) 'rp_' + key end diff --git a/lib/report_portal/tasks.rb b/lib/report_portal/tasks.rb index 9acb5ba..c74250a 100644 --- a/lib/report_portal/tasks.rb +++ b/lib/report_portal/tasks.rb @@ -8,10 +8,10 @@ task :start_launch do description = ENV['description'] || ReportPortal::Settings.instance.description file_to_write_launch_id = ENV['file_for_launch_id'] || ReportPortal::Settings.instance.file_with_launch_id - file_to_write_launch_id ||= Pathname(Dir.tmpdir) + 'rp_launch_id.tmp' + file_to_write_launch_id ||= Pathname(Dir.pwd) + 'rp_launch_id.tmp' launch_id = ReportPortal.start_launch(description) File.write(file_to_write_launch_id, launch_id) - puts launch_id + launch_id end desc 'Finish launch in Report Portal (for use with attach_to_launch formatter mode)' @@ -21,7 +21,6 @@ puts "Launch id isn't provided. Provide it either via RP_LAUNCH_ID or RP_FILE_WITH_LAUNCH_ID environment variables" if !launch_id && !file_with_launch_id puts 'Both RP_LAUNCH_ID and RP_FILE_WITH_LAUNCH_ID are provided via environment variables' if launch_id && file_with_launch_id ReportPortal.launch_id = launch_id || File.read(file_with_launch_id) - ReportPortal.close_child_items(nil) ReportPortal.finish_launch end end