Commit 6432a81f authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents fcc09621 9f2cc6df
...@@ -1853,25 +1853,29 @@ class MergeRequest < ApplicationRecord ...@@ -1853,25 +1853,29 @@ class MergeRequest < ApplicationRecord
override :ensure_metrics override :ensure_metrics
def ensure_metrics def ensure_metrics
# Backward compatibility: some merge request metrics records will not have target_project_id filled in. if Feature.enabled?(:use_upsert_query_for_mr_metrics)
# In that case the first `safe_find_or_create_by` will return false. MergeRequest::Metrics.record!(self)
# The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507 else
metrics_record = MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id, target_project_id: target_project_id) || MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id) # Backward compatibility: some merge request metrics records will not have target_project_id filled in.
# In that case the first `safe_find_or_create_by` will return false.
metrics_record.tap do |metrics_record| # The second finder call will be eliminated in https://gitlab.com/gitlab-org/gitlab/-/issues/233507
# Make sure we refresh the loaded association object with the newly created/loaded item. metrics_record = MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id, target_project_id: target_project_id) || MergeRequest::Metrics.safe_find_or_create_by(merge_request_id: id)
# This is needed in order to have the exact functionality than before.
# metrics_record.tap do |metrics_record|
# Example: # Make sure we refresh the loaded association object with the newly created/loaded item.
# # This is needed in order to have the exact functionality than before.
# merge_request.metrics.destroy #
# merge_request.ensure_metrics # Example:
# merge_request.metrics # should return the metrics record and not nil #
# merge_request.metrics.merge_request # should return the same MR record # merge_request.metrics.destroy
# merge_request.ensure_metrics
metrics_record.target_project_id = target_project_id # merge_request.metrics # should return the metrics record and not nil
metrics_record.association(:merge_request).target = self # merge_request.metrics.merge_request # should return the same MR record
association(:metrics).target = metrics_record
metrics_record.target_project_id = target_project_id
metrics_record.association(:merge_request).target = self
association(:metrics).target = metrics_record
end
end end
end end
......
...@@ -14,8 +14,23 @@ class MergeRequest::Metrics < ApplicationRecord ...@@ -14,8 +14,23 @@ class MergeRequest::Metrics < ApplicationRecord
scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) } scope :with_valid_time_to_merge, -> { where(arel_table[:merged_at].gt(arel_table[:created_at])) }
scope :by_target_project, ->(project) { where(target_project_id: project) } scope :by_target_project, ->(project) { where(target_project_id: project) }
def self.time_to_merge_expression class << self
Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))') def time_to_merge_expression
Arel.sql('EXTRACT(epoch FROM SUM(AGE(merge_request_metrics.merged_at, merge_request_metrics.created_at)))')
end
def record!(mr)
sql = <<~SQL
INSERT INTO #{self.table_name} (merge_request_id, target_project_id, updated_at, created_at)
VALUES (#{mr.id}, #{mr.target_project_id}, NOW(), NOW())
ON CONFLICT (merge_request_id)
DO UPDATE SET
target_project_id = EXCLUDED.target_project_id,
updated_at = NOW()
SQL
connection.execute(sql)
end
end end
private private
......
---
name: use_upsert_query_for_mr_metrics
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69240
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339677
milestone: '14.3'
type: development
group: group::optimize
default_enabled: false
...@@ -44,3 +44,4 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec ...@@ -44,3 +44,4 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. | | `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
| `:testcase` | The link to the test case issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/). | | `:testcase` | The link to the test case issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/). |
| `:transient` | The test tests transient bugs. It is excluded by default. | | `:transient` | The test tests transient bugs. It is excluded by default. |
| `:issue`, `:issue_${num}` | Optional links to issues which might be related to the spec. Helps keeping track of related issues and can also be used by tools that create test reports. Currently added automatically to `Allure` test report. Multiple tags can be used by adding optional number postfix like `issue_1`, `issue_2` etc. |
...@@ -8,7 +8,9 @@ module Analytics ...@@ -8,7 +8,9 @@ module Analytics
def execute(force: false) def execute(force: false)
merge_requests.each do |mr| merge_requests.each do |mr|
metrics = mr.ensure_metrics mr.ensure_metrics
mr.reset # clear already loaded (nil) metrics association
metrics = mr.metrics
next if !force && metric_already_present?(metrics) next if !force && metric_already_present?(metrics)
......
...@@ -4,7 +4,7 @@ source 'https://rubygems.org' ...@@ -4,7 +4,7 @@ source 'https://rubygems.org'
gem 'gitlab-qa', require: 'gitlab/qa' gem 'gitlab-qa', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile gem 'activesupport', '~> 6.1.3.2' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.14.1' gem 'allure-rspec', '~> 2.14.5'
gem 'capybara', '~> 3.35.0' gem 'capybara', '~> 3.35.0'
gem 'capybara-screenshot', '~> 1.0.23' gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.3' gem 'rake', '~> 12.3.3'
......
...@@ -19,10 +19,10 @@ GEM ...@@ -19,10 +19,10 @@ GEM
rack-test (>= 1.1.0, < 2.0) rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0) rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8) rspec (~> 3.8)
allure-rspec (2.14.2) allure-rspec (2.14.5)
allure-ruby-commons (= 2.14.2) allure-ruby-commons (= 2.14.5)
rspec-core (>= 3.8, < 4) rspec-core (>= 3.8, < 4)
allure-ruby-commons (2.14.2) allure-ruby-commons (2.14.5)
mime-types (>= 3.3, < 4) mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4) oj (>= 3.10, < 4)
require_all (>= 2, < 4) require_all (>= 2, < 4)
...@@ -111,7 +111,7 @@ GEM ...@@ -111,7 +111,7 @@ GEM
octokit (4.21.0) octokit (4.21.0)
faraday (>= 0.9) faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3) sawyer (~> 0.8.0, >= 0.5.3)
oj (3.12.1) oj (3.13.2)
parallel (1.19.2) parallel (1.19.2)
parallel_tests (2.29.0) parallel_tests (2.29.0)
parallel parallel
...@@ -212,7 +212,7 @@ PLATFORMS ...@@ -212,7 +212,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
activesupport (~> 6.1.3.2) activesupport (~> 6.1.3.2)
airborne (~> 0.3.4) airborne (~> 0.3.4)
allure-rspec (~> 2.14.1) allure-rspec (~> 2.14.5)
capybara (~> 3.35.0) capybara (~> 3.35.0)
capybara-screenshot (~> 1.0.23) capybara-screenshot (~> 1.0.23)
chemlab (~> 0.7) chemlab (~> 0.7)
......
...@@ -29,6 +29,13 @@ module QA ...@@ -29,6 +29,13 @@ module QA
AllureRspec.configure do |config| AllureRspec.configure do |config|
config.results_directory = 'tmp/allure-results' config.results_directory = 'tmp/allure-results'
config.clean_results_directory = true config.clean_results_directory = true
# automatically attach links to testcases and issues
config.tms_tag = :testcase
config.link_tms_pattern = '{}'
config.issue_tag = :issue
config.link_issue_pattern = '{}'
config.environment_properties = environment_info if Env.running_in_ci? config.environment_properties = environment_info if Env.running_in_ci?
# Set custom environment name to separate same specs executed on different environments # Set custom environment name to separate same specs executed on different environments
......
...@@ -71,9 +71,6 @@ module QA ...@@ -71,9 +71,6 @@ module QA
end end
end end
# Non blocking issues:
# https://gitlab.com/gitlab-org/gitlab/-/issues/331252
# https://gitlab.com/gitlab-org/gitlab/-/issues/333678 <- can cause 500 when creating user and group back to back
it( it(
'imports group with subgroups and labels', 'imports group with subgroups and labels',
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1871' testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1871'
......
...@@ -54,10 +54,14 @@ module QA ...@@ -54,10 +54,14 @@ module QA
end end
end end
# Non blocking issues: it(
# https://gitlab.com/gitlab-org/gitlab/-/issues/331252 'imports group from UI',
# https://gitlab.com/gitlab-org/gitlab/-/issues/333678 <- can cause 500 when creating user and group back to back testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1785',
it 'imports group from UI', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1785' do issue_1: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331252',
issue_2: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333678',
# mostly impacts testing as it makes small groups import slower
issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351'
) do
Page::Group::BulkImport.perform do |import_page| Page::Group::BulkImport.perform do |import_page|
import_page.import_group(imported_group.path, imported_group.sandbox.path) import_page.import_group(imported_group.path, imported_group.sandbox.path)
......
...@@ -17,9 +17,6 @@ module QA ...@@ -17,9 +17,6 @@ module QA
def example_started(example_notification) def example_started(example_notification)
example = example_notification.example example = example_notification.example
testcase = example.metadata[:testcase]
example.tms('Testcase', testcase) if testcase
quarantine_issue = example.metadata.dig(:quarantine, :issue) quarantine_issue = example.metadata.dig(:quarantine, :issue)
example.issue('Quarantine issue', quarantine_issue) if quarantine_issue example.issue('Quarantine issue', quarantine_issue) if quarantine_issue
......
...@@ -34,7 +34,6 @@ describe QA::Support::AllureMetadataFormatter do ...@@ -34,7 +34,6 @@ describe QA::Support::AllureMetadataFormatter do
formatter.example_started(rspec_example_notification) formatter.example_started(rspec_example_notification)
aggregate_failures do aggregate_failures do
expect(rspec_example).to have_received(:tms).with('Testcase', 'testcase')
expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue') expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue')
expect(rspec_example).to have_received(:add_link).with(name: "Job(#{ci_job})", url: ci_job_url) expect(rspec_example).to have_received(:add_link).with(name: "Job(#{ci_job})", url: ci_job_url)
expect(rspec_example).to have_received(:issue).with( expect(rspec_example).to have_received(:issue).with(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment