lib/testrail.rb in gridium-1.0.17 vs lib/testrail.rb in gridium-1.0.18

- old
+ new

@@ -2,122 +2,152 @@ require 'net/https' require 'uri' require 'json' module Gridium - class TestRail - ENV_ERROR = "Environment Variable not set!" + class TestRail + ENV_ERROR = "Environment Variable not set!" + CONFIG = {:pass => 1, :blocked => 2, :untested => 3, :retest => 4, :fail => 5}.freeze - #TestRail Statuses - PASSED = 1 - BLOCKED = 2 - UNTESTED = 3 - RETEST = 4 - FAILED = 5 - def initialize + def initialize if Gridium.config.testrail @url = ENV['GRIDIUM_TR_URL'].empty? || ENV['GRIDIUM_TR_URL'].nil? ? ENV_ERROR : ENV['GRIDIUM_TR_URL'] + '/index.php?/api/v2/' @user = ENV['GRIDIUM_TR_USER'].empty? || ENV['GRIDIUM_TR_USER'].nil? ? ENV_ERROR : ENV['GRIDIUM_TR_USER'] @password = ENV['GRIDIUM_TR_PW'].empty? || ENV['GRIDIUM_TR_PW'].nil? ? ENV_ERROR : ENV['GRIDIUM_TR_PW'] @pid = ENV['GRIDIUM_TR_PID'].empty? || ENV['GRIDIUM_TR_PID'].nil? ? ENV_ERROR : ENV['GRIDIUM_TR_PID'] - @testcase_ids = Array.new - @testcase_infos = Array.new + @retry_attempts = 5 + @time_between_retries = 3 + @tc_results = Array.new + @tc_ids = Array.new end - end + @run_info = {:id => 0 ,:error => false, :include_all => false} + end + # Creates a new test Run in your TestRail instance. + # + # @param name [String] the name of the test run. Error text will be added if an error occurs + # @param desc [String] a description of the run being added. Error text will be added if an error occurs + # @return [int] The run ID of the created run or zero if no run created. def add_run(name, desc) if Gridium.config.testrail Log.debug("[GRIDIUM::TestRail] Creating Test Run: name: #{name} desc: #{desc}") if name.nil? || name.empty? then - raise(ArgumentError, "Empty Run Name - Run name is required") + @run_info[:error] = true + else + @run_info[:name] = name + @run_info[:desc] = desc end - r = _send_request('POST', "add_run/#{@pid}", {:name => name, :description => desc, :include_all => false}) - Log.debug("Result: #{r}") - unless r["id"].nil? - @runid = r["id"] + r = _send_request('POST', "#{@url}add_run/#{@pid}", @run_info) + if r.key?('error') || r["id"].nil? + @run_info[:error] = true + else + @run_info[:id] = r["id"] + Log.debug("[GRIDIUM::TestRail] Run Added: #{r}") end end + return @run_info[:id] end - def add_case(rspec_test) - if Gridium.config.testrail - Log.debug("[GRIDIUM::TestRail] Adding to list of TestRail Cases...") - if rspec_test.nil? then - Log.error("[GRIDIUM::TestRail] No test added to results. Turn of Gridium.config.testrail\n") - end - if rspec_test.exception - status = FAILED - message = rspec_test.exception.message - else - status = PASSED - message = 'Test Passed.' - end - test_info = {:trid => rspec_test.metadata[:testrail_id], :status_id => status, :message => message} - @testcase_infos.push(test_info) - @testcase_ids.push(test_info[:trid]) - end - end + # Adds determines what the result of the test is and adds information to various arrays for processing during closing. + # + # @param rspec_test [RSpec::Example] the example provided by RSpec + # @return [bool] determine if case was added or not + def add_case(rspec_test) + added = false + if Gridium.config.testrail + Log.debug("[GRIDIUM::TestRail] Adding to list of TestRail Cases...") + if rspec_test.nil? then + Log.error("[GRIDIUM::TestRail] No test added to results. Turn of Gridium.config.testrail\n") + end + if rspec_test.exception + status = CONFIG[:fail] + message = rspec_test.exception.message + else + status = CONFIG[:pass] + message = 'Test Passed.' + end + test_info = {:case_id => rspec_test.metadata[:testrail_id], :status_id => status, :comment => message} + @tc_results.push(test_info) + @tc_ids.push(test_info[:case_id]) + added = true + end + return added + end - def close_run - if Gridium.config.testrail - Log.debug("[GRIDIUM::TestRail] Closing test runid: #{@runid}\n") - unless @runid.nil? - r = _send_request('POST', "update_run/#{@runid}", {:case_ids => @testcase_ids}) - @testcase_infos.each do |tc| - r = _send_request( - 'POST', - "add_result_for_case/#{@runid}/#{tc[:trid]}", - status_id: tc[:status_id], - comment: tc[:message] - ) - sleep(0.25) - end - r = _send_request('POST', "close_run/#{@runid}", nil) - end - end - end + # Updates the existing test run with test cases and results. Adds error text for missing test cases if needed. Closes the run as long as it exists. + # + # @return [bool] if the run was closed or not + def close_run + closed = false + if Gridium.config.testrail && !@run_info[:error] + Log.debug("[GRIDIUM::TestRail] Closing test runid: #{@run_info[:id]}\n") + r = _send_request('POST', "#{@url}update_run/#{@run_info[:id]}", {:case_ids => @tc_ids}) + Log.debug("[GRIDIUM::TestRail] UPDATE RUN: #{r}") + sleep 0.25 + r = _send_request('POST', "#{@url}add_results_for_cases/#{@run_info[:id]}", {results: @tc_results}) + Log.debug("[GRIDIUM::TestRail] ADD RESULTS: #{r}") + sleep 0.25 + Log.debug("#{r.class}") + if r.is_a?(Hash) + r = _send_request('POST', "#{@url}update_run/#{@run_info[:id]}", {:name => "ER:#{@run_info[:name]}", :description => "#{@run_info[:desc]}\nThe following was returned when adding cases: #{r}"}) + Log.warn("[GRIDIUM::TestRail] ERROR: #{r}") + sleep 0.25 + end + r = _send_request('POST', "#{@url}close_run/#{@run_info[:id]}", nil) + Log.debug("[GRIDIUM::TestRail] CLOSE RUN: #{r}") + closed = true + end + return closed + end private - def _send_request(method, uri, data) - url = URI.parse(@url + uri) - Log.debug("[GRIDIUM::TestRail] Method: #{method} URL:#{uri} Data:#{data}") - if method == 'POST' - request = Net::HTTP::Post.new(url.path + '?' + url.query) - request.body = JSON.dump(data) - else - request = Net::HTTP::Get.new(url.path + '?' + url.query) - end - request.basic_auth(@user, @password) - request.add_field('Content-Type', 'application/json') + def _send_request(method, uri, data) + attempts = @retry_attempts + url = URI.parse(uri) + Log.debug("[GRIDIUM::TestRail] Method: #{method} URL:#{uri} Data:#{data}") + if method == 'POST' + request = Net::HTTP::Post.new(url.path + '?' + url.query) + request.body = JSON.dump(data) + else + request = Net::HTTP::Get.new(url.path + '?' + url.query) + end + request.basic_auth(@user, @password) + request.add_field('Content-Type', 'application/json') - conn = Net::HTTP.new(url.host, url.port) - if url.scheme == 'https' - conn.use_ssl = true - conn.verify_mode = OpenSSL::SSL::VERIFY_NONE - end - response = conn.request(request) - if response.body && !response.body.empty? - result = JSON.parse(response.body) - else - result = {} - end + conn = Net::HTTP.new(url.host, url.port) + if url.scheme == 'https' + conn.use_ssl = true + conn.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + begin + response = conn.request(request) + if response.body && !response.body.empty? + result = JSON.parse(response.body) + else + result = {} + end - if response.code != '200' + if response.code != '200' + if result && result.key?('error') + error = '"' + result['error'] + '"' + else + error = 'No additional error message received' + end + Log.error("[GRIDIUM::TestRail] #{response.code} - Error with request: #{error}") + end + rescue SocketError => error + Log.warn("[GRIDIUM::TestRail] SocketError - Retrying....") + if attempts > 0 + attempts -= 1 + sleep @time_between_retries + retry + end + Log.error("[GRIDIUM::TestRail] Socket Error after numerous attempts. Error: #{error}") + result = {error: "SocketError after #{@retry_attempts} attempts. See Error Log."} + end - if result && result.key?('error') - error = '"' + result['error'] + '"' - else - error = 'No additional error message received' - end - Log.debug("[GRIDIUM::TestRail] Error with request: #{error}") - raise APIError.new('TestRail API returned HTTP %s (%s)' % - [response.code, error]) - end + result + end + end - result - end - end - - class APIError < StandardError - end end