287 lines
8.8 KiB
Ruby
287 lines
8.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rspec/core/sandbox'
|
|
require 'active_support/testing/time_helpers'
|
|
|
|
describe QA::Support::Formatters::TestStatsFormatter do
|
|
include QA::Support::Helpers::StubEnv
|
|
include QA::Specs::Helpers::RSpec
|
|
include ActiveSupport::Testing::TimeHelpers
|
|
|
|
let(:url) { 'http://influxdb.net' }
|
|
let(:token) { 'token' }
|
|
let(:ci_timestamp) { '2021-02-23T20:58:41Z' }
|
|
let(:ci_job_name) { 'test-job 1/5' }
|
|
let(:ci_job_url) { 'url' }
|
|
let(:ci_pipeline_url) { 'url' }
|
|
let(:ci_pipeline_id) { '123' }
|
|
let(:run_type) { 'staging-full' }
|
|
let(:smoke) { 'false' }
|
|
let(:reliable) { 'false' }
|
|
let(:quarantined) { 'false' }
|
|
let(:influx_client) { instance_double('InfluxDB2::Client', create_write_api: influx_write_api) }
|
|
let(:influx_write_api) { instance_double('InfluxDB2::WriteApi', write: nil) }
|
|
let(:stage) { '1_manage' }
|
|
let(:file_path) { "./qa/specs/features/#{stage}/subfolder/some_spec.rb" }
|
|
let(:ui_fabrication) { 0 }
|
|
let(:api_fabrication) { 0 }
|
|
let(:fabrication_resources) { {} }
|
|
let(:testcase) { 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234' }
|
|
|
|
let(:influx_client_args) do
|
|
{
|
|
bucket: 'e2e-test-stats',
|
|
org: 'gitlab-qa',
|
|
precision: InfluxDB2::WritePrecision::NANOSECOND
|
|
}
|
|
end
|
|
|
|
let(:data) do
|
|
{
|
|
name: 'test-stats',
|
|
time: DateTime.strptime(ci_timestamp).to_time,
|
|
tags: {
|
|
name: 'stats export spec',
|
|
file_path: file_path.gsub('./qa/specs/features', ''),
|
|
status: :passed,
|
|
smoke: smoke,
|
|
reliable: reliable,
|
|
quarantined: quarantined,
|
|
retried: 'false',
|
|
job_name: 'test-job',
|
|
merge_request: 'false',
|
|
run_type: run_type,
|
|
stage: stage.match(%r{\d{1,2}_(\w+)}).captures.first,
|
|
testcase: testcase
|
|
},
|
|
fields: {
|
|
id: './spec/support/formatters/test_stats_formatter_spec.rb[1:1]',
|
|
run_time: 0,
|
|
api_fabrication: api_fabrication * 1000,
|
|
ui_fabrication: ui_fabrication * 1000,
|
|
total_fabrication: (api_fabrication + ui_fabrication) * 1000,
|
|
retry_attempts: 0,
|
|
job_url: ci_job_url,
|
|
pipeline_url: ci_pipeline_url,
|
|
pipeline_id: ci_pipeline_id,
|
|
merge_request_iid: nil
|
|
}
|
|
}
|
|
end
|
|
|
|
def run_spec(&spec)
|
|
spec ||= -> { it('spec', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {} }
|
|
|
|
describe_successfully('stats export', &spec).tap do |example_group|
|
|
example_group.examples.each { |ex| ex.metadata[:file_path] = file_path }
|
|
end
|
|
send_stop_notification
|
|
end
|
|
|
|
around do |example|
|
|
RSpec::Core::Sandbox.sandboxed do |config|
|
|
config.formatter = QA::Support::Formatters::TestStatsFormatter
|
|
config.before(:context) { RSpec.current_example = nil }
|
|
|
|
example.run
|
|
end
|
|
end
|
|
|
|
before do
|
|
allow(InfluxDB2::Client).to receive(:new).with(url, token, **influx_client_args) { influx_client }
|
|
allow(QA::Tools::TestResourceDataProcessor).to receive(:resources) { fabrication_resources }
|
|
allow_any_instance_of(RSpec::Core::Example::ExecutionResult).to receive(:run_time).and_return(0) # rubocop:disable RSpec/AnyInstanceOf
|
|
end
|
|
|
|
context 'without influxdb variables configured' do
|
|
it 'skips export without influxdb url' do
|
|
stub_env('QA_INFLUXDB_URL', nil)
|
|
stub_env('QA_INFLUXDB_TOKEN', nil)
|
|
|
|
run_spec
|
|
|
|
expect(influx_client).not_to have_received(:create_write_api)
|
|
end
|
|
|
|
it 'skips export without influxdb token' do
|
|
stub_env('QA_INFLUXDB_URL', url)
|
|
stub_env('QA_INFLUXDB_TOKEN', nil)
|
|
|
|
run_spec
|
|
|
|
expect(influx_client).not_to have_received(:create_write_api)
|
|
end
|
|
end
|
|
|
|
context 'with influxdb variables configured' do
|
|
let(:spec_name) { 'exports data' }
|
|
let(:run_type) { ci_job_name.gsub(%r{ \d{1,2}/\d{1,2}}, '') }
|
|
|
|
before do
|
|
stub_env('QA_INFLUXDB_URL', url)
|
|
stub_env('QA_INFLUXDB_TOKEN', token)
|
|
stub_env('CI_PIPELINE_CREATED_AT', ci_timestamp)
|
|
stub_env('CI_JOB_URL', ci_job_url)
|
|
stub_env('CI_JOB_NAME', ci_job_name)
|
|
stub_env('CI_PIPELINE_URL', ci_pipeline_url)
|
|
stub_env('CI_PIPELINE_ID', ci_pipeline_id)
|
|
stub_env('CI_MERGE_REQUEST_IID', nil)
|
|
stub_env('TOP_UPSTREAM_MERGE_REQUEST_IID', nil)
|
|
stub_env('QA_RUN_TYPE', run_type)
|
|
end
|
|
|
|
context 'with reliable spec' do
|
|
let(:reliable) { 'true' }
|
|
|
|
it 'exports data to influxdb with correct reliable tag' do
|
|
run_spec do
|
|
it('spec', :reliable, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
|
|
end
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with smoke spec' do
|
|
let(:smoke) { 'true' }
|
|
|
|
it 'exports data to influxdb with correct smoke tag' do
|
|
run_spec do
|
|
it('spec', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
|
|
end
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with quarantined spec' do
|
|
let(:quarantined) { 'true' }
|
|
|
|
it 'exports data to influxdb with correct quarantine tag' do
|
|
run_spec do
|
|
it('spec', :quarantine, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234') {}
|
|
end
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with context quarantined spec' do
|
|
let(:quarantined) { 'false' }
|
|
|
|
it 'exports data to influxdb with correct qurantine tag' do
|
|
run_spec do
|
|
it(
|
|
'spec',
|
|
quarantine: { only: { job: 'praefect' } },
|
|
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234'
|
|
) {}
|
|
end
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with staging full run' do
|
|
let(:run_type) { 'staging-full' }
|
|
|
|
before do
|
|
stub_env('CI_PROJECT_NAME', 'staging')
|
|
stub_env('QA_RUN_TYPE', nil)
|
|
end
|
|
|
|
it 'exports data to influxdb with correct run type' do
|
|
run_spec
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with staging sanity no admin' do
|
|
let(:run_type) { 'staging-sanity-no-admin' }
|
|
|
|
before do
|
|
stub_env('CI_PROJECT_NAME', 'staging')
|
|
stub_env('NO_ADMIN', 'true')
|
|
stub_env('SMOKE_ONLY', 'true')
|
|
stub_env('QA_RUN_TYPE', nil)
|
|
end
|
|
|
|
it 'exports data to influxdb with correct run type' do
|
|
run_spec
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with fabrication runtimes' do
|
|
let(:api_fabrication) { 4 }
|
|
let(:ui_fabrication) { 10 }
|
|
let(:testcase) { nil }
|
|
|
|
it 'exports data to influxdb with fabrication times' do
|
|
run_spec do
|
|
# Main logic tracks fabrication time in thread local variable and injects it as metadata from
|
|
# global after hook defined in main spec_helper.
|
|
#
|
|
# Inject the values directly since we do not load e2e test spec_helper in unit tests
|
|
it('spec', api_fabrication: 4, browser_ui_fabrication: 10) {}
|
|
end
|
|
|
|
expect(influx_write_api).to have_received(:write).once
|
|
expect(influx_write_api).to have_received(:write).with(data: [data])
|
|
end
|
|
end
|
|
|
|
context 'with fabrication resources' do
|
|
let(:fabrication_resources) do
|
|
{
|
|
'QA::Resource::Project' => [{
|
|
info: "with id '1'",
|
|
api_path: '/project',
|
|
fabrication_method: :api,
|
|
fabrication_time: 1,
|
|
http_method: :post,
|
|
timestamp: Time.now.to_s
|
|
}]
|
|
}
|
|
end
|
|
|
|
let(:fabrication_data) do
|
|
{
|
|
name: 'fabrication-stats',
|
|
time: DateTime.strptime(ci_timestamp).to_time,
|
|
tags: {
|
|
resource: 'QA::Resource::Project',
|
|
fabrication_method: :api,
|
|
http_method: :post,
|
|
run_type: run_type,
|
|
merge_request: "false"
|
|
},
|
|
fields: {
|
|
fabrication_time: 1,
|
|
info: "with id '1'",
|
|
job_url: ci_job_url,
|
|
timestamp: Time.now.to_s
|
|
}
|
|
}
|
|
end
|
|
|
|
around do |example|
|
|
freeze_time { example.run }
|
|
end
|
|
|
|
it 'exports fabrication stats data to influxdb' do
|
|
run_spec
|
|
|
|
expect(influx_write_api).to have_received(:write).with(data: [fabrication_data])
|
|
end
|
|
end
|
|
end
|
|
end
|