diff options
Diffstat (limited to 'qa/qa/support/formatters')
-rw-r--r-- | qa/qa/support/formatters/allure_metadata_formatter.rb | 11 | ||||
-rw-r--r-- | qa/qa/support/formatters/test_metrics_formatter.rb | 67 |
2 files changed, 60 insertions, 18 deletions
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb index 02719536b17..c8ddbeb4536 100644 --- a/qa/qa/support/formatters/allure_metadata_formatter.rb +++ b/qa/qa/support/formatters/allure_metadata_formatter.rb @@ -116,8 +116,7 @@ module QA # @return [Array] def flaky_specs @flaky_specs ||= influx_data.lazy.each_with_object({}) do |data, result| - # Do not consider failures in same merge request - records = data.records.reject { |r| r.values["_value"] == merge_request_iid } + records = data.records runs = records.count failed = records.count { |r| r.values["status"] == "failed" } @@ -136,14 +135,14 @@ module QA def influx_data return [] unless run_type - query_api.query(query: <<~QUERY).values - from(bucket: "#{Support::InfluxdbTools::INFLUX_TEST_METRICS_BUCKET}") - |> range(start: -14d) + query_api.query(query: <<~QUERY) + from(bucket: "#{Support::InfluxdbTools::INFLUX_MAIN_TEST_METRICS_BUCKET}") + |> range(start: -30d) |> filter(fn: (r) => r._measurement == "test-stats") |> filter(fn: (r) => r.run_type == "#{run_type}" and r.status != "pending" and r.quarantined == "false" and - r._field == "merge_request_iid" + r._field == "id" ) |> group(columns: ["testcase"]) QUERY diff --git a/qa/qa/support/formatters/test_metrics_formatter.rb b/qa/qa/support/formatters/test_metrics_formatter.rb index e84373a487d..6e6cdc35af5 100644 --- a/qa/qa/support/formatters/test_metrics_formatter.rb +++ b/qa/qa/support/formatters/test_metrics_formatter.rb @@ -8,6 +8,8 @@ module QA class TestMetricsFormatter < RSpec::Core::Formatters::BaseFormatter include Support::InfluxdbTools + CUSTOM_METRICS_KEY = :custom_test_metrics + RSpec::Core::Formatters.register(self, :stop) # Finish test execution @@ -19,16 +21,15 @@ module QA parse_execution_data(notification.examples) - if Runtime::Env.export_metrics? - push_test_metrics - push_fabrication_metrics - end - - save_test_metrics if Runtime::Env.save_metrics_json? + push_test_metrics + push_fabrication_metrics + save_test_metrics end private + delegate :export_metrics?, :save_metrics_json?, :ci_job_url, :ci_job_name, to: "QA::Runtime::Env" + # Save execution data for the run # # @param [Array<RSpec::Core::Example>] examples @@ -42,6 +43,8 @@ module QA # # @return [void] def push_test_metrics + return log(:debug, "Metrics export not enabled, skipping test metrics export") unless export_metrics? + write_api.write(data: execution_data) log(:debug, "Pushed #{execution_data.length} test execution entries to influxdb") rescue StandardError => e @@ -52,6 +55,8 @@ module QA # # @return [void] def push_fabrication_metrics + return log(:debug, "Metrics export not enabled, skipping fabrication metrics export") unless export_metrics? + data = Tools::TestResourceDataProcessor.resources.flat_map do |resource, values| values.map { |v| fabrication_stats(resource: resource, **v) } end @@ -67,6 +72,8 @@ module QA # # @return [void] def save_test_metrics + return log(:debug, "Saving test metrics json not enabled, skipping") unless save_metrics_json? + File.write("tmp/test-metrics-#{env('CI_JOB_NAME_SLUG') || 'local'}.json", execution_data.to_json) rescue StandardError => e log(:error, "Failed to save test execution metrics, error: #{e}") @@ -101,7 +108,8 @@ module QA run_type: run_type, stage: devops_stage(file_path), product_group: example.metadata[:product_group], - testcase: example.metadata[:testcase] + testcase: example.metadata[:testcase], + **custom_metrics_tags(example.metadata) }, fields: { id: example.id, @@ -110,11 +118,12 @@ module QA ui_fabrication: ui_fabrication, total_fabrication: api_fabrication + ui_fabrication, retry_attempts: retry_attempts(example.metadata), - job_url: QA::Runtime::Env.ci_job_url, + job_url: ci_job_url, pipeline_url: env('CI_PIPELINE_URL'), pipeline_id: env('CI_PIPELINE_ID'), job_id: env('CI_JOB_ID'), - merge_request_iid: merge_request_iid + merge_request_iid: merge_request_iid, + **custom_metrics_fields(example.metadata) } } rescue StandardError => e @@ -139,13 +148,13 @@ module QA resource: resource, fabrication_method: fabrication_method, http_method: http_method, - run_type: env('QA_RUN_TYPE') || run_type, + run_type: run_type, merge_request: merge_request }, fields: { fabrication_time: fabrication_time, info: info, - job_url: QA::Runtime::Env.ci_job_url, + job_url: ci_job_url, timestamp: timestamp } } @@ -155,7 +164,7 @@ module QA # # @return [String] def job_name - @job_name ||= QA::Runtime::Env.ci_job_name&.gsub(%r{ \d{1,2}/\d{1,2}}, '') + @job_name ||= ci_job_name&.gsub(%r{ \d{1,2}/\d{1,2}}, '') end # Single common timestamp for all exported example metrics to keep data points consistently grouped @@ -220,6 +229,40 @@ module QA metadata[:retry_attempts] || 0 end + # Additional custom metrics tags + # + # @param [Hash] metadata + # @return [Hash] + def custom_metrics_tags(metadata) + custom_metrics(metadata, :tags) + end + + # Additional custom metrics fields + # + # @param [Hash] metadata + # @return [Hash] + def custom_metrics_fields(metadata) + custom_metrics(metadata, :fields) + end + + # Custom test metrics + # + # @param [Hash] metadata + # @param [Symbol] type type of metric, :fields or :tags + # @return [Hash] + def custom_metrics(metadata, type) + custom_metrics = metadata[CUSTOM_METRICS_KEY] + return {} unless custom_metrics + return {} unless custom_metrics.is_a?(Hash) && custom_metrics[type].is_a?(Hash) + + custom_metrics[type].to_h do |key, value| + k = key.to_sym + v = value.is_a?(Numeric) || value.nil? ? value : value.to_s + + [k, v] + end + end + # Print log message # # @param [Symbol] level |