Commit a3566e71 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent b5de70e680e5
# frozen_string_literal: true
require 'spec_helper'
describe SnippetsFinder do
......
# frozen_string_literal: true
require 'spec_helper'
describe TagsFinder do
......
# frozen_string_literal: true
require 'spec_helper'
describe TemplateFinder do
......
# frozen_string_literal: true
require 'spec_helper'
describe TodosFinder do
......
# frozen_string_literal: true
require 'spec_helper'
describe UserRecentEventsFinder do
......
# frozen_string_literal: true
require 'spec_helper'
describe UsersFinder do
......
......@@ -6,7 +6,7 @@
subject { described_class.new }
before do
allow(subject).to receive(:start_working)
allow(subject).to receive(:run_thread)
allow(subject).to receive(:stop_working)
end
......@@ -44,7 +44,7 @@
it 'starts the Daemon' do
expect { subject.start.join }.to change { subject.thread? }.from(false).to(true)
expect(subject).to have_received(:start_working)
expect(subject).to have_received(:run_thread)
end
end
......@@ -52,7 +52,21 @@
it "doesn't shutdown stopped Daemon" do
expect { subject.stop }.not_to change { subject.thread? }
expect(subject).not_to have_received(:start_working)
expect(subject).not_to have_received(:run_thread)
end
end
end
describe '#start_working' do
context 'when start_working fails' do
before do
expect(subject).to receive(:start_working) { false }
end
it 'does not start thread' do
expect(subject).not_to receive(:run_thread)
expect(subject.start).to eq(nil)
end
end
end
......@@ -66,7 +80,7 @@
it "doesn't start running Daemon" do
expect { subject.start.join }.not_to change { subject.thread }
expect(subject).to have_received(:start_working).once
expect(subject).to have_received(:run_thread).once
end
end
......@@ -79,7 +93,7 @@
context 'when stop_working raises exception' do
before do
allow(subject).to receive(:start_working) do
allow(subject).to receive(:run_thread) do
sleep(1000)
end
end
......@@ -108,7 +122,7 @@
expect(subject.start).to be_nil
expect { subject.start }.not_to change { subject.thread? }
expect(subject).not_to have_received(:start_working)
expect(subject).not_to have_received(:run_thread)
end
end
......
......@@ -2,11 +2,13 @@
require 'fast_spec_helper'
require 'rspec-parameterized'
require 'gitlab/danger/teammate'
describe Gitlab::Danger::Teammate do
subject { described_class.new(options) }
let(:options) { { 'projects' => projects, 'role' => role } }
subject { described_class.new(options.stringify_keys) }
let(:options) { { username: 'luigi', projects: projects, role: role } }
let(:projects) { { project => capabilities } }
let(:role) { 'Engineer, Manage' }
let(:labels) { [] }
......@@ -95,4 +97,64 @@
expect(subject.maintainer?(project, :frontend, labels)).to be_falsey
end
end
describe '#status' do
let(:capabilities) { ['dish washing'] }
context 'with empty cache' do
context 'for successful request' do
it 'returns the response' do
mock_status = double(does_not: 'matter')
expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json)
.and_return(mock_status)
expect(subject.status).to be mock_status
end
end
context 'for failing request' do
it 'returns nil' do
expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json)
.and_raise(Gitlab::Danger::RequestHelper::HTTPError.new)
expect(subject.status).to be nil
end
end
end
context 'with filled cache' do
it 'returns the cached response' do
mock_status = double(does_not: 'matter')
expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json)
.and_return(mock_status)
subject.status
expect(Gitlab::Danger::RequestHelper).not_to receive(:http_get_json)
expect(subject.status).to be mock_status
end
end
end
describe '#out_of_office?' do
using RSpec::Parameterized::TableSyntax
let(:capabilities) { ['dry head'] }
where(:status, :result) do
nil | false
{} | false
{ message: 'dear reader' } | false
{ message: 'OOO: massage' } | true
{ message: 'love it SOOO much' } | true
end
with_them do
before do
expect(Gitlab::Danger::RequestHelper).to receive(:http_get_json)
.and_return(status&.stringify_keys)
end
it { expect(subject.out_of_office?).to be result }
end
end
end
......@@ -12,8 +12,8 @@
allow(Sidekiq.logger).to receive(:warn)
end
describe '#start_working' do
subject { memory_killer.send(:start_working) }
describe '#run_thread' do
subject { memory_killer.send(:run_thread) }
before do
# let enabled? return 3 times: true, true, false
......@@ -37,7 +37,7 @@
.with(
class: described_class.to_s,
pid: pid,
message: "Exception from start_working: My Exception")
message: "Exception from run_thread: My Exception")
expect(memory_killer).to receive(:rss_within_range?).twice.and_raise(StandardError, 'My Exception')
expect(memory_killer).to receive(:sleep).twice.with(Gitlab::SidekiqDaemon::MemoryKiller::CHECK_INTERVAL_SECONDS)
......@@ -50,7 +50,7 @@
.with(
class: described_class.to_s,
pid: pid,
message: "Exception from start_working: My Exception")
message: "Exception from run_thread: My Exception")
expect(memory_killer).to receive(:rss_within_range?).once.and_raise(Exception, 'My Exception')
......
......@@ -37,8 +37,8 @@
end
end
describe '#start_working when notification channel not enabled' do
subject { monitor.send(:start_working) }
describe '#run_thread when notification channel not enabled' do
subject { monitor.send(:run_thread) }
it 'return directly' do
allow(monitor).to receive(:notification_channel_enabled?).and_return(nil)
......@@ -52,8 +52,8 @@
end
end
describe '#start_working when notification channel enabled' do
subject { monitor.send(:start_working) }
describe '#run_thread when notification channel enabled' do
subject { monitor.send(:run_thread) }
before do
# we want to run at most once cycle
......
......@@ -19,17 +19,24 @@
it { is_expected.to belong_to(:runner) }
it { is_expected.to belong_to(:trigger_request) }
it { is_expected.to belong_to(:erased_by) }
it { is_expected.to have_many(:trace_sections) }
it { is_expected.to have_many(:needs) }
it { is_expected.to have_many(:sourced_pipelines) }
it { is_expected.to have_many(:job_variables) }
it { is_expected.to have_one(:deployment) }
it { is_expected.to have_one(:runner_session) }
it { is_expected.to have_many(:job_variables) }
it { is_expected.to validate_presence_of(:ref) }
it { is_expected.to respond_to(:has_trace?) }
it { is_expected.to respond_to(:trace) }
it { is_expected.to delegate_method(:merge_request_event?).to(:pipeline) }
it { is_expected.to delegate_method(:merge_request_ref?).to(:pipeline) }
it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) }
it { is_expected.to include_module(Ci::PipelineDelegator) }
describe 'associations' do
......
......@@ -28,7 +28,13 @@
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:auto_canceled_pipelines) }
it { is_expected.to have_many(:auto_canceled_jobs) }
it { is_expected.to have_many(:sourced_pipelines) }
it { is_expected.to have_many(:triggered_pipelines) }
it { is_expected.to have_one(:chat_data) }
it { is_expected.to have_one(:source_pipeline) }
it { is_expected.to have_one(:triggered_by_pipeline) }
it { is_expected.to have_one(:source_job) }
it { is_expected.to validate_presence_of(:sha) }
it { is_expected.to validate_presence_of(:status) }
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::Sources::Pipeline do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:pipeline) }
it { is_expected.to belong_to(:source_project) }
it { is_expected.to belong_to(:source_job) }
it { is_expected.to belong_to(:source_pipeline) }
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:pipeline) }
it { is_expected.to validate_presence_of(:source_project) }
it { is_expected.to validate_presence_of(:source_job) }
it { is_expected.to validate_presence_of(:source_pipeline) }
end
......@@ -101,6 +101,8 @@
it { is_expected.to have_many(:deploy_tokens).through(:project_deploy_tokens) }
it { is_expected.to have_many(:cycle_analytics_stages) }
it { is_expected.to have_many(:external_pull_requests) }
it { is_expected.to have_many(:sourced_pipelines) }
it { is_expected.to have_many(:source_pipelines) }
it 'has an inverse relationship with merge requests' do
expect(described_class.reflect_on_association(:merge_requests).has_inverse?).to eq(:target_project)
......
......@@ -138,5 +138,40 @@
expect(subject[:flags][:yaml_errors]).to be false
end
end
context 'when pipeline is triggered by other pipeline' do
let(:pipeline) { create(:ci_empty_pipeline) }
before do
create(:ci_sources_pipeline, pipeline: pipeline)
end
it 'contains an information about depedent pipeline' do
expect(subject[:triggered_by]).to be_a(Hash)
expect(subject[:triggered_by][:path]).not_to be_nil
expect(subject[:triggered_by][:details]).not_to be_nil
expect(subject[:triggered_by][:details][:status]).not_to be_nil
expect(subject[:triggered_by][:project]).not_to be_nil
end
end
context 'when pipeline triggered other pipeline' do
let(:pipeline) { create(:ci_empty_pipeline) }
let(:build) { create(:ci_build, pipeline: pipeline) }
before do
create(:ci_sources_pipeline, source_job: build)
create(:ci_sources_pipeline, source_job: build)
end
it 'contains an information about depedent pipeline' do
expect(subject[:triggered]).to be_a(Array)
expect(subject[:triggered].length).to eq(2)
expect(subject[:triggered].first[:path]).not_to be_nil
expect(subject[:triggered].first[:details]).not_to be_nil
expect(subject[:triggered].first[:details][:status]).not_to be_nil
expect(subject[:triggered].first[:project]).not_to be_nil
end
end
end
end
......@@ -158,7 +158,7 @@
it 'verifies number of queries', :request_store do
recorded = ActiveRecord::QueryRecorder.new { subject }
expected_queries = Gitlab.ee? ? 38 : 31
expected_queries = Gitlab.ee? ? 38 : 35
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
......@@ -179,7 +179,8 @@ def ref
# pipeline. With the same ref this check is cached but if refs are
# different then there is an extra query per ref
# https://gitlab.com/gitlab-org/gitlab-foss/issues/46368
expected_queries = Gitlab.ee? ? 44 : 38
expected_queries = Gitlab.ee? ? 44 : 41
expect(recorded.count).to be_within(2).of(expected_queries)
expect(recorded.cached_count).to eq(0)
end
......
......@@ -11,76 +11,158 @@
describe '#execute' do
let(:user) { create(:user) }
let(:trigger) { create(:ci_trigger, project: project, owner: user) }
let(:result) { described_class.new(project, user, params).execute }
before do
project.add_developer(user)
end
context 'when trigger belongs to a different project' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) }
context 'with a trigger token' do
let(:trigger) { create(:ci_trigger, project: project, owner: user) }
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
end
end
context 'when params have an existsed trigger token' do
context 'when params have an existsed ref' do
context 'when trigger belongs to a different project' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) }
it 'triggers a pipeline' do
expect { result }.to change { Ci::Pipeline.count }.by(1)
expect(result[:pipeline].ref).to eq('master')
expect(result[:pipeline].project).to eq(project)
expect(result[:pipeline].user).to eq(trigger.owner)
expect(result[:pipeline].trigger_requests.to_a)
.to eq(result[:pipeline].builds.map(&:trigger_request).uniq)
expect(result[:status]).to eq(:success)
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
end
end
context 'when commit message has [ci skip]' do
before do
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' }
end
context 'when params have an existsed trigger token' do
context 'when params have an existsed ref' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
it 'ignores [ci skip] and create as general' do
it 'triggers a pipeline' do
expect { result }.to change { Ci::Pipeline.count }.by(1)
expect(result[:pipeline].ref).to eq('master')
expect(result[:pipeline].project).to eq(project)
expect(result[:pipeline].user).to eq(trigger.owner)
expect(result[:pipeline].trigger_requests.to_a)
.to eq(result[:pipeline].builds.map(&:trigger_request).uniq)
expect(result[:status]).to eq(:success)
end
context 'when commit message has [ci skip]' do
before do
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' }
end
it 'ignores [ci skip] and create as general' do
expect { result }.to change { Ci::Pipeline.count }.by(1)
expect(result[:status]).to eq(:success)
end
end
context 'when params have a variable' do
let(:params) { { token: trigger.token, ref: 'master', variables: variables } }
let(:variables) { { 'AAA' => 'AAA123' } }
it 'has a variable' do
expect { result }.to change { Ci::PipelineVariable.count }.by(1)
.and change { Ci::TriggerRequest.count }.by(1)
expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables)
expect(result[:pipeline].trigger_requests.last.variables).to be_nil
end
end
end
context 'when params have a variable' do
let(:params) { { token: trigger.token, ref: 'master', variables: variables } }
let(:variables) { { 'AAA' => 'AAA123' } }
context 'when params have a non-existsed ref' do
let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } }
it 'has a variable' do
expect { result }.to change { Ci::PipelineVariable.count }.by(1)
.and change { Ci::TriggerRequest.count }.by(1)
expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables)
expect(result[:pipeline].trigger_requests.last.variables).to be_nil
it 'does not trigger a pipeline' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result[:http_status]).to eq(400)
end
end
end
context 'when params have a non-existsed ref' do
let(:params) { { token: trigger.token, ref: 'invalid-ref', variables: nil } }
context 'when params have a non-existsed trigger token' do
let(:params) { { token: 'invalid-token', ref: nil, variables: nil } }
it 'does not trigger a pipeline' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result[:http_status]).to eq(400)
expect(result).to be_nil
end
end
end
context 'when params have a non-existsed trigger token' do
let(:params) { { token: 'invalid-token', ref: nil, variables: nil } }
context 'with a pipeline job token' do
let!(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :running, pipeline: pipeline, user: user) }
context 'when job user does not have a permission to read a project' do
let(:params) { { token: job.token, ref: 'master', variables: nil } }
let(:job) { create(:ci_build, pipeline: pipeline, user: create(:user)) }
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
end
end
context 'when job is not running' do
let(:params) { { token: job.token, ref: 'master', variables: nil } }
let(:job) { create(:ci_build, :success, pipeline: pipeline, user: user) }
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result[:message]).to eq('400 Job has to be running')
end
end
it 'does not trigger a pipeline' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result).to be_nil
context 'when params have an existsed job token' do
context 'when params have an existsed ref' do
let(:params) { { token: job.token, ref: 'master', variables: nil } }
it 'triggers a pipeline' do
expect { result }.to change { Ci::Pipeline.count }.by(1)
expect(result[:pipeline].ref).to eq('master')
expect(result[:pipeline].project).to eq(project)
expect(result[:pipeline].user).to eq(job.user)
expect(result[:status]).to eq(:success)
end
context 'when commit message has [ci skip]' do
before do
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { '[ci skip]' }
end
it 'ignores [ci skip] and create as general' do
expect { result }.to change { Ci::Pipeline.count }.by(1)
expect(result[:status]).to eq(:success)
end
end
context 'when params have a variable' do
let(:params) { { token: job.token, ref: 'master', variables: variables } }
let(:variables) { { 'AAA' => 'AAA123' } }
it 'has a variable' do
expect { result }.to change { Ci::PipelineVariable.count }.by(1)
.and change { Ci::Sources::Pipeline.count }.by(1)
expect(result[:pipeline].variables.map { |v| { v.key => v.value } }.first).to eq(variables)
expect(job.sourced_pipelines.last.pipeline_id).to eq(result[:pipeline].id)
end
end
end
context 'when params have a non-existsed ref' do
let(:params) { { token: job.token, ref: 'invalid-ref', variables: nil } }
it 'does not job a pipeline' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result[:http_status]).to eq(400)
end
end
end
context 'when params have a non-existsed trigger token' do
let(:params) { { token: 'invalid-token', ref: nil, variables: nil } }
it 'does not trigger a pipeline' do
expect { result }.not_to change { Ci::Pipeline.count }
expect(result).to be_nil
end
end
end
end
......
......@@ -426,5 +426,22 @@
end
end
end
context 'when a project in group has container images' do
let(:group) { create(:group, :public, :nested) }
let!(:project) { create(:project, :repository, :public, namespace: group) }
before do
stub_container_registry_tags(repository: /image/, tags: %w[rc1])
create(:container_repository, project: project, name: :image)
create(:group_member, :owner, group: new_parent_group, user: user)
end
it 'does not allow group to be transferred' do
transfer_service.execute(new_parent_group)