Skip to content
Snippets Groups Projects
Commit 0d6fa033 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 0eb3d2f7
No related branches found
No related tags found
No related merge requests found
Showing
with 448 additions and 113 deletions
Loading
Loading
@@ -3,6 +3,23 @@
require 'spec_helper'
 
describe Gitlab::Runtime do
shared_examples "valid runtime" do |runtime, max_threads|
it "identifies itself" do
expect(subject.identify).to eq(runtime)
expect(subject.public_send("#{runtime}?")).to be(true)
end
it "does not identify as others" do
(described_class::AVAILABLE_RUNTIMES - [runtime]).each do |runtime|
expect(subject.public_send("#{runtime}?")).to eq(false)
end
end
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(max_threads)
end
end
before do
allow(described_class).to receive(:process_name).and_return('ruby')
stub_rails_env('production')
Loading
Loading
@@ -27,117 +44,42 @@ describe Gitlab::Runtime do
 
context "puma" do
let(:puma_type) { double('::Puma') }
let(:options) do
{
max_threads: 2
}
end
 
before do
stub_const('::Puma', puma_type)
allow(puma_type).to receive_message_chain(:cli_config, :options).and_return(options)
end
it "identifies itself" do
expect(subject.identify).to eq(:puma)
expect(subject.puma?).to be(true)
allow(puma_type).to receive_message_chain(:cli_config, :options).and_return(max_threads: 2)
end
 
it "does not identify as others" do
expect(subject.unicorn?).to be(false)
expect(subject.sidekiq?).to be(false)
expect(subject.console?).to be(false)
expect(subject.rake?).to be(false)
expect(subject.test_suite?).to be(false)
end
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(2)
end
it_behaves_like "valid runtime", :puma, 2
end
 
context "unicorn" do
let(:unicorn_type) { Module.new }
let(:unicorn_server_type) { Class.new }
before do
stub_const('::Unicorn', unicorn_type)
stub_const('::Unicorn::HttpServer', unicorn_server_type)
stub_const('::Unicorn', Module.new)
stub_const('::Unicorn::HttpServer', Class.new)
end
 
it "identifies itself" do
expect(subject.identify).to eq(:unicorn)
expect(subject.unicorn?).to be(true)
end
it "does not identify as others" do
expect(subject.puma?).to be(false)
expect(subject.sidekiq?).to be(false)
expect(subject.console?).to be(false)
expect(subject.rake?).to be(false)
expect(subject.test_suite?).to be(false)
end
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(1)
end
it_behaves_like "valid runtime", :unicorn, 1
end
 
context "sidekiq" do
let(:sidekiq_type) { double('::Sidekiq') }
let(:options) do
{
concurrency: 2
}
end
 
before do
stub_const('::Sidekiq', sidekiq_type)
allow(sidekiq_type).to receive(:server?).and_return(true)
allow(sidekiq_type).to receive(:options).and_return(options)
allow(sidekiq_type).to receive(:options).and_return(concurrency: 2)
end
 
it "identifies itself" do
expect(subject.identify).to eq(:sidekiq)
expect(subject.sidekiq?).to be(true)
end
it "does not identify as others" do
expect(subject.unicorn?).to be(false)
expect(subject.puma?).to be(false)
expect(subject.console?).to be(false)
expect(subject.rake?).to be(false)
expect(subject.test_suite?).to be(false)
end
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(2)
end
it_behaves_like "valid runtime", :sidekiq, 2
end
 
context "console" do
let(:console_type) { double('::Rails::Console') }
before do
stub_const('::Rails::Console', console_type)
end
it "identifies itself" do
expect(subject.identify).to eq(:console)
expect(subject.console?).to be(true)
end
it "does not identify as others" do
expect(subject.unicorn?).to be(false)
expect(subject.sidekiq?).to be(false)
expect(subject.puma?).to be(false)
expect(subject.rake?).to be(false)
expect(subject.test_suite?).to be(false)
stub_const('::Rails::Console', double('::Rails::Console'))
end
 
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(1)
end
it_behaves_like "valid runtime", :console, 1
end
 
context "test suite" do
Loading
Loading
@@ -145,20 +87,14 @@ describe Gitlab::Runtime do
stub_rails_env('test')
end
 
it "identifies itself" do
expect(subject.identify).to eq(:test_suite)
expect(subject.test_suite?).to be(true)
end
it_behaves_like "valid runtime", :test_suite, 1
end
 
it "does not identify as others" do
expect(subject.unicorn?).to be(false)
expect(subject.sidekiq?).to be(false)
expect(subject.rake?).to be(false)
expect(subject.puma?).to be(false)
context "geo log cursor" do
before do
stub_const('::GeoLogCursorOptionParser', double('::GeoLogCursorOptionParser'))
end
 
it "reports its maximum concurrency" do
expect(subject.max_threads).to eq(1)
end
it_behaves_like "valid runtime", :geo_log_cursor, 1
end
end
Loading
Loading
@@ -14,28 +14,28 @@ describe MigrateIssueTrackersData, :migration do
}
end
let!(:jira_service) do
services.create(id: 10, type: 'JiraService', properties: properties, category: 'issue_tracker')
services.create(type: 'JiraService', properties: properties, category: 'issue_tracker')
end
let!(:jira_service_nil) do
services.create(id: 11, type: 'JiraService', properties: nil, category: 'issue_tracker')
services.create(type: 'JiraService', properties: nil, category: 'issue_tracker')
end
let!(:bugzilla_service) do
services.create(id: 12, type: 'BugzillaService', properties: properties, category: 'issue_tracker')
services.create(type: 'BugzillaService', properties: properties, category: 'issue_tracker')
end
let!(:youtrack_service) do
services.create(id: 13, type: 'YoutrackService', properties: properties, category: 'issue_tracker')
services.create(type: 'YoutrackService', properties: properties, category: 'issue_tracker')
end
let!(:youtrack_service_empty) do
services.create(id: 14, type: 'YoutrackService', properties: '', category: 'issue_tracker')
services.create(type: 'YoutrackService', properties: '', category: 'issue_tracker')
end
let!(:gitlab_service) do
services.create(id: 15, type: 'GitlabIssueTrackerService', properties: properties, category: 'issue_tracker')
services.create(type: 'GitlabIssueTrackerService', properties: properties, category: 'issue_tracker')
end
let!(:gitlab_service_empty) do
services.create(id: 16, type: 'GitlabIssueTrackerService', properties: {}, category: 'issue_tracker')
services.create(type: 'GitlabIssueTrackerService', properties: {}, category: 'issue_tracker')
end
let!(:other_service) do
services.create(id: 17, type: 'OtherService', properties: properties, category: 'other_category')
services.create(type: 'OtherService', properties: properties, category: 'other_category')
end
 
before do
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200130145430_reschedule_migrate_issue_trackers_data.rb')
 
describe RescheduleMigrateIssueTrackersData, :migration, :sidekiq do
describe RescheduleMigrateIssueTrackersData, :migration do
let(:services) { table(:services) }
let(:migration_class) { Gitlab::BackgroundMigration::MigrateIssueTrackersSensitiveData }
let(:migration_name) { migration_class.to_s.demodulize }
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20200110121314_schedule_update_existing_subgroup_to_match_visibility_level_of_parent.rb')
 
describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent, :migration, :sidekiq do
describe ScheduleUpdateExistingSubgroupToMatchVisibilityLevelOfParent, :migration do
include MigrationHelpers::NamespacesHelpers
let(:migration_class) { described_class::MIGRATION }
let(:migration_name) { migration_class.to_s.demodulize }
Loading
Loading
Loading
Loading
@@ -4,14 +4,25 @@ require 'spec_helper'
 
describe Ci::Bridge do
set(:project) { create(:project) }
set(:target_project) { create(:project, name: 'project', namespace: create(:namespace, name: 'my')) }
set(:pipeline) { create(:ci_pipeline, project: project) }
 
let(:bridge) do
create(:ci_bridge, pipeline: pipeline)
create(:ci_bridge, :variables, status: :created,
options: options,
pipeline: pipeline)
end
let(:options) do
{ trigger: { project: 'my/project', branch: 'master' } }
end
 
it { is_expected.to include_module(Ci::PipelineDelegator) }
 
it 'has many sourced pipelines' do
expect(bridge).to have_many(:sourced_pipelines)
end
describe '#tags' do
it 'only has a bridge tag' do
expect(bridge.tags).to eq [:bridge]
Loading
Loading
@@ -41,4 +52,222 @@ describe Ci::Bridge do
expect(bridge.scoped_variables_hash.keys).to include(*variables)
end
end
describe '#inherit_status_from_downstream!' do
let(:downstream_pipeline) { build(:ci_pipeline, status: downstream_status) }
before do
bridge.status = 'pending'
create(:ci_sources_pipeline, pipeline: downstream_pipeline, source_job: bridge)
end
subject { bridge.inherit_status_from_downstream!(downstream_pipeline) }
context 'when status is not supported' do
(::Ci::Pipeline::AVAILABLE_STATUSES - ::Ci::Pipeline::COMPLETED_STATUSES).map(&:to_s).each do |status|
context "when status is #{status}" do
let(:downstream_status) { status }
it 'returns false' do
expect(subject).to eq(false)
end
it 'does not change the bridge status' do
expect { subject }.not_to change { bridge.status }.from('pending')
end
end
end
end
context 'when status is supported' do
using RSpec::Parameterized::TableSyntax
where(:downstream_status, :upstream_status) do
[
%w[success success],
*::Ci::Pipeline.completed_statuses.without(:success).map { |status| [status.to_s, 'failed'] }
]
end
with_them do
it 'inherits the downstream status' do
expect { subject }.to change { bridge.status }.from('pending').to(upstream_status)
end
end
end
end
describe '#dependent?' do
subject { bridge.dependent? }
context 'when bridge has strategy depend' do
let(:options) { { trigger: { project: 'my/project', strategy: 'depend' } } }
it { is_expected.to be true }
end
context 'when bridge does not have strategy depend' do
it { is_expected.to be false }
end
end
describe '#yaml_variables' do
it 'returns YAML variables' do
expect(bridge.yaml_variables)
.to include(key: 'BRIDGE', value: 'cross', public: true)
end
end
describe '#downstream_variables' do
it 'returns variables that are going to be passed downstream' do
expect(bridge.downstream_variables)
.to include(key: 'BRIDGE', value: 'cross')
end
context 'when using variables interpolation' do
let(:yaml_variables) do
[
{
key: 'EXPANDED',
value: '$BRIDGE-bridge',
public: true
},
{
key: 'UPSTREAM_CI_PIPELINE_ID',
value: '$CI_PIPELINE_ID',
public: true
},
{
key: 'UPSTREAM_CI_PIPELINE_URL',
value: '$CI_PIPELINE_URL',
public: true
}
]
end
before do
bridge.yaml_variables.concat(yaml_variables)
end
it 'correctly expands variables with interpolation' do
expanded_values = pipeline
.persisted_variables
.to_hash
.transform_keys { |key| "UPSTREAM_#{key}" }
.map { |key, value| { key: key, value: value } }
.push(key: 'EXPANDED', value: 'cross-bridge')
expect(bridge.downstream_variables)
.to match(a_collection_including(*expanded_values))
end
end
context 'when recursive interpolation has been used' do
before do
bridge.yaml_variables << { key: 'EXPANDED', value: '$EXPANDED', public: true }
end
it 'does not expand variable recursively' do
expect(bridge.downstream_variables)
.to include(key: 'EXPANDED', value: '$EXPANDED')
end
end
end
describe 'metadata support' do
it 'reads YAML variables from metadata' do
expect(bridge.yaml_variables).not_to be_empty
expect(bridge.metadata).to be_a Ci::BuildMetadata
expect(bridge.read_attribute(:yaml_variables)).to be_nil
expect(bridge.metadata.config_variables).to be bridge.yaml_variables
end
it 'reads options from metadata' do
expect(bridge.options).not_to be_empty
expect(bridge.metadata).to be_a Ci::BuildMetadata
expect(bridge.read_attribute(:options)).to be_nil
expect(bridge.metadata.config_options).to be bridge.options
end
end
describe '#triggers_child_pipeline?' do
subject { bridge.triggers_child_pipeline? }
context 'when bridge defines a downstream YAML' do
let(:options) do
{
trigger: {
include: 'path/to/child.yml'
}
}
end
it { is_expected.to be_truthy }
end
context 'when bridge does not define a downstream YAML' do
let(:options) do
{
trigger: {
project: project.full_path
}
}
end
it { is_expected.to be_falsey }
end
end
describe '#yaml_for_downstream' do
subject { bridge.yaml_for_downstream }
context 'when bridge defines a downstream YAML' do
let(:options) do
{
trigger: {
include: 'path/to/child.yml'
}
}
end
let(:yaml) do
<<~EOY
---
include: path/to/child.yml
EOY
end
it { is_expected.to eq yaml }
end
context 'when bridge does not define a downstream YAML' do
let(:options) { {} }
it { is_expected.to be_nil }
end
end
describe '#target_ref' do
context 'when trigger is defined' do
it 'returns a ref name' do
expect(bridge.target_ref).to eq 'master'
end
context 'when using variable expansion' do
let(:options) { { trigger: { project: 'my/project', branch: '$BRIDGE-master' } } }
it 'correctly expands variables' do
expect(bridge.target_ref).to eq('cross-master')
end
end
end
context 'when trigger does not have project defined' do
let(:options) { nil }
it 'returns nil' do
expect(bridge.target_ref).to be_nil
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe PrometheusAlert do
let_it_be(:project) { build(:project) }
let(:metric) { build(:prometheus_metric) }
describe '.distinct_projects' do
let(:project1) { create(:project) }
let(:project2) { create(:project) }
before do
create(:prometheus_alert, project: project1)
create(:prometheus_alert, project: project1)
create(:prometheus_alert, project: project2)
end
subject { described_class.distinct_projects.count }
it 'returns a count of all distinct projects which have an alert' do
expect(subject).to eq(2)
end
end
describe 'operators' do
it 'contains the correct equality operator' do
expect(described_class::OPERATORS_MAP.values).to include('==')
expect(described_class::OPERATORS_MAP.values).not_to include('=')
end
end
describe 'associations' do
it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:environment) }
end
describe 'project validations' do
let(:environment) { build(:environment, project: project) }
let(:metric) { build(:prometheus_metric, project: project) }
subject do
build(:prometheus_alert, prometheus_metric: metric, environment: environment, project: project)
end
it { is_expected.to validate_presence_of(:environment) }
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:prometheus_metric) }
context 'when environment and metric belongs same project' do
it { is_expected.to be_valid }
end
context 'when environment belongs to different project' do
let(:environment) { build(:environment) }
it { is_expected.not_to be_valid }
end
context 'when metric belongs to different project' do
let(:metric) { build(:prometheus_metric) }
it { is_expected.not_to be_valid }
end
context 'when metric is common' do
let(:metric) { build(:prometheus_metric, :common) }
it { is_expected.to be_valid }
end
end
describe '#full_query' do
before do
subject.operator = "gt"
subject.threshold = 1
subject.prometheus_metric = metric
end
it 'returns the concatenated query' do
expect(subject.full_query).to eq("#{metric.query} > 1.0")
end
end
describe '#to_param' do
before do
subject.operator = "gt"
subject.threshold = 1
subject.prometheus_metric = metric
end
it 'returns the params of the prometheus alert' do
expect(subject.to_param).to eq(
"alert" => metric.title,
"expr" => "#{metric.query} > 1.0",
"for" => "5m",
"labels" => {
"gitlab" => "hook",
"gitlab_alert_id" => metric.id
})
end
end
end
Loading
Loading
@@ -74,7 +74,7 @@ describe PushEvent do
create(:push_event_payload, event: event4, ref: 'baz', action: :removed)
create(:push_event_payload, event: event5, ref: 'baz', ref_type: :tag)
 
project.repository.create_branch('bar', 'master')
project.repository.create_branch('bar')
 
create(
:merge_request,
Loading
Loading
@@ -83,7 +83,7 @@ describe PushEvent do
source_branch: 'bar'
)
 
project.repository.create_branch('qux', 'master')
project.repository.create_branch('qux')
 
create(
:merge_request,
Loading
Loading
Loading
Loading
@@ -17,4 +17,37 @@ describe UserCallout do
it { is_expected.to validate_presence_of(:feature_name) }
it { is_expected.to validate_uniqueness_of(:feature_name).scoped_to(:user_id).ignoring_case_sensitivity }
end
describe 'scopes' do
describe '.with_feature_name' do
let(:second_feature_name) { described_class.feature_names.keys.second }
let(:last_feature_name) { described_class.feature_names.keys.last }
it 'returns callout for requested feature name only' do
callout1 = create(:user_callout, feature_name: second_feature_name )
create(:user_callout, feature_name: last_feature_name )
callouts = described_class.with_feature_name(second_feature_name)
expect(callouts).to match_array([callout1])
end
end
describe '.with_dismissed_after' do
let(:some_feature_name) { described_class.feature_names.keys.second }
let(:callout_dismissed_month_ago) { create(:user_callout, feature_name: some_feature_name, dismissed_at: 1.month.ago )}
it 'does not return callouts dismissed before specified date' do
callouts = described_class.with_dismissed_after(15.days.ago)
expect(callouts).to match_array([])
end
it 'returns callouts dismissed after specified date' do
callouts = described_class.with_dismissed_after(2.months.ago)
expect(callouts).to match_array([callout_dismissed_month_ago])
end
end
end
end
Loading
Loading
@@ -4157,6 +4157,40 @@ describe User, :do_not_mock_admin_mode do
end
end
 
describe '#dismissed_callout?' do
subject(:user) { create(:user) }
let(:feature_name) { UserCallout.feature_names.keys.first }
context 'when no callout dismissal record exists' do
it 'returns false when no ignore_dismissal_earlier_than provided' do
expect(user.dismissed_callout?(feature_name: feature_name)).to eq false
end
it 'returns false when ignore_dismissal_earlier_than provided' do
expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
end
end
context 'when dismissed callout exists' do
before do
create(:user_callout, user: user, feature_name: feature_name, dismissed_at: 4.months.ago)
end
it 'returns true when no ignore_dismissal_earlier_than provided' do
expect(user.dismissed_callout?(feature_name: feature_name)).to eq true
end
it 'returns true when ignore_dismissal_earlier_than is earlier than dismissed_at' do
expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 6.months.ago)).to eq true
end
it 'returns false when ignore_dismissal_earlier_than is later than dismissed_at' do
expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
end
end
end
describe 'bots & humans' do
it 'returns corresponding users' do
human = create(:user)
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@ shared_examples 'project import rate limiter' do
post :create, params: {}
 
expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(302)
expect(response).to have_gitlab_http_status(:found)
end
end
end
Loading
Loading
@@ -41,7 +41,7 @@ module ApiHelpers
end
 
def expect_paginated_array_response(items)
expect(response).to have_gitlab_http_status(200)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |item| item['id'] }).to eq(Array(items))
Loading
Loading
Loading
Loading
@@ -28,6 +28,6 @@ module RackAttackSpecHelpers
def expect_rejection(&block)
yield
 
expect(response).to have_http_status(429)
expect(response).to have_gitlab_http_status(:too_many_requests)
end
end
Loading
Loading
@@ -2,7 +2,7 @@
 
require 'rake_helper'
 
describe 'gitlab:seed:group_seed rake task', :sidekiq do
describe 'gitlab:seed:group_seed rake task' do
let(:username) { 'group_seed' }
let!(:user) { create(:user, username: username) }
let(:task_params) { [2, username] }
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment