summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 18:08:22 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-06 18:08:22 +0000
commit5a73318262aab6ab952f2b7205b3674ea1f20053 (patch)
treee53191adbc529ce23ca08a73e1235c7b6fb6ced5 /spec
parent552877c4d1c535f529be13862692a8fe826a72a2 (diff)
downloadgitlab-ce-5a73318262aab6ab952f2b7205b3674ea1f20053.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/incidents/incident_details_spec.rb2
-rw-r--r--spec/features/milestones/user_creates_milestone_spec.rb2
-rw-r--r--spec/frontend/editor/components/source_editor_toolbar_button_spec.js19
-rw-r--r--spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb128
-rw-r--r--spec/lib/gitlab/github_gists_import/representation/gist_spec.rb111
-rw-r--r--spec/lib/gitlab/memory/watchdog/configurator_spec.rb2
-rw-r--r--spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb64
-rw-r--r--spec/lib/gitlab/merge_requests/message_generator_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb11
-rw-r--r--spec/lib/version_check_spec.rb41
-rw-r--r--spec/models/ci/build_need_spec.rb60
-rw-r--r--spec/models/ci/processable_spec.rb4
-rw-r--r--spec/requests/api/helpers_spec.rb2
-rw-r--r--spec/requests/api/project_attributes.yml1
-rw-r--r--spec/services/ci/create_pipeline_service/partitioning_spec.rb21
-rw-r--r--spec/support/models/ci/partitioning_testing/cascade_check.rb7
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb94
18 files changed, 540 insertions, 32 deletions
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index 7c24943eb6f..e1167285464 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Incident details', :js do
+RSpec.describe 'Incident details', :js, feature_category: :incident_management do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') }
diff --git a/spec/features/milestones/user_creates_milestone_spec.rb b/spec/features/milestones/user_creates_milestone_spec.rb
index 1ab231632fb..b750f035e36 100644
--- a/spec/features/milestones/user_creates_milestone_spec.rb
+++ b/spec/features/milestones/user_creates_milestone_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe "User creates milestone", :js do
+RSpec.describe "User creates milestone", :js, feature_category: :team_planning do
let_it_be(:developer) { create(:user) }
let_it_be(:inherited_guest) { create(:user) }
let_it_be(:inherited_developer) { create(:user) }
diff --git a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
index ded31bb62dc..f62061f6eaf 100644
--- a/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
+++ b/spec/frontend/editor/components/source_editor_toolbar_button_spec.js
@@ -54,6 +54,25 @@ describe('Source Editor Toolbar button', () => {
});
});
+ describe('data attributes', () => {
+ it.each`
+ description | data | expectedDataset
+ ${'does not set any attribute'} | ${undefined} | ${{}}
+ ${'does not set any attribute'} | ${[]} | ${{}}
+ ${'does not set any attribute'} | ${['foo']} | ${{}}
+ ${'does not set any attribute'} | ${'bar'} | ${{}}
+ ${'does set single attribute correctly'} | ${{ qaSelector: 'foo' }} | ${{ qaSelector: 'foo' }}
+ ${'does set multiple attributes correctly'} | ${{ qaSelector: 'foo', youCanSeeMe: true }} | ${{ qaSelector: 'foo', youCanSeeMe: 'true' }}
+ `('$description when data="$data"', ({ data, expectedDataset }) => {
+ createComponent({
+ button: {
+ data,
+ },
+ });
+ expect(findButton().element.dataset).toEqual(expect.objectContaining(expectedDataset));
+ });
+ });
+
describe('click handler', () => {
let clickEvent;
diff --git a/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb
new file mode 100644
index 00000000000..69a4d646562
--- /dev/null
+++ b/spec/lib/gitlab/github_gists_import/importer/gist_importer_spec.rb
@@ -0,0 +1,128 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::Importer::GistImporter, feature_category: :importer do
+ subject { described_class.new(gist_object, user.id).execute }
+
+ let_it_be(:user) { create(:user) }
+ let(:created_at) { Time.utc(2022, 1, 9, 12, 15) }
+ let(:updated_at) { Time.utc(2022, 5, 9, 12, 17) }
+ let(:gist_file) { { file_name: '_Summary.md', file_content: 'File content' } }
+ let(:url) { 'https://host.com/gistid.git' }
+ let(:gist_object) do
+ instance_double('Gitlab::GithubGistsImport::Representation::Gist',
+ truncated_title: 'My Gist',
+ visibility_level: 0,
+ files: { '_Summary.md': gist_file },
+ first_file: gist_file,
+ git_pull_url: url,
+ created_at: created_at,
+ updated_at: updated_at
+ )
+ end
+
+ let(:expected_snippet_attrs) do
+ {
+ title: 'My Gist',
+ visibility_level: 0,
+ content: 'File content',
+ file_name: '_Summary.md',
+ author_id: user.id,
+ created_at: gist_object.created_at,
+ updated_at: gist_object.updated_at
+ }.stringify_keys
+ end
+
+ describe '#execute' do
+ context 'when success' do
+ it 'creates expected snippet and snippet repository' do
+ expect_next_instance_of(Repository) do |repository|
+ expect(repository).to receive(:fetch_as_mirror)
+ end
+
+ expect { subject }.to change { user.snippets.count }.by(1)
+ expect(user.snippets[0].attributes).to include expected_snippet_attrs
+ end
+ end
+
+ context 'when file size limit exeeded' do
+ before do
+ files = [].tap { |array| 11.times { |n| array << ["file#{n}.txt", {}] } }.to_h
+
+ allow(gist_object).to receive(:files).and_return(files)
+ allow_next_instance_of(Repository) do |repository|
+ allow(repository).to receive(:fetch_as_mirror)
+ allow(repository).to receive(:empty?).and_return(false)
+ allow(repository).to receive(:ls_files).and_return(files.keys)
+ end
+ end
+
+ it 'returns error' do
+ result = subject
+
+ expect(user.snippets.count).to eq(0)
+ expect(result.error?).to eq(true)
+ expect(result.errors).to match_array(['Snippet max file count exceeded'])
+ end
+ end
+
+ context 'when invalid attributes' do
+ let(:gist_file) { { file_name: '_Summary.md', file_content: nil } }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(ActiveRecord::RecordInvalid, "Validation failed: Content can't be blank")
+ end
+ end
+
+ context 'when repository cloning fails' do
+ it 'returns error' do
+ expect_next_instance_of(Repository) do |repository|
+ expect(repository).to receive(:fetch_as_mirror).and_raise(Gitlab::Shell::Error)
+ expect(repository).to receive(:remove)
+ end
+
+ expect { subject }.to raise_error(Gitlab::Shell::Error)
+ expect(user.snippets.count).to eq(0)
+ end
+ end
+
+ context 'when url is invalid' do
+ let(:url) { 'invalid' }
+
+ context 'when local network is allowed' do
+ before do
+ allow(::Gitlab::CurrentSettings)
+ .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true)
+ end
+
+ it 'raises error' do
+ expect(Gitlab::UrlBlocker)
+ .to receive(:validate!)
+ .with(url, ports: [80, 443], schemes: %w[http https git],
+ allow_localhost: true, allow_local_network: true)
+ .and_raise(Gitlab::UrlBlocker::BlockedUrlError)
+
+ expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError)
+ end
+ end
+
+ context 'when local network is not allowed' do
+ before do
+ allow(::Gitlab::CurrentSettings)
+ .to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(false)
+ end
+
+ it 'raises error' do
+ expect(Gitlab::UrlBlocker)
+ .to receive(:validate!)
+ .with(url, ports: [80, 443], schemes: %w[http https git],
+ allow_localhost: false, allow_local_network: false)
+ .and_raise(Gitlab::UrlBlocker::BlockedUrlError)
+
+ expect { subject }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb
new file mode 100644
index 00000000000..f36fbc637d0
--- /dev/null
+++ b/spec/lib/gitlab/github_gists_import/representation/gist_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::Representation::Gist do
+ shared_examples 'a Gist' do
+ it 'returns an instance of Gist' do
+ expect(gist).to be_an_instance_of(described_class)
+ end
+
+ context 'with Gist' do
+ it 'includes gist attributes' do
+ expect(gist).to have_attributes(
+ id: '1',
+ description: 'Gist title',
+ is_public: true,
+ files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ git_pull_url: 'https://gist.github.com/gistid.git'
+ )
+ end
+ end
+ end
+
+ describe '.from_api_response' do
+ let(:response) do
+ {
+ id: '1',
+ description: 'Gist title',
+ public: true,
+ created_at: '2022-04-26 18:30:53 UTC',
+ updated_at: '2022-04-26 18:30:53 UTC',
+ files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ git_pull_url: 'https://gist.github.com/gistid.git'
+ }
+ end
+
+ it_behaves_like 'a Gist' do
+ let(:gist) { described_class.from_api_response(response) }
+ end
+ end
+
+ describe '.from_json_hash' do
+ it_behaves_like 'a Gist' do
+ let(:hash) do
+ {
+ 'id' => '1',
+ 'description' => 'Gist title',
+ 'is_public' => true,
+ 'files' => { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } },
+ 'git_pull_url' => 'https://gist.github.com/gistid.git'
+ }
+ end
+
+ let(:gist) { described_class.from_json_hash(hash) }
+ end
+ end
+
+ describe '#truncated_title' do
+ it 'truncates the title to 255 characters' do
+ object = described_class.new(description: 'm' * 300)
+
+ expect(object.truncated_title.length).to eq(255)
+ end
+
+ it 'does not truncate the title if it is shorter than 255 characters' do
+ object = described_class.new(description: 'foo')
+
+ expect(object.truncated_title).to eq('foo')
+ end
+ end
+
+ describe '#github_identifiers' do
+ it 'returns a hash with needed identifiers' do
+ github_identifiers = { id: 1 }
+ gist = described_class.new(github_identifiers.merge(something_else: '_something_else_'))
+
+ expect(gist.github_identifiers).to eq(github_identifiers)
+ end
+ end
+
+ describe '#visibility_level' do
+ it 'returns 20 when public' do
+ visibility = { is_public: true }
+ gist = described_class.new(visibility.merge(something_else: '_something_else_'))
+
+ expect(gist.visibility_level).to eq(20)
+ end
+
+ it 'returns 0 when private' do
+ visibility = { is_public: false }
+ gist = described_class.new(visibility.merge(something_else: '_something_else_'))
+
+ expect(gist.visibility_level).to eq(0)
+ end
+ end
+
+ describe '#first_file' do
+ let(:http_response) { instance_double('HTTParty::Response', body: 'File content') }
+
+ before do
+ allow(Gitlab::HTTP).to receive(:try_get).and_return(http_response)
+ end
+
+ it 'returns a hash with needed identifiers' do
+ files = { files: { '_Summary.md': { filename: '_Summary.md', raw_url: 'https://some_url' } } }
+ gist = described_class.new(files.merge(something_else: '_something_else_'))
+
+ expect(gist.first_file).to eq(file_name: '_Summary.md', file_content: 'File content')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
index 892bad603a8..72661829bab 100644
--- a/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
+++ b/spec/lib/gitlab/memory/watchdog/configurator_spec.rb
@@ -243,7 +243,7 @@ RSpec.describe Gitlab::Memory::Watchdog::Configurator do
it_behaves_like 'as configurator',
Gitlab::Memory::Watchdog::TermProcessHandler,
- Gitlab::Memory::Watchdog::EventReporter,
+ Gitlab::Memory::Watchdog::SidekiqEventReporter,
'SIDEKIQ_MEMORY_KILLER_CHECK_INTERVAL',
described_class::DEFAULT_SIDEKIQ_SLEEP_INTERVAL_S
diff --git a/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb
new file mode 100644
index 00000000000..b6be4c59a0e
--- /dev/null
+++ b/spec/lib/gitlab/memory/watchdog/sidekiq_event_reporter_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Memory::Watchdog::SidekiqEventReporter, feature_category: :application_performance do
+ let(:counter) { instance_double(::Prometheus::Client::Counter) }
+
+ before do
+ allow(Gitlab::Metrics).to receive(:counter).and_return(counter)
+ allow(counter).to receive(:increment)
+ end
+
+ describe 'delegations' do
+ it { is_expected.to delegate_method(:started).to(:event_reporter) }
+ it { is_expected.to delegate_method(:stopped).to(:event_reporter) }
+ it { is_expected.to delegate_method(:threshold_violated).to(:event_reporter) }
+ it { is_expected.to delegate_method(:logger).to(:event_reporter) }
+ end
+
+ describe '#strikes_exceeded' do
+ let(:sidekiq_event_reporter) { described_class.new(logger: logger) }
+ let(:sidekiq_watchdog_running_jobs_counter) { instance_double(::Prometheus::Client::Counter) }
+ let(:logger) { instance_double(::Logger) }
+ let(:queue) { 'default' }
+ let(:jid) { SecureRandom.hex }
+ let(:running_jobs) { { jid => { worker_class: DummyWorker } } }
+ let(:worker) do
+ Class.new do
+ def self.name
+ 'DummyWorker'
+ end
+ end
+ end
+
+ before do
+ stub_const("DummyWorker", worker)
+ allow(::Gitlab::Metrics).to receive(:counter)
+ .with(:sidekiq_watchdog_running_jobs_total, anything)
+ .and_return(sidekiq_watchdog_running_jobs_counter)
+ allow(sidekiq_watchdog_running_jobs_counter).to receive(:increment)
+ allow(logger).to receive(:warn)
+
+ allow(Gitlab::SidekiqDaemon::Monitor.instance).to receive(:with_running_jobs).and_yield(running_jobs)
+ end
+
+ it 'delegates #strikes_exceeded with correct arguments' do
+ is_expected.to delegate_method(:strikes_exceeded).to(:event_reporter)
+ .with_arguments(
+ :monitor_name,
+ {
+ message: 'dummy_text',
+ running_jobs: running_jobs
+ }
+ )
+ end
+
+ it 'increment running jobs counter' do
+ expect(sidekiq_watchdog_running_jobs_counter).to receive(:increment)
+ .with({ worker_class: "DummyWorker" })
+
+ sidekiq_event_reporter.strikes_exceeded(:monitor_name, { message: 'dummy_text' })
+ end
+ end
+end
diff --git a/spec/lib/gitlab/merge_requests/message_generator_spec.rb b/spec/lib/gitlab/merge_requests/message_generator_spec.rb
index fbdd6a1e56d..59aaffc4377 100644
--- a/spec/lib/gitlab/merge_requests/message_generator_spec.rb
+++ b/spec/lib/gitlab/merge_requests/message_generator_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::MergeRequests::MessageGenerator do
+RSpec.describe Gitlab::MergeRequests::MessageGenerator, feature_category: :code_review do
let(:merge_commit_template) { nil }
let(:squash_commit_template) { nil }
let(:project) do
diff --git a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
index f93c0e28fc0..9f49605be8a 100644
--- a/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
+++ b/spec/lib/gitlab/sidekiq_daemon/monitor_spec.rb
@@ -37,6 +37,17 @@ RSpec.describe Gitlab::SidekiqDaemon::Monitor do
end
end
+ describe '#with_running_jobs' do
+ it 'yields with correct jobs' do
+ jid = SecureRandom.hex
+ running_jobs = { jid => hash_including(worker_class: 'worker_class') }
+
+ monitor.within_job('worker_class', jid, 'queue') do
+ expect { |b| monitor.with_running_jobs(&b) }.to yield_with_args(running_jobs)
+ end
+ end
+ end
+
describe '#run_thread when notification channel not enabled' do
subject { monitor.send(:run_thread) }
diff --git a/spec/lib/version_check_spec.rb b/spec/lib/version_check_spec.rb
index 1803dd66ba7..f14b38c55dd 100644
--- a/spec/lib/version_check_spec.rb
+++ b/spec/lib/version_check_spec.rb
@@ -2,7 +2,9 @@
require 'spec_helper'
-RSpec.describe VersionCheck do
+RSpec.describe VersionCheck, :use_clean_rails_memory_store_caching do
+ include ReactiveCachingHelpers
+
describe '.url' do
it 'returns the correct URL' do
expect(described_class.url).to match(%r{\A#{Regexp.escape(described_class.host)}/check\.json\?gitlab_info=\w+})
@@ -30,7 +32,7 @@ RSpec.describe VersionCheck do
end
it 'returns the response object' do
- expect(described_class.new.calculate_reactive_cache).to eq("{ \"status\": \"success\" }")
+ expect(described_class.new.calculate_reactive_cache).to eq({ "status" => "success" })
end
end
@@ -39,38 +41,31 @@ RSpec.describe VersionCheck do
stub_request(:get, described_class.url).to_return(status: 500, body: nil, headers: {})
end
- it 'returns nil' do
- expect(described_class.new.calculate_reactive_cache).to be(nil)
+ it 'returns an error hash' do
+ expect(described_class.new.calculate_reactive_cache).to eq({ error: 'version check failed', status: 500 })
end
end
end
describe '#response' do
context 'cache returns value' do
- let(:response) { { "severity" => "success" }.to_json }
-
- before do
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:with_reactive_cache).and_return(response)
- end
- end
-
it 'returns the response object' do
- expect(described_class.new.response).to be(response)
+ version_check = described_class.new
+ data = { status: 'success' }
+ stub_reactive_cache(version_check, data)
+
+ expect(version_check.response).to eq(data)
end
end
- context 'cache returns nil' do
- let(:response) { nil }
-
- before do
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:with_reactive_cache).and_return(response)
- end
- end
+ context 'cache returns error' do
+ it 'returns nil and invalidates the reactive cache' do
+ version_check = described_class.new
+ stub_reactive_cache(version_check, error: 'version check failed')
- it 'returns nil' do
- expect(described_class.new.response).to be(nil)
+ expect(version_check).to receive(:refresh_reactive_cache!).and_call_original
+ expect(version_check.response).to be_nil
+ expect(read_reactive_cache(version_check)).to be_nil
end
end
end
diff --git a/spec/models/ci/build_need_spec.rb b/spec/models/ci/build_need_spec.rb
index c2cf9027055..aa1c57d1788 100644
--- a/spec/models/ci/build_need_spec.rb
+++ b/spec/models/ci/build_need_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Ci::BuildNeed, model: true do
+RSpec.describe Ci::BuildNeed, model: true, feature_category: :continuous_integration do
let(:build_need) { build(:ci_build_need) }
it { is_expected.to belong_to(:build).class_name('Ci::Processable') }
@@ -35,4 +35,62 @@ RSpec.describe Ci::BuildNeed, model: true do
end
end
end
+
+ describe 'partitioning' do
+ context 'with build' do
+ let(:build) { FactoryBot.build(:ci_build, partition_id: ci_testing_partition_id) }
+ let(:build_need) { FactoryBot.build(:ci_build_need, build: build) }
+
+ it 'sets partition_id to the current partition value' do
+ expect { build_need.valid? }.to change { build_need.partition_id }.to(ci_testing_partition_id)
+ end
+
+ context 'when it is already set' do
+ let(:build_need) { FactoryBot.build(:ci_build_need, partition_id: 125) }
+
+ it 'does not change the partition_id value' do
+ expect { build_need.valid? }.not_to change { build_need.partition_id }
+ end
+ end
+ end
+
+ context 'without build' do
+ let(:build_need) { FactoryBot.build(:ci_build_need, build: nil) }
+
+ it { is_expected.to validate_presence_of(:partition_id) }
+
+ it 'does not change the partition_id value' do
+ expect { build_need.valid? }.not_to change { build_need.partition_id }
+ end
+ end
+
+ context 'when using bulk_insert' do
+ include Ci::PartitioningHelpers
+
+ let(:new_pipeline) { create(:ci_pipeline) }
+ let(:ci_build) { build(:ci_build, pipeline: new_pipeline) }
+
+ before do
+ stub_current_partition_id
+ end
+
+ it 'creates build needs successfully', :aggregate_failures do
+ ci_build.needs_attributes = [
+ { name: "build", artifacts: true },
+ { name: "build2", artifacts: true },
+ { name: "build3", artifacts: true }
+ ]
+
+ expect(described_class).to receive(:bulk_insert!).and_call_original
+
+ BulkInsertableAssociations.with_bulk_insert do
+ ci_build.save!
+ end
+
+ expect(described_class.count).to eq(3)
+ expect(described_class.first.partition_id).to eq(ci_testing_partition_id)
+ expect(described_class.second.partition_id).to eq(ci_testing_partition_id)
+ end
+ end
+ end
end
diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb
index e62e5f84a6d..2ff29bf207e 100644
--- a/spec/models/ci/processable_spec.rb
+++ b/spec/models/ci/processable_spec.rb
@@ -423,8 +423,8 @@ RSpec.describe Ci::Processable do
it 'returns all needs attributes' do
is_expected.to contain_exactly(
- { 'artifacts' => true, 'name' => 'test1', 'optional' => false },
- { 'artifacts' => true, 'name' => 'test2', 'optional' => false }
+ { 'artifacts' => true, 'name' => 'test1', 'optional' => false, 'partition_id' => build.partition_id },
+ { 'artifacts' => true, 'name' => 'test2', 'optional' => false, 'partition_id' => build.partition_id }
)
end
end
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index e29e5c31a34..38275ce0057 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
require 'raven/transports/dummy'
require_relative '../../../config/initializers/sentry'
-RSpec.describe API::Helpers do
+RSpec.describe API::Helpers, :enable_admin_mode, feature_category: :authentication_and_authorization do
include API::APIGuard::HelperMethods
include described_class
include TermsHelper
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index da478a3547e..c0e64b51853 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -164,6 +164,7 @@ project_setting:
- suggested_reviewers_enabled
- jitsu_key
- mirror_branch_regex
+ - allow_pipeline_trigger_approve_deployment
build_service_desk_setting: # service_desk_setting
unexposed_attributes:
diff --git a/spec/services/ci/create_pipeline_service/partitioning_spec.rb b/spec/services/ci/create_pipeline_service/partitioning_spec.rb
index f34d103d965..a87135cefdd 100644
--- a/spec/services/ci/create_pipeline_service/partitioning_spec.rb
+++ b/spec/services/ci/create_pipeline_service/partitioning_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectness, :aggregate_failures,
-:ci_partitionable do
+:ci_partitionable, feature_category: :continuous_integration do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.first_owner }
@@ -15,8 +15,13 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
- test
- deploy
+ needs:build:
+ stage: build
+ script: echo "needs..."
+
build:
stage: build
+ needs: ["needs:build"]
script: make build
test:
@@ -95,6 +100,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
expect(pipeline.variables.size).to eq(2)
expect(variables_partition_ids).to eq([current_partition_id])
end
+
+ it 'assigns partition_id to needs' do
+ needs = find_need('build')
+
+ expect(needs.partition_id).to eq(current_partition_id)
+ end
end
context 'with parent child pipelines' do
@@ -144,4 +155,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
.find { |job| job.name == name }
.metadata
end
+
+ def find_need(name)
+ pipeline
+ .processables
+ .find { |job| job.name == name }
+ .needs
+ .first
+ end
end
diff --git a/spec/support/models/ci/partitioning_testing/cascade_check.rb b/spec/support/models/ci/partitioning_testing/cascade_check.rb
index f553a47ef4f..bcfc9675476 100644
--- a/spec/support/models/ci/partitioning_testing/cascade_check.rb
+++ b/spec/support/models/ci/partitioning_testing/cascade_check.rb
@@ -15,6 +15,13 @@ module PartitioningTesting
raise "partition_id was expected to equal #{partition_scope_value} but it was #{partition_id}."
end
+
+ class_methods do
+ # Allowing partition callback to be used with BulkInsertSafe
+ def _bulk_insert_callback_allowed?(name, args)
+ super || args.first == :after && args.second == :check_partition_cascade_value
+ end
+ end
end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 1cee67f68ab..70772fd8b52 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -286,6 +286,7 @@ RSpec.describe 'Every Sidekiq worker' do
'Gitlab::GithubImport::Stage::ImportPullRequestsReviewsWorker' => 5,
'Gitlab::GithubImport::Stage::ImportPullRequestsWorker' => 5,
'Gitlab::GithubImport::Stage::ImportRepositoryWorker' => 5,
+ 'Gitlab::GithubGistsImport::ImportGistWorker' => 5,
'Gitlab::JiraImport::AdvanceStageWorker' => 5,
'Gitlab::JiraImport::ImportIssueWorker' => 5,
'Gitlab::JiraImport::Stage::FinishImportWorker' => 5,
diff --git a/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
new file mode 100644
index 00000000000..dfc5084bb10
--- /dev/null
+++ b/spec/workers/gitlab/github_gists_import/import_gist_worker_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubGistsImport::ImportGistWorker, feature_category: :importer do
+ subject { described_class.new }
+
+ let_it_be(:user) { create(:user) }
+ let(:token) { 'token' }
+ let(:gist_hash) do
+ {
+ id: '055b70',
+ git_pull_url: 'https://gist.github.com/foo/bar.git',
+ files: {
+ 'random.txt': {
+ filename: 'random.txt',
+ type: 'text/plain',
+ language: 'Text',
+ raw_url: 'https://gist.githubusercontent.com/user_name/055b70/raw/66a7be0d/random.txt',
+ size: 166903
+ }
+ },
+ is_public: false,
+ created_at: '2022-09-06T11:38:18Z',
+ updated_at: '2022-09-06T11:38:18Z',
+ description: 'random text'
+ }
+ end
+
+ let(:importer) { instance_double('Gitlab::GithubGistsImport::Importer::GistImporter') }
+ let(:importer_result) { instance_double('ServiceResponse', success?: true) }
+ let(:gist_object) do
+ instance_double('Gitlab::GithubGistsImport::Representation::Gist',
+ gist_hash.merge(github_identifiers: { id: '055b70' }, truncated_title: 'random text', visibility_level: 0))
+ end
+
+ let(:log_attributes) do
+ {
+ 'user_id' => user.id,
+ 'github_identifiers' => { 'id': gist_object.id },
+ 'class' => 'Gitlab::GithubGistsImport::ImportGistWorker',
+ 'correlation_id' => 'new-correlation-id',
+ 'jid' => nil,
+ 'job_status' => 'running',
+ 'queue' => 'github_gists_importer:github_gists_import_import_gist'
+ }
+ end
+
+ describe '#perform' do
+ before do
+ allow(Gitlab::GithubGistsImport::Representation::Gist)
+ .to receive(:from_json_hash)
+ .with(gist_hash)
+ .and_return(gist_object)
+
+ allow(Gitlab::GithubGistsImport::Importer::GistImporter)
+ .to receive(:new)
+ .with(gist_object, user.id)
+ .and_return(importer)
+
+ allow(Gitlab::ApplicationContext).to receive(:current).and_return('correlation_id' => 'new-correlation-id')
+ allow(described_class).to receive(:queue).and_return('github_gists_importer:github_gists_import_import_gist')
+ end
+
+ context 'when success' do
+ it 'imports gist' do
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:info)
+ .with(log_attributes.merge('message' => 'start importer'))
+ expect(importer).to receive(:execute).and_return(importer_result)
+ expect(Gitlab::JobWaiter).to receive(:notify).with('some_key', subject.jid)
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:info)
+ .with(log_attributes.merge('message' => 'importer finished'))
+
+ subject.perform(user.id, gist_hash, 'some_key')
+ end
+ end
+
+ context 'when importer raised an error' do
+ it 'raises an error' do
+ exception = StandardError.new('_some_error_')
+
+ expect(importer).to receive(:execute).and_raise(exception)
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:error)
+ .with(log_attributes.merge('message' => 'importer failed', 'error.message' => '_some_error_'))
+ expect(Gitlab::ErrorTracking).to receive(:track_exception)
+
+ expect { subject.perform(user.id, gist_hash, 'some_key') }.to raise_error(StandardError)
+ end
+ end
+ end
+end