summaryrefslogtreecommitdiff
path: root/spec/support
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-20 08:43:02 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-20 08:43:02 +0000
commitd9ab72d6080f594d0b3cae15f14b3ef2c6c638cb (patch)
tree2341ef426af70ad1e289c38036737e04b0aa5007 /spec/support
parentd6e514dd13db8947884cd58fe2a9c2a063400a9b (diff)
downloadgitlab-ce-d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb.tar.gz
Add latest changes from gitlab-org/gitlab@14-4-stable-eev14.4.0-rc42
Diffstat (limited to 'spec/support')
-rw-r--r--spec/support/before_all_adapter.rb14
-rw-r--r--spec/support/capybara.rb3
-rw-r--r--spec/support/database/cross-database-modification-allowlist.yml1343
-rw-r--r--spec/support/database/cross-join-allowlist.yml151
-rw-r--r--spec/support/database/multiple_databases.rb52
-rw-r--r--spec/support/database/prevent_cross_database_modification.rb24
-rw-r--r--spec/support/database/prevent_cross_joins.rb27
-rw-r--r--spec/support/database_cleaner.rb27
-rw-r--r--spec/support/database_load_balancing.rb30
-rw-r--r--spec/support/db_cleaner.rb75
-rw-r--r--spec/support/helpers/dependency_proxy_helpers.rb14
-rw-r--r--spec/support/helpers/feature_flag_helpers.rb2
-rw-r--r--spec/support/helpers/javascript_fixtures_helpers.rb13
-rw-r--r--spec/support/helpers/navbar_structure_helper.rb8
-rw-r--r--spec/support/helpers/stub_gitlab_calls.rb12
-rw-r--r--spec/support/helpers/usage_data_helpers.rb12
-rw-r--r--spec/support/matchers/be_request_urgency.rb8
-rw-r--r--spec/support/matchers/graphql_matchers.rb28
-rw-r--r--spec/support/matchers/markdown_matchers.rb2
-rw-r--r--spec/support/redis.rb16
-rw-r--r--spec/support/redis/redis_helpers.rb10
-rw-r--r--spec/support/redis/redis_new_instance_shared_examples.rb55
-rw-r--r--spec/support/redis/redis_shared_examples.rb28
-rw-r--r--spec/support/shared_contexts/bulk_imports_requests_shared_context.rb52
-rw-r--r--spec/support/shared_contexts/lib/gitlab/import_export/relation_tree_restorer_shared_context.rb2
-rw-r--r--spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb20
-rw-r--r--spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb5
-rw-r--r--spec/support/shared_contexts/policies/project_policy_shared_context.rb1
-rw-r--r--spec/support/shared_examples/ci/stuck_builds_shared_examples.rb35
-rw-r--r--spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/features/container_registry_shared_examples.rb9
-rw-r--r--spec/support/shared_examples/features/discussion_comments_shared_example.rb30
-rw-r--r--spec/support/shared_examples/features/project_upload_files_shared_examples.rb50
-rw-r--r--spec/support/shared_examples/graphql/connection_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb18
-rw-r--r--spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb22
-rw-r--r--spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb35
-rw-r--r--spec/support/shared_examples/lib/gitlab/import_export/attributes_permitter_shared_examples.rb40
-rw-r--r--spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb68
-rw-r--r--spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb51
-rw-r--r--spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb11
-rw-r--r--spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb37
-rw-r--r--spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb7
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/requests/api/issuable_search_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb16
-rw-r--r--spec/support/shared_examples/requests/rack_attack_shared_examples.rb5
-rw-r--r--spec/support/shared_examples/services/dependency_proxy_settings_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb53
-rw-r--r--spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb24
52 files changed, 2317 insertions, 358 deletions
diff --git a/spec/support/before_all_adapter.rb b/spec/support/before_all_adapter.rb
index f48e0f46e80..890bdd6a2c4 100644
--- a/spec/support/before_all_adapter.rb
+++ b/spec/support/before_all_adapter.rb
@@ -1,25 +1,25 @@
# frozen_string_literal: true
class BeforeAllAdapter # rubocop:disable Gitlab/NamespacedClass
- def self.all_connection_pools
- ::ActiveRecord::Base.connection_handler.all_connection_pools
+ def self.all_connection_classes
+ @all_connection_classes ||= [ActiveRecord::Base] + ActiveRecord::Base.descendants.select(&:connection_class?) # rubocop: disable Database/MultipleDatabases
end
def self.begin_transaction
- self.all_connection_pools.each do |connection_pool|
- connection_pool.connection.begin_transaction(joinable: false)
+ self.all_connection_classes.each do |connection_class|
+ connection_class.connection.begin_transaction(joinable: false)
end
end
def self.rollback_transaction
- self.all_connection_pools.each do |connection_pool|
- if connection_pool.connection.open_transactions.zero?
+ self.all_connection_classes.each do |connection_class|
+ if connection_class.connection.open_transactions.zero?
warn "!!! before_all transaction has been already rollbacked and " \
"could work incorrectly"
next
end
- connection_pool.connection.rollback_transaction
+ connection_class.connection.rollback_transaction
end
end
end
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index 6f96d552da6..ac35662ec93 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -22,7 +22,8 @@ JS_CONSOLE_FILTER = Regexp.union([
'"[WDS] Live Reloading enabled."',
'Download the Vue Devtools extension',
'Download the Apollo DevTools',
- "Unrecognized feature: 'interest-cohort'"
+ "Unrecognized feature: 'interest-cohort'",
+ 'Does this page need fixes or improvements?'
])
CAPYBARA_WINDOW_SIZE = [1366, 768].freeze
diff --git a/spec/support/database/cross-database-modification-allowlist.yml b/spec/support/database/cross-database-modification-allowlist.yml
new file mode 100644
index 00000000000..627967f65f3
--- /dev/null
+++ b/spec/support/database/cross-database-modification-allowlist.yml
@@ -0,0 +1,1343 @@
+- "./ee/spec/controllers/admin/geo/nodes_controller_spec.rb"
+- "./ee/spec/controllers/admin/geo/projects_controller_spec.rb"
+- "./ee/spec/controllers/admin/projects_controller_spec.rb"
+- "./ee/spec/controllers/concerns/internal_redirect_spec.rb"
+- "./ee/spec/controllers/ee/projects/jobs_controller_spec.rb"
+- "./ee/spec/controllers/oauth/geo_auth_controller_spec.rb"
+- "./ee/spec/controllers/projects/approver_groups_controller_spec.rb"
+- "./ee/spec/controllers/projects/approvers_controller_spec.rb"
+- "./ee/spec/controllers/projects/merge_requests_controller_spec.rb"
+- "./ee/spec/controllers/projects/merge_requests/creations_controller_spec.rb"
+- "./ee/spec/controllers/projects/settings/access_tokens_controller_spec.rb"
+- "./ee/spec/controllers/projects/subscriptions_controller_spec.rb"
+- "./ee/spec/features/account_recovery_regular_check_spec.rb"
+- "./ee/spec/features/admin/admin_audit_logs_spec.rb"
+- "./ee/spec/features/admin/admin_credentials_inventory_spec.rb"
+- "./ee/spec/features/admin/admin_dashboard_spec.rb"
+- "./ee/spec/features/admin/admin_dev_ops_report_spec.rb"
+- "./ee/spec/features/admin/admin_merge_requests_approvals_spec.rb"
+- "./ee/spec/features/admin/admin_reset_pipeline_minutes_spec.rb"
+- "./ee/spec/features/admin/admin_sends_notification_spec.rb"
+- "./ee/spec/features/admin/admin_settings_spec.rb"
+- "./ee/spec/features/admin/admin_show_new_user_signups_cap_alert_spec.rb"
+- "./ee/spec/features/admin/admin_users_spec.rb"
+- "./ee/spec/features/admin/geo/admin_geo_nodes_spec.rb"
+- "./ee/spec/features/admin/geo/admin_geo_projects_spec.rb"
+- "./ee/spec/features/admin/geo/admin_geo_replication_nav_spec.rb"
+- "./ee/spec/features/admin/geo/admin_geo_sidebar_spec.rb"
+- "./ee/spec/features/admin/geo/admin_geo_uploads_spec.rb"
+- "./ee/spec/features/admin/groups/admin_changes_plan_spec.rb"
+- "./ee/spec/features/admin/licenses/admin_uploads_license_spec.rb"
+- "./ee/spec/features/admin/licenses/show_user_count_threshold_spec.rb"
+- "./ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb"
+- "./ee/spec/features/analytics/code_analytics_spec.rb"
+- "./ee/spec/features/billings/billing_plans_spec.rb"
+- "./ee/spec/features/billings/extend_reactivate_trial_spec.rb"
+- "./ee/spec/features/billings/qrtly_reconciliation_alert_spec.rb"
+- "./ee/spec/features/boards/boards_licensed_features_spec.rb"
+- "./ee/spec/features/boards/boards_spec.rb"
+- "./ee/spec/features/boards/group_boards/board_deletion_spec.rb"
+- "./ee/spec/features/boards/group_boards/multiple_boards_spec.rb"
+- "./ee/spec/features/boards/new_issue_spec.rb"
+- "./ee/spec/features/boards/scoped_issue_board_spec.rb"
+- "./ee/spec/features/boards/sidebar_spec.rb"
+- "./ee/spec/features/boards/swimlanes/epics_swimlanes_drag_drop_spec.rb"
+- "./ee/spec/features/boards/swimlanes/epics_swimlanes_filtering_spec.rb"
+- "./ee/spec/features/boards/swimlanes/epics_swimlanes_sidebar_labels_spec.rb"
+- "./ee/spec/features/boards/swimlanes/epics_swimlanes_sidebar_spec.rb"
+- "./ee/spec/features/boards/swimlanes/epics_swimlanes_spec.rb"
+- "./ee/spec/features/boards/user_adds_lists_to_board_spec.rb"
+- "./ee/spec/features/boards/user_visits_board_spec.rb"
+- "./ee/spec/features/burndown_charts_spec.rb"
+- "./ee/spec/features/burnup_charts_spec.rb"
+- "./ee/spec/features/ci/ci_minutes_spec.rb"
+- "./ee/spec/features/ci_shared_runner_warnings_spec.rb"
+- "./ee/spec/features/clusters/create_agent_spec.rb"
+- "./ee/spec/features/dashboards/activity_spec.rb"
+- "./ee/spec/features/dashboards/groups_spec.rb"
+- "./ee/spec/features/dashboards/issues_spec.rb"
+- "./ee/spec/features/dashboards/merge_requests_spec.rb"
+- "./ee/spec/features/dashboards/operations_spec.rb"
+- "./ee/spec/features/dashboards/projects_spec.rb"
+- "./ee/spec/features/dashboards/todos_spec.rb"
+- "./ee/spec/features/discussion_comments/epic_quick_actions_spec.rb"
+- "./ee/spec/features/discussion_comments/epic_spec.rb"
+- "./ee/spec/features/epic_boards/epic_boards_sidebar_spec.rb"
+- "./ee/spec/features/epic_boards/epic_boards_spec.rb"
+- "./ee/spec/features/epic_boards/multiple_epic_boards_spec.rb"
+- "./ee/spec/features/epic_boards/new_epic_spec.rb"
+- "./ee/spec/features/epics/delete_epic_spec.rb"
+- "./ee/spec/features/epics/epic_issues_spec.rb"
+- "./ee/spec/features/epics/epic_labels_spec.rb"
+- "./ee/spec/features/epics/epic_show_spec.rb"
+- "./ee/spec/features/epics/epics_list_spec.rb"
+- "./ee/spec/features/epics/filtered_search/visual_tokens_spec.rb"
+- "./ee/spec/features/epics/gfm_autocomplete_spec.rb"
+- "./ee/spec/features/epics/issue_promotion_spec.rb"
+- "./ee/spec/features/epics/referencing_epics_spec.rb"
+- "./ee/spec/features/epics/shortcuts_epic_spec.rb"
+- "./ee/spec/features/epics/todo_spec.rb"
+- "./ee/spec/features/epics/update_epic_spec.rb"
+- "./ee/spec/features/epics/user_uses_quick_actions_spec.rb"
+- "./ee/spec/features/geo_node_spec.rb"
+- "./ee/spec/features/groups/analytics/ci_cd_analytics_spec.rb"
+- "./ee/spec/features/groups/analytics/cycle_analytics/charts_spec.rb"
+- "./ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb"
+- "./ee/spec/features/groups/analytics/cycle_analytics/multiple_value_streams_spec.rb"
+- "./ee/spec/features/groups/audit_events_spec.rb"
+- "./ee/spec/features/groups/billing_spec.rb"
+- "./ee/spec/features/groups/contribution_analytics_spec.rb"
+- "./ee/spec/features/groups/group_overview_spec.rb"
+- "./ee/spec/features/groups/group_roadmap_spec.rb"
+- "./ee/spec/features/groups/group_settings_spec.rb"
+- "./ee/spec/features/groups/groups_security_credentials_spec.rb"
+- "./ee/spec/features/groups/hooks/user_tests_hooks_spec.rb"
+- "./ee/spec/features/groups/insights_spec.rb"
+- "./ee/spec/features/groups/issues_spec.rb"
+- "./ee/spec/features/groups/iterations/iterations_list_spec.rb"
+- "./ee/spec/features/groups/iteration_spec.rb"
+- "./ee/spec/features/groups/iterations/user_creates_iteration_in_cadence_spec.rb"
+- "./ee/spec/features/groups/iterations/user_edits_iteration_cadence_spec.rb"
+- "./ee/spec/features/groups/iterations/user_edits_iteration_spec.rb"
+- "./ee/spec/features/groups/iterations/user_views_iteration_cadence_spec.rb"
+- "./ee/spec/features/groups/iterations/user_views_iteration_spec.rb"
+- "./ee/spec/features/groups/ldap_group_links_spec.rb"
+- "./ee/spec/features/groups/ldap_settings_spec.rb"
+- "./ee/spec/features/groups/members/leave_group_spec.rb"
+- "./ee/spec/features/groups/members/list_members_spec.rb"
+- "./ee/spec/features/groups/members/override_ldap_memberships_spec.rb"
+- "./ee/spec/features/groups/new_spec.rb"
+- "./ee/spec/features/groups/push_rules_spec.rb"
+- "./ee/spec/features/groups/saml_providers_spec.rb"
+- "./ee/spec/features/groups/scim_token_spec.rb"
+- "./ee/spec/features/groups/seat_usage/seat_usage_spec.rb"
+- "./ee/spec/features/groups/security/compliance_dashboards_spec.rb"
+- "./ee/spec/features/groups/settings/user_configures_insights_spec.rb"
+- "./ee/spec/features/groups/settings/user_searches_in_settings_spec.rb"
+- "./ee/spec/features/groups/sso_spec.rb"
+- "./ee/spec/features/groups/wikis_spec.rb"
+- "./ee/spec/features/groups/wiki/user_views_wiki_empty_spec.rb"
+- "./ee/spec/features/ide/user_commits_changes_spec.rb"
+- "./ee/spec/features/ide/user_opens_ide_spec.rb"
+- "./ee/spec/features/integrations/jira/jira_issues_list_spec.rb"
+- "./ee/spec/features/issues/blocking_issues_spec.rb"
+- "./ee/spec/features/issues/epic_in_issue_sidebar_spec.rb"
+- "./ee/spec/features/issues/filtered_search/filter_issues_by_iteration_spec.rb"
+- "./ee/spec/features/issues/filtered_search/filter_issues_epic_spec.rb"
+- "./ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb"
+- "./ee/spec/features/issues/form_spec.rb"
+- "./ee/spec/features/issues/gfm_autocomplete_ee_spec.rb"
+- "./ee/spec/features/issues/issue_actions_spec.rb"
+- "./ee/spec/features/issues/issue_sidebar_spec.rb"
+- "./ee/spec/features/issues/move_issue_resource_weight_events_spec.rb"
+- "./ee/spec/features/issues/related_issues_spec.rb"
+- "./ee/spec/features/issues/resource_weight_events_spec.rb"
+- "./ee/spec/features/issues/user_bulk_edits_issues_spec.rb"
+- "./ee/spec/features/issues/user_edits_issue_spec.rb"
+- "./ee/spec/features/issues/user_uses_quick_actions_spec.rb"
+- "./ee/spec/features/issues/user_views_issues_spec.rb"
+- "./ee/spec/features/labels_hierarchy_spec.rb"
+- "./ee/spec/features/markdown/metrics_spec.rb"
+- "./ee/spec/features/merge_requests/user_filters_by_approvers_spec.rb"
+- "./ee/spec/features/merge_requests/user_resets_approvers_spec.rb"
+- "./ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb"
+- "./ee/spec/features/merge_request/user_approves_with_password_spec.rb"
+- "./ee/spec/features/merge_request/user_creates_merge_request_spec.rb"
+- "./ee/spec/features/merge_request/user_creates_merge_request_with_blocking_mrs_spec.rb"
+- "./ee/spec/features/merge_request/user_creates_multiple_assignees_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_creates_multiple_reviewers_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_edits_approval_rules_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_edits_merge_request_blocking_mrs_spec.rb"
+- "./ee/spec/features/merge_request/user_edits_multiple_assignees_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_edits_multiple_reviewers_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_merges_immediately_spec.rb"
+- "./ee/spec/features/merge_request/user_merges_with_push_rules_spec.rb"
+- "./ee/spec/features/merge_request/user_sees_approval_widget_spec.rb"
+- "./ee/spec/features/merge_request/user_sees_closing_issues_message_spec.rb"
+- "./ee/spec/features/merge_request/user_sees_merge_widget_spec.rb"
+- "./ee/spec/features/merge_request/user_sees_status_checks_widget_spec.rb"
+- "./ee/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb"
+- "./ee/spec/features/merge_request/user_sets_approval_rules_spec.rb"
+- "./ee/spec/features/merge_request/user_sets_approvers_spec.rb"
+- "./ee/spec/features/merge_request/user_uses_slash_commands_spec.rb"
+- "./ee/spec/features/merge_request/user_views_blocked_merge_request_spec.rb"
+- "./ee/spec/features/merge_trains/user_adds_merge_request_to_merge_train_spec.rb"
+- "./ee/spec/features/merge_trains/user_adds_to_merge_train_when_pipeline_succeeds_spec.rb"
+- "./ee/spec/features/oncall_schedules/user_creates_schedule_spec.rb"
+- "./ee/spec/features/operations_nav_link_spec.rb"
+- "./ee/spec/features/profiles/account_spec.rb"
+- "./ee/spec/features/profiles/billing_spec.rb"
+- "./ee/spec/features/projects/audit_events_spec.rb"
+- "./ee/spec/features/projects/cluster_agents_spec.rb"
+- "./ee/spec/features/projects/custom_projects_template_spec.rb"
+- "./ee/spec/features/projects/environments/environments_spec.rb"
+- "./ee/spec/features/projects/feature_flags/feature_flag_issues_spec.rb"
+- "./ee/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb"
+- "./ee/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb"
+- "./ee/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb"
+- "./ee/spec/features/projects/insights_spec.rb"
+- "./ee/spec/features/projects/integrations/user_activates_jira_spec.rb"
+- "./ee/spec/features/projects/issues/user_creates_issue_spec.rb"
+- "./ee/spec/features/projects/iterations/iteration_cadences_list_spec.rb"
+- "./ee/spec/features/projects/iterations/iterations_list_spec.rb"
+- "./ee/spec/features/projects/iterations/user_views_iteration_spec.rb"
+- "./ee/spec/features/projects/jobs_spec.rb"
+- "./ee/spec/features/projects/kerberos_clone_instructions_spec.rb"
+- "./ee/spec/features/projects/licenses/maintainer_views_policies_spec.rb"
+- "./ee/spec/features/projects/members/member_is_removed_from_project_spec.rb"
+- "./ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb"
+- "./ee/spec/features/projects/merge_requests/user_edits_merge_request_spec.rb"
+- "./ee/spec/features/projects/mirror_spec.rb"
+- "./ee/spec/features/projects/new_project_from_template_spec.rb"
+- "./ee/spec/features/projects/new_project_spec.rb"
+- "./ee/spec/features/projects/path_locks_spec.rb"
+- "./ee/spec/features/projects/pipelines/pipeline_spec.rb"
+- "./ee/spec/features/projects/push_rules_spec.rb"
+- "./ee/spec/features/projects/quality/test_case_create_spec.rb"
+- "./ee/spec/features/projects/quality/test_case_list_spec.rb"
+- "./ee/spec/features/projects/quality/test_case_show_spec.rb"
+- "./ee/spec/features/projects/releases/user_views_release_spec.rb"
+- "./ee/spec/features/projects/requirements_management/requirements_list_spec.rb"
+- "./ee/spec/features/projects/security/dast_scanner_profiles_spec.rb"
+- "./ee/spec/features/projects/security/dast_site_profiles_spec.rb"
+- "./ee/spec/features/projects/security/user_creates_on_demand_scan_spec.rb"
+- "./ee/spec/features/projects/security/user_views_security_configuration_spec.rb"
+- "./ee/spec/features/projects/services/prometheus_custom_metrics_spec.rb"
+- "./ee/spec/features/projects/services/user_activates_github_spec.rb"
+- "./ee/spec/features/projects/settings/disable_merge_trains_setting_spec.rb"
+- "./ee/spec/features/projects/settings/ee/repository_mirrors_settings_spec.rb"
+- "./ee/spec/features/projects/settings/ee/service_desk_setting_spec.rb"
+- "./ee/spec/features/projects/settings/issues_settings_spec.rb"
+- "./ee/spec/features/projects/settings/merge_request_approvals_settings_spec.rb"
+- "./ee/spec/features/projects/settings/merge_requests_settings_spec.rb"
+- "./ee/spec/features/projects/settings/pipeline_subscriptions_spec.rb"
+- "./ee/spec/features/projects/settings/protected_environments_spec.rb"
+- "./ee/spec/features/projects/settings/user_manages_merge_pipelines_spec.rb"
+- "./ee/spec/features/projects/settings/user_manages_merge_trains_spec.rb"
+- "./ee/spec/features/projects_spec.rb"
+- "./ee/spec/features/projects/user_applies_custom_file_template_spec.rb"
+- "./ee/spec/features/projects/view_blob_with_code_owners_spec.rb"
+- "./ee/spec/features/projects/wiki/user_views_wiki_empty_spec.rb"
+- "./ee/spec/features/promotion_spec.rb"
+- "./ee/spec/features/protected_branches_spec.rb"
+- "./ee/spec/features/protected_tags_spec.rb"
+- "./ee/spec/features/registrations/combined_registration_spec.rb"
+- "./ee/spec/features/registrations/trial_during_signup_flow_spec.rb"
+- "./ee/spec/features/registrations/user_sees_new_onboarding_flow_spec.rb"
+- "./ee/spec/features/registrations/welcome_spec.rb"
+- "./ee/spec/features/search/elastic/global_search_spec.rb"
+- "./ee/spec/features/search/elastic/group_search_spec.rb"
+- "./ee/spec/features/search/elastic/project_search_spec.rb"
+- "./ee/spec/features/search/elastic/snippet_search_spec.rb"
+- "./ee/spec/features/search/user_searches_for_epics_spec.rb"
+- "./ee/spec/features/subscriptions/groups/edit_spec.rb"
+- "./ee/spec/features/trial_registrations/signup_spec.rb"
+- "./ee/spec/features/trials/capture_lead_spec.rb"
+- "./ee/spec/features/trials/select_namespace_spec.rb"
+- "./ee/spec/features/trials/show_trial_banner_spec.rb"
+- "./ee/spec/features/users/login_spec.rb"
+- "./ee/spec/finders/geo/attachment_legacy_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/container_repository_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/lfs_object_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/merge_request_diff_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/package_file_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/pages_deployment_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/pipeline_artifact_registry_finder_spec.rb"
+- "./ee/spec/finders/geo/project_registry_finder_spec.rb"
+- "./ee/spec/finders/merge_requests/by_approvers_finder_spec.rb"
+- "./ee/spec/frontend/fixtures/analytics/value_streams.rb"
+- "./ee/spec/graphql/mutations/dast_on_demand_scans/create_spec.rb"
+- "./ee/spec/graphql/mutations/dast/profiles/create_spec.rb"
+- "./ee/spec/graphql/mutations/dast/profiles/run_spec.rb"
+- "./ee/spec/graphql/mutations/dast/profiles/update_spec.rb"
+- "./ee/spec/graphql/mutations/merge_requests/accept_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/group_wiki_repository_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/lfs_object_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/merge_request_diff_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/package_file_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/pages_deployment_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/pipeline_artifact_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/snippet_repository_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/terraform_state_version_registries_resolver_spec.rb"
+- "./ee/spec/graphql/resolvers/geo/upload_registries_resolver_spec.rb"
+- "./ee/spec/helpers/application_helper_spec.rb"
+- "./ee/spec/helpers/ee/geo_helper_spec.rb"
+- "./ee/spec/lib/analytics/devops_adoption/snapshot_calculator_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/backfill_iteration_cadence_id_for_boards_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/backfill_version_data_from_gitaly_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/create_security_setting_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/fix_ruby_object_in_audit_events_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_check_progress_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_in_batch_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_devops_segments_to_groups_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/migrate_security_scans_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_namespace_statistics_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_historical_statistics_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/prune_orphaned_geo_events_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_duplicate_cs_findings_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_duplicated_cs_findings_without_vulnerability_id_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_inaccessible_epic_todos_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_undefined_occurrence_confidence_level_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_undefined_occurrence_severity_level_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_undefined_vulnerability_confidence_level_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/remove_undefined_vulnerability_severity_level_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/update_location_fingerprint_for_container_scanning_findings_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/update_vulnerabilities_from_dismissal_feedback_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/update_vulnerabilities_to_dismissed_spec.rb"
+- "./ee/spec/lib/ee/gitlab/background_migration/update_vulnerability_confidence_spec.rb"
+- "./ee/spec/lib/ee/gitlab/database/connection_spec.rb"
+- "./ee/spec/lib/ee/gitlab/database_spec.rb"
+- "./ee/spec/lib/ee/gitlab/middleware/read_only_spec.rb"
+- "./ee/spec/lib/ee/gitlab/usage_data_spec.rb"
+- "./ee/spec/lib/gitlab/background_migration/fix_orphan_promoted_issues_spec.rb"
+- "./ee/spec/lib/gitlab/background_migration/user_mentions/create_resource_user_mention_spec.rb"
+- "./ee/spec/lib/gitlab/ci/templates/Jobs/dast_default_branch_gitlab_ci_yaml_spec.rb"
+- "./ee/spec/lib/gitlab/geo/base_request_spec.rb"
+- "./ee/spec/lib/gitlab/geo/database_tasks_spec.rb"
+- "./ee/spec/lib/gitlab/geo/event_gap_tracking_spec.rb"
+- "./ee/spec/lib/gitlab/geo/geo_tasks_spec.rb"
+- "./ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb"
+- "./ee/spec/lib/gitlab/geo/log_cursor/events/design_repository_updated_event_spec.rb"
+- "./ee/spec/lib/gitlab/geo/log_cursor/events/job_artifact_deleted_event_spec.rb"
+- "./ee/spec/lib/gitlab/geo/log_cursor/events/repository_created_event_spec.rb"
+- "./ee/spec/lib/gitlab/geo/log_cursor/events/repository_updated_event_spec.rb"
+- "./ee/spec/lib/gitlab/geo/oauth/login_state_spec.rb"
+- "./ee/spec/lib/gitlab/geo/oauth/logout_token_spec.rb"
+- "./ee/spec/lib/gitlab/geo/oauth/session_spec.rb"
+- "./ee/spec/lib/gitlab/geo/registry_batcher_spec.rb"
+- "./ee/spec/lib/gitlab/geo/replicable_model_spec.rb"
+- "./ee/spec/lib/gitlab/geo/replication/blob_downloader_spec.rb"
+- "./ee/spec/lib/gitlab/geo/replication/file_transfer_spec.rb"
+- "./ee/spec/lib/gitlab/geo/replicator_spec.rb"
+- "./ee/spec/lib/gitlab/git_access_spec.rb"
+- "./ee/spec/lib/pseudonymizer/dumper_spec.rb"
+- "./ee/spec/lib/system_check/geo/geo_database_configured_check_spec.rb"
+- "./ee/spec/lib/system_check/geo/http_connection_check_spec.rb"
+- "./ee/spec/lib/system_check/rake_task/geo_task_spec.rb"
+- "./ee/spec/mailers/notify_spec.rb"
+- "./ee/spec/migrations/20190926180443_schedule_epic_issues_after_epics_move_spec.rb"
+- "./ee/spec/migrations/add_non_null_constraint_for_escalation_rule_on_pending_alert_escalations_spec.rb"
+- "./ee/spec/migrations/add_unique_constraint_to_software_licenses_spec.rb"
+- "./ee/spec/migrations/backfill_namespace_statistics_with_wiki_size_spec.rb"
+- "./ee/spec/migrations/backfill_operations_feature_flags_iid_spec.rb"
+- "./ee/spec/migrations/backfill_software_licenses_spdx_identifiers_spec.rb"
+- "./ee/spec/migrations/backfill_version_author_and_created_at_spec.rb"
+- "./ee/spec/migrations/cleanup_deploy_access_levels_for_removed_groups_spec.rb"
+- "./ee/spec/migrations/create_elastic_reindexing_subtasks_spec.rb"
+- "./ee/spec/migrations/fix_any_approver_rule_for_projects_spec.rb"
+- "./ee/spec/migrations/migrate_design_notes_mentions_to_db_spec.rb"
+- "./ee/spec/migrations/migrate_epic_mentions_to_db_spec.rb"
+- "./ee/spec/migrations/migrate_epic_notes_mentions_to_db_spec.rb"
+- "./ee/spec/migrations/migrate_license_management_artifacts_to_license_scanning_spec.rb"
+- "./ee/spec/migrations/migrate_saml_identities_to_scim_identities_spec.rb"
+- "./ee/spec/migrations/migrate_scim_identities_to_saml_for_new_users_spec.rb"
+- "./ee/spec/migrations/migrate_vulnerability_dismissal_feedback_spec.rb"
+- "./ee/spec/migrations/migrate_vulnerability_dismissals_spec.rb"
+- "./ee/spec/migrations/nullify_feature_flag_plaintext_tokens_spec.rb"
+- "./ee/spec/migrations/populate_vulnerability_historical_statistics_for_year_spec.rb"
+- "./ee/spec/migrations/remove_creations_in_gitlab_subscription_histories_spec.rb"
+- "./ee/spec/migrations/remove_cycle_analytics_total_stage_data_spec.rb"
+- "./ee/spec/migrations/remove_duplicated_cs_findings_spec.rb"
+- "./ee/spec/migrations/remove_duplicated_cs_findings_without_vulnerability_id_spec.rb"
+- "./ee/spec/migrations/remove_schedule_and_status_null_constraints_from_pending_escalations_alert_spec.rb"
+- "./ee/spec/migrations/schedule_fix_orphan_promoted_issues_spec.rb"
+- "./ee/spec/migrations/schedule_fix_ruby_object_in_audit_events_spec.rb"
+- "./ee/spec/migrations/schedule_merge_request_any_approval_rule_migration_spec.rb"
+- "./ee/spec/migrations/schedule_populate_dismissed_state_for_vulnerabilities_spec.rb"
+- "./ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb"
+- "./ee/spec/migrations/schedule_populate_vulnerability_historical_statistics_spec.rb"
+- "./ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb"
+- "./ee/spec/migrations/schedule_remove_inaccessible_epic_todos_spec.rb"
+- "./ee/spec/migrations/schedule_sync_blocking_issues_count_spec.rb"
+- "./ee/spec/migrations/schedule_uuid_population_for_security_findings2_spec.rb"
+- "./ee/spec/migrations/set_report_type_for_vulnerabilities_spec.rb"
+- "./ee/spec/migrations/set_resolved_state_on_vulnerabilities_spec.rb"
+- "./ee/spec/migrations/update_cs_vulnerability_confidence_column_spec.rb"
+- "./ee/spec/migrations/update_gitlab_subscriptions_start_at_post_eoa_spec.rb"
+- "./ee/spec/migrations/update_location_fingerprint_column_for_cs_spec.rb"
+- "./ee/spec/migrations/update_occurrence_severity_column_spec.rb"
+- "./ee/spec/migrations/update_undefined_confidence_from_occurrences_spec.rb"
+- "./ee/spec/migrations/update_undefined_confidence_from_vulnerabilities_spec.rb"
+- "./ee/spec/migrations/update_vulnerability_severity_column_spec.rb"
+- "./ee/spec/models/analytics/cycle_analytics/group_level_spec.rb"
+- "./ee/spec/models/approval_merge_request_rule_spec.rb"
+- "./ee/spec/models/approval_project_rule_spec.rb"
+- "./ee/spec/models/approval_state_spec.rb"
+- "./ee/spec/models/approval_wrapped_code_owner_rule_spec.rb"
+- "./ee/spec/models/approval_wrapped_rule_spec.rb"
+- "./ee/spec/models/approver_group_spec.rb"
+- "./ee/spec/models/ci/bridge_spec.rb"
+- "./ee/spec/models/ci/build_spec.rb"
+- "./ee/spec/models/ci/minutes/additional_pack_spec.rb"
+- "./ee/spec/models/ci/pipeline_spec.rb"
+- "./ee/spec/models/ci/subscriptions/project_spec.rb"
+- "./ee/spec/models/concerns/approval_rule_like_spec.rb"
+- "./ee/spec/models/concerns/approver_migrate_hook_spec.rb"
+- "./ee/spec/models/dora/daily_metrics_spec.rb"
+- "./ee/spec/models/ee/ci/job_artifact_spec.rb"
+- "./ee/spec/models/ee/ci/pipeline_artifact_spec.rb"
+- "./ee/spec/models/ee/ci/runner_spec.rb"
+- "./ee/spec/models/ee/merge_request_diff_spec.rb"
+- "./ee/spec/models/ee/pages_deployment_spec.rb"
+- "./ee/spec/models/ee/terraform/state_version_spec.rb"
+- "./ee/spec/models/geo/container_repository_registry_spec.rb"
+- "./ee/spec/models/geo/deleted_project_spec.rb"
+- "./ee/spec/models/geo/design_registry_spec.rb"
+- "./ee/spec/models/geo/job_artifact_registry_spec.rb"
+- "./ee/spec/models/geo_node_namespace_link_spec.rb"
+- "./ee/spec/models/geo_node_spec.rb"
+- "./ee/spec/models/geo_node_status_spec.rb"
+- "./ee/spec/models/geo/package_file_registry_spec.rb"
+- "./ee/spec/models/geo/project_registry_spec.rb"
+- "./ee/spec/models/group_member_spec.rb"
+- "./ee/spec/models/group_wiki_repository_spec.rb"
+- "./ee/spec/models/merge_request_spec.rb"
+- "./ee/spec/models/packages/package_file_spec.rb"
+- "./ee/spec/models/project_spec.rb"
+- "./ee/spec/models/requirements_management/requirement_spec.rb"
+- "./ee/spec/models/snippet_repository_spec.rb"
+- "./ee/spec/models/upload_spec.rb"
+- "./ee/spec/models/visible_approvable_spec.rb"
+- "./ee/spec/policies/ci/build_policy_spec.rb"
+- "./ee/spec/presenters/approval_rule_presenter_spec.rb"
+- "./ee/spec/presenters/merge_request_presenter_spec.rb"
+- "./ee/spec/replicators/geo/pipeline_artifact_replicator_spec.rb"
+- "./ee/spec/replicators/geo/terraform_state_version_replicator_spec.rb"
+- "./ee/spec/requests/api/ci/pipelines_spec.rb"
+- "./ee/spec/requests/api/geo_nodes_spec.rb"
+- "./ee/spec/requests/api/geo_replication_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/dast_on_demand_scans/create_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/dast/profiles/create_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/dast/profiles/run_spec.rb"
+- "./ee/spec/requests/api/graphql/mutations/dast/profiles/update_spec.rb"
+- "./ee/spec/requests/api/graphql/project/pipeline/dast_profile_spec.rb"
+- "./ee/spec/requests/api/merge_request_approval_rules_spec.rb"
+- "./ee/spec/requests/api/merge_requests_spec.rb"
+- "./ee/spec/requests/api/project_approval_rules_spec.rb"
+- "./ee/spec/requests/api/project_approval_settings_spec.rb"
+- "./ee/spec/requests/api/project_approvals_spec.rb"
+- "./ee/spec/requests/api/project_snapshots_spec.rb"
+- "./ee/spec/requests/api/status_checks_spec.rb"
+- "./ee/spec/requests/api/vulnerability_findings_spec.rb"
+- "./ee/spec/requests/projects/merge_requests_controller_spec.rb"
+- "./ee/spec/routing/admin_routing_spec.rb"
+- "./ee/spec/serializers/dashboard_operations_project_entity_spec.rb"
+- "./ee/spec/serializers/ee/evidences/release_entity_spec.rb"
+- "./ee/spec/serializers/ee/user_serializer_spec.rb"
+- "./ee/spec/serializers/evidences/evidence_entity_spec.rb"
+- "./ee/spec/serializers/merge_request_widget_entity_spec.rb"
+- "./ee/spec/serializers/pipeline_serializer_spec.rb"
+- "./ee/spec/services/approval_rules/create_service_spec.rb"
+- "./ee/spec/services/approval_rules/finalize_service_spec.rb"
+- "./ee/spec/services/approval_rules/merge_request_rule_destroy_service_spec.rb"
+- "./ee/spec/services/approval_rules/params_filtering_service_spec.rb"
+- "./ee/spec/services/approval_rules/project_rule_destroy_service_spec.rb"
+- "./ee/spec/services/approval_rules/update_service_spec.rb"
+- "./ee/spec/services/app_sec/dast/profiles/create_service_spec.rb"
+- "./ee/spec/services/app_sec/dast/profiles/update_service_spec.rb"
+- "./ee/spec/services/app_sec/dast/scans/create_service_spec.rb"
+- "./ee/spec/services/app_sec/dast/scans/run_service_spec.rb"
+- "./ee/spec/services/ci/compare_license_scanning_reports_service_spec.rb"
+- "./ee/spec/services/ci/compare_metrics_reports_service_spec.rb"
+- "./ee/spec/services/ci/create_pipeline_service/dast_configuration_spec.rb"
+- "./ee/spec/services/ci/destroy_pipeline_service_spec.rb"
+- "./ee/spec/services/ci/minutes/track_live_consumption_service_spec.rb"
+- "./ee/spec/services/ci/minutes/update_build_minutes_service_spec.rb"
+- "./ee/spec/services/ci/register_job_service_spec.rb"
+- "./ee/spec/services/ci/retry_build_service_spec.rb"
+- "./ee/spec/services/ci/run_dast_scan_service_spec.rb"
+- "./ee/spec/services/ci/subscribe_bridge_service_spec.rb"
+- "./ee/spec/services/ci/sync_reports_to_approval_rules_service_spec.rb"
+- "./ee/spec/services/ci/trigger_downstream_subscription_service_spec.rb"
+- "./ee/spec/services/dast_on_demand_scans/create_service_spec.rb"
+- "./ee/spec/services/deployments/auto_rollback_service_spec.rb"
+- "./ee/spec/services/ee/ci/job_artifacts/destroy_all_expired_service_spec.rb"
+- "./ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb"
+- "./ee/spec/services/ee/integrations/test/project_service_spec.rb"
+- "./ee/spec/services/ee/issuable/destroy_service_spec.rb"
+- "./ee/spec/services/ee/merge_requests/refresh_service_spec.rb"
+- "./ee/spec/services/ee/merge_requests/update_service_spec.rb"
+- "./ee/spec/services/ee/notification_service_spec.rb"
+- "./ee/spec/services/ee/post_receive_service_spec.rb"
+- "./ee/spec/services/ee/releases/create_evidence_service_spec.rb"
+- "./ee/spec/services/ee/users/destroy_service_spec.rb"
+- "./ee/spec/services/external_status_checks/create_service_spec.rb"
+- "./ee/spec/services/external_status_checks/destroy_service_spec.rb"
+- "./ee/spec/services/external_status_checks/update_service_spec.rb"
+- "./ee/spec/services/geo/container_repository_sync_service_spec.rb"
+- "./ee/spec/services/geo/hashed_storage_migrated_event_store_spec.rb"
+- "./ee/spec/services/geo/hashed_storage_migration_service_spec.rb"
+- "./ee/spec/services/geo/node_create_service_spec.rb"
+- "./ee/spec/services/geo/node_status_request_service_spec.rb"
+- "./ee/spec/services/geo/node_update_service_spec.rb"
+- "./ee/spec/services/geo/project_housekeeping_service_spec.rb"
+- "./ee/spec/services/geo/registry_consistency_service_spec.rb"
+- "./ee/spec/services/geo/repositories_changed_event_store_spec.rb"
+- "./ee/spec/services/geo/repository_updated_event_store_spec.rb"
+- "./ee/spec/services/geo/repository_verification_reset_spec.rb"
+- "./ee/spec/services/geo/repository_verification_secondary_service_spec.rb"
+- "./ee/spec/services/merge_requests/merge_service_spec.rb"
+- "./ee/spec/services/merge_requests/reset_approvals_service_spec.rb"
+- "./ee/spec/services/merge_requests/sync_report_approver_approval_rules_spec.rb"
+- "./ee/spec/services/projects/transfer_service_spec.rb"
+- "./ee/spec/services/security/security_orchestration_policies/rule_schedule_service_spec.rb"
+- "./ee/spec/services/todo_service_spec.rb"
+- "./ee/spec/services/vulnerability_feedback/create_service_spec.rb"
+- "./ee/spec/services/wiki_pages/create_service_spec.rb"
+- "./ee/spec/services/wiki_pages/destroy_service_spec.rb"
+- "./ee/spec/services/wiki_pages/update_service_spec.rb"
+- "./ee/spec/support/shared_examples/fixtures/analytics_value_streams_shared_examples.rb"
+- "./ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb"
+- "./ee/spec/support/shared_examples/graphql/mutations/dast_on_demand_scans_shared_examples.rb"
+- "./ee/spec/support/shared_examples/graphql/mutations/dast_on_demand_scan_with_user_abilities_shared_examples.rb"
+- "./ee/spec/support/shared_examples/lib/gitlab/geo/geo_log_cursor_event_shared_examples.rb"
+- "./ee/spec/support/shared_examples/lib/gitlab/geo/geo_logs_event_source_info_shared_examples.rb"
+- "./ee/spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb"
+- "./ee/spec/support/shared_examples/models/concerns/replicable_model_shared_examples.rb"
+- "./ee/spec/support/shared_examples/models/concerns/verifiable_replicator_shared_examples.rb"
+- "./ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb"
+- "./ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb"
+- "./ee/spec/support/shared_examples/services/audit_event_logging_shared_examples.rb"
+- "./ee/spec/support/shared_examples/services/build_execute_shared_examples.rb"
+- "./ee/spec/support/shared_examples/services/dast_on_demand_scans_shared_examples.rb"
+- "./ee/spec/support/shared_examples/services/geo_event_store_shared_examples.rb"
+- "./ee/spec/tasks/geo_rake_spec.rb"
+- "./ee/spec/tasks/gitlab/geo_rake_spec.rb"
+- "./ee/spec/workers/geo/file_download_dispatch_worker_spec.rb"
+- "./ee/spec/workers/geo/metrics_update_worker_spec.rb"
+- "./ee/spec/workers/geo/prune_event_log_worker_spec.rb"
+- "./ee/spec/workers/geo/registry_sync_worker_spec.rb"
+- "./ee/spec/workers/geo/repository_cleanup_worker_spec.rb"
+- "./ee/spec/workers/geo/repository_sync_worker_spec.rb"
+- "./ee/spec/workers/geo/repository_verification/secondary/scheduler_worker_spec.rb"
+- "./ee/spec/workers/geo/repository_verification/secondary/single_worker_spec.rb"
+- "./ee/spec/workers/geo/verification_worker_spec.rb"
+- "./ee/spec/workers/refresh_license_compliance_checks_worker_spec.rb"
+- "./spec/controllers/abuse_reports_controller_spec.rb"
+- "./spec/controllers/admin/spam_logs_controller_spec.rb"
+- "./spec/controllers/admin/users_controller_spec.rb"
+- "./spec/controllers/omniauth_callbacks_controller_spec.rb"
+- "./spec/controllers/projects/issues_controller_spec.rb"
+- "./spec/controllers/projects/jobs_controller_spec.rb"
+- "./spec/controllers/projects/merge_requests/content_controller_spec.rb"
+- "./spec/controllers/projects/merge_requests_controller_spec.rb"
+- "./spec/controllers/projects/pipelines_controller_spec.rb"
+- "./spec/controllers/projects/pipelines/tests_controller_spec.rb"
+- "./spec/controllers/projects/settings/access_tokens_controller_spec.rb"
+- "./spec/controllers/projects/tags_controller_spec.rb"
+- "./spec/controllers/sent_notifications_controller_spec.rb"
+- "./spec/factories_spec.rb"
+- "./spec/features/action_cable_logging_spec.rb"
+- "./spec/features/admin/admin_abuse_reports_spec.rb"
+- "./spec/features/admin/admin_appearance_spec.rb"
+- "./spec/features/admin/admin_broadcast_messages_spec.rb"
+- "./spec/features/admin/admin_builds_spec.rb"
+- "./spec/features/admin/admin_dev_ops_report_spec.rb"
+- "./spec/features/admin/admin_disables_git_access_protocol_spec.rb"
+- "./spec/features/admin/admin_disables_two_factor_spec.rb"
+- "./spec/features/admin/admin_groups_spec.rb"
+- "./spec/features/admin/admin_hooks_spec.rb"
+- "./spec/features/admin/admin_labels_spec.rb"
+- "./spec/features/admin/admin_mode/login_spec.rb"
+- "./spec/features/admin/admin_mode/logout_spec.rb"
+- "./spec/features/admin/admin_mode_spec.rb"
+- "./spec/features/admin/admin_mode/workers_spec.rb"
+- "./spec/features/admin/admin_projects_spec.rb"
+- "./spec/features/admin/admin_runners_spec.rb"
+- "./spec/features/admin/admin_search_settings_spec.rb"
+- "./spec/features/admin/admin_serverless_domains_spec.rb"
+- "./spec/features/admin/admin_settings_spec.rb"
+- "./spec/features/admin/admin_users_impersonation_tokens_spec.rb"
+- "./spec/features/admin/admin_uses_repository_checks_spec.rb"
+- "./spec/features/admin/clusters/eks_spec.rb"
+- "./spec/features/admin/dashboard_spec.rb"
+- "./spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb"
+- "./spec/features/admin/users/user_spec.rb"
+- "./spec/features/admin/users/users_spec.rb"
+- "./spec/features/alert_management/alert_details_spec.rb"
+- "./spec/features/alert_management/alert_management_list_spec.rb"
+- "./spec/features/alert_management_spec.rb"
+- "./spec/features/alert_management/user_filters_alerts_by_status_spec.rb"
+- "./spec/features/alert_management/user_searches_alerts_spec.rb"
+- "./spec/features/alert_management/user_updates_alert_status_spec.rb"
+- "./spec/features/alerts_settings/user_views_alerts_settings_spec.rb"
+- "./spec/features/atom/dashboard_spec.rb"
+- "./spec/features/boards/boards_spec.rb"
+- "./spec/features/boards/focus_mode_spec.rb"
+- "./spec/features/boards/issue_ordering_spec.rb"
+- "./spec/features/boards/keyboard_shortcut_spec.rb"
+- "./spec/features/boards/multiple_boards_spec.rb"
+- "./spec/features/boards/new_issue_spec.rb"
+- "./spec/features/boards/reload_boards_on_browser_back_spec.rb"
+- "./spec/features/boards/sidebar_due_date_spec.rb"
+- "./spec/features/boards/sidebar_labels_in_namespaces_spec.rb"
+- "./spec/features/boards/sidebar_labels_spec.rb"
+- "./spec/features/boards/sidebar_milestones_spec.rb"
+- "./spec/features/boards/sidebar_spec.rb"
+- "./spec/features/boards/user_adds_lists_to_board_spec.rb"
+- "./spec/features/boards/user_visits_board_spec.rb"
+- "./spec/features/broadcast_messages_spec.rb"
+- "./spec/features/calendar_spec.rb"
+- "./spec/features/callouts/registration_enabled_spec.rb"
+- "./spec/features/clusters/cluster_detail_page_spec.rb"
+- "./spec/features/clusters/cluster_health_dashboard_spec.rb"
+- "./spec/features/commit_spec.rb"
+- "./spec/features/commits_spec.rb"
+- "./spec/features/commits/user_uses_quick_actions_spec.rb"
+- "./spec/features/contextual_sidebar_spec.rb"
+- "./spec/features/cycle_analytics_spec.rb"
+- "./spec/features/dashboard/activity_spec.rb"
+- "./spec/features/dashboard/archived_projects_spec.rb"
+- "./spec/features/dashboard/datetime_on_tooltips_spec.rb"
+- "./spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb"
+- "./spec/features/dashboard/groups_list_spec.rb"
+- "./spec/features/dashboard/group_spec.rb"
+- "./spec/features/dashboard/issues_filter_spec.rb"
+- "./spec/features/dashboard/issues_spec.rb"
+- "./spec/features/dashboard/label_filter_spec.rb"
+- "./spec/features/dashboard/merge_requests_spec.rb"
+- "./spec/features/dashboard/milestones_spec.rb"
+- "./spec/features/dashboard/project_member_activity_index_spec.rb"
+- "./spec/features/dashboard/projects_spec.rb"
+- "./spec/features/dashboard/root_spec.rb"
+- "./spec/features/dashboard/shortcuts_spec.rb"
+- "./spec/features/dashboard/snippets_spec.rb"
+- "./spec/features/dashboard/todos/todos_filtering_spec.rb"
+- "./spec/features/dashboard/todos/todos_spec.rb"
+- "./spec/features/dashboard/user_filters_projects_spec.rb"
+- "./spec/features/discussion_comments/commit_spec.rb"
+- "./spec/features/discussion_comments/issue_spec.rb"
+- "./spec/features/discussion_comments/merge_request_spec.rb"
+- "./spec/features/discussion_comments/snippets_spec.rb"
+- "./spec/features/error_pages_spec.rb"
+- "./spec/features/error_tracking/user_filters_errors_by_status_spec.rb"
+- "./spec/features/error_tracking/user_searches_sentry_errors_spec.rb"
+- "./spec/features/error_tracking/user_sees_error_details_spec.rb"
+- "./spec/features/error_tracking/user_sees_error_index_spec.rb"
+- "./spec/features/expand_collapse_diffs_spec.rb"
+- "./spec/features/explore/groups_list_spec.rb"
+- "./spec/features/explore/groups_spec.rb"
+- "./spec/features/explore/user_explores_projects_spec.rb"
+- "./spec/features/file_uploads/attachment_spec.rb"
+- "./spec/features/file_uploads/ci_artifact_spec.rb"
+- "./spec/features/file_uploads/git_lfs_spec.rb"
+- "./spec/features/file_uploads/graphql_add_design_spec.rb"
+- "./spec/features/file_uploads/group_import_spec.rb"
+- "./spec/features/file_uploads/maven_package_spec.rb"
+- "./spec/features/file_uploads/multipart_invalid_uploads_spec.rb"
+- "./spec/features/file_uploads/nuget_package_spec.rb"
+- "./spec/features/file_uploads/project_import_spec.rb"
+- "./spec/features/file_uploads/rubygem_package_spec.rb"
+- "./spec/features/file_uploads/user_avatar_spec.rb"
+- "./spec/features/frequently_visited_projects_and_groups_spec.rb"
+- "./spec/features/gitlab_experiments_spec.rb"
+- "./spec/features/global_search_spec.rb"
+- "./spec/features/groups/activity_spec.rb"
+- "./spec/features/groups/board_sidebar_spec.rb"
+- "./spec/features/groups/board_spec.rb"
+- "./spec/features/groups/clusters/eks_spec.rb"
+- "./spec/features/groups/clusters/user_spec.rb"
+- "./spec/features/groups/container_registry_spec.rb"
+- "./spec/features/groups/dependency_proxy_spec.rb"
+- "./spec/features/groups/empty_states_spec.rb"
+- "./spec/features/groups/import_export/connect_instance_spec.rb"
+- "./spec/features/groups/import_export/export_file_spec.rb"
+- "./spec/features/groups/import_export/import_file_spec.rb"
+- "./spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb"
+- "./spec/features/groups/issues_spec.rb"
+- "./spec/features/groups/labels/index_spec.rb"
+- "./spec/features/groups/labels/search_labels_spec.rb"
+- "./spec/features/groups/labels/sort_labels_spec.rb"
+- "./spec/features/groups/labels/subscription_spec.rb"
+- "./spec/features/groups/members/filter_members_spec.rb"
+- "./spec/features/groups/members/leave_group_spec.rb"
+- "./spec/features/groups/members/list_members_spec.rb"
+- "./spec/features/groups/members/manage_groups_spec.rb"
+- "./spec/features/groups/members/manage_members_spec.rb"
+- "./spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb"
+- "./spec/features/groups/members/master_manages_access_requests_spec.rb"
+- "./spec/features/groups/members/search_members_spec.rb"
+- "./spec/features/groups/members/sort_members_spec.rb"
+- "./spec/features/groups/members/tabs_spec.rb"
+- "./spec/features/groups/merge_requests_spec.rb"
+- "./spec/features/groups/milestones/gfm_autocomplete_spec.rb"
+- "./spec/features/groups/milestone_spec.rb"
+- "./spec/features/groups/milestones_sorting_spec.rb"
+- "./spec/features/groups/packages_spec.rb"
+- "./spec/features/groups/settings/group_badges_spec.rb"
+- "./spec/features/groups/settings/packages_and_registries_spec.rb"
+- "./spec/features/groups/settings/repository_spec.rb"
+- "./spec/features/groups/settings/user_searches_in_settings_spec.rb"
+- "./spec/features/groups/show_spec.rb"
+- "./spec/features/groups_spec.rb"
+- "./spec/features/groups/user_browse_projects_group_page_spec.rb"
+- "./spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb"
+- "./spec/features/help_pages_spec.rb"
+- "./spec/features/ide_spec.rb"
+- "./spec/features/ide/user_commits_changes_spec.rb"
+- "./spec/features/ide/user_opens_merge_request_spec.rb"
+- "./spec/features/import/manifest_import_spec.rb"
+- "./spec/features/incidents/incident_details_spec.rb"
+- "./spec/features/incidents/incidents_list_spec.rb"
+- "./spec/features/incidents/user_creates_new_incident_spec.rb"
+- "./spec/features/incidents/user_filters_incidents_by_status_spec.rb"
+- "./spec/features/incidents/user_searches_incidents_spec.rb"
+- "./spec/features/incidents/user_views_incident_spec.rb"
+- "./spec/features/issuables/issuable_list_spec.rb"
+- "./spec/features/issuables/markdown_references/internal_references_spec.rb"
+- "./spec/features/issuables/markdown_references/jira_spec.rb"
+- "./spec/features/issuables/sorting_list_spec.rb"
+- "./spec/features/issuables/user_sees_sidebar_spec.rb"
+- "./spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb"
+- "./spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb"
+- "./spec/features/issues/csv_spec.rb"
+- "./spec/features/issues/discussion_lock_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_assignee_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_author_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_base_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_emoji_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_hint_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_label_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_milestone_spec.rb"
+- "./spec/features/issues/filtered_search/dropdown_release_spec.rb"
+- "./spec/features/issues/filtered_search/filter_issues_spec.rb"
+- "./spec/features/issues/filtered_search/recent_searches_spec.rb"
+- "./spec/features/issues/filtered_search/search_bar_spec.rb"
+- "./spec/features/issues/filtered_search/visual_tokens_spec.rb"
+- "./spec/features/issues/form_spec.rb"
+- "./spec/features/issues/gfm_autocomplete_spec.rb"
+- "./spec/features/issues/group_label_sidebar_spec.rb"
+- "./spec/features/issues/incident_issue_spec.rb"
+- "./spec/features/issues/issue_detail_spec.rb"
+- "./spec/features/issues/issue_header_spec.rb"
+- "./spec/features/issues/issue_sidebar_spec.rb"
+- "./spec/features/issues/keyboard_shortcut_spec.rb"
+- "./spec/features/issues/markdown_toolbar_spec.rb"
+- "./spec/features/issues/move_spec.rb"
+- "./spec/features/issues/note_polling_spec.rb"
+- "./spec/features/issues/notes_on_issues_spec.rb"
+- "./spec/features/issues/related_issues_spec.rb"
+- "./spec/features/issues/resource_label_events_spec.rb"
+- "./spec/features/issues/service_desk_spec.rb"
+- "./spec/features/issues/spam_issues_spec.rb"
+- "./spec/features/issues/todo_spec.rb"
+- "./spec/features/issues/user_bulk_edits_issues_labels_spec.rb"
+- "./spec/features/issues/user_bulk_edits_issues_spec.rb"
+- "./spec/features/issues/user_comments_on_issue_spec.rb"
+- "./spec/features/issues/user_creates_branch_and_merge_request_spec.rb"
+- "./spec/features/issues/user_creates_confidential_merge_request_spec.rb"
+- "./spec/features/issues/user_creates_issue_by_email_spec.rb"
+- "./spec/features/issues/user_creates_issue_spec.rb"
+- "./spec/features/issues/user_edits_issue_spec.rb"
+- "./spec/features/issues/user_filters_issues_spec.rb"
+- "./spec/features/issues/user_interacts_with_awards_spec.rb"
+- "./spec/features/issues/user_invites_from_a_comment_spec.rb"
+- "./spec/features/issues/user_resets_their_incoming_email_token_spec.rb"
+- "./spec/features/issues/user_sees_empty_state_spec.rb"
+- "./spec/features/issues/user_sees_live_update_spec.rb"
+- "./spec/features/issues/user_sees_sidebar_updates_in_realtime_spec.rb"
+- "./spec/features/issues/user_sorts_issue_comments_spec.rb"
+- "./spec/features/issues/user_sorts_issues_spec.rb"
+- "./spec/features/issues/user_toggles_subscription_spec.rb"
+- "./spec/features/issues/user_uses_quick_actions_spec.rb"
+- "./spec/features/issues/user_views_issue_spec.rb"
+- "./spec/features/issues/user_views_issues_spec.rb"
+- "./spec/features/jira_connect/branches_spec.rb"
+- "./spec/features/labels_hierarchy_spec.rb"
+- "./spec/features/markdown/copy_as_gfm_spec.rb"
+- "./spec/features/markdown/gitlab_flavored_markdown_spec.rb"
+- "./spec/features/markdown/keyboard_shortcuts_spec.rb"
+- "./spec/features/markdown/math_spec.rb"
+- "./spec/features/markdown/mermaid_spec.rb"
+- "./spec/features/markdown/metrics_spec.rb"
+- "./spec/features/merge_request/batch_comments_spec.rb"
+- "./spec/features/merge_request/close_reopen_report_toggle_spec.rb"
+- "./spec/features/merge_request/maintainer_edits_fork_spec.rb"
+- "./spec/features/merge_request/merge_request_discussion_lock_spec.rb"
+- "./spec/features/merge_requests/filters_generic_behavior_spec.rb"
+- "./spec/features/merge_requests/user_exports_as_csv_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_approvals_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_assignees_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_deployments_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_draft_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_labels_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_milestones_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_multiple_criteria_spec.rb"
+- "./spec/features/merge_requests/user_filters_by_target_branch_spec.rb"
+- "./spec/features/merge_requests/user_mass_updates_spec.rb"
+- "./spec/features/merge_request/user_accepts_merge_request_spec.rb"
+- "./spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb"
+- "./spec/features/merge_request/user_approves_spec.rb"
+- "./spec/features/merge_request/user_assigns_themselves_spec.rb"
+- "./spec/features/merge_request/user_awards_emoji_spec.rb"
+- "./spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb"
+- "./spec/features/merge_request/user_comments_on_commit_spec.rb"
+- "./spec/features/merge_request/user_comments_on_diff_spec.rb"
+- "./spec/features/merge_request/user_comments_on_merge_request_spec.rb"
+- "./spec/features/merge_request/user_creates_image_diff_notes_spec.rb"
+- "./spec/features/merge_request/user_creates_merge_request_spec.rb"
+- "./spec/features/merge_request/user_creates_mr_spec.rb"
+- "./spec/features/merge_request/user_customizes_merge_commit_message_spec.rb"
+- "./spec/features/merge_request/user_edits_assignees_sidebar_spec.rb"
+- "./spec/features/merge_request/user_edits_merge_request_spec.rb"
+- "./spec/features/merge_request/user_edits_mr_spec.rb"
+- "./spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb"
+- "./spec/features/merge_request/user_expands_diff_spec.rb"
+- "./spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb"
+- "./spec/features/merge_request/user_invites_from_a_comment_spec.rb"
+- "./spec/features/merge_request/user_jumps_to_discussion_spec.rb"
+- "./spec/features/merge_request/user_locks_discussion_spec.rb"
+- "./spec/features/merge_request/user_manages_subscription_spec.rb"
+- "./spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb"
+- "./spec/features/merge_request/user_merges_immediately_spec.rb"
+- "./spec/features/merge_request/user_merges_merge_request_spec.rb"
+- "./spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb"
+- "./spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb"
+- "./spec/features/merge_request/user_posts_diff_notes_spec.rb"
+- "./spec/features/merge_request/user_posts_notes_spec.rb"
+- "./spec/features/merge_request/user_rebases_merge_request_spec.rb"
+- "./spec/features/merge_request/user_resolves_conflicts_spec.rb"
+- "./spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb"
+- "./spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb"
+- "./spec/features/merge_request/user_resolves_wip_mr_spec.rb"
+- "./spec/features/merge_request/user_reverts_merge_request_spec.rb"
+- "./spec/features/merge_request/user_reviews_image_spec.rb"
+- "./spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb"
+- "./spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb"
+- "./spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb"
+- "./spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb"
+- "./spec/features/merge_request/user_sees_closing_issues_message_spec.rb"
+- "./spec/features/merge_request/user_sees_deleted_target_branch_spec.rb"
+- "./spec/features/merge_request/user_sees_deployment_widget_spec.rb"
+- "./spec/features/merge_request/user_sees_diff_spec.rb"
+- "./spec/features/merge_request/user_sees_discussions_spec.rb"
+- "./spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb"
+- "./spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb"
+- "./spec/features/merge_request/user_sees_merge_widget_spec.rb"
+- "./spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb"
+- "./spec/features/merge_request/user_sees_mr_from_deleted_forked_project_spec.rb"
+- "./spec/features/merge_request/user_sees_mr_with_deleted_source_branch_spec.rb"
+- "./spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb"
+- "./spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb"
+- "./spec/features/merge_request/user_sees_pipelines_spec.rb"
+- "./spec/features/merge_request/user_sees_suggest_pipeline_spec.rb"
+- "./spec/features/merge_request/user_sees_system_notes_spec.rb"
+- "./spec/features/merge_request/user_sees_versions_spec.rb"
+- "./spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb"
+- "./spec/features/merge_request/user_squashes_merge_request_spec.rb"
+- "./spec/features/merge_request/user_suggests_changes_on_diff_spec.rb"
+- "./spec/features/merge_request/user_toggles_whitespace_changes_spec.rb"
+- "./spec/features/merge_request/user_uses_quick_actions_spec.rb"
+- "./spec/features/merge_request/user_views_auto_expanding_diff_spec.rb"
+- "./spec/features/merge_request/user_views_diffs_commit_spec.rb"
+- "./spec/features/merge_request/user_views_diffs_file_by_file_spec.rb"
+- "./spec/features/merge_request/user_views_diffs_spec.rb"
+- "./spec/features/merge_request/user_views_open_merge_request_spec.rb"
+- "./spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb"
+- "./spec/features/milestone_spec.rb"
+- "./spec/features/milestones/user_creates_milestone_spec.rb"
+- "./spec/features/milestones/user_deletes_milestone_spec.rb"
+- "./spec/features/milestones/user_edits_milestone_spec.rb"
+- "./spec/features/milestones/user_views_milestone_spec.rb"
+- "./spec/features/milestones/user_views_milestones_spec.rb"
+- "./spec/features/nav/top_nav_responsive_spec.rb"
+- "./spec/features/oauth_login_spec.rb"
+- "./spec/features/participants_autocomplete_spec.rb"
+- "./spec/features/populate_new_pipeline_vars_with_params_spec.rb"
+- "./spec/features/profiles/account_spec.rb"
+- "./spec/features/profiles/active_sessions_spec.rb"
+- "./spec/features/profiles/keys_spec.rb"
+- "./spec/features/profiles/oauth_applications_spec.rb"
+- "./spec/features/profile_spec.rb"
+- "./spec/features/profiles/personal_access_tokens_spec.rb"
+- "./spec/features/profiles/user_changes_notified_of_own_activity_spec.rb"
+- "./spec/features/profiles/user_edit_preferences_spec.rb"
+- "./spec/features/profiles/user_edit_profile_spec.rb"
+- "./spec/features/profiles/user_search_settings_spec.rb"
+- "./spec/features/profiles/user_visits_notifications_tab_spec.rb"
+- "./spec/features/profiles/user_visits_profile_preferences_page_spec.rb"
+- "./spec/features/profiles/user_visits_profile_spec.rb"
+- "./spec/features/project_group_variables_spec.rb"
+- "./spec/features/projects/activity/user_sees_activity_spec.rb"
+- "./spec/features/projects/activity/user_sees_design_activity_spec.rb"
+- "./spec/features/projects/activity/user_sees_design_comment_spec.rb"
+- "./spec/features/projects/activity/user_sees_private_activity_spec.rb"
+- "./spec/features/projects/artifacts/file_spec.rb"
+- "./spec/features/projects/artifacts/raw_spec.rb"
+- "./spec/features/projects/artifacts/user_browses_artifacts_spec.rb"
+- "./spec/features/projects/badges/list_spec.rb"
+- "./spec/features/projects/badges/pipeline_badge_spec.rb"
+- "./spec/features/projects/blobs/balsamiq_spec.rb"
+- "./spec/features/projects/blobs/blob_line_permalink_updater_spec.rb"
+- "./spec/features/projects/blobs/blob_show_spec.rb"
+- "./spec/features/projects/blobs/edit_spec.rb"
+- "./spec/features/projects/blobs/shortcuts_blob_spec.rb"
+- "./spec/features/projects/blobs/user_creates_new_blob_in_new_project_spec.rb"
+- "./spec/features/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb"
+- "./spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb"
+- "./spec/features/projects/branches/new_branch_ref_dropdown_spec.rb"
+- "./spec/features/projects/branches_spec.rb"
+- "./spec/features/projects/branches/user_creates_branch_spec.rb"
+- "./spec/features/projects/branches/user_deletes_branch_spec.rb"
+- "./spec/features/projects/branches/user_views_branches_spec.rb"
+- "./spec/features/projects/ci/editor_spec.rb"
+- "./spec/features/projects/clusters/eks_spec.rb"
+- "./spec/features/projects/clusters/gcp_spec.rb"
+- "./spec/features/projects/clusters_spec.rb"
+- "./spec/features/projects/clusters/user_spec.rb"
+- "./spec/features/projects/commit/builds_spec.rb"
+- "./spec/features/projects/commit/cherry_pick_spec.rb"
+- "./spec/features/projects/commit/comments/user_adds_comment_spec.rb"
+- "./spec/features/projects/commit/comments/user_deletes_comments_spec.rb"
+- "./spec/features/projects/commit/comments/user_edits_comments_spec.rb"
+- "./spec/features/projects/commit/diff_notes_spec.rb"
+- "./spec/features/projects/commit/mini_pipeline_graph_spec.rb"
+- "./spec/features/projects/commits/user_browses_commits_spec.rb"
+- "./spec/features/projects/commit/user_comments_on_commit_spec.rb"
+- "./spec/features/projects/commit/user_reverts_commit_spec.rb"
+- "./spec/features/projects/commit/user_views_user_status_on_commit_spec.rb"
+- "./spec/features/projects/compare_spec.rb"
+- "./spec/features/projects/container_registry_spec.rb"
+- "./spec/features/projects/deploy_keys_spec.rb"
+- "./spec/features/projects/diffs/diff_show_spec.rb"
+- "./spec/features/projects/environments/environment_metrics_spec.rb"
+- "./spec/features/projects/environments/environment_spec.rb"
+- "./spec/features/projects/environments/environments_spec.rb"
+- "./spec/features/projects/environments_pod_logs_spec.rb"
+- "./spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb"
+- "./spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb"
+- "./spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb"
+- "./spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb"
+- "./spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb"
+- "./spec/features/projects/feature_flag_user_lists/user_edits_feature_flag_user_list_spec.rb"
+- "./spec/features/projects/feature_flag_user_lists/user_sees_feature_flag_user_list_details_spec.rb"
+- "./spec/features/projects/features_visibility_spec.rb"
+- "./spec/features/projects/files/dockerfile_dropdown_spec.rb"
+- "./spec/features/projects/files/edit_file_soft_wrap_spec.rb"
+- "./spec/features/projects/files/files_sort_submodules_with_folders_spec.rb"
+- "./spec/features/projects/files/find_file_keyboard_spec.rb"
+- "./spec/features/projects/files/gitignore_dropdown_spec.rb"
+- "./spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb"
+- "./spec/features/projects/files/project_owner_creates_license_file_spec.rb"
+- "./spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb"
+- "./spec/features/projects/files/template_selector_menu_spec.rb"
+- "./spec/features/projects/files/template_type_dropdown_spec.rb"
+- "./spec/features/projects/files/undo_template_spec.rb"
+- "./spec/features/projects/files/user_browses_a_tree_with_a_folder_containing_only_a_folder_spec.rb"
+- "./spec/features/projects/files/user_browses_files_spec.rb"
+- "./spec/features/projects/files/user_browses_lfs_files_spec.rb"
+- "./spec/features/projects/files/user_creates_directory_spec.rb"
+- "./spec/features/projects/files/user_creates_files_spec.rb"
+- "./spec/features/projects/files/user_deletes_files_spec.rb"
+- "./spec/features/projects/files/user_edits_files_spec.rb"
+- "./spec/features/projects/files/user_find_file_spec.rb"
+- "./spec/features/projects/files/user_reads_pipeline_status_spec.rb"
+- "./spec/features/projects/files/user_replaces_files_spec.rb"
+- "./spec/features/projects/files/user_uploads_files_spec.rb"
+- "./spec/features/projects/fork_spec.rb"
+- "./spec/features/projects/gfm_autocomplete_load_spec.rb"
+- "./spec/features/projects/graph_spec.rb"
+- "./spec/features/projects/import_export/export_file_spec.rb"
+- "./spec/features/projects/import_export/import_file_spec.rb"
+- "./spec/features/projects/infrastructure_registry_spec.rb"
+- "./spec/features/projects/integrations/user_activates_asana_spec.rb"
+- "./spec/features/projects/integrations/user_activates_assembla_spec.rb"
+- "./spec/features/projects/integrations/user_activates_atlassian_bamboo_ci_spec.rb"
+- "./spec/features/projects/integrations/user_activates_flowdock_spec.rb"
+- "./spec/features/projects/integrations/user_activates_jira_spec.rb"
+- "./spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb"
+- "./spec/features/projects/integrations/user_uses_inherited_settings_spec.rb"
+- "./spec/features/projects/issuable_templates_spec.rb"
+- "./spec/features/projects/issues/design_management/user_paginates_designs_spec.rb"
+- "./spec/features/projects/issues/design_management/user_permissions_upload_spec.rb"
+- "./spec/features/projects/issues/design_management/user_uploads_designs_spec.rb"
+- "./spec/features/projects/issues/design_management/user_views_design_spec.rb"
+- "./spec/features/projects/issues/design_management/user_views_designs_spec.rb"
+- "./spec/features/projects/issues/design_management/user_views_designs_with_svg_xss_spec.rb"
+- "./spec/features/projects/issues/email_participants_spec.rb"
+- "./spec/features/projects/jobs/permissions_spec.rb"
+- "./spec/features/projects/jobs_spec.rb"
+- "./spec/features/projects/jobs/user_browses_job_spec.rb"
+- "./spec/features/projects/jobs/user_browses_jobs_spec.rb"
+- "./spec/features/projects/labels/issues_sorted_by_priority_spec.rb"
+- "./spec/features/projects/labels/search_labels_spec.rb"
+- "./spec/features/projects/labels/sort_labels_spec.rb"
+- "./spec/features/projects/labels/subscription_spec.rb"
+- "./spec/features/projects/labels/update_prioritization_spec.rb"
+- "./spec/features/projects/labels/user_removes_labels_spec.rb"
+- "./spec/features/projects/members/anonymous_user_sees_members_spec.rb"
+- "./spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb"
+- "./spec/features/projects/members/group_members_spec.rb"
+- "./spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb"
+- "./spec/features/projects/members/groups_with_access_list_spec.rb"
+- "./spec/features/projects/members/invite_group_spec.rb"
+- "./spec/features/projects/members/list_spec.rb"
+- "./spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb"
+- "./spec/features/projects/members/master_manages_access_requests_spec.rb"
+- "./spec/features/projects/members/sorting_spec.rb"
+- "./spec/features/projects/members/tabs_spec.rb"
+- "./spec/features/projects/members/user_requests_access_spec.rb"
+- "./spec/features/projects/merge_request_button_spec.rb"
+- "./spec/features/projects/milestones/gfm_autocomplete_spec.rb"
+- "./spec/features/projects/milestones/milestones_sorting_spec.rb"
+- "./spec/features/projects/milestones/new_spec.rb"
+- "./spec/features/projects/milestones/user_interacts_with_labels_spec.rb"
+- "./spec/features/projects/network_graph_spec.rb"
+- "./spec/features/projects/new_project_from_template_spec.rb"
+- "./spec/features/projects/new_project_spec.rb"
+- "./spec/features/projects/packages_spec.rb"
+- "./spec/features/projects/pages/user_adds_domain_spec.rb"
+- "./spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb"
+- "./spec/features/projects/pages/user_edits_settings_spec.rb"
+- "./spec/features/projects/pipeline_schedules_spec.rb"
+- "./spec/features/projects/pipelines/pipeline_spec.rb"
+- "./spec/features/projects/pipelines/pipelines_spec.rb"
+- "./spec/features/projects/product_analytics/graphs_spec.rb"
+- "./spec/features/projects/releases/user_creates_release_spec.rb"
+- "./spec/features/projects/releases/user_views_edit_release_spec.rb"
+- "./spec/features/projects/releases/user_views_release_spec.rb"
+- "./spec/features/projects/releases/user_views_releases_spec.rb"
+- "./spec/features/projects/remote_mirror_spec.rb"
+- "./spec/features/projects/serverless/functions_spec.rb"
+- "./spec/features/projects/services/disable_triggers_spec.rb"
+- "./spec/features/projects/services/prometheus_external_alerts_spec.rb"
+- "./spec/features/projects/services/user_activates_emails_on_push_spec.rb"
+- "./spec/features/projects/services/user_activates_irker_spec.rb"
+- "./spec/features/projects/services/user_activates_issue_tracker_spec.rb"
+- "./spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb"
+- "./spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb"
+- "./spec/features/projects/services/user_activates_packagist_spec.rb"
+- "./spec/features/projects/services/user_activates_prometheus_spec.rb"
+- "./spec/features/projects/services/user_activates_pushover_spec.rb"
+- "./spec/features/projects/services/user_activates_slack_notifications_spec.rb"
+- "./spec/features/projects/services/user_activates_slack_slash_command_spec.rb"
+- "./spec/features/projects/services/user_views_services_spec.rb"
+- "./spec/features/projects/settings/access_tokens_spec.rb"
+- "./spec/features/projects/settings/lfs_settings_spec.rb"
+- "./spec/features/projects/settings/monitor_settings_spec.rb"
+- "./spec/features/projects/settings/packages_settings_spec.rb"
+- "./spec/features/projects/settings/project_badges_spec.rb"
+- "./spec/features/projects/settings/project_settings_spec.rb"
+- "./spec/features/projects/settings/registry_settings_spec.rb"
+- "./spec/features/projects/settings/repository_settings_spec.rb"
+- "./spec/features/projects/settings/service_desk_setting_spec.rb"
+- "./spec/features/projects/settings/user_changes_default_branch_spec.rb"
+- "./spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb"
+- "./spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb"
+- "./spec/features/projects/settings/user_manages_project_members_spec.rb"
+- "./spec/features/projects/settings/user_searches_in_settings_spec.rb"
+- "./spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb"
+- "./spec/features/projects/settings/user_tags_project_spec.rb"
+- "./spec/features/projects/settings/user_transfers_a_project_spec.rb"
+- "./spec/features/projects/settings/visibility_settings_spec.rb"
+- "./spec/features/projects/settings/webhooks_settings_spec.rb"
+- "./spec/features/projects/show/schema_markup_spec.rb"
+- "./spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb"
+- "./spec/features/projects/show/user_interacts_with_stars_spec.rb"
+- "./spec/features/projects/show/user_manages_notifications_spec.rb"
+- "./spec/features/projects/show/user_sees_collaboration_links_spec.rb"
+- "./spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb"
+- "./spec/features/projects/show/user_sees_readme_spec.rb"
+- "./spec/features/projects/show/user_uploads_files_spec.rb"
+- "./spec/features/projects/snippets/create_snippet_spec.rb"
+- "./spec/features/projects/snippets/show_spec.rb"
+- "./spec/features/projects/snippets/user_comments_on_snippet_spec.rb"
+- "./spec/features/projects/snippets/user_deletes_snippet_spec.rb"
+- "./spec/features/projects/snippets/user_updates_snippet_spec.rb"
+- "./spec/features/projects_spec.rb"
+- "./spec/features/projects/sub_group_issuables_spec.rb"
+- "./spec/features/projects/tags/user_edits_tags_spec.rb"
+- "./spec/features/projects/terraform_spec.rb"
+- "./spec/features/projects/tree/create_directory_spec.rb"
+- "./spec/features/projects/tree/create_file_spec.rb"
+- "./spec/features/projects/tree/tree_show_spec.rb"
+- "./spec/features/projects/tree/upload_file_spec.rb"
+- "./spec/features/projects/user_changes_project_visibility_spec.rb"
+- "./spec/features/projects/user_creates_project_spec.rb"
+- "./spec/features/projects/user_sees_sidebar_spec.rb"
+- "./spec/features/projects/user_sees_user_popover_spec.rb"
+- "./spec/features/projects/user_uses_shortcuts_spec.rb"
+- "./spec/features/projects/user_views_empty_project_spec.rb"
+- "./spec/features/projects/view_on_env_spec.rb"
+- "./spec/features/projects/wikis_spec.rb"
+- "./spec/features/projects/wiki/user_views_wiki_empty_spec.rb"
+- "./spec/features/project_variables_spec.rb"
+- "./spec/features/promotion_spec.rb"
+- "./spec/features/protected_branches_spec.rb"
+- "./spec/features/protected_tags_spec.rb"
+- "./spec/features/reportable_note/commit_spec.rb"
+- "./spec/features/reportable_note/issue_spec.rb"
+- "./spec/features/reportable_note/merge_request_spec.rb"
+- "./spec/features/reportable_note/snippets_spec.rb"
+- "./spec/features/runners_spec.rb"
+- "./spec/features/search/user_searches_for_code_spec.rb"
+- "./spec/features/search/user_searches_for_commits_spec.rb"
+- "./spec/features/search/user_searches_for_issues_spec.rb"
+- "./spec/features/search/user_searches_for_merge_requests_spec.rb"
+- "./spec/features/search/user_searches_for_milestones_spec.rb"
+- "./spec/features/search/user_searches_for_projects_spec.rb"
+- "./spec/features/search/user_searches_for_users_spec.rb"
+- "./spec/features/search/user_searches_for_wiki_pages_spec.rb"
+- "./spec/features/search/user_uses_header_search_field_spec.rb"
+- "./spec/features/search/user_uses_search_filters_spec.rb"
+- "./spec/features/signed_commits_spec.rb"
+- "./spec/features/snippets/embedded_snippet_spec.rb"
+- "./spec/features/snippets/internal_snippet_spec.rb"
+- "./spec/features/snippets/notes_on_personal_snippets_spec.rb"
+- "./spec/features/snippets/private_snippets_spec.rb"
+- "./spec/features/snippets/public_snippets_spec.rb"
+- "./spec/features/snippets/show_spec.rb"
+- "./spec/features/snippets/user_creates_snippet_spec.rb"
+- "./spec/features/snippets/user_deletes_snippet_spec.rb"
+- "./spec/features/snippets/user_edits_snippet_spec.rb"
+- "./spec/features/tags/developer_creates_tag_spec.rb"
+- "./spec/features/tags/developer_deletes_tag_spec.rb"
+- "./spec/features/tags/developer_updates_tag_spec.rb"
+- "./spec/features/task_lists_spec.rb"
+- "./spec/features/triggers_spec.rb"
+- "./spec/features/u2f_spec.rb"
+- "./spec/features/uploads/user_uploads_avatar_to_profile_spec.rb"
+- "./spec/features/uploads/user_uploads_file_to_note_spec.rb"
+- "./spec/features/user_can_display_performance_bar_spec.rb"
+- "./spec/features/user_opens_link_to_comment_spec.rb"
+- "./spec/features/user_sees_revert_modal_spec.rb"
+- "./spec/features/users/login_spec.rb"
+- "./spec/features/users/logout_spec.rb"
+- "./spec/features/users/overview_spec.rb"
+- "./spec/features/users/signup_spec.rb"
+- "./spec/features/users/snippets_spec.rb"
+- "./spec/features/users/terms_spec.rb"
+- "./spec/features/users/user_browses_projects_on_user_page_spec.rb"
+- "./spec/features/webauthn_spec.rb"
+- "./spec/features/whats_new_spec.rb"
+- "./spec/finders/ci/pipeline_schedules_finder_spec.rb"
+- "./spec/finders/ci/pipelines_finder_spec.rb"
+- "./spec/finders/ci/pipelines_for_merge_request_finder_spec.rb"
+- "./spec/finders/projects_finder_spec.rb"
+- "./spec/finders/releases/evidence_pipeline_finder_spec.rb"
+- "./spec/frontend/fixtures/analytics.rb"
+- "./spec/frontend/fixtures/jobs.rb"
+- "./spec/frontend/fixtures/pipeline_schedules.rb"
+- "./spec/frontend/fixtures/pipelines.rb"
+- "./spec/graphql/mutations/design_management/upload_spec.rb"
+- "./spec/graphql/mutations/merge_requests/accept_spec.rb"
+- "./spec/graphql/resolvers/ci/test_report_summary_resolver_spec.rb"
+- "./spec/helpers/issuables_helper_spec.rb"
+- "./spec/initializers/active_record_locking_spec.rb"
+- "./spec/initializers/database_config_spec.rb"
+- "./spec/lib/gitlab/auth_spec.rb"
+- "./spec/lib/gitlab/ci/badge/pipeline/status_spec.rb"
+- "./spec/lib/gitlab/ci/build/policy/changes_spec.rb"
+- "./spec/lib/gitlab/ci/charts_spec.rb"
+- "./spec/lib/gitlab/ci/config_spec.rb"
+- "./spec/lib/gitlab/ci/pipeline/chain/create_spec.rb"
+- "./spec/lib/gitlab/ci/pipeline/chain/seed_block_spec.rb"
+- "./spec/lib/gitlab/ci/pipeline/seed/build_spec.rb"
+- "./spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb"
+- "./spec/lib/gitlab/ci/status/stage/common_spec.rb"
+- "./spec/lib/gitlab/ci/status/stage/factory_spec.rb"
+- "./spec/lib/gitlab/ci/status/stage/play_manual_spec.rb"
+- "./spec/lib/gitlab/ci/templates/5_minute_production_app_ci_yaml_spec.rb"
+- "./spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb"
+- "./spec/lib/gitlab/ci/templates/AWS/deploy_ecs_gitlab_ci_yaml_spec.rb"
+- "./spec/lib/gitlab/ci/templates/Jobs/deploy_gitlab_ci_yaml_spec.rb"
+- "./spec/lib/gitlab/ci/templates/managed_cluster_applications_gitlab_ci_yaml_spec.rb"
+- "./spec/lib/gitlab/database/bulk_update_spec.rb"
+- "./spec/lib/gitlab/database/connection_spec.rb"
+- "./spec/lib/gitlab/database/load_balancing/host_spec.rb"
+- "./spec/lib/gitlab/database/load_balancing_spec.rb"
+- "./spec/lib/gitlab/database/postgresql_adapter/force_disconnectable_mixin_spec.rb"
+- "./spec/lib/gitlab/database/postgresql_adapter/type_map_cache_spec.rb"
+- "./spec/lib/gitlab/database/schema_migrations/context_spec.rb"
+- "./spec/lib/gitlab/database/with_lock_retries_outside_transaction_spec.rb"
+- "./spec/lib/gitlab/database/with_lock_retries_spec.rb"
+- "./spec/lib/gitlab/data_builder/pipeline_spec.rb"
+- "./spec/lib/gitlab/email/handler/create_issue_handler_spec.rb"
+- "./spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb"
+- "./spec/lib/gitlab/email/handler/create_note_handler_spec.rb"
+- "./spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb"
+- "./spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb"
+- "./spec/lib/gitlab/usage_data_spec.rb"
+- "./spec/lib/peek/views/active_record_spec.rb"
+- "./spec/mailers/emails/pipelines_spec.rb"
+- "./spec/migrations/20210205174154_remove_bad_dependency_proxy_manifests_spec.rb"
+- "./spec/migrations/20210722150102_operations_feature_flags_correct_flexible_rollout_values_spec.rb"
+- "./spec/migrations/backfill_escalation_policies_for_oncall_schedules_spec.rb"
+- "./spec/migrations/insert_ci_daily_pipeline_schedule_triggers_plan_limits_spec.rb"
+- "./spec/migrations/remove_duplicate_dast_site_tokens_with_same_token_spec.rb"
+- "./spec/models/ci/bridge_spec.rb"
+- "./spec/models/ci/build_need_spec.rb"
+- "./spec/models/ci/build_spec.rb"
+- "./spec/models/ci/build_trace_chunk_spec.rb"
+- "./spec/models/ci/commit_with_pipeline_spec.rb"
+- "./spec/models/ci/group_spec.rb"
+- "./spec/models/ci/group_variable_spec.rb"
+- "./spec/models/ci/instance_variable_spec.rb"
+- "./spec/models/ci/job_artifact_spec.rb"
+- "./spec/models/ci/job_variable_spec.rb"
+- "./spec/models/ci/legacy_stage_spec.rb"
+- "./spec/models/ci/pipeline_schedule_spec.rb"
+- "./spec/models/ci/pipeline_spec.rb"
+- "./spec/models/ci/runner_namespace_spec.rb"
+- "./spec/models/ci/runner_project_spec.rb"
+- "./spec/models/ci/runner_spec.rb"
+- "./spec/models/ci/running_build_spec.rb"
+- "./spec/models/ci/stage_spec.rb"
+- "./spec/models/ci/variable_spec.rb"
+- "./spec/models/clusters/applications/jupyter_spec.rb"
+- "./spec/models/clusters/applications/runner_spec.rb"
+- "./spec/models/commit_collection_spec.rb"
+- "./spec/models/commit_status_spec.rb"
+- "./spec/models/concerns/batch_destroy_dependent_associations_spec.rb"
+- "./spec/models/concerns/bulk_insertable_associations_spec.rb"
+- "./spec/models/concerns/cron_schedulable_spec.rb"
+- "./spec/models/concerns/has_environment_scope_spec.rb"
+- "./spec/models/concerns/schedulable_spec.rb"
+- "./spec/models/concerns/token_authenticatable_spec.rb"
+- "./spec/models/design_management/version_spec.rb"
+- "./spec/models/environment_status_spec.rb"
+- "./spec/models/hooks/system_hook_spec.rb"
+- "./spec/models/issue_spec.rb"
+- "./spec/models/members/project_member_spec.rb"
+- "./spec/models/merge_request_spec.rb"
+- "./spec/models/plan_spec.rb"
+- "./spec/models/project_feature_usage_spec.rb"
+- "./spec/models/project_spec.rb"
+- "./spec/models/spam_log_spec.rb"
+- "./spec/models/user_spec.rb"
+- "./spec/models/user_status_spec.rb"
+- "./spec/policies/ci/build_policy_spec.rb"
+- "./spec/policies/ci/pipeline_policy_spec.rb"
+- "./spec/presenters/ci/stage_presenter_spec.rb"
+- "./spec/requests/api/admin/ci/variables_spec.rb"
+- "./spec/requests/api/admin/plan_limits_spec.rb"
+- "./spec/requests/api/ci/jobs_spec.rb"
+- "./spec/requests/api/ci/pipeline_schedules_spec.rb"
+- "./spec/requests/api/ci/pipelines_spec.rb"
+- "./spec/requests/api/ci/runner/runners_post_spec.rb"
+- "./spec/requests/api/ci/runners_spec.rb"
+- "./spec/requests/api/commits_spec.rb"
+- "./spec/requests/api/commit_statuses_spec.rb"
+- "./spec/requests/api/graphql/ci/runner_spec.rb"
+- "./spec/requests/api/graphql/mutations/ci/pipeline_destroy_spec.rb"
+- "./spec/requests/api/graphql/project/issues_spec.rb"
+- "./spec/requests/api/graphql/project/merge_request_spec.rb"
+- "./spec/requests/api/graphql/project_query_spec.rb"
+- "./spec/requests/api/issues/issues_spec.rb"
+- "./spec/requests/api/merge_requests_spec.rb"
+- "./spec/requests/api/projects_spec.rb"
+- "./spec/requests/api/resource_access_tokens_spec.rb"
+- "./spec/requests/api/users_spec.rb"
+- "./spec/requests/lfs_http_spec.rb"
+- "./spec/requests/projects/cycle_analytics_events_spec.rb"
+- "./spec/serializers/ci/downloadable_artifact_entity_spec.rb"
+- "./spec/serializers/ci/downloadable_artifact_serializer_spec.rb"
+- "./spec/serializers/ci/pipeline_entity_spec.rb"
+- "./spec/serializers/merge_request_poll_cached_widget_entity_spec.rb"
+- "./spec/serializers/merge_request_poll_widget_entity_spec.rb"
+- "./spec/serializers/merge_request_widget_entity_spec.rb"
+- "./spec/serializers/pipeline_details_entity_spec.rb"
+- "./spec/serializers/pipeline_serializer_spec.rb"
+- "./spec/serializers/stage_entity_spec.rb"
+- "./spec/serializers/stage_serializer_spec.rb"
+- "./spec/serializers/test_report_entity_spec.rb"
+- "./spec/serializers/test_report_summary_entity_spec.rb"
+- "./spec/serializers/test_suite_entity_spec.rb"
+- "./spec/serializers/test_suite_summary_entity_spec.rb"
+- "./spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb"
+- "./spec/services/ci/compare_accessibility_reports_service_spec.rb"
+- "./spec/services/ci/compare_codequality_reports_service_spec.rb"
+- "./spec/services/ci/compare_reports_base_service_spec.rb"
+- "./spec/services/ci/compare_test_reports_service_spec.rb"
+- "./spec/services/ci/create_pipeline_service/environment_spec.rb"
+- "./spec/services/ci/create_pipeline_service_spec.rb"
+- "./spec/services/ci/destroy_pipeline_service_spec.rb"
+- "./spec/services/ci/disable_user_pipeline_schedules_service_spec.rb"
+- "./spec/services/ci/ensure_stage_service_spec.rb"
+- "./spec/services/ci/expire_pipeline_cache_service_spec.rb"
+- "./spec/services/ci/generate_codequality_mr_diff_report_service_spec.rb"
+- "./spec/services/ci/generate_coverage_reports_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_associations_service_spec.rb"
+- "./spec/services/ci/job_artifacts/destroy_batch_service_spec.rb"
+- "./spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb"
+- "./spec/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service_spec.rb"
+- "./spec/services/ci/pipeline_bridge_status_service_spec.rb"
+- "./spec/services/ci/pipeline_processing/shared_processing_service.rb"
+- "./spec/services/ci/pipelines/add_job_service_spec.rb"
+- "./spec/services/ci/pipeline_schedule_service_spec.rb"
+- "./spec/services/ci/pipeline_trigger_service_spec.rb"
+- "./spec/services/ci/register_job_service_spec.rb"
+- "./spec/services/ci/retry_build_service_spec.rb"
+- "./spec/services/ci/test_failure_history_service_spec.rb"
+- "./spec/services/ci/update_instance_variables_service_spec.rb"
+- "./spec/services/deployments/update_environment_service_spec.rb"
+- "./spec/services/design_management/save_designs_service_spec.rb"
+- "./spec/services/environments/stop_service_spec.rb"
+- "./spec/services/groups/transfer_service_spec.rb"
+- "./spec/services/integrations/test/project_service_spec.rb"
+- "./spec/services/issuable/destroy_service_spec.rb"
+- "./spec/services/issue_links/list_service_spec.rb"
+- "./spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb"
+- "./spec/services/merge_requests/mergeability_check_service_spec.rb"
+- "./spec/services/merge_requests/post_merge_service_spec.rb"
+- "./spec/services/merge_requests/refresh_service_spec.rb"
+- "./spec/services/pages/migrate_from_legacy_storage_service_spec.rb"
+- "./spec/services/projects/destroy_service_spec.rb"
+- "./spec/services/projects/transfer_service_spec.rb"
+- "./spec/services/projects/update_service_spec.rb"
+- "./spec/services/releases/create_service_spec.rb"
+- "./spec/services/resource_access_tokens/revoke_service_spec.rb"
+- "./spec/services/todo_service_spec.rb"
+- "./spec/services/users/activity_service_spec.rb"
+- "./spec/services/users/destroy_service_spec.rb"
+- "./spec/services/users/reject_service_spec.rb"
+- "./spec/support/shared_contexts/email_shared_context.rb"
+- "./spec/support/shared_examples/controllers/access_tokens_controller_shared_examples.rb"
+- "./spec/support/shared_examples/features/master_manages_access_requests_shared_example.rb"
+- "./spec/support/shared_examples/integrations/test_examples.rb"
+- "./spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb"
+- "./spec/support/shared_examples/models/cluster_application_status_shared_examples.rb"
+- "./spec/support/shared_examples/models/cluster_application_version_shared_examples.rb"
+- "./spec/support/shared_examples/models/concerns/cron_schedulable_shared_examples.rb"
+- "./spec/support/shared_examples/models/concerns/limitable_shared_examples.rb"
+- "./spec/support/shared_examples/models/update_highest_role_shared_examples.rb"
+- "./spec/support/shared_examples/models/update_project_statistics_shared_examples.rb"
+- "./spec/support/shared_examples/models/with_uploads_shared_examples.rb"
+- "./spec/support/shared_examples/requests/api/status_shared_examples.rb"
+- "./spec/support/shared_examples/requests/lfs_http_shared_examples.rb"
+- "./spec/support/shared_examples/services/destroy_label_links_shared_examples.rb"
+- "./spec/support/shared_examples/services/issuable/destroy_service_shared_examples.rb"
+- "./spec/support/shared_examples/services/notification_service_shared_examples.rb"
+- "./spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb"
+- "./spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb"
+- "./spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb"
+- "./spec/support/shared_examples/workers/idempotency_shared_examples.rb"
+- "./spec/views/projects/artifacts/_artifact.html.haml_spec.rb"
+- "./spec/views/projects/commits/_commit.html.haml_spec.rb"
+- "./spec/views/projects/jobs/_build.html.haml_spec.rb"
+- "./spec/views/projects/jobs/_generic_commit_status.html.haml_spec.rb"
+- "./spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb"
+- "./spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb"
+- "./spec/views/shared/runners/_runner_details.html.haml_spec.rb"
+- "./spec/workers/authorized_project_update/user_refresh_from_replica_worker_spec.rb"
+- "./spec/workers/ci/pipeline_artifacts/create_quality_report_worker_spec.rb"
+- "./spec/workers/container_expiration_policy_worker_spec.rb"
+- "./spec/workers/merge_requests/create_pipeline_worker_spec.rb"
+- "./spec/workers/pipeline_metrics_worker_spec.rb"
+- "./spec/workers/pipeline_schedule_worker_spec.rb"
+- "./spec/workers/releases/create_evidence_worker_spec.rb"
+- "./spec/workers/remove_expired_members_worker_spec.rb"
+- "./spec/workers/repository_cleanup_worker_spec.rb"
+- "./spec/workers/stage_update_worker_spec.rb"
+- "./spec/workers/stuck_merge_jobs_worker_spec.rb"
+- "./ee/spec/requests/api/graphql/project/pipelines/dast_profile_spec.rb"
+- "./spec/services/projects/overwrite_project_service_spec.rb"
diff --git a/spec/support/database/cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml
index 45e95cf3262..c209d275fc8 100644
--- a/spec/support/database/cross-join-allowlist.yml
+++ b/spec/support/database/cross-join-allowlist.yml
@@ -1,197 +1,58 @@
-- "./ee/spec/controllers/operations_controller_spec.rb"
-- "./ee/spec/controllers/projects/issues_controller_spec.rb"
-- "./ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb"
- "./ee/spec/features/ci/ci_minutes_spec.rb"
-- "./ee/spec/features/merge_request/user_merges_immediately_spec.rb"
-- "./ee/spec/features/merge_request/user_sees_merge_widget_spec.rb"
- "./ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb"
- "./ee/spec/features/merge_trains/user_adds_merge_request_to_merge_train_spec.rb"
-- "./ee/spec/features/merge_trains/user_adds_to_merge_train_when_pipeline_succeeds_spec.rb"
-- "./ee/spec/features/projects/pipelines/pipeline_spec.rb"
-- "./ee/spec/features/projects/settings/auto_rollback_spec.rb"
-- "./ee/spec/features/projects/settings/pipeline_subscriptions_spec.rb"
-- "./ee/spec/features/projects/settings/protected_environments_spec.rb"
- "./ee/spec/finders/ee/namespaces/projects_finder_spec.rb"
-- "./ee/spec/finders/group_projects_finder_spec.rb"
-- "./ee/spec/finders/security/findings_finder_spec.rb"
- "./ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb"
-- "./ee/spec/lib/analytics/devops_adoption/snapshot_calculator_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/migrate_security_scans_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb"
-- "./ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id_spec.rb"
-- "./ee/spec/lib/ee/gitlab/usage_data_spec.rb"
-- "./ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb"
-- "./ee/spec/models/ci/build_spec.rb"
- "./ee/spec/models/ci/minutes/project_monthly_usage_spec.rb"
-- "./ee/spec/models/ci/pipeline_spec.rb"
-- "./ee/spec/models/ee/vulnerability_spec.rb"
-- "./ee/spec/models/merge_request_spec.rb"
- "./ee/spec/models/project_spec.rb"
- "./ee/spec/models/security/finding_spec.rb"
- "./ee/spec/models/security/scan_spec.rb"
-- "./ee/spec/presenters/ci/pipeline_presenter_spec.rb"
- "./ee/spec/requests/api/ci/minutes_spec.rb"
- "./ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb"
-- "./ee/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb"
-- "./ee/spec/requests/api/graphql/mutations/vulnerabilities/create_external_issue_link_spec.rb"
-- "./ee/spec/requests/api/graphql/project/pipeline/security_report_summary_spec.rb"
-- "./ee/spec/requests/api/graphql/vulnerabilities/location_spec.rb"
-- "./ee/spec/requests/api/groups_spec.rb"
- "./ee/spec/requests/api/namespaces_spec.rb"
-- "./ee/spec/requests/api/vulnerability_findings_spec.rb"
-- "./ee/spec/serializers/dashboard_environment_entity_spec.rb"
-- "./ee/spec/serializers/dashboard_environments_serializer_spec.rb"
-- "./ee/spec/services/auto_merge/add_to_merge_train_when_pipeline_succeeds_service_spec.rb"
-- "./ee/spec/services/ci/create_pipeline_service/runnable_builds_spec.rb"
- "./ee/spec/services/ci/minutes/additional_packs/change_namespace_service_spec.rb"
- "./ee/spec/services/ci/minutes/additional_packs/create_service_spec.rb"
- "./ee/spec/services/ci/minutes/refresh_cached_data_service_spec.rb"
-- "./ee/spec/services/ci/process_pipeline_service_spec.rb"
-- "./ee/spec/services/ci/trigger_downstream_subscription_service_spec.rb"
-- "./ee/spec/services/clear_namespace_shared_runners_minutes_service_spec.rb"
-- "./ee/spec/services/deployments/auto_rollback_service_spec.rb"
-- "./ee/spec/services/ee/ci/job_artifacts/destroy_all_expired_service_spec.rb"
-- "./ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb"
-- "./ee/spec/services/ee/issues/build_from_vulnerability_service_spec.rb"
-- "./ee/spec/services/ee/merge_requests/create_pipeline_service_spec.rb"
-- "./ee/spec/services/ee/merge_requests/refresh_service_spec.rb"
-- "./ee/spec/services/security/report_summary_service_spec.rb"
-- "./ee/spec/services/security/vulnerability_counting_service_spec.rb"
-- "./ee/spec/workers/scan_security_report_secrets_worker_spec.rb"
-- "./ee/spec/workers/security/store_scans_worker_spec.rb"
- "./spec/controllers/admin/runners_controller_spec.rb"
-- "./spec/controllers/groups/runners_controller_spec.rb"
- "./spec/controllers/groups/settings/ci_cd_controller_spec.rb"
-- "./spec/controllers/projects/logs_controller_spec.rb"
-- "./spec/controllers/projects/merge_requests_controller_spec.rb"
-- "./spec/controllers/projects/runners_controller_spec.rb"
-- "./spec/controllers/projects/serverless/functions_controller_spec.rb"
- "./spec/controllers/projects/settings/ci_cd_controller_spec.rb"
- "./spec/features/admin/admin_runners_spec.rb"
-- "./spec/features/groups/settings/ci_cd_spec.rb"
- "./spec/features/ide/user_opens_merge_request_spec.rb"
-- "./spec/features/merge_request/user_merges_immediately_spec.rb"
-- "./spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb"
-- "./spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb"
-- "./spec/features/merge_request/user_resolves_wip_mr_spec.rb"
-- "./spec/features/merge_request/user_sees_deployment_widget_spec.rb"
- "./spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb"
-- "./spec/features/merge_request/user_sees_merge_widget_spec.rb"
-- "./spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb"
-- "./spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb"
-- "./spec/features/merge_request/user_sees_pipelines_spec.rb"
-- "./spec/features/project_group_variables_spec.rb"
-- "./spec/features/project_variables_spec.rb"
-- "./spec/features/projects/badges/list_spec.rb"
-- "./spec/features/projects/environments_pod_logs_spec.rb"
- "./spec/features/projects/infrastructure_registry_spec.rb"
-- "./spec/features/projects/jobs_spec.rb"
-- "./spec/features/projects/package_files_spec.rb"
-- "./spec/features/projects/pipelines/pipeline_spec.rb"
-- "./spec/features/projects/pipelines/pipelines_spec.rb"
-- "./spec/features/projects/serverless/functions_spec.rb"
-- "./spec/features/projects/settings/pipelines_settings_spec.rb"
-- "./spec/features/runners_spec.rb"
-- "./spec/features/security/project/internal_access_spec.rb"
-- "./spec/features/security/project/private_access_spec.rb"
-- "./spec/features/security/project/public_access_spec.rb"
-- "./spec/features/triggers_spec.rb"
-- "./spec/finders/ci/pipelines_finder_spec.rb"
- "./spec/finders/ci/pipelines_for_merge_request_finder_spec.rb"
- "./spec/finders/ci/runners_finder_spec.rb"
-- "./spec/finders/clusters/knative_services_finder_spec.rb"
-- "./spec/finders/projects/serverless/functions_finder_spec.rb"
- "./spec/frontend/fixtures/runner.rb"
-- "./spec/graphql/mutations/ci/runner/delete_spec.rb"
- "./spec/graphql/resolvers/ci/group_runners_resolver_spec.rb"
-- "./spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb"
-- "./spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb"
-- "./spec/graphql/types/ci/job_token_scope_type_spec.rb"
-- "./spec/helpers/packages_helper_spec.rb"
- "./spec/lib/api/entities/package_spec.rb"
-- "./spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb"
-- "./spec/lib/gitlab/prometheus/query_variables_spec.rb"
-- "./spec/mailers/emails/pipelines_spec.rb"
+- "./spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb"
+- "./spec/lib/gitlab/background_migration/migrate_pages_metadata_spec.rb"
- "./spec/migrations/20210907211557_finalize_ci_builds_bigint_conversion_spec.rb"
-- "./spec/migrations/cleanup_legacy_artifact_migration_spec.rb"
-- "./spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb"
-- "./spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb"
-- "./spec/migrations/schedule_migrate_security_scans_spec.rb"
-- "./spec/models/ci/build_spec.rb"
-- "./spec/models/ci/job_artifact_spec.rb"
-- "./spec/models/ci/job_token/scope_spec.rb"
+- "./spec/migrations/associate_existing_dast_builds_with_variables_spec.rb"
+- "./spec/migrations/schedule_copy_ci_builds_columns_to_security_scans2_spec.rb"
+- "./spec/migrations/schedule_pages_metadata_migration_spec.rb"
- "./spec/models/ci/pipeline_spec.rb"
- "./spec/models/ci/runner_spec.rb"
-- "./spec/models/clusters/applications/runner_spec.rb"
-- "./spec/models/deployment_spec.rb"
-- "./spec/models/environment_spec.rb"
- "./spec/models/merge_request_spec.rb"
- "./spec/models/project_spec.rb"
- "./spec/models/user_spec.rb"
-- "./spec/presenters/ci/build_runner_presenter_spec.rb"
-- "./spec/presenters/ci/pipeline_presenter_spec.rb"
- "./spec/presenters/packages/detail/package_presenter_spec.rb"
-- "./spec/requests/api/ci/pipelines_spec.rb"
-- "./spec/requests/api/ci/runner/jobs_request_post_spec.rb"
- "./spec/requests/api/ci/runner/runners_post_spec.rb"
- "./spec/requests/api/ci/runners_spec.rb"
-- "./spec/requests/api/commit_statuses_spec.rb"
+- "./spec/requests/api/graphql/ci/runner_spec.rb"
- "./spec/requests/api/graphql/group_query_spec.rb"
-- "./spec/requests/api/graphql/merge_request/merge_request_spec.rb"
-- "./spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb"
-- "./spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb"
-- "./spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb"
-- "./spec/requests/api/graphql/mutations/merge_requests/create_spec.rb"
- "./spec/requests/api/graphql/packages/composer_spec.rb"
- "./spec/requests/api/graphql/packages/conan_spec.rb"
- "./spec/requests/api/graphql/packages/maven_spec.rb"
- "./spec/requests/api/graphql/packages/nuget_spec.rb"
- "./spec/requests/api/graphql/packages/package_spec.rb"
- "./spec/requests/api/graphql/packages/pypi_spec.rb"
-- "./spec/requests/api/graphql/project/merge_request/pipelines_spec.rb"
-- "./spec/requests/api/graphql/project/merge_request_spec.rb"
-- "./spec/requests/api/graphql/project/merge_requests_spec.rb"
-- "./spec/requests/api/graphql/project/pipeline_spec.rb"
-- "./spec/requests/api/merge_requests_spec.rb"
- "./spec/requests/api/package_files_spec.rb"
-- "./spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb"
-- "./spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb"
-- "./spec/services/ci/create_pipeline_service/needs_spec.rb"
-- "./spec/services/ci/create_pipeline_service_spec.rb"
-- "./spec/services/ci/destroy_pipeline_service_spec.rb"
-- "./spec/services/ci/expire_pipeline_cache_service_spec.rb"
-- "./spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb"
-- "./spec/services/ci/job_artifacts/destroy_associations_service_spec.rb"
-- "./spec/services/ci/job_artifacts/destroy_batch_service_spec.rb"
-- "./spec/services/ci/pipeline_processing/shared_processing_service.rb"
-- "./spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb"
-- "./spec/services/ci/register_job_service_spec.rb"
-- "./spec/services/clusters/applications/prometheus_config_service_spec.rb"
-- "./spec/services/deployments/older_deployments_drop_service_spec.rb"
-- "./spec/services/environments/auto_stop_service_spec.rb"
- "./spec/services/environments/stop_service_spec.rb"
-- "./spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb"
-- "./spec/services/merge_requests/create_service_spec.rb"
- "./spec/services/merge_requests/post_merge_service_spec.rb"
-- "./spec/services/merge_requests/refresh_service_spec.rb"
-- "./spec/support/prometheus/additional_metrics_shared_examples.rb"
-- "./spec/support/shared_examples/ci/pipeline_email_shared_examples.rb"
- "./spec/support/shared_examples/features/packages_shared_examples.rb"
-- "./spec/support/shared_examples/features/search_settings_shared_examples.rb"
-- "./spec/support/shared_examples/features/variable_list_shared_examples.rb"
- "./spec/support/shared_examples/models/concerns/limitable_shared_examples.rb"
-- "./spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb"
- "./spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb"
- "./spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb"
-- "./spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb"
-- "./spec/support/shared_examples/requests/api/status_shared_examples.rb"
- "./spec/support/shared_examples/requests/graphql_shared_examples.rb"
-- "./spec/support/shared_examples/services/onboarding_progress_shared_examples.rb"
- "./spec/support/shared_examples/services/packages_shared_examples.rb"
-- "./spec/support/shared_examples/workers/idempotency_shared_examples.rb"
-- "./spec/tasks/gitlab/generate_sample_prometheus_data_spec.rb"
-- "./spec/workers/pipeline_process_worker_spec.rb"
-- "./spec/workers/pipeline_schedule_worker_spec.rb"
diff --git a/spec/support/database/multiple_databases.rb b/spec/support/database/multiple_databases.rb
index 8ce642a682c..5e1ae60536f 100644
--- a/spec/support/database/multiple_databases.rb
+++ b/spec/support/database/multiple_databases.rb
@@ -5,5 +5,57 @@ module Database
def skip_if_multiple_databases_not_setup
skip 'Skipping because multiple databases not set up' unless Gitlab::Database.has_config?(:ci)
end
+
+ # The usage of this method switches temporarily used `connection_handler`
+ # allowing full manipulation of ActiveRecord::Base connections without
+ # having side effects like:
+ # - misaligned transactions since this is managed by `BeforeAllAdapter`
+ # - removal of primary connections
+ #
+ # The execution within a block ensures safe cleanup of all allocated resources.
+ #
+ # rubocop:disable Database/MultipleDatabases
+ def with_reestablished_active_record_base(reconnect: true)
+ connection_classes = ActiveRecord::Base.connection_handler.connection_pool_names.map(&:constantize).to_h do |klass|
+ [klass, klass.connection_db_config]
+ end
+
+ original_handler = ActiveRecord::Base.connection_handler
+ new_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
+ ActiveRecord::Base.connection_handler = new_handler
+
+ if reconnect
+ connection_classes.each { |klass, db_config| klass.establish_connection(db_config) }
+ end
+
+ yield
+ ensure
+ ActiveRecord::Base.connection_handler = original_handler
+ new_handler&.clear_all_connections!
+ end
+ # rubocop:enable Database/MultipleDatabases
+ end
+
+ module ActiveRecordBaseEstablishConnection
+ def establish_connection(*args)
+ # rubocop:disable Database/MultipleDatabases
+ if connected? && connection&.transaction_open? && ActiveRecord::Base.connection_handler == ActiveRecord::Base.default_connection_handler
+ raise "Cannot re-establish '#{self}.establish_connection' within an open transaction (#{connection&.open_transactions.to_i}). " \
+ "Use `with_reestablished_active_record_base` instead or add `:reestablished_active_record_base` to rspec context."
+ end
+ # rubocop:enable Database/MultipleDatabases
+
+ super
+ end
end
end
+
+RSpec.configure do |config|
+ config.around(:each, :reestablished_active_record_base) do |example|
+ with_reestablished_active_record_base(reconnect: example.metadata.fetch(:reconnect, true)) do
+ example.run
+ end
+ end
+end
+
+ActiveRecord::Base.singleton_class.prepend(::Database::ActiveRecordBaseEstablishConnection) # rubocop:disable Database/MultipleDatabases
diff --git a/spec/support/database/prevent_cross_database_modification.rb b/spec/support/database/prevent_cross_database_modification.rb
index b4c968e3c41..7ded85b65ce 100644
--- a/spec/support/database/prevent_cross_database_modification.rb
+++ b/spec/support/database/prevent_cross_database_modification.rb
@@ -33,8 +33,10 @@ module Database
end
def cleanup_with_cross_database_modification_prevented
- ActiveSupport::Notifications.unsubscribe(PreventCrossDatabaseModification.cross_database_context[:subscriber])
- PreventCrossDatabaseModification.cross_database_context[:enabled] = false
+ if PreventCrossDatabaseModification.cross_database_context
+ ActiveSupport::Notifications.unsubscribe(PreventCrossDatabaseModification.cross_database_context[:subscriber])
+ PreventCrossDatabaseModification.cross_database_context[:enabled] = false
+ end
end
end
@@ -55,8 +57,11 @@ module Database
end
def self.prevent_cross_database_modification!(connection, sql)
+ return unless cross_database_context
return unless cross_database_context[:enabled]
+ return if connection.pool.instance_of?(ActiveRecord::ConnectionAdapters::NullPool)
+
database = connection.pool.db_config.name
if sql.start_with?('SAVEPOINT')
@@ -74,6 +79,8 @@ module Database
return if cross_database_context[:transaction_depth_by_db].values.all?(&:zero?)
+ # PgQuery might fail in some cases due to limited nesting:
+ # https://github.com/pganalyze/pg_query/issues/209
parsed_query = PgQuery.parse(sql)
tables = sql.downcase.include?(' for update') ? parsed_query.tables : parsed_query.dml_tables
@@ -87,7 +94,8 @@ module Database
if schemas.many?
raise Database::PreventCrossDatabaseModification::CrossDatabaseModificationAcrossUnsupportedTablesError,
"Cross-database data modification of '#{schemas.to_a.join(", ")}' were detected within " \
- "a transaction modifying the '#{all_tables.to_a.join(", ")}'"
+ "a transaction modifying the '#{all_tables.to_a.join(", ")}' tables." \
+ "Please refer to https://docs.gitlab.com/ee/development/database/multiple_databases.html#removing-cross-database-transactions for details on how to resolve this exception."
end
end
end
@@ -96,16 +104,20 @@ end
Gitlab::Database.singleton_class.prepend(
Database::PreventCrossDatabaseModification::GitlabDatabaseMixin)
+CROSS_DB_MODIFICATION_ALLOW_LIST = Set.new(YAML.load_file(File.join(__dir__, 'cross-database-modification-allowlist.yml'))).freeze
+
RSpec.configure do |config|
config.include(::Database::PreventCrossDatabaseModification::SpecHelpers)
# Using before and after blocks because the around block causes problems with the let_it_be
# record creations. It makes an extra savepoint which breaks the transaction count logic.
- config.before(:each, :prevent_cross_database_modification) do
- with_cross_database_modification_prevented
+ config.before do |example_file|
+ if CROSS_DB_MODIFICATION_ALLOW_LIST.exclude?(example_file.file_path)
+ with_cross_database_modification_prevented
+ end
end
- config.after(:each, :prevent_cross_database_modification) do
+ config.after do |example_file|
cleanup_with_cross_database_modification_prevented
end
end
diff --git a/spec/support/database/prevent_cross_joins.rb b/spec/support/database/prevent_cross_joins.rb
index 4b78aa9014c..f5ed2a8f22e 100644
--- a/spec/support/database/prevent_cross_joins.rb
+++ b/spec/support/database/prevent_cross_joins.rb
@@ -22,9 +22,10 @@ module Database
CrossJoinAcrossUnsupportedTablesError = Class.new(StandardError)
ALLOW_THREAD_KEY = :allow_cross_joins_across_databases
+ ALLOW_ANNOTATE_KEY = ALLOW_THREAD_KEY.to_s.freeze
def self.validate_cross_joins!(sql)
- return if Thread.current[ALLOW_THREAD_KEY]
+ return if Thread.current[ALLOW_THREAD_KEY] || sql.include?(ALLOW_ANNOTATE_KEY)
# Allow spec/support/database_cleaner.rb queries to disable/enable triggers for many tables
# See https://gitlab.com/gitlab-org/gitlab/-/issues/339396
@@ -32,21 +33,14 @@ module Database
# PgQuery might fail in some cases due to limited nesting:
# https://github.com/pganalyze/pg_query/issues/209
- #
- # Also, we disable GC while parsing because of https://github.com/pganalyze/pg_query/issues/226
- begin
- GC.disable
- tables = PgQuery.parse(sql).tables
- ensure
- GC.enable
- end
+ tables = PgQuery.parse(sql).tables
schemas = Database::GitlabSchema.table_schemas(tables)
if schemas.include?(:gitlab_ci) && schemas.include?(:gitlab_main)
Thread.current[:has_cross_join_exception] = true
raise CrossJoinAcrossUnsupportedTablesError,
- "Unsupported cross-join across '#{tables.join(", ")}' modifying '#{schemas.to_a.join(", ")}' discovered " \
+ "Unsupported cross-join across '#{tables.join(", ")}' querying '#{schemas.to_a.join(", ")}' discovered " \
"when executing query '#{sql}'. Please refer to https://docs.gitlab.com/ee/development/database/multiple_databases.html#removing-joins-between-ci_-and-non-ci_-tables for details on how to resolve this exception."
end
end
@@ -63,6 +57,10 @@ module Database
ensure
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
end
+
+ def allow_cross_joins_across_databases(url:, &block)
+ ::Gitlab::Database.allow_cross_joins_across_databases(url: url, &block)
+ end
end
module GitlabDatabaseMixin
@@ -75,12 +73,21 @@ module Database
Thread.current[ALLOW_THREAD_KEY] = old_value
end
end
+
+ module ActiveRecordRelationMixin
+ def allow_cross_joins_across_databases(url:)
+ super.annotate(ALLOW_ANNOTATE_KEY)
+ end
+ end
end
end
Gitlab::Database.singleton_class.prepend(
Database::PreventCrossJoins::GitlabDatabaseMixin)
+ActiveRecord::Relation.prepend(
+ Database::PreventCrossJoins::ActiveRecordRelationMixin)
+
ALLOW_LIST = Set.new(YAML.load_file(File.join(__dir__, 'cross-join-allowlist.yml'))).freeze
RSpec.configure do |config|
diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb
index b31881e3082..8f706fdebc9 100644
--- a/spec/support/database_cleaner.rb
+++ b/spec/support/database_cleaner.rb
@@ -17,32 +17,9 @@ RSpec.configure do |config|
delete_from_all_tables!(except: ['work_item_types'])
# Postgres maximum number of columns in a table is 1600 (https://github.com/postgres/postgres/blob/de41869b64d57160f58852eab20a27f248188135/src/include/access/htup_details.h#L23-L47).
- # And since:
- # "The DROP COLUMN form does not physically remove the column, but simply makes
- # it invisible to SQL operations. Subsequent insert and update operations in the
- # table will store a null value for the column. Thus, dropping a column is quick
- # but it will not immediately reduce the on-disk size of your table, as the space
- # occupied by the dropped column is not reclaimed.
- # The space will be reclaimed over time as existing rows are updated."
- # according to https://www.postgresql.org/docs/current/sql-altertable.html.
# We drop and recreate the database if any table has more than 1200 columns, just to be safe.
- max_allowed_columns = 1200
- tables_with_more_than_allowed_columns =
- ApplicationRecord.connection.execute("SELECT attrelid::regclass::text AS table, COUNT(*) AS column_count FROM pg_attribute GROUP BY attrelid HAVING COUNT(*) > #{max_allowed_columns}")
-
- if tables_with_more_than_allowed_columns.any?
- tables_with_more_than_allowed_columns.each do |result|
- puts "The #{result['table']} table has #{result['column_count']} columns."
- end
- puts "Recreating the database"
- start = Gitlab::Metrics::System.monotonic_time
-
- ActiveRecord::Tasks::DatabaseTasks.drop_current
- ActiveRecord::Tasks::DatabaseTasks.create_current
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current
- ActiveRecord::Tasks::DatabaseTasks.migrate
-
- puts "Database re-creation done in #{Gitlab::Metrics::System.monotonic_time - start}"
+ if any_connection_class_with_more_than_allowed_columns?
+ recreate_all_databases!
end
end
diff --git a/spec/support/database_load_balancing.rb b/spec/support/database_load_balancing.rb
index f22c69ea613..014575e8a82 100644
--- a/spec/support/database_load_balancing.rb
+++ b/spec/support/database_load_balancing.rb
@@ -1,22 +1,30 @@
# frozen_string_literal: true
RSpec.configure do |config|
- config.before(:each, :db_load_balancing) do
- allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
+ config.around(:each, :database_replica) do |example|
+ old_proxies = []
- config = Gitlab::Database::LoadBalancing::Configuration
- .new(ActiveRecord::Base, [Gitlab::Database.main.config['host']])
- lb = ::Gitlab::Database::LoadBalancing::LoadBalancer.new(config)
- proxy = ::Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
+ Gitlab::Database::LoadBalancing.base_models.each do |model|
+ config = Gitlab::Database::LoadBalancing::Configuration
+ .new(model, [model.connection_db_config.configuration_hash[:host]])
+ lb = Gitlab::Database::LoadBalancing::LoadBalancer.new(config)
- allow(ActiveRecord::Base).to receive(:load_balancing_proxy).and_return(proxy)
+ old_proxies << [model, model.connection]
- ::Gitlab::Database::LoadBalancing::Session.clear_session
+ model.connection =
+ Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
+ end
+
+ Gitlab::Database::LoadBalancing::Session.clear_session
redis_shared_state_cleanup!
- end
- config.after(:each, :db_load_balancing) do
- ::Gitlab::Database::LoadBalancing::Session.clear_session
+ example.run
+
+ Gitlab::Database::LoadBalancing::Session.clear_session
redis_shared_state_cleanup!
+
+ old_proxies.each do |(model, proxy)|
+ model.connection = proxy
+ end
end
end
diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb
index 940ff2751d3..316d645f99f 100644
--- a/spec/support/db_cleaner.rb
+++ b/spec/support/db_cleaner.rb
@@ -2,7 +2,7 @@
module DbCleaner
def all_connection_classes
- ::ActiveRecord::Base.connection_handler.connection_pool_names.map(&:constantize)
+ ::BeforeAllAdapter.all_connection_classes
end
def delete_from_all_tables!(except: [])
@@ -20,6 +20,79 @@ module DbCleaner
DatabaseCleaner[:active_record, { connection: connection_class }]
end
end
+
+ def any_connection_class_with_more_than_allowed_columns?
+ all_connection_classes.any? do |connection_class|
+ more_than_allowed_columns?(connection_class)
+ end
+ end
+
+ def more_than_allowed_columns?(connection_class)
+ # Postgres maximum number of columns in a table is 1600 (https://github.com/postgres/postgres/blob/de41869b64d57160f58852eab20a27f248188135/src/include/access/htup_details.h#L23-L47).
+ # And since:
+ # "The DROP COLUMN form does not physically remove the column, but simply makes
+ # it invisible to SQL operations. Subsequent insert and update operations in the
+ # table will store a null value for the column. Thus, dropping a column is quick
+ # but it will not immediately reduce the on-disk size of your table, as the space
+ # occupied by the dropped column is not reclaimed.
+ # The space will be reclaimed over time as existing rows are updated."
+ # according to https://www.postgresql.org/docs/current/sql-altertable.html.
+ # We drop and recreate the database if any table has more than 1200 columns, just to be safe.
+ max_allowed_columns = 1200
+ tables_with_more_than_allowed_columns = connection_class.connection.execute(<<-SQL)
+ SELECT attrelid::regclass::text AS table, COUNT(*) AS column_count
+ FROM pg_attribute
+ GROUP BY attrelid
+ HAVING COUNT(*) > #{max_allowed_columns}
+ SQL
+
+ tables_with_more_than_allowed_columns.each do |result|
+ puts "The #{result['table']} (#{connection_class.connection_db_config.name}) table has #{result['column_count']} columns."
+ end
+
+ tables_with_more_than_allowed_columns.any?
+ end
+
+ def recreate_all_databases!
+ start = Gitlab::Metrics::System.monotonic_time
+
+ puts "Recreating the database"
+
+ force_disconnect_all_connections!
+
+ ActiveRecord::Tasks::DatabaseTasks.drop_current
+ ActiveRecord::Tasks::DatabaseTasks.create_current
+ ActiveRecord::Tasks::DatabaseTasks.load_schema_current
+
+ # Migrate each database individually
+ with_reestablished_active_record_base do
+ all_connection_classes.each do |connection_class|
+ ActiveRecord::Base.establish_connection(connection_class.connection_db_config)
+
+ ActiveRecord::Tasks::DatabaseTasks.migrate
+ end
+ end
+
+ puts "Databases re-creation done in #{Gitlab::Metrics::System.monotonic_time - start}"
+ end
+
+ def force_disconnect_all_connections!
+ all_connection_classes.each do |connection_class|
+ # We use `connection_pool` to avoid going through
+ # Load Balancer since it does retry ops
+ pool = connection_class.connection_pool
+
+ # Force disconnect https://www.cybertec-postgresql.com/en/terminating-database-connections-in-postgresql/
+ pool.connection.execute(<<-SQL)
+ SELECT pg_terminate_backend(pid)
+ FROM pg_stat_activity
+ WHERE datname = #{pool.connection.quote(pool.db_config.database)}
+ AND pid != pg_backend_pid();
+ SQL
+
+ connection_class.connection_pool.disconnect!
+ end
+ end
end
DbCleaner.prepend_mod_with('DbCleaner')
diff --git a/spec/support/helpers/dependency_proxy_helpers.rb b/spec/support/helpers/dependency_proxy_helpers.rb
index 9413cb93199..75dc09ec159 100644
--- a/spec/support/helpers/dependency_proxy_helpers.rb
+++ b/spec/support/helpers/dependency_proxy_helpers.rb
@@ -34,12 +34,20 @@ module DependencyProxyHelpers
def build_jwt(user = nil, expire_time: nil)
JSONWebToken::HMACToken.new(::Auth::DependencyProxyAuthenticationService.secret).tap do |jwt|
- jwt['user_id'] = user.id if user.is_a?(User)
- jwt['deploy_token'] = user.token if user.is_a?(DeployToken)
- jwt.expire_time = expire_time || jwt.issued_at + 1.minute
+ if block_given?
+ yield(jwt)
+ else
+ jwt['user_id'] = user.id if user.is_a?(User)
+ jwt['deploy_token'] = user.token if user.is_a?(DeployToken)
+ jwt.expire_time = expire_time || jwt.issued_at + 1.minute
+ end
end
end
+ def jwt_token_authorization_headers(jwt)
+ { 'AUTHORIZATION' => "Bearer #{jwt.encoded}" }
+ end
+
private
def registry
diff --git a/spec/support/helpers/feature_flag_helpers.rb b/spec/support/helpers/feature_flag_helpers.rb
index 51ba9039b70..4e57002a7c6 100644
--- a/spec/support/helpers/feature_flag_helpers.rb
+++ b/spec/support/helpers/feature_flag_helpers.rb
@@ -71,7 +71,7 @@ module FeatureFlagHelpers
end
def add_linked_issue_button
- find('.js-issue-count-badge-add-button')
+ find_button 'Add a related issue'
end
def remove_linked_issue_button
diff --git a/spec/support/helpers/javascript_fixtures_helpers.rb b/spec/support/helpers/javascript_fixtures_helpers.rb
index 5174c145a93..fb909008f12 100644
--- a/spec/support/helpers/javascript_fixtures_helpers.rb
+++ b/spec/support/helpers/javascript_fixtures_helpers.rb
@@ -3,6 +3,8 @@
require 'action_dispatch/testing/test_request'
require 'fileutils'
+require_relative '../../../lib/gitlab/popen'
+
module JavaScriptFixturesHelpers
extend ActiveSupport::Concern
include Gitlab::Popen
@@ -25,17 +27,6 @@ module JavaScriptFixturesHelpers
'tmp/tests/frontend/fixtures' + (Gitlab.ee? ? '-ee' : '')
end
- # Public: Removes all fixture files from given directory
- #
- # directory_name - directory of the fixtures (relative to .fixture_root_path)
- #
- def clean_frontend_fixtures(directory_name)
- full_directory_name = File.expand_path(directory_name, fixture_root_path)
- Dir[File.expand_path('*.{html,json,md}', full_directory_name)].each do |file_name|
- FileUtils.rm(file_name)
- end
- end
-
def remove_repository(project)
Gitlab::Shell.new.remove_repository(project.repository_storage, project.disk_path)
end
diff --git a/spec/support/helpers/navbar_structure_helper.rb b/spec/support/helpers/navbar_structure_helper.rb
index 826108a63a5..96e79427278 100644
--- a/spec/support/helpers/navbar_structure_helper.rb
+++ b/spec/support/helpers/navbar_structure_helper.rb
@@ -52,4 +52,12 @@ module NavbarStructureHelper
new_sub_nav_item_name: _('Infrastructure Registry')
)
end
+
+ def insert_infrastructure_google_cloud_nav
+ insert_after_sub_nav_item(
+ _('Terraform'),
+ within: _('Infrastructure'),
+ new_sub_nav_item_name: _('Google Cloud')
+ )
+ end
end
diff --git a/spec/support/helpers/stub_gitlab_calls.rb b/spec/support/helpers/stub_gitlab_calls.rb
index 5ab778c11cb..6f530d57caf 100644
--- a/spec/support/helpers/stub_gitlab_calls.rb
+++ b/spec/support/helpers/stub_gitlab_calls.rb
@@ -79,6 +79,18 @@ module StubGitlabCalls
end
end
+ def stub_container_registry_info(info: {})
+ allow(ContainerRegistry::Client)
+ .to receive(:registry_info)
+ .and_return(info)
+ end
+
+ def stub_container_registry_network_error(client_method:)
+ allow_next_instance_of(ContainerRegistry::Client) do |client|
+ allow(client).to receive(client_method).and_raise(::Faraday::Error, nil, nil)
+ end
+ end
+
def stub_commonmark_sourcepos_disabled
allow_any_instance_of(Banzai::Filter::MarkdownEngines::CommonMark)
.to receive(:render_options)
diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb
index b1a9aade043..5ead1813439 100644
--- a/spec/support/helpers/usage_data_helpers.rb
+++ b/spec/support/helpers/usage_data_helpers.rb
@@ -54,15 +54,8 @@ module UsageDataHelpers
clusters_platforms_eks
clusters_platforms_gke
clusters_platforms_user
- clusters_applications_helm
- clusters_applications_ingress
- clusters_applications_cert_managers
- clusters_applications_prometheus
- clusters_applications_crossplane
- clusters_applications_runner
- clusters_applications_knative
- clusters_applications_elastic_stack
- clusters_applications_jupyter
+ clusters_integrations_elastic_stack
+ clusters_integrations_prometheus
clusters_management_project
in_review_folder
grafana_integrated_projects
@@ -112,6 +105,7 @@ module UsageDataHelpers
projects_with_expiration_policy_enabled_with_older_than_set_to_7d
projects_with_expiration_policy_enabled_with_older_than_set_to_14d
projects_with_expiration_policy_enabled_with_older_than_set_to_30d
+ projects_with_expiration_policy_enabled_with_older_than_set_to_60d
projects_with_expiration_policy_enabled_with_older_than_set_to_90d
projects_with_expiration_policy_enabled_with_cadence_set_to_1d
projects_with_expiration_policy_enabled_with_cadence_set_to_7d
diff --git a/spec/support/matchers/be_request_urgency.rb b/spec/support/matchers/be_request_urgency.rb
new file mode 100644
index 00000000000..e88f157366b
--- /dev/null
+++ b/spec/support/matchers/be_request_urgency.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+RSpec::Matchers.define :be_request_urgency do |expected|
+ match do |actual|
+ actual.is_a?(::Gitlab::EndpointAttributes::Config::RequestUrgency) &&
+ actual.name == expected
+ end
+end
diff --git a/spec/support/matchers/graphql_matchers.rb b/spec/support/matchers/graphql_matchers.rb
index 904b7efdd7f..dcaec176687 100644
--- a/spec/support/matchers/graphql_matchers.rb
+++ b/spec/support/matchers/graphql_matchers.rb
@@ -3,14 +3,30 @@
RSpec::Matchers.define_negated_matcher :be_nullable, :be_non_null
RSpec::Matchers.define :require_graphql_authorizations do |*expected|
+ def permissions_for(klass)
+ if klass.respond_to?(:required_permissions)
+ klass.required_permissions
+ else
+ [klass.to_graphql.metadata[:authorize]]
+ end
+ end
+
match do |klass|
- permissions = if klass.respond_to?(:required_permissions)
- klass.required_permissions
- else
- [klass.to_graphql.metadata[:authorize]]
- end
+ actual = permissions_for(klass)
+
+ expect(actual).to match_array(expected)
+ end
+
+ failure_message do |klass|
+ actual = permissions_for(klass)
+ missing = actual - expected
+ extra = expected - actual
- expect(permissions).to eq(expected)
+ message = []
+ message << "is missing permissions: #{missing.inspect}" if missing.any?
+ message << "contained unexpected permissions: #{extra.inspect}" if extra.any?
+
+ message.join("\n")
end
end
diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb
index dfdb5bc01ae..f01c4075eeb 100644
--- a/spec/support/matchers/markdown_matchers.rb
+++ b/spec/support/matchers/markdown_matchers.rb
@@ -41,7 +41,7 @@ module MarkdownMatchers
set_default_markdown_messages
match do |actual|
- expect(actual).to have_selector('gl-emoji', count: 10)
+ expect(actual).to have_selector('gl-emoji', count: 12)
emoji_element = actual.at_css('gl-emoji')
expect(emoji_element['data-name'].to_s).not_to be_empty
diff --git a/spec/support/redis.rb b/spec/support/redis.rb
index eeeb93fa811..421079af8e0 100644
--- a/spec/support/redis.rb
+++ b/spec/support/redis.rb
@@ -38,4 +38,20 @@ RSpec.configure do |config|
redis_trace_chunks_cleanup!
end
+
+ config.around(:each, :clean_gitlab_redis_rate_limiting) do |example|
+ redis_rate_limiting_cleanup!
+
+ example.run
+
+ redis_rate_limiting_cleanup!
+ end
+
+ config.around(:each, :clean_gitlab_redis_sessions) do |example|
+ redis_sessions_cleanup!
+
+ example.run
+
+ redis_sessions_cleanup!
+ end
end
diff --git a/spec/support/redis/redis_helpers.rb b/spec/support/redis/redis_helpers.rb
index 3511d906203..f27d873eb31 100644
--- a/spec/support/redis/redis_helpers.rb
+++ b/spec/support/redis/redis_helpers.rb
@@ -22,4 +22,14 @@ module RedisHelpers
def redis_trace_chunks_cleanup!
Gitlab::Redis::TraceChunks.with(&:flushdb)
end
+
+ # Usage: rate limiting state (for Rack::Attack)
+ def redis_rate_limiting_cleanup!
+ Gitlab::Redis::RateLimiting.with(&:flushdb)
+ end
+
+ # Usage: session state
+ def redis_sessions_cleanup!
+ Gitlab::Redis::Sessions.with(&:flushdb)
+ end
end
diff --git a/spec/support/redis/redis_new_instance_shared_examples.rb b/spec/support/redis/redis_new_instance_shared_examples.rb
new file mode 100644
index 00000000000..e9b1e3e4da1
--- /dev/null
+++ b/spec/support/redis/redis_new_instance_shared_examples.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples "redis_new_instance_shared_examples" do |name, fallback_class|
+ let(:instance_specific_config_file) { "config/redis.#{name}.yml" }
+ let(:environment_config_file_name) { "GITLAB_REDIS_#{name.upcase}_CONFIG_FILE" }
+ let(:fallback_config_file) { nil }
+
+ before do
+ allow(fallback_class).to receive(:config_file_name).and_return(fallback_config_file)
+ end
+
+ include_examples "redis_shared_examples"
+
+ describe '.config_file_name' do
+ subject { described_class.config_file_name }
+
+ let(:rails_root) { Dir.mktmpdir('redis_shared_examples') }
+
+ before do
+ # Undo top-level stub of config_file_name because we are testing that method now.
+ allow(described_class).to receive(:config_file_name).and_call_original
+
+ allow(described_class).to receive(:rails_root).and_return(rails_root)
+ FileUtils.mkdir_p(File.join(rails_root, 'config'))
+ end
+
+ after do
+ FileUtils.rm_rf(rails_root)
+ end
+
+ context 'when there is only a resque.yml' do
+ before do
+ FileUtils.touch(File.join(rails_root, 'config/resque.yml'))
+ end
+
+ it { expect(subject).to eq("#{rails_root}/config/resque.yml") }
+
+ context 'and there is a global env override' do
+ before do
+ stub_env('GITLAB_REDIS_CONFIG_FILE', 'global override')
+ end
+
+ it { expect(subject).to eq('global override') }
+
+ context "and #{fallback_class.name.demodulize} has a different config file" do
+ let(:fallback_config_file) { 'fallback config file' }
+
+ it { expect(subject).to eq('fallback config file') }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/redis/redis_shared_examples.rb b/spec/support/redis/redis_shared_examples.rb
index 25eab5fd6e4..dd916aea3e8 100644
--- a/spec/support/redis/redis_shared_examples.rb
+++ b/spec/support/redis/redis_shared_examples.rb
@@ -255,6 +255,28 @@ RSpec.shared_examples "redis_shared_examples" do
end
end
+ describe '#db' do
+ let(:rails_env) { 'development' }
+
+ subject { described_class.new(rails_env).db }
+
+ context 'with old format' do
+ let(:config_file_name) { config_old_format_host }
+
+ it 'returns the correct db' do
+ expect(subject).to eq(redis_database)
+ end
+ end
+
+ context 'with new format' do
+ let(:config_file_name) { config_new_format_host }
+
+ it 'returns the correct db' do
+ expect(subject).to eq(redis_database)
+ end
+ end
+ end
+
describe '#sentinels' do
subject { described_class.new(rails_env).sentinels }
@@ -327,6 +349,12 @@ RSpec.shared_examples "redis_shared_examples" do
expect(subject.send(:fetch_config)).to eq false
end
+
+ it 'has a value for the legacy default URL' do
+ allow(subject).to receive(:fetch_config) { false }
+
+ expect(subject.send(:raw_config_hash)).to include(url: a_string_matching(%r{\Aredis://localhost:638[012]\Z}))
+ end
end
def clear_raw_config
diff --git a/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb b/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb
new file mode 100644
index 00000000000..62d708420c3
--- /dev/null
+++ b/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'bulk imports requests context' do |url|
+ let(:page_response_headers) do
+ {
+ 'Content-Type' => 'application/json',
+ 'X-Next-Page' => 2,
+ 'X-Page' => 1,
+ 'X-Per-Page' => 20,
+ 'X-Total' => 42,
+ 'X-Total-Pages' => 2
+ }
+ end
+
+ let(:request_headers) { { 'Authorization' => 'Bearer demo-pat', 'Content-Type' => 'application/json' } }
+
+ before do
+ stub_request(:get, "#{url}/api/v4/version")
+ .with(headers: request_headers)
+ .to_return(
+ status: 200,
+ body: { version: ::BulkImport.min_gl_version_for_project_migration.to_s }.to_json,
+ headers: { 'Content-Type' => 'application/json' })
+
+ stub_request(:get, "https://gitlab.example.com/api/v4/groups?min_access_level=50&page=1&per_page=20&search=test&top_level_only=true")
+ .with(headers: request_headers)
+ .to_return(status: 200,
+ body: [{
+ id: 2595440,
+ web_url: 'https://gitlab.com/groups/test',
+ name: 'Test',
+ path: 'stub-test-group',
+ full_name: 'Test',
+ full_path: 'stub-test-group'
+ }].to_json,
+ headers: page_response_headers
+ )
+
+ stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: url })
+ .to_return(
+ body: [{
+ id: 2595438,
+ web_url: 'https://gitlab.com/groups/auto-breakfast',
+ name: 'Stub',
+ path: 'stub-group',
+ full_name: 'Stub',
+ full_path: 'stub-group'
+ }].to_json,
+ headers: page_response_headers
+ )
+ end
+end
diff --git a/spec/support/shared_contexts/lib/gitlab/import_export/relation_tree_restorer_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/import_export/relation_tree_restorer_shared_context.rb
index 6b9ddc70691..7176e38bf7c 100644
--- a/spec/support/shared_contexts/lib/gitlab/import_export/relation_tree_restorer_shared_context.rb
+++ b/spec/support/shared_contexts/lib/gitlab/import_export/relation_tree_restorer_shared_context.rb
@@ -3,7 +3,7 @@
RSpec.shared_context 'relation tree restorer shared context' do
include ImportExport::CommonUtil
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
let(:shared) { Gitlab::ImportExport::Shared.new(importable) }
let(:attributes) { relation_reader.consume_attributes(importable_name) }
diff --git a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
index 5a72b330707..b7966e25b38 100644
--- a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
+++ b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
@@ -39,17 +39,25 @@ RSpec.shared_context 'structured_logger' do
)
end
+ let(:db_payload_defaults) do
+ metrics =
+ ::Gitlab::Metrics::Subscribers::ActiveRecord.load_balancing_metric_counter_keys +
+ ::Gitlab::Metrics::Subscribers::ActiveRecord.load_balancing_metric_duration_keys +
+ ::Gitlab::Metrics::Subscribers::ActiveRecord.db_counter_keys +
+ [:db_duration_s]
+
+ metrics.each_with_object({}) do |key, result|
+ result[key.to_s] = 0
+ end
+ end
+
let(:end_payload) do
- start_payload.merge(
+ start_payload.merge(db_payload_defaults).merge(
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: done: 0.0 sec',
'job_status' => 'done',
'duration_s' => 0.0,
'completed_at' => timestamp.to_f,
- 'cpu_s' => 1.111112,
- 'db_duration_s' => 0.0,
- 'db_cached_count' => 0,
- 'db_count' => 0,
- 'db_write_count' => 0
+ 'cpu_s' => 1.111112
)
end
diff --git a/spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb
index 73de631e293..0d992f33c61 100644
--- a/spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb
+++ b/spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb
@@ -15,8 +15,12 @@ RSpec.shared_context 'server metrics with mocked prometheus' do
let(:redis_seconds_metric) { double('redis seconds metric') }
let(:elasticsearch_seconds_metric) { double('elasticsearch seconds metric') }
let(:elasticsearch_requests_total) { double('elasticsearch calls total metric') }
+ let(:load_balancing_metric) { double('load balancing metric') }
before do
+ allow(Gitlab::Metrics).to receive(:histogram).and_call_original
+ allow(Gitlab::Metrics).to receive(:counter).and_call_original
+
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything, anything, anything).and_return(completion_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric)
@@ -28,6 +32,7 @@ RSpec.shared_context 'server metrics with mocked prometheus' do
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_retried_total, anything).and_return(retried_total_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_redis_requests_total, anything).and_return(redis_requests_total)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_elasticsearch_requests_total, anything).and_return(elasticsearch_requests_total)
+ allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_load_balancing_count, anything).and_return(load_balancing_metric)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_running_jobs, anything, {}, :all).and_return(running_jobs_metric)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_concurrency, anything, {}, :all).and_return(concurrency_metric)
diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
index de1b46c65ad..d7e4864cb08 100644
--- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb
+++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb
@@ -49,6 +49,7 @@ RSpec.shared_context 'ProjectPolicy context' do
resolve_note update_build update_commit_status update_container_image
update_deployment update_environment update_merge_request
update_metrics_dashboard_annotation update_pipeline update_release destroy_release
+ read_resource_group update_resource_group
]
end
diff --git a/spec/support/shared_examples/ci/stuck_builds_shared_examples.rb b/spec/support/shared_examples/ci/stuck_builds_shared_examples.rb
new file mode 100644
index 00000000000..4fcea18393c
--- /dev/null
+++ b/spec/support/shared_examples/ci/stuck_builds_shared_examples.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'job is dropped with failure reason' do |failure_reason|
+ it 'changes status' do
+ service.execute
+ job.reload
+
+ expect(job).to be_failed
+ expect(job.failure_reason).to eq(failure_reason)
+ end
+
+ context 'when job has data integrity problem' do
+ it 'drops the job and logs the reason' do
+ job.update_columns(yaml_variables: '[{"key" => "value"}]')
+
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(anything, a_hash_including(build_id: job.id))
+ .once
+ .and_call_original
+
+ service.execute
+ job.reload
+
+ expect(job).to be_failed
+ expect(job.failure_reason).to eq('data_integrity_failure')
+ end
+ end
+end
+
+RSpec.shared_examples 'job is unchanged' do
+ it 'does not change status' do
+ expect { service.execute }.not_to change(job, :status)
+ end
+end
diff --git a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
index e8f7e62d0d7..30710e43357 100644
--- a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
@@ -299,7 +299,7 @@ RSpec.shared_examples 'wiki controller actions' do
expect(response.headers['Content-Disposition']).to match(/^inline/)
expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq('true')
expect(response.cache_control[:public]).to be(false)
- expect(response.headers['Cache-Control']).to eq('no-store')
+ expect(response.headers['Cache-Control']).to eq('private, no-store')
end
end
end
diff --git a/spec/support/shared_examples/features/container_registry_shared_examples.rb b/spec/support/shared_examples/features/container_registry_shared_examples.rb
new file mode 100644
index 00000000000..06b2b8c621c
--- /dev/null
+++ b/spec/support/shared_examples/features/container_registry_shared_examples.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'handling feature network errors with the container registry' do
+ it 'displays the error message' do
+ visit_container_registry
+
+ expect(page).to have_content 'We are having trouble connecting to the Container Registry'
+ end
+end
diff --git a/spec/support/shared_examples/features/discussion_comments_shared_example.rb b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
index 318ba67b9e9..6c06cbf9082 100644
--- a/spec/support/shared_examples/features/discussion_comments_shared_example.rb
+++ b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
@@ -3,9 +3,9 @@
RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name|
let(:form_selector) { '.js-main-target-form' }
let(:dropdown_selector) { "#{form_selector} .comment-type-dropdown" }
- let(:toggle_selector) { "#{dropdown_selector} .dropdown-toggle" }
+ let(:toggle_selector) { "#{dropdown_selector} .gl-dropdown-toggle" }
let(:menu_selector) { "#{dropdown_selector} .dropdown-menu" }
- let(:submit_selector) { "#{form_selector} .js-comment-submit-button" }
+ let(:submit_selector) { "#{form_selector} .js-comment-submit-button > button:first-child" }
let(:close_selector) { "#{form_selector} .btn-comment-and-close" }
let(:comments_selector) { '.timeline > .note.timeline-entry:not(.being-posted)' }
let(:comment) { 'My comment' }
@@ -43,13 +43,11 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
expect(items.first).to have_content 'Comment'
expect(items.first).to have_content "Add a general comment to this #{resource_name}."
- expect(items.first).to have_selector '[data-testid="check-icon"]'
- expect(items.first['class']).to match 'droplab-item-selected'
+ expect(items.first).to have_selector '[data-testid="dropdown-item-checkbox"]'
expect(items.last).to have_content 'Start thread'
expect(items.last).to have_content "Discuss a specific suggestion or question#{' that needs to be resolved' if resource_name == 'merge request'}."
- expect(items.last).not_to have_selector '[data-testid="check-icon"]'
- expect(items.last['class']).not_to match 'droplab-item-selected'
+ expect(items.last).not_to have_selector '[data-testid="dropdown-item-checkbox"]'
end
it 'closes the menu when clicking the toggle or body' do
@@ -75,14 +73,14 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
expect(find(dropdown_selector)).to have_content 'Comment'
find(toggle_selector).click
- execute_script("document.querySelector('#{menu_selector} .divider').click()")
+ execute_script("document.querySelector('#{menu_selector} .dropdown-divider').click()")
else
execute_script("document.querySelector('#{menu_selector}').click()")
expect(page).to have_selector menu_selector
expect(find(dropdown_selector)).to have_content 'Comment'
- execute_script("document.querySelector('#{menu_selector} .divider').click()")
+ execute_script("document.querySelector('#{menu_selector} .dropdown-divider').click()")
expect(page).to have_selector menu_selector
end
@@ -97,7 +95,7 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
end
it 'updates the submit button text and closes the dropdown' do
- expect(find(submit_selector).value).to eq 'Start thread'
+ expect(find(submit_selector).text).to eq 'Start thread'
expect(page).not_to have_selector menu_selector
end
@@ -137,12 +135,10 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
items = all("#{menu_selector} li")
expect(items.first).to have_content 'Comment'
- expect(items.first).not_to have_selector '[data-testid="check-icon"]'
- expect(items.first['class']).not_to match 'droplab-item-selected'
+ expect(items.first).not_to have_selector '[data-testid="dropdown-item-checkbox"]'
expect(items.last).to have_content 'Start thread'
- expect(items.last).to have_selector '[data-testid="check-icon"]'
- expect(items.last['class']).to match 'droplab-item-selected'
+ expect(items.last).to have_selector '[data-testid="dropdown-item-checkbox"]'
end
describe 'when selecting "Comment"' do
@@ -153,7 +149,7 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
it 'updates the submit button text and closes the dropdown' do
button = find(submit_selector)
- expect(button.value).to eq 'Comment'
+ expect(button.text).to eq 'Comment'
expect(page).not_to have_selector menu_selector
end
@@ -166,12 +162,10 @@ RSpec.shared_examples 'thread comments for commit and snippet' do |resource_name
aggregate_failures do
expect(items.first).to have_content 'Comment'
- expect(items.first).to have_selector '[data-testid="check-icon"]'
- expect(items.first['class']).to match 'droplab-item-selected'
+ expect(items.first).to have_selector '[data-testid="dropdown-item-checkbox"]'
expect(items.last).to have_content 'Start thread'
- expect(items.last).not_to have_selector '[data-testid="check-icon"]'
- expect(items.last['class']).not_to match 'droplab-item-selected'
+ expect(items.last).not_to have_selector '[data-testid="dropdown-item-checkbox"]'
end
end
end
diff --git a/spec/support/shared_examples/features/project_upload_files_shared_examples.rb b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
index 7adf303bde4..85434ba7afd 100644
--- a/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
+++ b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-RSpec.shared_examples 'it uploads and commits a new text file' do
+RSpec.shared_examples 'it uploads and commits a new text file' do |drop: false|
it 'uploads and commits a new text file', :js do
find('.add-to-tree').click
@@ -10,7 +10,11 @@ RSpec.shared_examples 'it uploads and commits a new text file' do
wait_for_requests
end
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
@@ -32,7 +36,7 @@ RSpec.shared_examples 'it uploads and commits a new text file' do
end
end
-RSpec.shared_examples 'it uploads and commits a new image file' do
+RSpec.shared_examples 'it uploads and commits a new image file' do |drop: false|
it 'uploads and commits a new image file', :js do
find('.add-to-tree').click
@@ -42,7 +46,11 @@ RSpec.shared_examples 'it uploads and commits a new image file' do
wait_for_requests
end
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'), make_visible: true)
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg'), make_visible: true)
+ end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
@@ -58,7 +66,7 @@ RSpec.shared_examples 'it uploads and commits a new image file' do
end
end
-RSpec.shared_examples 'it uploads and commits a new pdf file' do
+RSpec.shared_examples 'it uploads and commits a new pdf file' do |drop: false|
it 'uploads and commits a new pdf file', :js do
find('.add-to-tree').click
@@ -68,7 +76,11 @@ RSpec.shared_examples 'it uploads and commits a new pdf file' do
wait_for_requests
end
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'), make_visible: true)
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'git-cheat-sheet.pdf'), make_visible: true)
+ end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
@@ -84,7 +96,7 @@ RSpec.shared_examples 'it uploads and commits a new pdf file' do
end
end
-RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
+RSpec.shared_examples 'it uploads and commits a new file to a forked project' do |drop: false|
let(:fork_message) do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
@@ -100,7 +112,12 @@ RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
find('.add-to-tree').click
click_link('Upload file')
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
@@ -123,7 +140,7 @@ RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
end
end
-RSpec.shared_examples 'it uploads a file to a sub-directory' do
+RSpec.shared_examples 'it uploads a file to a sub-directory' do |drop: false|
it 'uploads a file to a sub-directory', :js do
click_link 'files'
@@ -133,7 +150,12 @@ RSpec.shared_examples 'it uploads a file to a sub-directory' do
find('.add-to-tree').click
click_link('Upload file')
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ end
page.within('#modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
@@ -150,11 +172,15 @@ RSpec.shared_examples 'it uploads a file to a sub-directory' do
end
end
-RSpec.shared_examples 'uploads and commits a new text file via "upload file" button' do
+RSpec.shared_examples 'uploads and commits a new text file via "upload file" button' do |drop: false|
it 'uploads and commits a new text file via "upload file" button', :js do
find('[data-testid="upload-file-button"]').click
- attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ if drop
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ else
+ attach_file('upload_file', File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'), make_visible: true)
+ end
page.within('#details-modal-upload-blob') do
fill_in(:commit_message, with: 'New commit message')
diff --git a/spec/support/shared_examples/graphql/connection_shared_examples.rb b/spec/support/shared_examples/graphql/connection_shared_examples.rb
index 4cba5b5a69d..895bab1f51a 100644
--- a/spec/support/shared_examples/graphql/connection_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/connection_shared_examples.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.shared_examples 'a connection with collection methods' do
- %i[to_a size include? empty?].each do |method_name|
+ %i[to_a size map include? empty?].each do |method_name|
it "responds to #{method_name}" do
expect(connection).to respond_to(method_name)
end
diff --git a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
index eaeb5faee3b..37a805902a9 100644
--- a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
@@ -9,7 +9,7 @@
# data_path: the keys necessary to dig into the return GraphQL data to get the
# returned results
# first_param: number of items expected (like a page size)
-# expected_results: array of comparison data of all items sorted correctly
+# all_records: array of comparison data of all items sorted correctly
# pagination_query: method that specifies the GraphQL query
# pagination_results_data: method that extracts the sorted data used to compare against
# the expected results
@@ -38,9 +38,9 @@
# let(:ordered_issues) { issues.sort_by(&:weight) }
#
# it_behaves_like 'sorted paginated query' do
-# let(:sort_param) { :WEIGHT_ASC }
-# let(:first_param) { 2 }
-# let(:expected_results) { ordered_issues.map(&:iid) }
+# let(:sort_param) { :WEIGHT_ASC }
+# let(:first_param) { 2 }
+# let(:all_records) { ordered_issues.map(&:iid) }
# end
# end
#
@@ -51,7 +51,7 @@ RSpec.shared_examples 'sorted paginated query' do |conditions = {}|
let(:node_path) { ['id'] }
it_behaves_like 'requires variables' do
- let(:required_variables) { [:sort_param, :first_param, :expected_results, :data_path, :current_user] }
+ let(:required_variables) { [:sort_param, :first_param, :all_records, :data_path, :current_user] }
end
describe do
@@ -101,13 +101,13 @@ RSpec.shared_examples 'sorted paginated query' do |conditions = {}|
context 'when sorting' do
it 'sorts correctly' do
- expect(results).to eq expected_results
+ expect(results).to eq all_records
end
context 'when paginating' do
let(:params) { sort_argument.merge(first: first_param) }
- let(:first_page) { expected_results.first(first_param) }
- let(:rest) { expected_results.drop(first_param) }
+ let(:first_page) { all_records.first(first_param) }
+ let(:rest) { all_records.drop(first_param) }
it 'paginates correctly' do
expect(results).to eq first_page
@@ -130,7 +130,7 @@ RSpec.shared_examples 'sorted paginated query' do |conditions = {}|
it 'fetches last elements without error' do
post_graphql(pagination_query(params), current_user: current_user)
- expect(results.first).to eq(expected_results.last)
+ expect(results.first).to eq(all_records.last)
end
end
end
diff --git a/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb
index 3760325675a..8b4ecd7d5ae 100644
--- a/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb
@@ -35,8 +35,8 @@ RSpec.shared_examples 'common trace features' do
stub_feature_flags(gitlab_ci_archived_trace_consistent_reads: trace.job.project)
end
- it 'calls ::Gitlab::Database::LoadBalancing::Sticking.unstick_or_continue_sticking' do
- expect(::Gitlab::Database::LoadBalancing::Sticking).to receive(:unstick_or_continue_sticking)
+ it 'calls ::ApplicationRecord.sticking.unstick_or_continue_sticking' do
+ expect(::ApplicationRecord.sticking).to receive(:unstick_or_continue_sticking)
.with(described_class::LOAD_BALANCING_STICKING_NAMESPACE, trace.job.id)
.and_call_original
@@ -49,8 +49,8 @@ RSpec.shared_examples 'common trace features' do
stub_feature_flags(gitlab_ci_archived_trace_consistent_reads: false)
end
- it 'does not call ::Gitlab::Database::LoadBalancing::Sticking.unstick_or_continue_sticking' do
- expect(::Gitlab::Database::LoadBalancing::Sticking).not_to receive(:unstick_or_continue_sticking)
+ it 'does not call ::ApplicationRecord.sticking.unstick_or_continue_sticking' do
+ expect(::ApplicationRecord.sticking).not_to receive(:unstick_or_continue_sticking)
trace.read { |stream| stream }
end
@@ -305,8 +305,8 @@ RSpec.shared_examples 'common trace features' do
stub_feature_flags(gitlab_ci_archived_trace_consistent_reads: trace.job.project)
end
- it 'calls ::Gitlab::Database::LoadBalancing::Sticking.stick' do
- expect(::Gitlab::Database::LoadBalancing::Sticking).to receive(:stick)
+ it 'calls ::ApplicationRecord.sticking.stick' do
+ expect(::ApplicationRecord.sticking).to receive(:stick)
.with(described_class::LOAD_BALANCING_STICKING_NAMESPACE, trace.job.id)
.and_call_original
@@ -319,8 +319,8 @@ RSpec.shared_examples 'common trace features' do
stub_feature_flags(gitlab_ci_archived_trace_consistent_reads: false)
end
- it 'does not call ::Gitlab::Database::LoadBalancing::Sticking.stick' do
- expect(::Gitlab::Database::LoadBalancing::Sticking).not_to receive(:stick)
+ it 'does not call ::ApplicationRecord.sticking.stick' do
+ expect(::ApplicationRecord.sticking).not_to receive(:stick)
subject
end
@@ -497,7 +497,7 @@ RSpec.shared_examples 'trace with disabled live trace feature' do
expect(build.job_artifacts_trace.file.filename).to eq('job.log')
expect(File.exist?(src_path)).to be_falsy
expect(src_checksum)
- .to eq(described_class.hexdigest(build.job_artifacts_trace.file.path))
+ .to eq(described_class.sha256_hexdigest(build.job_artifacts_trace.file.path))
expect(build.job_artifacts_trace.file_sha256).to eq(src_checksum)
end
end
@@ -523,7 +523,7 @@ RSpec.shared_examples 'trace with disabled live trace feature' do
expect(build.job_artifacts_trace.file.filename).to eq('job.log')
expect(build.old_trace).to be_nil
expect(src_checksum)
- .to eq(described_class.hexdigest(build.job_artifacts_trace.file.path))
+ .to eq(described_class.sha256_hexdigest(build.job_artifacts_trace.file.path))
expect(build.job_artifacts_trace.file_sha256).to eq(src_checksum)
end
end
@@ -861,7 +861,7 @@ RSpec.shared_examples 'trace with enabled live trace feature' do
expect(build.job_artifacts_trace.file.filename).to eq('job.log')
expect(Ci::BuildTraceChunk.where(build: build)).not_to be_exist
expect(src_checksum)
- .to eq(described_class.hexdigest(build.job_artifacts_trace.file.path))
+ .to eq(described_class.sha256_hexdigest(build.job_artifacts_trace.file.path))
expect(build.job_artifacts_trace.file_sha256).to eq(src_checksum)
end
end
diff --git a/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb
index 6e12b5a0e85..bd8bdd70ce5 100644
--- a/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/cycle_analytics/event_shared_examples.rb
@@ -33,3 +33,38 @@ RSpec.shared_examples_for 'value stream analytics event' do
end
end
end
+
+RSpec.shared_examples_for 'LEFT JOIN-able value stream analytics event' do
+ let(:params) { {} }
+ let(:instance) { described_class.new(params) }
+ let(:record_with_data) { nil }
+ let(:record_without_data) { nil }
+ let(:scope) { instance.object_type.all }
+
+ let(:records) do
+ scope_with_left_join = instance.include_in(scope)
+ scope_with_left_join.select(scope.model.arel_table[:id], instance.timestamp_projection.as('timestamp_column_data')).to_a
+ end
+
+ it 'can use the event as LEFT JOIN' do
+ expected_record_count = record_without_data.nil? ? 1 : 2
+
+ expect(records.count).to eq(expected_record_count)
+ end
+
+ context 'when looking at the record with data' do
+ subject(:record) { records.to_a.find { |r| r.id == record_with_data.id } }
+
+ it 'contains the timestamp expression' do
+ expect(record.timestamp_column_data).not_to eq(nil)
+ end
+ end
+
+ context 'when looking at the record without data' do
+ subject(:record) { records.to_a.find { |r| r.id == record_without_data.id } }
+
+ it 'returns nil for the timestamp expression' do
+ expect(record.timestamp_column_data).to eq(nil) if record_without_data
+ end
+ end
+end
diff --git a/spec/support/shared_examples/lib/gitlab/import_export/attributes_permitter_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/import_export/attributes_permitter_shared_examples.rb
new file mode 100644
index 00000000000..5ce698c4701
--- /dev/null
+++ b/spec/support/shared_examples/lib/gitlab/import_export/attributes_permitter_shared_examples.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+RSpec.shared_examples 'a permitted attribute' do |relation_sym, permitted_attributes|
+ let(:prohibited_attributes) { %i[remote_url my_attributes my_ids token my_id test] }
+
+ let(:import_export_config) { Gitlab::ImportExport::Config.new.to_h }
+ let(:project_relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
+
+ let(:relation_hash) { (permitted_attributes + prohibited_attributes).map(&:to_s).zip([]).to_h }
+ let(:relation_name) { project_relation_factory.overrides[relation_sym]&.to_sym || relation_sym }
+ let(:relation_class) { project_relation_factory.relation_class(relation_name) }
+ let(:excluded_keys) { import_export_config.dig(:excluded_keys, relation_sym) || [] }
+
+ let(:cleaned_hash) do
+ Gitlab::ImportExport::AttributeCleaner.new(
+ relation_hash: relation_hash,
+ relation_class: relation_class,
+ excluded_keys: excluded_keys
+ ).clean
+ end
+
+ let(:permitted_hash) { subject.permit(relation_sym, relation_hash) }
+
+ if described_class.new.permitted_attributes_defined?(relation_sym)
+ it 'contains only attributes that are defined as permitted in the import/export config' do
+ expect(permitted_hash.keys).to contain_exactly(*permitted_attributes.map(&:to_s))
+ end
+
+ it 'does not contain attributes that would be cleaned with AttributeCleaner' do
+ expect(cleaned_hash.keys).to include(*permitted_hash.keys)
+ end
+
+ it 'does not contain prohibited attributes that are not related to given relation' do
+ expect(permitted_hash.keys).not_to include(*prohibited_attributes.map(&:to_s))
+ end
+ else
+ it 'is disabled' do
+ expect(subject).not_to be_permitted_attributes_defined(relation_sym)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb b/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
index c6d6ff6bc1d..c06083ba952 100644
--- a/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
+++ b/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
@@ -4,14 +4,20 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
let(:db_config_name) { ::Gitlab::Database.db_config_names.first }
let(:expected_payload_defaults) do
+ result = {}
metrics =
::Gitlab::Metrics::Subscribers::ActiveRecord.load_balancing_metric_counter_keys +
- ::Gitlab::Metrics::Subscribers::ActiveRecord.load_balancing_metric_duration_keys +
::Gitlab::Metrics::Subscribers::ActiveRecord.db_counter_keys
- metrics.each_with_object({}) do |key, result|
+ metrics.each do |key|
result[key] = 0
end
+
+ ::Gitlab::Metrics::Subscribers::ActiveRecord.load_balancing_metric_duration_keys.each do |key|
+ result[key] = 0.0
+ end
+
+ result
end
def transform_hash(hash, another_hash)
@@ -36,8 +42,8 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
"db_primary_#{db_config_name}_cached_count": record_cached_query ? 1 : 0,
db_primary_count: record_query ? 1 : 0,
"db_primary_#{db_config_name}_count": record_query ? 1 : 0,
- db_primary_duration_s: record_query ? 0.002 : 0,
- "db_primary_#{db_config_name}_duration_s": record_query ? 0.002 : 0,
+ db_primary_duration_s: record_query ? 0.002 : 0.0,
+ "db_primary_#{db_config_name}_duration_s": record_query ? 0.002 : 0.0,
db_primary_wal_count: record_wal_query ? 1 : 0,
"db_primary_#{db_config_name}_wal_count": record_wal_query ? 1 : 0,
db_primary_wal_cached_count: record_wal_query && record_cached_query ? 1 : 0,
@@ -52,19 +58,29 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
"db_replica_#{db_config_name}_cached_count": record_cached_query ? 1 : 0,
db_replica_count: record_query ? 1 : 0,
"db_replica_#{db_config_name}_count": record_query ? 1 : 0,
- db_replica_duration_s: record_query ? 0.002 : 0,
- "db_replica_#{db_config_name}_duration_s": record_query ? 0.002 : 0,
+ db_replica_duration_s: record_query ? 0.002 : 0.0,
+ "db_replica_#{db_config_name}_duration_s": record_query ? 0.002 : 0.0,
db_replica_wal_count: record_wal_query ? 1 : 0,
"db_replica_#{db_config_name}_wal_count": record_wal_query ? 1 : 0,
db_replica_wal_cached_count: record_wal_query && record_cached_query ? 1 : 0,
"db_replica_#{db_config_name}_wal_cached_count": record_wal_query && record_cached_query ? 1 : 0
})
else
- {
+ transform_hash(expected_payload_defaults, {
db_count: record_query ? 1 : 0,
db_write_count: record_write_query ? 1 : 0,
- db_cached_count: record_cached_query ? 1 : 0
- }
+ db_cached_count: record_cached_query ? 1 : 0,
+ db_primary_cached_count: 0,
+ "db_primary_#{db_config_name}_cached_count": 0,
+ db_primary_count: 0,
+ "db_primary_#{db_config_name}_count": 0,
+ db_primary_duration_s: 0.0,
+ "db_primary_#{db_config_name}_duration_s": 0.0,
+ db_primary_wal_count: 0,
+ "db_primary_#{db_config_name}_wal_count": 0,
+ db_primary_wal_cached_count: 0,
+ "db_primary_#{db_config_name}_wal_cached_count": 0
+ })
end
expect(described_class.db_counter_payload).to eq(expected)
@@ -89,7 +105,7 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
end
RSpec.shared_examples 'record ActiveRecord metrics in a metrics transaction' do |db_role|
- let(:db_config_name) { ::Gitlab::Database.db_config_name(ApplicationRecord.connection) }
+ let(:db_config_name) { ::Gitlab::Database.db_config_name(ApplicationRecord.retrieve_connection) }
it 'increments only db counters' do
if record_query
diff --git a/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
new file mode 100644
index 00000000000..f928fb1eb43
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'StageEventModel' do
+ describe '.upsert_data' do
+ let(:time) { Time.parse(Time.current.to_s(:db)) } # truncating the timestamp so we can compare it with the timestamp loaded from the DB
+ let(:input_data) do
+ [
+ {
+ stage_event_hash_id: 1,
+ issuable_id: 2,
+ group_id: 3,
+ project_id: 4,
+ author_id: 5,
+ milestone_id: 6,
+ start_event_timestamp: time,
+ end_event_timestamp: time
+ },
+ {
+ stage_event_hash_id: 7,
+ issuable_id: 8,
+ group_id: 10,
+ project_id: 11,
+ author_id: 12,
+ milestone_id: 13,
+ start_event_timestamp: time,
+ end_event_timestamp: time
+ }
+ ]
+ end
+
+ let(:column_order) do
+ [
+ :stage_event_hash_id,
+ described_class.issuable_id_column,
+ :group_id,
+ :project_id,
+ :milestone_id,
+ :author_id,
+ :start_event_timestamp,
+ :end_event_timestamp
+ ]
+ end
+
+ subject(:upsert_data) { described_class.upsert_data(input_data) }
+
+ it 'inserts the data' do
+ upsert_data
+
+ expect(described_class.count).to eq(input_data.count)
+ end
+
+ it 'does not produce duplicate rows' do
+ 2.times { upsert_data }
+
+ expect(described_class.count).to eq(input_data.count)
+ end
+
+ it 'inserts the data correctly' do
+ upsert_data
+
+ output_data = described_class.all.map do |record|
+ column_order.map { |column| record[column] }
+ end.sort
+
+ expect(input_data.map(&:values).sort).to eq(output_data)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb b/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb
new file mode 100644
index 00000000000..a4e0d6c871e
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/ttl_expirable_shared_examples.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'ttl_expirable' do
+ let_it_be(:class_symbol) { described_class.model_name.param_key.to_sym }
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:status) }
+ end
+
+ describe '.updated_before' do
+ # rubocop:disable Rails/SaveBang
+ let_it_be_with_reload(:item1) { create(class_symbol) }
+ let_it_be(:item2) { create(class_symbol) }
+ # rubocop:enable Rails/SaveBang
+
+ before do
+ item1.update_column(:updated_at, 1.month.ago)
+ end
+
+ it 'returns items with created at older than the supplied number of days' do
+ expect(described_class.updated_before(10)).to contain_exactly(item1)
+ end
+ end
+
+ describe '.active' do
+ # rubocop:disable Rails/SaveBang
+ let_it_be(:item1) { create(class_symbol) }
+ let_it_be(:item2) { create(class_symbol, :expired) }
+ let_it_be(:item3) { create(class_symbol, status: :error) }
+ # rubocop:enable Rails/SaveBang
+
+ it 'returns only active items' do
+ expect(described_class.active).to contain_exactly(item1)
+ end
+ end
+
+ describe '.lock_next_by' do
+ let_it_be(:item1) { create(class_symbol, created_at: 1.month.ago, updated_at: 1.day.ago) }
+ let_it_be(:item2) { create(class_symbol, created_at: 1.year.ago, updated_at: 1.year.ago) }
+ let_it_be(:item3) { create(class_symbol, created_at: 2.years.ago, updated_at: 1.month.ago) }
+
+ it 'returns the first item sorted by the argument' do
+ expect(described_class.lock_next_by(:updated_at)).to contain_exactly(item2)
+ expect(described_class.lock_next_by(:created_at)).to contain_exactly(item3)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb b/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
index 274fbae3dfd..750d3dd11e3 100644
--- a/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
+++ b/spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
@@ -193,42 +193,6 @@ RSpec.shared_examples 'Debian Distribution' do |factory, container, can_freeze|
end
end
- describe '#needs_update?' do
- subject { distribution.needs_update? }
-
- context 'with new distribution' do
- let(:distribution) { create(factory, container: distribution_with_suite.container) }
-
- it { is_expected.to be_truthy }
- end
-
- context 'with file' do
- context 'without valid_time_duration_seconds' do
- let(:distribution) { create(factory, :with_file, container: distribution_with_suite.container) }
-
- it { is_expected.to be_falsey }
- end
-
- context 'with valid_time_duration_seconds' do
- let(:distribution) { create(factory, :with_file, container: distribution_with_suite.container, valid_time_duration_seconds: 2.days.to_i) }
-
- context 'when not yet expired' do
- it { is_expected.to be_falsey }
- end
-
- context 'when expired' do
- it do
- distribution
-
- travel_to(4.days.from_now) do
- is_expected.to be_truthy
- end
- end
- end
- end
- end
- end
-
if container == :project
describe 'project distribution specifics' do
describe 'relationships' do
diff --git a/spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
index b86c0529338..e45be21f152 100644
--- a/spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
@@ -85,7 +85,18 @@ RSpec.shared_examples 'Composer package creation' do |user_type, status, add_mem
expect(response).to have_gitlab_http_status(status)
end
+
it_behaves_like 'a package tracking event', described_class.name, 'push_package'
+
+ context 'when package creation fails' do
+ before do
+ allow_next_instance_of(::Packages::Composer::CreatePackageService) do |create_package_service|
+ allow(create_package_service).to receive(:execute).and_raise(StandardError)
+ end
+ end
+
+ it_behaves_like 'not a package tracking event'
+ end
end
end
diff --git a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
index e776cf13217..e1e75be2494 100644
--- a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
@@ -79,3 +79,40 @@ RSpec.shared_examples 'returns repositories for allowed users' do |user_type, sc
end
end
end
+
+RSpec.shared_examples 'handling network errors with the container registry' do
+ before do
+ stub_container_registry_network_error(client_method: :repository_tags)
+ end
+
+ it 'returns a connection error' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:service_unavailable)
+ expect(json_response['message']).to include('We are having trouble connecting to the Container Registry')
+ end
+end
+
+RSpec.shared_examples 'handling graphql network errors with the container registry' do
+ before do
+ stub_container_registry_network_error(client_method: :repository_tags)
+ end
+
+ it 'returns a connection error' do
+ subject
+
+ expect_graphql_errors_to_include('We are having trouble connecting to the Container Registry')
+ end
+end
+
+RSpec.shared_examples 'not hitting graphql network errors with the container registry' do
+ before do
+ stub_container_registry_network_error(client_method: :repository_tags)
+ end
+
+ it 'does not return any error' do
+ subject
+
+ expect_graphql_errors_to_be_empty
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
index 274516cd87b..01ed6c26576 100644
--- a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
@@ -62,9 +62,10 @@ RSpec.shared_examples 'group and project boards query' do
context 'when ascending' do
it_behaves_like 'sorted paginated query' do
- let(:sort_param) { }
- let(:first_param) { 2 }
- let(:expected_results) do
+ let(:sort_param) { }
+ let(:first_param) { 2 }
+
+ let(:all_records) do
if board_parent.multiple_issue_boards_available?
boards.map { |board| global_id_of(board) }
else
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
index af4c9286e7c..367c6d4fa3a 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
@@ -17,9 +17,11 @@ RSpec.shared_examples 'group and project packages query' do
let(:package_names) { graphql_data_at(resource_type, :packages, :nodes, :name) }
let(:target_shas) { graphql_data_at(resource_type, :packages, :nodes, :metadata, :target_sha) }
let(:packages) { graphql_data_at(resource_type, :packages, :nodes) }
+ let(:packages_count) { graphql_data_at(resource_type, :packages, :count) }
let(:fields) do
<<~QUERY
+ count
nodes {
#{all_graphql_fields_for('packages'.classify, excluded: ['project'])}
metadata { #{query_graphql_fragment('ComposerMetadata')} }
@@ -55,6 +57,10 @@ RSpec.shared_examples 'group and project packages query' do
it 'deals with metadata' do
expect(target_shas).to contain_exactly(composer_metadatum.target_sha)
end
+
+ it 'returns the count of the packages' do
+ expect(packages_count).to eq(4)
+ end
end
context 'when the user does not have access to the resource' do
@@ -95,7 +101,7 @@ RSpec.shared_examples 'group and project packages query' do
it_behaves_like 'sorted paginated query' do
let(:sort_param) { order }
let(:first_param) { 4 }
- let(:expected_results) { ascending_packages }
+ let(:all_records) { ascending_packages }
end
end
end
@@ -105,7 +111,7 @@ RSpec.shared_examples 'group and project packages query' do
it_behaves_like 'sorted paginated query' do
let(:sort_param) { order }
let(:first_param) { 4 }
- let(:expected_results) { ascending_packages.reverse }
+ let(:all_records) { ascending_packages.reverse }
end
end
end
diff --git a/spec/support/shared_examples/requests/api/issuable_search_shared_examples.rb b/spec/support/shared_examples/requests/api/issuable_search_shared_examples.rb
new file mode 100644
index 00000000000..9f67bd69560
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/issuable_search_shared_examples.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'issuable anonymous search' do
+ context 'with anonymous user' do
+ context 'with disable_anonymous_search disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'returns issuables matching given search string for title' do
+ get api(url), params: { scope: 'all', search: issuable.title }
+
+ expect_paginated_array_response(result)
+ end
+
+ it 'returns issuables matching given search string for description' do
+ get api(url), params: { scope: 'all', search: issuable.description }
+
+ expect_paginated_array_response(result)
+ end
+ end
+
+ context 'with disable_anonymous_search enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it "returns 422 error" do
+ get api(url), params: { scope: 'all', search: issuable.title }
+
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ expect(json_response['message']).to eq('User must be authenticated to use search')
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb b/spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb
index cb06c9fa596..3e9c4a5eb68 100644
--- a/spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb
@@ -15,6 +15,22 @@ RSpec.shared_examples 'storing arguments in the application context' do
end
end
+# For the API we need a slightly different approach as `client_id` is
+# calculated in API logging code.
+RSpec.shared_examples 'storing arguments in the application context for the API' do
+ it 'places the expected params in the application context' do
+ expect(::API::API::LOG_FORMATTER).to receive(:call) do
+ expect(Gitlab::ApplicationContext.current).to include(log_hash(expected_params))
+ end
+
+ subject
+ end
+
+ def log_hash(hash)
+ hash.transform_keys! { |key| "meta.#{key}" }
+ end
+end
+
RSpec.shared_examples 'not executing any extra queries for the application context' do |expected_extra_queries = 0|
it 'does not execute more queries than without adding anything to the application context' do
# Call the subject once to memoize all factories being used for the spec, so they won't
diff --git a/spec/support/shared_examples/requests/rack_attack_shared_examples.rb b/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
index 2a19ff6f590..b294467d482 100644
--- a/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
+++ b/spec/support/shared_examples/requests/rack_attack_shared_examples.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
#
# Requires let variables:
-# * throttle_setting_prefix: "throttle_authenticated_api", "throttle_authenticated_web", "throttle_protected_paths", "throttle_authenticated_packages_api", "throttle_authenticated_git_lfs", "throttle_authenticated_files_api"
+# * throttle_setting_prefix: "throttle_authenticated_api", "throttle_authenticated_web", "throttle_protected_paths", "throttle_authenticated_packages_api", "throttle_authenticated_git_lfs", "throttle_authenticated_files_api", "throttle_authenticated_deprecated_api"
# * request_method
# * request_args
# * other_user_request_args
@@ -16,7 +16,8 @@ RSpec.shared_examples 'rate-limited token-authenticated requests' do
"throttle_authenticated_web" => "throttle_authenticated_web",
"throttle_authenticated_packages_api" => "throttle_authenticated_packages_api",
"throttle_authenticated_git_lfs" => "throttle_authenticated_git_lfs",
- "throttle_authenticated_files_api" => "throttle_authenticated_files_api"
+ "throttle_authenticated_files_api" => "throttle_authenticated_files_api",
+ "throttle_authenticated_deprecated_api" => "throttle_authenticated_deprecated_api"
}
end
diff --git a/spec/support/shared_examples/services/dependency_proxy_settings_shared_examples.rb b/spec/support/shared_examples/services/dependency_proxy_settings_shared_examples.rb
new file mode 100644
index 00000000000..2c1dc2da560
--- /dev/null
+++ b/spec/support/shared_examples/services/dependency_proxy_settings_shared_examples.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'updating the dependency proxy group settings attributes' do |from: {}, to: {}|
+ it 'updates the dependency proxy settings' do
+ expect { subject }
+ .to change { group_settings.reload.enabled }.from(from[:enabled]).to(to[:enabled])
+ end
+end
diff --git a/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb b/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb
new file mode 100644
index 00000000000..c9014ad549c
--- /dev/null
+++ b/spec/support/shared_examples/workers/concerns/dependency_proxy/cleanup_worker_shared_examples.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'dependency_proxy_cleanup_worker' do
+ let_it_be(:group) { create(:group) }
+
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ subject(:perform_work) { worker.perform_work }
+
+ context 'with no work to do' do
+ it { is_expected.to be_nil }
+ end
+
+ context 'with work to do' do
+ let_it_be(:artifact1) { create(factory_type, :expired, group: group) }
+ let_it_be(:artifact2) { create(factory_type, :expired, group: group, updated_at: 6.months.ago, created_at: 2.years.ago) }
+ let_it_be_with_reload(:artifact3) { create(factory_type, :expired, group: group, updated_at: 1.year.ago, created_at: 1.year.ago) }
+ let_it_be(:artifact4) { create(factory_type, group: group, updated_at: 2.years.ago, created_at: 2.years.ago) }
+
+ it 'deletes the oldest expired artifact based on updated_at', :aggregate_failures do
+ expect(worker).to receive(:log_extra_metadata_on_done).with("#{factory_type}_id".to_sym, artifact3.id)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:group_id, group.id)
+
+ expect { perform_work }.to change { artifact1.class.count }.by(-1)
+ end
+ end
+ end
+
+ describe '#max_running_jobs' do
+ let(:capacity) { 5 }
+
+ subject { worker.max_running_jobs }
+
+ before do
+ stub_application_setting(dependency_proxy_ttl_group_policy_worker_capacity: capacity)
+ end
+
+ it { is_expected.to eq(capacity) }
+ end
+
+ describe '#remaining_work_count' do
+ let_it_be(:expired_artifacts) do
+ (1..3).map do |_|
+ create(factory_type, :expired, group: group)
+ end
+ end
+
+ subject { worker.remaining_work_count }
+
+ it { is_expected.to eq(3) }
+ end
+end
diff --git a/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb b/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
index 1b09b5fe613..d6e96ef37d6 100644
--- a/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
+++ b/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
-# Expects `subject` to be a job/worker instance
+# Expects `subject` to be a job/worker instance and
+# `job_args` to be arguments to #perform if it takes arguments
RSpec.shared_examples 'reenqueuer' do
before do
allow(subject).to receive(:sleep) # faster tests
end
+ let(:subject_perform) { defined?(job_args) ? subject.perform(job_args) : subject.perform }
+
it 'implements lease_timeout' do
expect(subject.lease_timeout).to be_a(ActiveSupport::Duration)
end
@@ -18,12 +21,13 @@ RSpec.shared_examples 'reenqueuer' do
it 'tries to obtain a lease' do
expect_to_obtain_exclusive_lease(subject.lease_key)
- subject.perform
+ subject_perform
end
end
end
-# Expects `subject` to be a job/worker instance
+# Expects `subject` to be a job/worker instance and
+# `job_args` to be arguments to #perform if it takes arguments
RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_duration|
before do
# Allow Timecop freeze and travel without the block form
@@ -38,13 +42,15 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
Timecop.safe_mode = true
end
+ let(:subject_perform) { defined?(job_args) ? subject.perform(job_args) : subject.perform }
+
context 'when the work finishes in 0 seconds' do
let(:actual_duration) { 0 }
it 'sleeps exactly the minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(minimum_duration))
- subject.perform
+ subject_perform
end
end
@@ -54,7 +60,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
it 'sleeps 90% of minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.9 * minimum_duration))
- subject.perform
+ subject_perform
end
end
@@ -64,7 +70,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
it 'sleeps 10% of minimum duration' do
expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.1 * minimum_duration))
- subject.perform
+ subject_perform
end
end
@@ -74,7 +80,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
it 'does not sleep' do
expect(subject).not_to receive(:sleep)
- subject.perform
+ subject_perform
end
end
@@ -84,7 +90,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
it 'does not sleep' do
expect(subject).not_to receive(:sleep)
- subject.perform
+ subject_perform
end
end
@@ -94,7 +100,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
it 'does not sleep' do
expect(subject).not_to receive(:sleep)
- subject.perform
+ subject_perform
end
end