diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-20 02:18:09 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-20 02:18:09 +0300 |
commit | 6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch) | |
tree | dc4d20fe6064752c0bd323187252c77e0a89144b /qa/qa/specs | |
parent | 9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff) |
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'qa/qa/specs')
63 files changed, 810 insertions, 477 deletions
diff --git a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb index 55ae0d215cf..2058d58d5d6 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/automatic_failover_and_recovery_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/automatic_failover_and_recovery_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create' do - context 'Gitaly automatic failover and recovery', :orchestrated, :gitaly_cluster do + RSpec.describe 'Systems' do + context 'with Gitaly automatic failover and recovery', :orchestrated, :gitaly_cluster do # Variables shared between contexts. They're used and shared between # contexts so they can't be `let` variables. praefect_manager = Service::PraefectManager.new @@ -47,11 +47,11 @@ module QA commit.project = project commit.commit_message = second_added_commit_message commit.add_files([ - { - file_path: "file-#{SecureRandom.hex(8)}", - content: 'This is created on gitaly2/gitaly3 while gitaly1 is unavailable' - } - ]) + { + file_path: "file-#{SecureRandom.hex(8)}", + content: 'This is created on gitaly2/gitaly3 while gitaly1 is unavailable' + } + ]) end # Confirm that we have access to the repo after failover, diff --git a/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb new file mode 100644 index 00000000000..0b4bdf550f8 --- /dev/null +++ b/qa/qa/specs/features/api/12_systems/gitaly/backend_node_recovery_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Systems' do + describe 'Gitaly backend node recovery', :orchestrated, :gitaly_cluster, :skip_live_env do + let(:praefect_manager) { Service::PraefectManager.new } + let(:project) do + Resource::Project.fabricate! do |project| + project.name = "gitaly_cluster" + project.initialize_with_readme = true + end + end + + before do + # Reset the cluster in case previous tests left it in a bad state + praefect_manager.start_all_nodes + end + + after do + # Leave the cluster in a suitable state for subsequent tests + praefect_manager.start_all_nodes + end + + it 'recovers from dataloss', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347832' do + # Create a new project with a commit and wait for it to replicate + praefect_manager.wait_for_replication(project.id) + + # Stop the primary node to trigger failover, and then wait + # for Gitaly to be ready for writes again + praefect_manager.stop_primary_node + praefect_manager.wait_for_primary_node_health_check_failure + + # Push a commit to the new primary + Resource::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.new_branch = false + push.commit_message = 'pushed after failover' + push.file_name = 'new_file' + push.file_content = 'new file' + end + + # Confirm that the commit is waiting to be replicated + expect(praefect_manager).to be_replication_pending + + # Start the old primary node again + praefect_manager.start_primary_node + praefect_manager.wait_for_health_check_all_nodes + + # Wait for automatic replication + praefect_manager.wait_for_replication(project.id) + + # Force switch to the old primary node + # This ensures that the commit was replicated + praefect_manager.stop_secondary_node + praefect_manager.stop_tertiary_node + + # Confirm that both commits are available + expect(project.commits.map { |commit| commit[:message].chomp }) + .to include("Initial commit").and include("pushed after failover") + end + end + end +end diff --git a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb index 5ee6dfdb8d8..18ec8e0a8b4 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/changing_repository_storage_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/changing_repository_storage_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create' do + RSpec.describe 'Systems' do describe 'Changing Gitaly repository storage', :requires_admin, except: { job: 'review-qa-*' } do praefect_manager = Service::PraefectManager.new @@ -9,7 +9,8 @@ module QA it 'confirms a `finished` status after moving project repository storage' do expect(project).to have_file('README.md') expect { project.change_repository_storage(destination_storage[:name]) }.not_to raise_error - expect { praefect_manager.verify_storage_move(source_storage, destination_storage, repo_type: :project) }.not_to raise_error + expect { praefect_manager.verify_storage_move(source_storage, destination_storage, repo_type: :project) } + .not_to raise_error Support::Retrier.retry_on_exception(sleep_interval: 5) do # For a short period of time after migrating, the repository can be 'read only' which may lead to errors @@ -18,8 +19,8 @@ module QA commit.project = project commit.commit_message = 'Add new file' commit.add_files([ - { file_path: 'new_file', content: '# This is a new file' } - ]) + { file_path: 'new_file', content: '# This is a new file' } + ]) end end @@ -28,7 +29,8 @@ module QA end end - context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347827' do + context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage, + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347827' do let(:source_storage) { { type: :gitaly, name: 'default' } } let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.additional_repository_storage } } let(:project) do @@ -49,7 +51,8 @@ module QA # Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect # scenario with other tests that aren't considered orchestrated. # It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage - context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347828' do + context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect, + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347828' do let(:source_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } } let(:destination_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } } let(:project) do @@ -71,7 +74,8 @@ module QA # Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect # scenario with other tests that aren't considered orchestrated. # It also runs on staging using nfs-file07 as non-cluster storage and nfs-file22 as cluster/praefect storage - context 'when moving from Gitaly Cluster to Gitaly', :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/369204' do + context 'when moving from Gitaly Cluster to Gitaly', :requires_praefect, + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/369204' do let(:source_storage) { { type: :praefect, name: QA::Runtime::Env.praefect_repository_storage } } let(:destination_storage) { { type: :gitaly, name: QA::Runtime::Env.non_cluster_repository_storage } } let(:project) do diff --git a/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb new file mode 100644 index 00000000000..692297e40ce --- /dev/null +++ b/qa/qa/specs/features/api/12_systems/gitaly/distributed_reads_spec.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require 'parallel' + +module QA + RSpec.describe 'Systems' do + describe 'Gitaly distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin do + let(:number_of_reads_per_loop) { 9 } + let(:praefect_manager) { Service::PraefectManager.new } + let(:project) do + Resource::Project.fabricate! do |project| + project.name = "gitaly_cluster" + project.initialize_with_readme = true + end + end + + before do + praefect_manager.start_all_nodes + praefect_manager.wait_for_replication(project.id) + end + + it 'reads from each node', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347833' do + pre_read_data = praefect_manager.query_read_distribution + + wait_for_reads_to_increase(project, number_of_reads_per_loop, pre_read_data) + + aggregate_failures "each gitaly node" do + praefect_manager.query_read_distribution.each_with_index do |data, index| + pre_read_count = praefect_manager.value_for_node(pre_read_data, data[:node]) + QA::Runtime::Logger.debug("Node: #{data[:node]}; before: #{pre_read_count}; now: #{data[:value]}") + expect(data[:value]).to be > pre_read_count, + "Read counts did not differ for node #{data[:node]}" + end + end + end + + context 'when a node is unhealthy' do + before do + praefect_manager.stop_secondary_node + end + + after do + # Leave the cluster in a suitable state for subsequent tests + praefect_manager.start_secondary_node + end + + it 'does not read from the unhealthy node', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347834' do + pre_read_data = praefect_manager.query_read_distribution + + read_from_project(project, number_of_reads_per_loop * 10) + + praefect_manager.wait_for_read_count_change(pre_read_data) + + post_read_data = praefect_manager.query_read_distribution + + aggregate_failures "each gitaly node" do + expect(praefect_manager.value_for_node(post_read_data, 'gitaly1')) + .to be > praefect_manager.value_for_node(pre_read_data, 'gitaly1') + expect(praefect_manager.value_for_node(post_read_data, 'gitaly2')) + .to eq praefect_manager.value_for_node(pre_read_data, 'gitaly2') + expect(praefect_manager.value_for_node(post_read_data, 'gitaly3')) + .to be > praefect_manager.value_for_node(pre_read_data, 'gitaly3') + end + end + end + + def read_from_project(project, number_of_reads) + QA::Runtime::Logger.info('Reading from the repository') + Parallel.each((1..number_of_reads)) do + Git::Repository.perform do |repository| + repository.uri = project.repository_http_location.uri + repository.use_default_credentials + repository.clone + end + end + end + + def wait_for_reads_to_increase(project, number_of_reads, pre_read_data) + diff_found = pre_read_data + + Support::Waiter.wait_until(sleep_interval: 5, raise_on_failure: false) do + read_from_project(project, number_of_reads) + + praefect_manager.query_read_distribution.each_with_index do |data, index| + diff_found[index] = {} unless diff_found[index] + if data[:value] > praefect_manager.value_for_node(pre_read_data, data[:node]) + diff_found[index][:diff] = true + end + end + diff_found.all? { |node| node.key?(:diff) && node[:diff] } + end + end + end + end +end diff --git a/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb new file mode 100644 index 00000000000..a4b39554453 --- /dev/null +++ b/qa/qa/specs/features/api/12_systems/gitaly/gitaly_mtls_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Systems' do + describe 'Gitaly using mTLS', :orchestrated, :mtls do + let(:intial_commit_message) { 'Initial commit' } + let(:first_added_commit_message) { 'commit over git' } + let(:second_added_commit_message) { 'commit over api' } + + it 'pushes to gitaly', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347677' do + project = Resource::Project.fabricate! do |project| + project.name = "mTLS" + project.initialize_with_readme = true + end + + Resource::Repository::ProjectPush.fabricate! do |push| + push.project = project + push.new_branch = false + push.commit_message = first_added_commit_message + push.file_content = 'First commit' + end + + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = second_added_commit_message + commit.add_files( + [{ + file_path: "file-#{SecureRandom.hex(8)}", + content: 'Second commit' + }] + ) + end + + expect(project.commits.map { |commit| commit[:message].chomp }) + .to include(intial_commit_message) + .and include(first_added_commit_message) + .and include(second_added_commit_message) + end + end + end +end diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb index 28469b99d04..f25b50f584d 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_connectivity_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_connectivity_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create' do - context 'Praefect connectivity commands', :orchestrated, :gitaly_cluster do + RSpec.describe 'Systems' do + describe 'Praefect connectivity commands', :orchestrated, :gitaly_cluster do praefect_manager = Service::PraefectManager.new before do @@ -10,22 +10,26 @@ module QA end context 'in a healthy environment' do - it 'confirms healthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349937' do + it 'confirms healthy connection to database', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349937' do expect(praefect_manager.praefect_sql_ping_healthy?).to be true end - it 'confirms healthy connection to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349938' do + it 'confirms healthy connection to gitaly nodes', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349938' do expect(praefect_manager.wait_for_dial_nodes_successful).to be true end end context 'in an unhealthy environment' do - it 'diagnoses unhealthy connection to database', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349939' do + it 'diagnoses unhealthy connection to database', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349939' do praefect_manager.stop_node(praefect_manager.postgres) expect(praefect_manager.praefect_sql_ping_healthy?).to be false end - it 'diagnoses connection issues to gitaly nodes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349940' do + it 'diagnoses connection issues to gitaly nodes', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349940' do praefect_manager.stop_node(praefect_manager.primary_node) praefect_manager.stop_node(praefect_manager.tertiary_node) expect(praefect_manager.praefect_dial_nodes_status?(praefect_manager.primary_node, false)).to be true diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb index 5b02cc4646c..944c58ebc83 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_dataloss_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create' do - context 'Praefect dataloss commands', :orchestrated, :gitaly_cluster do + RSpec.describe 'Systems' do + describe 'Praefect dataloss commands', :orchestrated, :gitaly_cluster do let(:praefect_manager) { Service::PraefectManager.new } let(:project) do @@ -16,13 +16,15 @@ module QA praefect_manager.start_all_nodes end - it 'confirms that changes are synced across all storages', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352691' do + it 'confirms that changes are synced across all storages', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352691' do expect { praefect_manager.praefect_dataloss_information(project.id) } .to(eventually_include('All repositories are fully available on all assigned storages!') .within(max_duration: 60)) end - it 'identifies how many changes are not in sync across storages', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352692' do + it 'identifies how many changes are not in sync across storages', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352692' do # Ensure our test repository is replicated and in a consistent state prior to test praefect_manager.wait_for_project_synced_across_all_storages(project.id) @@ -36,9 +38,11 @@ module QA commit.branch = "newbranch-#{SecureRandom.hex(8)}" commit.start_branch = project.default_branch commit.commit_message = 'Add new file' - commit.add_files([ - { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'new file' } - ]) + commit.add_files( + [{ + file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'new file' + }] + ) end end @@ -48,21 +52,25 @@ module QA project_data_loss = praefect_manager.praefect_dataloss_information(project.id) aggregate_failures "validate dataloss identified" do expect(project_data_loss).to include('gitaly1, assigned host') - expect(project_data_loss).to include("gitaly2 is behind by #{number_of_changes} changes or less, assigned host, unhealthy") + expect(project_data_loss) + .to include("gitaly2 is behind by #{number_of_changes} changes or less, assigned host, unhealthy") expect(project_data_loss).to include('gitaly3, assigned host, unhealthy') end end - it 'allows admin resolve scenario where data cannot be recovered', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352708' do + it 'allows admin resolve scenario where data cannot be recovered', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352708' do # Ensure everything is in sync before begining test praefect_manager.wait_for_project_synced_across_all_storages(project.id) Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project commit.commit_message = 'accept-dataloss-1' - commit.add_files([ - { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly1,gitaly2,gitaly3' } - ]) + commit.add_files( + [{ + file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly1,gitaly2,gitaly3' + }] + ) end praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.primary_node) @@ -70,9 +78,11 @@ module QA Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project commit.commit_message = 'accept-dataloss-2' - commit.add_files([ - { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly2,gitaly3' } - ]) + commit.add_files( + [{ + file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly2,gitaly3' + }] + ) end praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.secondary_node) @@ -81,8 +91,8 @@ module QA commit.project = project commit.commit_message = 'accept-dataloss-3' commit.add_files([ - { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly3' } - ]) + { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly3' } + ]) end # Confirms that they want to accept dataloss, using gitaly2 as authoritative storage to use as a base diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb index a53614960cd..f4efcf74956 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_replication_queue_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_replication_queue_spec.rb @@ -3,8 +3,8 @@ require 'parallel' module QA - RSpec.describe 'Create' do - context 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env do + RSpec.describe 'Systems' do + describe 'Gitaly Cluster replication queue', :orchestrated, :gitaly_cluster, :skip_live_env do let(:praefect_manager) { Service::PraefectManager.new } let(:project) do Resource::Project.fabricate! do |project| @@ -22,7 +22,8 @@ module QA praefect_manager.clear_replication_queue end - it 'allows replication of different repository after interruption', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347829' do + it 'allows replication of different repository after interruption', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347829' do # We want to fill the replication queue with 10 `in_progress` jobs, # while a lock has been acquired, which is when the problem occurred # as reported in https://gitlab.com/gitlab-org/gitaly/-/issues/2801 diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb b/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb index 47be7e0620b..064743ae469 100644 --- a/qa/qa/specs/features/api/3_create/gitaly/praefect_repo_sync_spec.rb +++ b/qa/qa/specs/features/api/12_systems/gitaly/praefect_repo_sync_spec.rb @@ -1,12 +1,17 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create' do - context 'Praefect repository commands', :orchestrated, :gitaly_cluster do + RSpec.describe 'Systems' do + describe 'Praefect repository commands', :orchestrated, :gitaly_cluster do let(:praefect_manager) { Service::PraefectManager.new } - let(:repo1) { { "relative_path" => "@hashed/repo1.git", "storage" => "gitaly1", "virtual_storage" => "default" } } - let(:repo2) { { "relative_path" => "@hashed/path/to/repo2.git", "storage" => "gitaly3", "virtual_storage" => "default" } } + let(:repo1) do + { "relative_path" => "@hashed/repo1.git", "storage" => "gitaly1", "virtual_storage" => "default" } + end + + let(:repo2) do + { "relative_path" => "@hashed/path/to/repo2.git", "storage" => "gitaly3", "virtual_storage" => "default" } + end before do praefect_manager.start_all_nodes @@ -21,54 +26,70 @@ module QA praefect_manager.remove_repository_from_praefect_database(repo2["relative_path"]) end - it 'allows admin to manage difference between praefect database and disk state', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347606' do + it 'allows admin to manage difference between praefect database and disk state', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347606' do # Some repos are on disk that praefect is not aware of untracked_repositories = praefect_manager.list_untracked_repositories expect(untracked_repositories).to include(repo1) expect(untracked_repositories).to include(repo2) # admin manually adds the first repo to the praefect database - praefect_manager.track_repository_in_praefect(repo1["relative_path"], repo1["storage"], repo1["virtual_storage"]) + praefect_manager + .track_repository_in_praefect(repo1["relative_path"], repo1["storage"], repo1["virtual_storage"]) untracked_repositories = praefect_manager.list_untracked_repositories expect(untracked_repositories).not_to include(repo1) expect(untracked_repositories).to include(repo2) - expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"])).to be true + expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"])) + .to be true expect(praefect_manager.praefect_database_tracks_repo?(repo1["relative_path"])).to be true # admin manually adds the second repo to the praefect database - praefect_manager.track_repository_in_praefect(repo2["relative_path"], repo2["storage"], repo2["virtual_storage"]) + praefect_manager + .track_repository_in_praefect(repo2["relative_path"], repo2["storage"], repo2["virtual_storage"]) untracked_repositories = praefect_manager.list_untracked_repositories expect(untracked_repositories).not_to include(repo2) - expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo2["relative_path"])).to be true + expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo2["relative_path"])) + .to be true expect(praefect_manager.praefect_database_tracks_repo?(repo2["relative_path"])).to be true # admin ensures replication to other nodes occurs - expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo1["relative_path"])).to be true - expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.tertiary_node, repo1["relative_path"])).to be true - expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.primary_node, repo2["relative_path"])).to be true - expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo2["relative_path"])).to be true + expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo1["relative_path"])) + .to be true + expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.tertiary_node, repo1["relative_path"])) + .to be true + expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.primary_node, repo2["relative_path"])) + .to be true + expect(praefect_manager.repository_replicated_to_disk?(praefect_manager.secondary_node, repo2["relative_path"])) + .to be true # admin chooses to remove the first repo completely from praefect and disk praefect_manager.remove_tracked_praefect_repository(repo1["relative_path"], repo1["virtual_storage"]) - expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"])).to be false - expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.secondary_node, repo1["relative_path"])).to be false - expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo1["relative_path"])).to be false + expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.primary_node, repo1["relative_path"])) + .to be false + expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager + .secondary_node, repo1["relative_path"])).to be false + expect(praefect_manager.repository_exists_on_node_disk?(praefect_manager.tertiary_node, repo1["relative_path"])) + .to be false expect(praefect_manager.praefect_database_tracks_repo?(repo1["relative_path"])).to be false untracked_repositories = praefect_manager.list_untracked_repositories expect(untracked_repositories).not_to include(repo1) end - it 'allows admin to control the number of replicas of data', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347566' do - praefect_manager.track_repository_in_praefect(repo1['relative_path'], repo1['storage'], repo1['virtual_storage']) + it 'allows admin to control the number of replicas of data', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347566' do + praefect_manager + .track_repository_in_praefect(repo1['relative_path'], repo1['storage'], repo1['virtual_storage']) praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 2) - replication_storages = praefect_manager.get_replication_storages(repo1['relative_path'], repo1['virtual_storage']) + replication_storages = praefect_manager + .get_replication_storages(repo1['relative_path'], repo1['virtual_storage']) expect(replication_storages).to have_attributes(size: 2) praefect_manager.set_replication_factor(repo1['relative_path'], repo1['virtual_storage'], 3) - replication_storages = praefect_manager.get_replication_storages(repo1['relative_path'], repo1['virtual_storage']) - expect(replication_storages).to eq(%w(gitaly1 gitaly2 gitaly3)) + replication_storages = praefect_manager + .get_replication_storages(repo1['relative_path'], repo1['virtual_storage']) + expect(replication_storages).to eq(%w[gitaly1 gitaly2 gitaly3]) end end end diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb index de460a39ccf..e6b60a5b090 100644 --- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb @@ -88,14 +88,19 @@ module QA let(:gh_issue_comments) do logger.debug("= Fetching issue comments =") github_client.issues_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash| - hash[c.html_url.gsub(/\#\S+/, "")] << c.body&.gsub(gh_link_pattern, dummy_url) # use base html url as key + # use base html url as key + hash[c.html_url.gsub(/\#\S+/, "")] << c.body&.gsub(gh_link_pattern, dummy_url) end end let(:gh_pr_comments) do logger.debug("= Fetching pr comments =") github_client.pull_requests_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash| - hash[c.html_url.gsub(/\#\S+/, "")] << c.body&.gsub(gh_link_pattern, dummy_url) # use base html url as key + # use base html url as key + hash[c.html_url.gsub(/\#\S+/, "")] << c.body + # some suggestions can contain extra whitespaces which gitlab will remove + &.gsub(/suggestion\s+\r/, "suggestion\r") + &.gsub(gh_link_pattern, dummy_url) end end diff --git a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb index 444d86f63d3..9f0e2664213 100644 --- a/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb +++ b/qa/qa/specs/features/api/1_manage/user_inherited_access_spec.rb @@ -71,7 +71,12 @@ module QA it( 'is allowed to commit to sub-group project via the API', :reliable, - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/363349' + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/363349', + quarantine: { + only: { subdomain: %i[staging staging-ref] }, + type: :investigating, + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/370282' + } ) do expect do Resource::Repository::Commit.fabricate_via_api! do |commit| diff --git a/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb deleted file mode 100644 index 25e860b4f6d..00000000000 --- a/qa/qa/specs/features/api/3_create/gitaly/backend_node_recovery_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Create' do - context 'Gitaly' do - describe 'Backend node recovery', :orchestrated, :gitaly_cluster, :skip_live_env do - let(:praefect_manager) { Service::PraefectManager.new } - let(:project) do - Resource::Project.fabricate! do |project| - project.name = "gitaly_cluster" - project.initialize_with_readme = true - end - end - - before do - # Reset the cluster in case previous tests left it in a bad state - praefect_manager.start_all_nodes - end - - after do - # Leave the cluster in a suitable state for subsequent tests - praefect_manager.start_all_nodes - end - - it 'recovers from dataloss', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347832' do - # Create a new project with a commit and wait for it to replicate - praefect_manager.wait_for_replication(project.id) - - # Stop the primary node to trigger failover, and then wait - # for Gitaly to be ready for writes again - praefect_manager.stop_primary_node - praefect_manager.wait_for_primary_node_health_check_failure - - # Push a commit to the new primary - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.new_branch = false - push.commit_message = 'pushed after failover' - push.file_name = 'new_file' - push.file_content = 'new file' - end - - # Confirm that the commit is waiting to be replicated - expect(praefect_manager).to be_replication_pending - - # Start the old primary node again - praefect_manager.start_primary_node - praefect_manager.wait_for_health_check_all_nodes - - # Wait for automatic replication - praefect_manager.wait_for_replication(project.id) - - # Force switch to the old primary node - # This ensures that the commit was replicated - praefect_manager.stop_secondary_node - praefect_manager.stop_tertiary_node - - # Confirm that both commits are available - expect(project.commits.map { |commit| commit[:message].chomp }) - .to include("Initial commit").and include("pushed after failover") - end - end - end - end -end diff --git a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb deleted file mode 100644 index 2b96c35415e..00000000000 --- a/qa/qa/specs/features/api/3_create/gitaly/distributed_reads_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require 'parallel' - -module QA - RSpec.describe 'Create' do - context 'Gitaly' do - describe 'Distributed reads', :orchestrated, :gitaly_cluster, :skip_live_env, :requires_admin do - let(:number_of_reads_per_loop) { 9 } - let(:praefect_manager) { Service::PraefectManager.new } - let(:project) do - Resource::Project.fabricate! do |project| - project.name = "gitaly_cluster" - project.initialize_with_readme = true - end - end - - before do - praefect_manager.start_all_nodes - praefect_manager.wait_for_replication(project.id) - end - - it 'reads from each node', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347833' do - pre_read_data = praefect_manager.query_read_distribution - - wait_for_reads_to_increase(project, number_of_reads_per_loop, pre_read_data) - - aggregate_failures "each gitaly node" do - praefect_manager.query_read_distribution.each_with_index do |data, index| - pre_read_count = praefect_manager.value_for_node(pre_read_data, data[:node]) - QA::Runtime::Logger.debug("Node: #{data[:node]}; before: #{pre_read_count}; now: #{data[:value]}") - expect(data[:value]).to be > pre_read_count, - "Read counts did not differ for node #{data[:node]}" - end - end - end - - context 'when a node is unhealthy' do - before do - praefect_manager.stop_secondary_node - end - - after do - # Leave the cluster in a suitable state for subsequent tests - praefect_manager.start_secondary_node - end - - it 'does not read from the unhealthy node', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347834' do - pre_read_data = praefect_manager.query_read_distribution - - read_from_project(project, number_of_reads_per_loop * 10) - - praefect_manager.wait_for_read_count_change(pre_read_data) - - post_read_data = praefect_manager.query_read_distribution - - aggregate_failures "each gitaly node" do - expect(praefect_manager.value_for_node(post_read_data, 'gitaly1')).to be > praefect_manager.value_for_node(pre_read_data, 'gitaly1') - expect(praefect_manager.value_for_node(post_read_data, 'gitaly2')).to eq praefect_manager.value_for_node(pre_read_data, 'gitaly2') - expect(praefect_manager.value_for_node(post_read_data, 'gitaly3')).to be > praefect_manager.value_for_node(pre_read_data, 'gitaly3') - end - end - end - - def read_from_project(project, number_of_reads) - QA::Runtime::Logger.info('Reading from the repository') - Parallel.each((1..number_of_reads)) do - Git::Repository.perform do |repository| - repository.uri = project.repository_http_location.uri - repository.use_default_credentials - repository.clone - end - end - end - - def wait_for_reads_to_increase(project, number_of_reads, pre_read_data) - diff_found = pre_read_data - - Support::Waiter.wait_until(sleep_interval: 5, raise_on_failure: false) do - read_from_project(project, number_of_reads) - - praefect_manager.query_read_distribution.each_with_index do |data, index| - diff_found[index] = {} unless diff_found[index] - diff_found[index][:diff] = true if data[:value] > praefect_manager.value_for_node(pre_read_data, data[:node]) - end - diff_found.all? { |node| node.key?(:diff) && node[:diff] } - end - end - end - end - end -end diff --git a/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb deleted file mode 100644 index 5000c273578..00000000000 --- a/qa/qa/specs/features/api/3_create/gitaly/gitaly_mtls_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Create' do - context 'Gitaly', :orchestrated, :mtls do - describe 'Using mTLS' do - let(:intial_commit_message) { 'Initial commit' } - let(:first_added_commit_message) { 'commit over git' } - let(:second_added_commit_message) { 'commit over api' } - - it 'pushes to gitaly', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347677' do - project = Resource::Project.fabricate! do |project| - project.name = "mTLS" - project.initialize_with_readme = true - end - - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.new_branch = false - push.commit_message = first_added_commit_message - push.file_content = 'First commit' - end - - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = project - commit.commit_message = second_added_commit_message - commit.add_files([ - { - file_path: "file-#{SecureRandom.hex(8)}", - content: 'Second commit' - } - ]) - end - - expect(project.commits.map { |commit| commit[:message].chomp }) - .to include(intial_commit_message) - .and include(first_added_commit_message) - .and include(second_added_commit_message) - end - end - end - end -end diff --git a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb index c06912e0367..9d47872a774 100644 --- a/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/commit_to_templated_project_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Create a new project from a template' do + describe 'Create a new project from a template', product_group: :source_code do let(:project) do Resource::Project.fabricate_via_api! do |project| project.name = 'templated-project' diff --git a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb index cba563ef85a..123a4a625ab 100644 --- a/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/default_branch_name_setting_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Default branch name instance setting', :requires_admin, :skip_live_env do + describe 'Default branch name instance setting', :requires_admin, :skip_live_env, product_group: :source_code do before(:context) do Runtime::ApplicationSettings.set_application_settings(default_branch_name: 'main') end diff --git a/qa/qa/specs/features/api/3_create/repository/files_spec.rb b/qa/qa/specs/features/api/3_create/repository/files_spec.rb index 151fd0fffe3..71bd03fab17 100644 --- a/qa/qa/specs/features/api/3_create/repository/files_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/files_spec.rb @@ -4,7 +4,7 @@ require 'airborne' module QA RSpec.describe 'Create' do - describe 'API basics' do + describe 'API basics', product_group: :source_code do before(:context) do @api_client = Runtime::API::Client.new(:gitlab) end diff --git a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb index 6f175272d91..a211eb6042d 100644 --- a/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/project_archive_compare_spec.rb @@ -5,7 +5,8 @@ require 'digest' module QA RSpec.describe 'Create' do - describe 'Compare archives of different user projects with the same name and check they\'re different' do + describe 'Compare archives of different user projects with the same name and check they\'re different', + product_group: :source_code do include Support::API let(:project_name) { "project-archive-download-#{SecureRandom.hex(8)}" } @@ -52,12 +53,11 @@ module QA project.api_client = api_client end - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.file_name = 'README.md' - push.file_content = '# This is a test project' - push.commit_message = 'Add README.md' - push.user = user + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.add_files([{ file_path: 'README.md', content: '# This is a test project' }]) + commit.commit_message = 'Add README.md' + commit.api_client = api_client end project @@ -65,7 +65,7 @@ module QA def download_project_archive_via_api(api_client, project, type = 'tar.gz') get_project_archive_zip = Runtime::API::Request.new(api_client, project.api_get_archive_path(type)) - project_archive_download = get(get_project_archive_zip.url, raw_response: true) + project_archive_download = Support::API.get(get_project_archive_zip.url, raw_response: true) expect(project_archive_download.code).to eq(200) project_archive_download.file diff --git a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb index 1a2a1679cca..1d41184df98 100644 --- a/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/push_postreceive_idempotent_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'PostReceive idempotent' do + describe 'PostReceive idempotent', product_group: :source_code do # Tests that a push does not result in multiple changes from repeated PostReceive executions. # One of the consequences would be duplicate push events diff --git a/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb b/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb index 406ff191f95..df3b5a4e7fb 100644 --- a/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/storage_size_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Repository Usage Quota', :skip_live_env, feature_flag: { + describe 'Repository Usage Quota', :skip_live_env, product_group: :source_code, feature_flag: { name: 'gitaly_revlist_for_repo_size', scope: :global } do diff --git a/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb b/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb index 98612d84b21..b34b4208337 100644 --- a/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb +++ b/qa/qa/specs/features/api/3_create/repository/tag_revision_trigger_prereceive_hook_spec.rb @@ -2,29 +2,32 @@ module QA RSpec.describe 'Create' do - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.initialize_with_readme = true + describe 'Prereceive hook', product_group: :source_code do + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.initialize_with_readme = true + end end - end - context 'when creating a tag for a ref' do - context 'when it triggers a prereceive hook configured with a custom error' do - before do - # The configuration test prereceive hook must match a specific naming pattern - # In this test we create a project with a different name and then change the path. - # Otherwise we wouldn't be able create any commits to be tagged due to the hook. - project.change_path("project-reject-prereceive-#{SecureRandom.hex(8)}") - end + context 'when creating a tag for a ref' do + context 'when it triggers a prereceive hook configured with a custom error' do + before do + # The configuration test prereceive hook must match a specific naming pattern + # In this test we create a project with a different name and then change the path. + # Otherwise we wouldn't be able create any commits to be tagged due to the hook. + project.change_path("project-reject-prereceive-#{SecureRandom.hex(8)}") + end - it 'returns a custom server hook error', - :skip_live_env, - except: { job: 'review-qa-*' }, - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/369053' do - expect { project.create_repository_tag('v1.2.3') }.to raise_error - .with_message( - /rejecting prereceive hook for projects with GL_PROJECT_PATH matching pattern reject-prereceive/ - ) + it 'returns a custom server hook error', + :skip_live_env, + except: { job: 'review-qa-*' }, + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/369053' do + expect { project.create_repository_tag('v1.2.3') } + .to raise_error + .with_message( + /rejecting prereceive hook for projects with GL_PROJECT_PATH matching pattern reject-prereceive/ + ) + end end end end diff --git a/qa/qa/specs/features/api/4_verify/file_variable_spec.rb b/qa/qa/specs/features/api/4_verify/file_variable_spec.rb new file mode 100644 index 00000000000..9722f62d5a7 --- /dev/null +++ b/qa/qa/specs/features/api/4_verify/file_variable_spec.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Verify', :runner, feature_flag: { + name: 'ci_stop_expanding_file_vars_for_runners', + scope: :project + } do + describe 'Pipeline with project file variables' do + let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" } + + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'project-with-file-variables' + end + end + + let(:runner) do + Resource::Runner.fabricate! do |runner| + runner.project = project + runner.name = executor + runner.tags = [executor] + end + end + + let(:add_ci_file) do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files( + [ + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + variables: + EXTRA_ARGS: "-f $TEST_FILE" + DOCKER_REMOTE_ARGS: --tlscacert="$DOCKER_CA_CERT" + EXTRACTED_CRT_FILE: ${DOCKER_CA_CERT}.crt + MY_FILE_VAR: $TEST_FILE + + test: + tags: [#{executor}] + script: + - echo "run something $EXTRA_ARGS" + - echo "docker run $DOCKER_REMOTE_ARGS" + - echo "run --output=$EXTRACTED_CRT_FILE" + - echo "Will read private key from $MY_FILE_VAR" + YAML + } + ] + ) + end + end + + let(:add_file_variables) do + { + 'TEST_FILE' => 'hello, this is test', + 'DOCKER_CA_CERT' => 'This is secret' + }.each do |file_name, content| + add_file_variable_to_project(file_name, content) + end + end + + after do + runner.remove_via_api! + end + + shared_examples 'variables are read correctly' do + it 'shows in job log accordingly' do + job = Resource::Job.fabricate_via_api! do |job| + job.project = project + job.id = project.job_by_name('test')[:id] + end + + aggregate_failures do + trace = job.trace + expect(trace).to have_content('run something -f hello, this is test') + expect(trace).to have_content('docker run --tlscacert="This is secret"') + expect(trace).to have_content('run --output=This is secret.crt') + expect(trace).to have_content('Will read private key from hello, this is test') + end + end + end + + # FF does not change current behavior + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94198#note_1057609893 + # + # TODO: Remove when FF is removed + # TODO: Archive testcase issue when FF is removed + # Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/369907 + context 'when FF is on', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370787' do + before do + Runtime::Feature.enable(:ci_stop_expanding_file_vars_for_runners, project: project) + + runner + add_file_variables + add_ci_file + trigger_pipeline + wait_for_pipeline + end + + it_behaves_like 'variables are read correctly' + end + + # TODO: Refactor when FF is removed + # TODO: Update testcase issue title and description to not refer to FF status + context 'when FF is off', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/370791' do + before do + runner + add_file_variables + add_ci_file + trigger_pipeline + wait_for_pipeline + end + + it_behaves_like 'variables are read correctly' + end + + private + + def add_file_variable_to_project(key, value) + Resource::CiVariable.fabricate_via_api! do |ci_variable| + ci_variable.project = project + ci_variable.key = key + ci_variable.value = value + ci_variable.variable_type = 'file' + end + end + + def trigger_pipeline + Resource::Pipeline.fabricate_via_api! do |pipeline| + pipeline.project = project + end + end + + def wait_for_pipeline + Support::Waiter.wait_until do + project.pipelines.present? && project.pipelines.first[:status] == 'success' + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb index c5efa833f04..ad90df4b90d 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb @@ -36,7 +36,11 @@ module QA group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER) end - it 'allows enforcing 2FA via UI and logging in with 2FA', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931' do + it( + 'allows enforcing 2FA via UI and logging in with 2FA', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931', + quarantine: { type: :flaky, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/369516' } + ) do enforce_two_factor_authentication_on_group(group) enable_two_factor_authentication_for_user(developer_user) diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb index 8cc772ed022..295702aa328 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb @@ -66,7 +66,7 @@ module QA end # TODO: Remove retry_on_exception once https://gitlab.com/gitlab-org/gitlab/-/issues/24294 is resolved - Support::Waiter.wait_until(retry_on_exception: true, sleep_interval: 3) { !user.exists? } + Support::Waiter.wait_until(max_duration: 120, retry_on_exception: true, sleep_interval: 3) { !user.exists? } end it 'allows recreating with same credentials', :reliable, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347868' do diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb index b1d59b90e9c..d299997dd3c 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb @@ -20,8 +20,10 @@ module QA Flow::Login.sign_in(as: user) Page::Dashboard::Welcome.perform do |welcome| - expect(welcome).to have_welcome_title("Welcome to GitLab") - + Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page, + retry_on_exception: true) do + expect(welcome).to have_welcome_title("Welcome to GitLab") + end # This would be better if it were a visual validation test expect(welcome).to have_loaded_all_images end diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb index ed271533f87..7e4a391c390 100644 --- a/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb +++ b/qa/qa/specs/features/browser_ui/2_plan/issue/create_issue_spec.rb @@ -64,7 +64,7 @@ module QA it( 'comments on an issue with an attachment', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347946', - except: { job: 'review-qa-smoke' } + except: { job: 'review-qa-*' } ) do Page::Project::Issue::Show.perform do |show| show.comment('See attached image for scale', attachment: file_to_attach) diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb index d198d79c5fe..109cf7b73c3 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_merge_request_from_fork_spec.rb @@ -17,7 +17,11 @@ module QA merge_request.fork.remove_via_api! end - it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347818' do + it 'can merge feature branch fork to mainline', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347818', quarantine: { + only: :production, + type: :investigating, + issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/372258' + } do merge_request.visit! Page::MergeRequest::Show.perform do |merge_request| diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb index 2280cc971a7..c7296b6eea2 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb @@ -12,11 +12,9 @@ module QA it 'user rebases source branch of merge request', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347735' do merge_request.project.visit! - Page::Project::Menu.perform(&:go_to_general_settings) - Page::Project::Settings::Main.perform do |main| - main.expand_merge_requests_settings do |settings| - settings.enable_ff_only - end + Page::Project::Menu.perform(&:go_to_merge_request_settings) + Page::Project::Settings::MergeRequest.perform do |settings| + settings.enable_ff_only end Resource::Repository::ProjectPush.fabricate! do |push| diff --git a/qa/qa/specs/features/browser_ui/3_create/pages/pages_pipeline_spec.rb b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb index 191c4a096e7..9c912080c5f 100644 --- a/qa/qa/specs/features/browser_ui/3_create/pages/pages_pipeline_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/pages/new_static_page_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true - module QA - RSpec.describe 'Release', :runner do + RSpec.describe 'Create', :runner, only: { subdomain: :staging } do # TODO: Convert back to :smoke once proved to be stable. Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/300906 describe 'Pages' do let!(:project) do @@ -27,12 +26,11 @@ module QA runner.project = project runner.executor = :docker end - pipeline.visit! end - it('runs a Pages-specific pipeline', - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669') do + it 'creates a Pages website', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669' do Page::Project::Pipeline::Show.perform do |show| expect(show).to have_job(:pages) show.click_job(:pages) @@ -41,6 +39,15 @@ module QA Page::Project::Job::Show.perform do |show| expect(show).to have_passed(timeout: 300) end + + Page::Project::Show.perform(&:go_to_pages_settings) + QA::Page::Project::Settings::Pages.perform do |pages| + pages.go_to_access_page + Support::Waiter.wait_until(sleep_interval: 2, max_duration: 60, reload_page: page, + retry_on_exception: true) do + expect(page).to have_content('Write an awesome description for your new site here.') + end + end end end end diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb index 107d72a9724..b4103bd0976 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_file_template_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'File templates' do + describe 'File templates', product_group: :source_code do include Runtime::Fixtures let(:project) do diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb index 0bd470fcb77..849022f5a93 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/add_list_delete_branches_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Create, list, and delete branches via web', :requires_admin do + describe 'Create, list, and delete branches via web', :requires_admin, product_group: :source_code do master_branch = nil second_branch = 'second-branch' third_branch = 'third-branch' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb index 9e77fd228da..aa332a76c94 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Branch with unusual name' do + describe 'Branch with unusual name', product_group: :source_code do let(:branch_name) { 'unUsually/named#br--anch' } let(:project) do Resource::Project.fabricate_via_api! do |resource| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb index d12fb05af77..b7df22fc2c2 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/clone_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Git clone over HTTP' do + describe 'Git clone over HTTP', product_group: :source_code do let(:project) do Resource::Project.fabricate_via_api! do |scenario| scenario.name = 'project-with-code' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb index 095444d99f1..d5f30c19738 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/create_file_via_web_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', :reliable do - context 'File management' do + RSpec.describe 'Create', :reliable, product_group: :source_code do + describe 'File management' do file_name = 'QA Test - File name' file_content = 'QA Test - File content' commit_message_for_create = 'QA Test - Create new file' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb index 02ecff22840..76243066476 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/delete_file_via_web_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - context 'File management' do + describe 'File management', product_group: :source_code do let(:file) { Resource::File.fabricate_via_api! } commit_message_for_delete = 'QA Test - Delete file' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb index 95e7a2a12d0..397796b76e5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/edit_file_via_web_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create', :reliable do - context 'File management' do + describe 'File management', product_group: :source_code do let(:file) { Resource::File.fabricate_via_api! } updated_file_content = 'QA Test - Updated file content' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb index eb6449181b5..d7da29219e6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/file/file_with_unusual_name_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'File with unusual name' do + describe 'File with unusual name', product_group: :source_code do let(:file_name) { '-un:usually;named#file?.md' } let(:project) do Resource::Project.fabricate_via_api! do |resource| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb index 3db8128bc6d..1ae1dd87c07 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/license_detecton_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Repository License Detection' do + describe 'Repository License Detection', product_group: :source_code do after do project.remove_via_api! end diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb index 153bfd292aa..a391e6313a6 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', :orchestrated, :repository_storage, :requires_admin do + RSpec.describe 'Create', :orchestrated, :repository_storage, :requires_admin, product_group: :source_code do describe 'Gitaly repository storage' do let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) } let(:parent_project) do diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb index fb87ca864f4..65a15ce96a5 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protected_tags_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Repository tags', :reliable do + describe 'Repository tags', :reliable, product_group: :source_code do let(:project) do Resource::Project.fabricate_via_api! do |project| project.name = 'project-for-tags' diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb index 34439042796..557a27c002d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_http_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Push over HTTP using Git protocol version 2', :requires_git_protocol_v2 do + describe 'Push over HTTP using Git protocol version 2', :requires_git_protocol_v2, product_group: :source_code do it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347760' do Flow::Login.sign_in diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb index 25d4da95dd9..2472d1cdf25 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Push over SSH using Git protocol version 2', :requires_git_protocol_v2 do + describe 'Push over SSH using Git protocol version 2', :requires_git_protocol_v2, product_group: :source_code do # Note: If you run this test against GDK make sure you've enabled sshd and # enabled setting the Git protocol by adding `AcceptEnv GIT_PROTOCOL` to # `sshd_config` diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb index 042fee38188..a785e4ae764 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_http_private_token_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Git push over HTTP', :smoke do + describe 'Git push over HTTP', :smoke, product_group: :source_code do it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347749' do Flow::Login.sign_in diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb index 9ab322df824..815a8696ff7 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', quarantine: { + RSpec.describe 'Create', product_group: :source_code, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/352525', type: :test_environment, only: { job: 'review-qa-*' } diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb index d644a7ead1e..b87c47761bd 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Push mirror a repository over HTTP' do + describe 'Push mirror a repository over HTTP', product_group: :source_code do it 'configures and syncs a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347741' do Runtime::Browser.visit(:gitlab, Page::Main::Login) Page::Main::Login.perform(&:sign_in_using_credentials) diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb index 0e4aa67162f..324dbbc46ef 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb @@ -3,7 +3,7 @@ module QA # This test modifies an instance level setting, # so skipping on live envs to avoid random transient issues - RSpec.describe 'Create', :requires_admin, :skip_live_env do + RSpec.describe 'Create', :requires_admin, :skip_live_env, product_group: :source_code do describe 'push after setting the file size limit via admin/application_settings' do include Support::API diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb index a782a50b55d..e8f7cb252a0 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Git push over HTTP' do + describe 'Git push over HTTP', product_group: :source_code do it 'user pushes code to the repository', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347747' do Flow::Login.sign_in diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb index 0323448878b..4fb52f1e54d 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'SSH key support' do + describe 'SSH key support', product_group: :source_code do # Note: If you run these tests against GDK make sure you've enabled sshd # See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb index 91b0940f137..e097e1fd2bb 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_protected_branch_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', :reliable do + RSpec.describe 'Create', :reliable, product_group: :source_code do describe 'Protected branch support' do let(:branch_name) { 'protected-branch' } let(:commit_message) { 'Protected push commit message' } diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb index 78abdb94dfe..d95a880c305 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_to_canary_gitaly_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Create', only: { subdomain: %i[staging staging-canary] } do + RSpec.describe 'Create', only: { subdomain: %i[staging staging-canary] }, product_group: :source_code do describe 'Git push to canary Gitaly node over HTTP' do it 'pushes to a project using a canary specific Gitaly repository storage', :smoke, :requires_admin, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/351116' do Flow::Login.sign_in_as_admin diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb index 55df1615f5c..64858287285 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'SSH keys support', :smoke do + describe 'SSH keys support', :smoke, product_group: :source_code do let(:key_title) { "key for ssh tests #{Time.now.to_f}" } key = nil diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb index bbf6c3ca37a..13b42209114 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb @@ -2,7 +2,7 @@ module QA RSpec.describe 'Create' do - describe 'Commit data' do + describe 'Commit data', product_group: :source_code do before(:context) do # Get the user's details to confirm they're included in the email patch @user = Resource::User.fabricate_via_api! do |user| diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb new file mode 100644 index 00000000000..8352ad6aa33 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/prefill_variables_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Verify' do + describe 'Pipeline with prefill variables' do + let(:prefill_variable_description1) { Faker::Lorem.sentence } + let(:prefill_variable_value1) { Faker::Lorem.word } + let(:prefill_variable_description2) { Faker::Lorem.sentence } + let(:project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'project-with-prefill-variables' + end + end + + let!(:commit) do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add .gitlab-ci.yml' + commit.add_files( + [ + { + file_path: '.gitlab-ci.yml', + content: <<~YAML + variables: + TEST1: + value: #{prefill_variable_value1} + description: #{prefill_variable_description1} + TEST2: + description: #{prefill_variable_description2} + TEST3: + value: test 3 value + TEST4: test 4 value + + test: + script: echo "$FOO" + YAML + } + ] + ) + end + end + + before do + Flow::Login.sign_in + project.visit! + + # Navigate to Run Pipeline page + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button) + end + + it( + 'shows only variables with description as prefill variables on the run pipeline page', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/371204' + ) do + Page::Project::Pipeline::New.perform do |new| + aggregate_failures do + expect(new).to have_field('Input variable key', with: 'TEST1') + expect(new).to have_field('Input variable value', with: prefill_variable_value1) + expect(new).to have_content(prefill_variable_description1) + + expect(new).to have_field('Input variable key', with: 'TEST2') + expect(new).to have_content(prefill_variable_description2) + + expect(new).not_to have_field('Input variable key', with: 'TEST3') + expect(new).not_to have_field('Input variable key', with: 'TEST4') + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb index 412498476f0..f9113573295 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_with_image_pull_policy_spec.rb @@ -1,12 +1,7 @@ # frozen_string_literal: true module QA - # TODO: remove feature flag upon rollout completion - # FF rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/363186 - RSpec.describe 'Verify', :runner, feature_flag: { - name: 'ci_docker_image_pull_policy', - scope: :global - } do + RSpec.describe 'Verify', :runner do describe 'Pipeline with image:pull_policy' do let(:runner_name) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" } let(:job_name) { "test-job-#{pull_policies.join('-')}" } @@ -27,10 +22,6 @@ module QA end before do - Runtime::Feature.enable(:ci_docker_image_pull_policy) - # Give the feature some time to switch - sleep(30) - update_runner_policy(allowed_policies) add_ci_file Flow::Login.sign_in @@ -39,12 +30,13 @@ module QA end after do - Runtime::Feature.disable(:ci_docker_image_pull_policy) - runner.remove_via_api! end - context 'when policy is allowed' do + context( + 'when policy is allowed', + quarantine: { type: :flaky, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/369397' } + ) do let(:allowed_policies) { %w[if-not-present always never] } where do @@ -102,7 +94,8 @@ module QA it( 'fails job with policy not allowed message', - testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/368853' + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/368853', + quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/371420', type: :stale } ) do visit_job diff --git a/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb new file mode 100644 index 00000000000..6ce395affc7 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/5_package/infrastructure_registry/terraform_module_registry_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module QA + RSpec.describe 'Package', :orchestrated, :packages do + describe 'Terraform Module Registry' do + include Runtime::Fixtures + + let(:group) { Resource::Group.fabricate_via_api! } + + let(:imported_project) do + Resource::ProjectImportedFromURL.fabricate_via_browser_ui! do |project| + project.name = 'terraform-module-test' + project.group = group + project.gitlab_repository_path = 'https://gitlab.com/mattkasa/terraform-module-test.git' + end + end + + let(:runner) do + Resource::Runner.fabricate! do |runner| + runner.name = "qa-runner-#{Time.now.to_i}" + runner.tags = ["runner-for-#{imported_project.name}"] + runner.executor = :docker + runner.project = imported_project + runner.token = group.reload!.runners_token + end + end + + before do + Flow::Login.sign_in + + imported_project + runner + end + + after do + runner.remove_via_api! + end + + it 'publishes a module', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/371583' do + Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do + Resource::Repository::Commit.fabricate_via_api! do |commit| + terraform_module_yaml = ERB.new( + read_fixture('package_managers/terraform', 'module_upload.yaml.erb') + ).result(binding) + commit.project = imported_project + commit.commit_message = 'Add gitlab-ci.yaml file' + commit.update_files([ + { + file_path: '.gitlab-ci.yml', + content: terraform_module_yaml + } + ] + ) + end + end + + Resource::Tag.fabricate_via_api! do |tag| + tag.project = imported_project + tag.ref = imported_project.default_branch + tag.name = "1.0.0" + end + + Flow::Pipeline.visit_latest_pipeline + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('upload') + end + + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 800) + end + + Page::Project::Menu.perform(&:go_to_infrastructure_registry) + + Page::Project::Packages::Index.perform do |index| + expect(index).to have_module("#{imported_project.name}/local") + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb index 180910e85a0..921b36b34af 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb @@ -142,7 +142,7 @@ module QA Page::Group::Menu.perform(&:go_to_package_settings) end - context 'when enabled' do + context 'when disabled' do where do { 'using a personal access token' => { @@ -176,7 +176,7 @@ module QA end before do - Page::Group::Settings::PackageRegistries.perform(&:set_reject_duplicates_enabled) + Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled) end it 'prevents users from publishing group level Maven packages duplicates', testcase: params[:testcase] do @@ -195,7 +195,7 @@ module QA end end - context 'when disabled' do + context 'when enabled' do where do { 'using a personal access token' => { @@ -229,7 +229,7 @@ module QA end before do - Page::Group::Settings::PackageRegistries.perform(&:set_reject_duplicates_disabled) + Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled) end it 'allows users to publish group level Maven packages duplicates', testcase: params[:testcase] do diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb index 22d76d684e5..012a03ca115 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb @@ -105,10 +105,6 @@ module QA QA::Runtime::Logger.debug('Visiting the secondary Geo site') QA::Flow::Login.while_signed_in(address: :geo_secondary) do - EE::Page::Main::Banner.perform do |banner| - expect(banner).to have_secondary_read_only_banner - end - Page::Main::Menu.perform(&:go_to_projects) Page::Dashboard::Projects.perform do |dashboard| diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb index f1a2eb71390..b839855c500 100644 --- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb +++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb @@ -1,78 +1,67 @@ # frozen_string_literal: true module QA - RSpec.describe 'Configure', - only: { subdomain: %i[staging staging-canary] }, - quarantine: { - issue: 'https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1198', - type: :waiting_on - } do - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'autodevops-project' - project.auto_devops_enabled = true + RSpec.describe 'Configure', only: { subdomain: %i[staging staging-canary] } do + describe 'Auto DevOps with a Kubernetes Agent' do + let!(:app_project) do + Resource::Project.fabricate_via_api! do |project| + project.name = 'autodevops-app-project' + project.template_name = 'express' + project.auto_devops_enabled = true + end end - end - before do - set_kube_ingress_base_domain(project) - disable_optional_jobs(project) - end + let!(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::Gcloud).create! } - describe 'Auto DevOps support' do - context 'when rbac is enabled' do - let(:cluster) { Service::KubernetesCluster.new.create! } + let!(:kubernetes_agent) do + Resource::Clusters::Agent.fabricate_via_api! do |agent| + agent.name = 'agent1' + agent.project = app_project + end + end - after do - cluster&.remove! - project.remove_via_api! + let!(:agent_token) do + Resource::Clusters::AgentToken.fabricate_via_api! do |token| + token.agent = kubernetes_agent end + end - it 'runs auto devops', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348061' do - Flow::Login.sign_in - - Resource::KubernetesCluster::ProjectCluster.fabricate! do |k8s_cluster| - k8s_cluster.project = project - k8s_cluster.cluster = cluster - k8s_cluster.install_ingress = true - end - - Resource::Repository::ProjectPush.fabricate! do |push| - push.project = project - push.directory = Pathname - .new(__dir__) - .join('../../../../../fixtures/auto_devops_rack') - push.commit_message = 'Create Auto DevOps compatible rack application' - end - - Flow::Pipeline.visit_latest_pipeline - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('build') - end - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 600) - - job.click_element(:pipeline_path) - end - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('test') - end - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 600) - - job.click_element(:pipeline_path) - end - - Page::Project::Pipeline::Show.perform do |pipeline| - pipeline.click_job('production') - end - Page::Project::Job::Show.perform do |job| - expect(job).to be_successful(timeout: 1200) - - job.click_element(:pipeline_path) - end + before do + cluster.install_kubernetes_agent(agent_token.token) + upload_agent_config(app_project, kubernetes_agent.name) + + set_kube_ingress_base_domain(app_project) + set_kube_context(app_project) + disable_optional_jobs(app_project) + end + + after do + cluster&.remove! + end + + it 'runs auto devops', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348061' do + Flow::Login.sign_in + + app_project.visit! + + Page::Project::Menu.perform(&:click_ci_cd_pipelines) + Page::Project::Pipeline::Index.perform(&:click_run_pipeline_button) + Page::Project::Pipeline::New.perform(&:click_run_pipeline_button) + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('build') + end + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 600) + + job.click_element(:pipeline_path) + end + + Page::Project::Pipeline::Show.perform do |pipeline| + pipeline.click_job('production') + end + Page::Project::Job::Show.perform do |job| + expect(job).to be_successful(timeout: 600) end end end @@ -88,12 +77,43 @@ module QA end end + def set_kube_context(project) + Resource::CiVariable.fabricate_via_api! do |resource| + resource.project = project + resource.key = 'KUBE_CONTEXT' + resource.value = "#{project.path_with_namespace}:#{kubernetes_agent.name}" + resource.masked = false + end + end + + def upload_agent_config(project, agent) + Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do + Resource::Repository::Commit.fabricate_via_api! do |commit| + commit.project = project + commit.commit_message = 'Add kubernetes agent configuration' + commit.add_files( + [ + { + file_path: ".gitlab/agents/#{agent}/config.yaml", + content: <<~YAML + ci_access: + projects: + - id: #{project.path_with_namespace} + YAML + } + ] + ) + end + end + end + def disable_optional_jobs(project) %w[ - CODE_QUALITY_DISABLED LICENSE_MANAGEMENT_DISABLED - SAST_DISABLED DAST_DISABLED DEPENDENCY_SCANNING_DISABLED - CONTAINER_SCANNING_DISABLED BROWSER_PERFORMANCE_DISABLED - SECRET_DETECTION_DISABLED + TEST_DISABLED CODE_QUALITY_DISABLED LICENSE_MANAGEMENT_DISABLED + BROWSER_PERFORMANCE_DISABLED LOAD_PERFORMANCE_DISABLED + SAST_DISABLED SECRET_DETECTION_DISABLED DEPENDENCY_SCANNING_DISABLED + CONTAINER_SCANNING_DISABLED DAST_DISABLED REVIEW_DISABLED + CODE_INTELLIGENCE_DISABLED CLUSTER_IMAGE_SCANNING_DISABLED ].each do |key| Resource::CiVariable.fabricate_via_api! do |resource| resource.project = project diff --git a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb deleted file mode 100644 index 94f9e9ec1f6..00000000000 --- a/qa/qa/specs/features/browser_ui/7_configure/kubernetes/kubernetes_integration_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.describe 'Configure', except: { job: 'review-qa-*' } do - describe 'Kubernetes Cluster Integration', :orchestrated, :requires_admin, :skip_live_env do - context 'Project Clusters' do - let!(:cluster) { Service::KubernetesCluster.new(provider_class: Service::ClusterProvider::K3s).create! } - let(:project) do - Resource::Project.fabricate_via_api! do |project| - project.name = 'project-with-k8s' - project.description = 'Project with Kubernetes cluster integration' - end - end - - before do - Flow::Login.sign_in_as_admin - end - - after do - cluster.remove! - end - - it 'can create and associate a project cluster', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348062' do - Resource::KubernetesCluster::ProjectCluster.fabricate_via_browser_ui! do |k8s_cluster| - k8s_cluster.project = project - k8s_cluster.cluster = cluster - end.project.visit! - - Page::Project::Menu.perform(&:go_to_infrastructure_kubernetes) - - Page::Project::Infrastructure::Kubernetes::Index.perform do |index| - expect(index).to have_cluster(cluster) - end - end - end - end - end -end diff --git a/qa/qa/specs/features/shared_examples/merge_with_code_owner_shared_examples.rb b/qa/qa/specs/features/shared_examples/merge_with_code_owner_shared_examples.rb index 4bbad9bf3e5..01b229192cc 100644 --- a/qa/qa/specs/features/shared_examples/merge_with_code_owner_shared_examples.rb +++ b/qa/qa/specs/features/shared_examples/merge_with_code_owner_shared_examples.rb @@ -8,11 +8,9 @@ module QA # Require one approval from any eligible user on any branch # This will confirm that this type of unrestricted approval is # also satisfied when a code owner grants approval - Page::Project::Menu.perform(&:go_to_general_settings) - Page::Project::Settings::Main.perform do |main| - main.expand_merge_request_approvals_settings do |settings| - settings.set_default_number_of_approvals_required(1) - end + Page::Project::Menu.perform(&:go_to_merge_request_settings) + Page::Project::Settings::MergeRequest.perform do |settings| + settings.set_default_number_of_approvals_required(1) end Resource::Repository::Commit.fabricate_via_api! do |commit| diff --git a/qa/qa/specs/helpers/context_selector.rb b/qa/qa/specs/helpers/context_selector.rb index 9ac79ad6196..3608fa7c581 100644 --- a/qa/qa/specs/helpers/context_selector.rb +++ b/qa/qa/specs/helpers/context_selector.rb @@ -30,6 +30,8 @@ module QA next unless option.is_a?(Hash) + opts.merge!(option) + if option[:pipeline].present? return true if Runtime::Env.ci_project_name.blank? @@ -41,8 +43,6 @@ module QA return job_matches?(option[:job]) elsif option[:subdomain].present? - opts.merge!(option) - opts[:subdomain] = case option[:subdomain] when Array "(#{option[:subdomain].join("|")})\\." diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb index 801b9b222a4..c46b6300200 100644 --- a/qa/qa/specs/runner.rb +++ b/qa/qa/specs/runner.rb @@ -86,8 +86,7 @@ module QA File.open(filename, 'w') { |f| f.write(total_examples) } if total_examples.to_i > 0 - saved_file_msg = total_examples.to_i > 0 ? ". Saved to file: #{filename}" : '' - $stdout.puts "Total examples in #{Runtime::Scenario.klass}: #{total_examples}#{saved_file_msg}" + $stdout.puts total_examples end def test_metadata_only(args) diff --git a/qa/qa/specs/spec_helper.rb b/qa/qa/specs/spec_helper.rb index e1c08515521..b9e67c2fa72 100644 --- a/qa/qa/specs/spec_helper.rb +++ b/qa/qa/specs/spec_helper.rb @@ -12,6 +12,9 @@ QA::Runtime::Browser.configure! unless QA::Runtime::Env.dry_run QA::Runtime::AllureReport.configure! QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes) +# Enable zero monkey patching mode before loading any other RSpec code. +RSpec.configure(&:disable_monkey_patching!) + Dir[::File.join(__dir__, "features/shared_examples/*.rb")].sort.each { |f| require f } Dir[::File.join(__dir__, "features/shared_contexts/*.rb")].sort.each { |f| require f } @@ -119,7 +122,6 @@ RSpec.configure do |config| end config.shared_context_metadata_behavior = :apply_to_host_groups - config.disable_monkey_patching! config.expose_dsl_globally = true config.profile_examples = 10 config.order = :random |