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

Add latest changes from gitlab-org/gitlab@master

parent 6763d278
No related branches found
No related tags found
No related merge requests found
Showing
with 519 additions and 58 deletions
Loading
Loading
@@ -17,7 +17,13 @@ GitLab monitors its own internal service metrics, and makes them available at th
`/-/metrics` endpoint. Unlike other [Prometheus](https://prometheus.io) exporters, in order to access
it, the client IP needs to be [included in a whitelist](../ip_whitelist.md).
 
For Omnibus and Chart installations, these metrics are automatically enabled and collected as of [GitLab 9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702). For source installations or earlier versions, these metrics will need to be enabled manually and collected by a Prometheus server.
For Omnibus and Chart installations, these metrics are automatically enabled
and collected as of [GitLab
9.4](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/1702). For
source installations or earlier versions, these metrics will need to be enabled
manually and collected by a Prometheus server.
See also [Sidekiq metrics](#sidekiq-metrics) for how to enable and view metrics from Sidekiq nodes.
 
## Metrics available
 
Loading
Loading
@@ -105,10 +111,12 @@ The following metrics can be controlled by feature flags:
| `gitlab_method_call_duration_seconds` | `prometheus_metrics_method_instrumentation` |
| `gitlab_view_rendering_duration_seconds` | `prometheus_metrics_view_instrumentation` |
 
## Sidekiq Metrics available for Geo **(PREMIUM)**
## Sidekiq metrics
 
Sidekiq jobs may also gather metrics, and these metrics can be accessed if the Sidekiq exporter is enabled (e.g. via
the `monitoring.sidekiq_exporter` configuration option in `gitlab.yml`.
Sidekiq jobs may also gather metrics, and these metrics can be accessed if the
Sidekiq exporter is enabled (for example, using the `monitoring.sidekiq_exporter`
configuration option in `gitlab.yml`. These metrics are served from the
`/metrics` path on the configured port.
 
| Metric | Type | Since | Description | Labels |
|:---------------------------------------------- |:------- |:----- |:----------- |:------ |
Loading
Loading
@@ -145,6 +153,7 @@ the `monitoring.sidekiq_exporter` configuration option in `gitlab.yml`.
| `geo_repositories_checked_failed_count` | Gauge | 11.1 | Number of repositories that have a failure from `git fsck` | url |
| `geo_repositories_retrying_verification_count` | Gauge | 11.2 | Number of repositories verification failures that Geo is actively trying to correct on secondary | url |
| `geo_wikis_retrying_verification_count` | Gauge | 11.2 | Number of wikis verification failures that Geo is actively trying to correct on secondary | url |
| `global_search_bulk_cron_queue_size` | Gauge | 12.10 | Number of database records waiting to be synchronized to Elasticsearch | |
 
## Database load balancing metrics **(PREMIUM ONLY)**
 
Loading
Loading
Loading
Loading
@@ -51,8 +51,6 @@ module Gitlab
end
 
def hash_of_the_latest_changes
return unless Feature.enabled?(:ci_file_based_cache, @pipeline.project, default_enabled: true)
ids = files.map { |path| last_commit_id_for_path(path) }
ids = ids.compact.sort.uniq
 
Loading
Loading
Loading
Loading
@@ -37,7 +37,7 @@ module Gitlab
case resource
when Hash
self.new(resource.symbolize_keys)
when ::HasVariable
when ::Ci::HasVariable
self.new(resource.to_runner_variable)
when self
resource.dup
Loading
Loading
Loading
Loading
@@ -4,7 +4,10 @@ import { visitUrl } from '~/lib/utils/url_utility';
import TableRow from '~/repository/components/table/row.vue';
import Icon from '~/vue_shared/components/icon.vue';
 
jest.mock('~/lib/utils/url_utility');
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
visitUrl: jest.fn(),
}));
 
let vm;
let $router;
Loading
Loading
Loading
Loading
@@ -204,7 +204,6 @@ describe BlobHelper do
end
 
describe '#show_suggest_pipeline_creation_celebration?' do
let(:blob) { fake_blob(path: Gitlab::FileDetector::PATTERNS[:gitlab_ci]) }
let(:current_user) { create(:user) }
 
before do
Loading
Loading
@@ -212,52 +211,68 @@ describe BlobHelper do
assign(:blob, blob)
assign(:commit, double('Commit', sha: 'whatever'))
helper.request.cookies["suggest_gitlab_ci_yml_commit_#{project.id}"] = 'true'
allow(blob).to receive(:auxiliary_viewer).and_return(double('viewer', valid?: true))
allow(helper).to receive(:current_user).and_return(current_user)
end
 
context 'experiment enabled' do
before do
allow(helper).to receive(:experiment_enabled?).and_return(true)
end
it 'is true' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_truthy
end
context 'when file is a pipeline config file' do
let(:data) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) }
let(:blob) { fake_blob(path: Gitlab::FileDetector::PATTERNS[:gitlab_ci], data: data) }
 
context 'file is invalid format' do
context 'experiment enabled' do
before do
allow(blob).to receive(:auxiliary_viewer).and_return(double('viewer', valid?: false))
allow(helper).to receive(:experiment_enabled?).and_return(true)
end
 
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
it 'is true' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_truthy
end
end
 
context 'path is not a ci file' do
before do
allow(blob).to receive(:path).and_return('something_bad')
context 'file is invalid format' do
let(:data) { 'foo' }
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
end
end
 
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
context 'does not use the default ci config' do
before do
project.ci_config_path = 'something_bad'
end
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
end
end
context 'does not have the needed cookie' do
before do
helper.request.cookies.delete "suggest_gitlab_ci_yml_commit_#{project.id}"
end
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
end
end
end
 
context 'does not use the default ci config' do
context 'experiment disabled' do
before do
project.ci_config_path = 'something_bad'
allow(helper).to receive(:experiment_enabled?).and_return(false)
end
 
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
end
end
end
 
context 'does not have the needed cookie' do
context 'when file is not a pipeline config file' do
let(:blob) { fake_blob(path: 'LICENSE') }
context 'experiment enabled' do
before do
helper.request.cookies.delete "suggest_gitlab_ci_yml_commit_#{project.id}"
allow(helper).to receive(:experiment_enabled?).and_return(true)
end
 
it 'is false' do
Loading
Loading
@@ -265,16 +280,6 @@ describe BlobHelper do
end
end
end
context 'experiment disabled' do
before do
allow(helper).to receive(:experiment_enabled?).and_return(false)
end
it 'is false' do
expect(helper.show_suggest_pipeline_creation_celebration?).to be_falsey
end
end
end
end
 
Loading
Loading
Loading
Loading
@@ -83,16 +83,6 @@ describe Gitlab::Ci::Pipeline::Seed::Build::Cache do
it_behaves_like 'version and gemfile files'
end
 
context 'with feature flag disabled' do
let(:files) { ['VERSION', 'Gemfile.zip'] }
before do
stub_feature_flags(ci_file_based_cache: false)
end
it_behaves_like 'default key'
end
context 'with files ending with /' do
let(:files) { ['Gemfile.zip/'] }
 
Loading
Loading
Loading
Loading
@@ -8,7 +8,7 @@ describe Ci::GroupVariable do
it_behaves_like "CI variable"
 
it { is_expected.to include_module(Presentable) }
it { is_expected.to include_module(Maskable) }
it { is_expected.to include_module(Ci::Maskable) }
it { is_expected.to validate_uniqueness_of(:key).scoped_to(:group_id).with_message(/\(\w+\) has already been taken/) }
 
describe '.unprotected' do
Loading
Loading
Loading
Loading
@@ -9,7 +9,7 @@ describe Ci::Variable do
 
describe 'validations' do
it { is_expected.to include_module(Presentable) }
it { is_expected.to include_module(Maskable) }
it { is_expected.to include_module(Ci::Maskable) }
it { is_expected.to include_module(HasEnvironmentScope) }
it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id, :environment_scope).with_message(/\(\w+\) has already been taken/) }
end
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
 
require 'spec_helper'
 
describe HasVariable do
describe Ci::HasVariable do
subject { build(:ci_variable) }
 
it { is_expected.to validate_presence_of(:key) }
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@
 
require 'spec_helper'
 
describe Maskable do
describe Ci::Maskable do
let(:variable) { build(:ci_variable) }
 
describe 'masked value validations' do
Loading
Loading
@@ -34,7 +34,7 @@ describe Maskable do
end
 
describe 'REGEX' do
subject { Maskable::REGEX }
subject { Ci::Maskable::REGEX }
 
it 'does not match strings shorter than 8 letters' do
expect(subject.match?('hello')).to eq(false)
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe JiraImportData do
let(:symbol_keys_project) do
{ key: 'AA', scheduled_at: 2.days.ago.strftime('%Y-%m-%d %H:%M:%S'), scheduled_by: { 'user_id' => 1, 'name' => 'tester1' } }
end
let(:string_keys_project) do
{ 'key': 'BB', 'scheduled_at': 1.hour.ago.strftime('%Y-%m-%d %H:%M:%S'), 'scheduled_by': { 'user_id': 2, 'name': 'tester2' } }
end
let(:jira_project_details) do
JiraImportData::JiraProjectDetails.new('CC', 1.day.ago.strftime('%Y-%m-%d %H:%M:%S'), { user_id: 3, name: 'tester3' })
end
describe '#projects' do
it 'returns empty array if no data' do
expect(described_class.new.projects).to eq([])
end
it 'returns empty array if no projects' do
import_data = described_class.new(data: { 'some-key' => 10 })
expect(import_data.projects).to eq([])
end
it 'returns JiraProjectDetails sorted by scheduled_at time' do
import_data = described_class.new(data: { jira: { projects: [symbol_keys_project, string_keys_project, jira_project_details] } })
expect(import_data.projects.size).to eq 3
expect(import_data.projects.map(&:key)).to eq(%w(AA CC BB))
expect(import_data.projects.map(&:scheduled_by).map {|e| e['name']}).to eq %w(tester1 tester3 tester2)
expect(import_data.projects.map(&:scheduled_by).map {|e| e['user_id']}).to eq [1, 3, 2]
end
end
describe 'add projects' do
it 'adds project when data is nil' do
import_data = described_class.new
expect(import_data.data).to be nil
import_data << string_keys_project
expect(import_data.data).to eq({ 'jira' => { 'projects' => [string_keys_project] } })
end
it 'adds project when data has some random info' do
import_data = described_class.new(data: { 'one-key': 10 })
expect(import_data.data).to eq({ 'one-key' => 10 })
import_data << string_keys_project
expect(import_data.data).to eq({ 'one-key' => 10, 'jira' => { 'projects' => [string_keys_project] } })
end
it 'adds project when data already has some jira projects' do
import_data = described_class.new(data: { jira: { projects: [symbol_keys_project] } })
expect(import_data.projects.map(&:to_h)).to eq [symbol_keys_project]
import_data << string_keys_project
expect(import_data.data['jira']['projects'].size).to eq 2
expect(import_data.projects.map(&:key)).to eq(%w(AA BB))
expect(import_data.projects.map(&:scheduled_by).map {|e| e['name']}).to eq %w(tester1 tester2)
expect(import_data.projects.map(&:scheduled_by).map {|e| e['user_id']}).to eq [1, 2]
end
end
describe '#force_import!' do
it 'sets force import when data is nil' do
import_data = described_class.new
import_data.force_import!
expect(import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be true
expect(import_data.force_import?).to be false
end
it 'sets force import when data is present but no jira key' do
import_data = described_class.new(data: { 'some-key': 'some-data' })
import_data.force_import!
expect(import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be true
expect(import_data.data).to eq({ 'some-key' => 'some-data', 'jira' => { JiraImportData::FORCE_IMPORT_KEY => true } })
expect(import_data.force_import?).to be false
end
it 'sets force import when data and jira keys exist' do
import_data = described_class.new(data: { 'some-key': 'some-data', 'jira': {} })
import_data.force_import!
expect(import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be true
expect(import_data.data).to eq({ 'some-key' => 'some-data', 'jira' => { JiraImportData::FORCE_IMPORT_KEY => true } })
expect(import_data.force_import?).to be false
end
it 'sets force import when data and jira project data exist' do
import_data = described_class.new(data: { jira: { projects: [symbol_keys_project], JiraImportData::FORCE_IMPORT_KEY => false }, 'some-key': 'some-data' })
import_data.force_import!
expect(import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be true
expect(import_data.data).to eq({ 'some-key' => 'some-data', 'jira' => { 'projects' => [symbol_keys_project.deep_stringify_keys!], JiraImportData::FORCE_IMPORT_KEY => true } })
expect(import_data.force_import?).to be true
end
end
describe '#force_import?' do
it 'returns false when data blank' do
expect(described_class.new.force_import?).to be false
end
it 'returns false if there is no project data present' do
import_data = described_class.new(data: { jira: { JiraImportData::FORCE_IMPORT_KEY => true }, 'one-key': 10 })
expect(import_data.force_import?).to be false
end
it 'returns false when force import set to false' do
import_data = described_class.new(data: { jira: { projects: [symbol_keys_project], JiraImportData::FORCE_IMPORT_KEY => false }, 'one-key': 10 })
expect(import_data.force_import?).to be false
end
it 'returns true when force import set to true' do
import_data = described_class.new(data: { jira: { projects: [symbol_keys_project], JiraImportData::FORCE_IMPORT_KEY => true } })
expect(import_data.force_import?).to be true
end
end
end
Loading
Loading
@@ -2353,6 +2353,63 @@ describe Project do
expect(project.add_import_job).to eq(import_jid)
end
end
context 'jira import' do
it 'schedules a jira import job' do
project = create(:project, import_type: 'jira')
expect(Gitlab::JiraImport::Stage::StartImportWorker).to receive(:perform_async).with(project.id).and_return(import_jid)
expect(project.add_import_job).to eq(import_jid)
end
end
end
describe '#jira_import?' do
subject(:project) { build(:project, import_type: 'jira') }
it { expect(project.jira_import?).to be true }
it { expect(project.import?).to be true }
end
describe '#jira_force_import?' do
let(:imported_jira_project) do
JiraImportData::JiraProjectDetails.new('xx', Time.now.strftime('%Y-%m-%d %H:%M:%S'), { user_id: 1, name: 'root' })
end
let(:jira_import_data) do
data = JiraImportData.new
data << imported_jira_project
data.force_import!
data
end
subject(:project) { build(:project, import_type: 'jira', import_data: jira_import_data) }
it { expect(project.jira_force_import?).to be true }
end
describe '#remove_import_data' do
let(:import_data) { ProjectImportData.new(data: { 'test' => 'some data' }) }
context 'when jira import' do
let!(:project) { create(:project, import_type: 'jira', import_data: import_data) }
it 'does not remove import data' do
expect(project.mirror?).to be false
expect(project.jira_import?).to be true
expect { project.remove_import_data }.not_to change { ProjectImportData.count }
end
end
context 'when not mirror neither jira import' do
let(:user) { create(:user) }
let!(:project) { create(:project, import_type: 'github', import_data: import_data) }
it 'removes import data' do
expect(project.mirror?).to be false
expect(project.jira_import?).to be false
expect { project.remove_import_data }.to change { ProjectImportData.count }.by(-1)
end
end
end
 
describe '#gitlab_project_import?' do
Loading
Loading
Loading
Loading
@@ -40,6 +40,16 @@ describe Milestones::TransferService do
expect(new_milestone.project_milestone?).to be_truthy
end
 
context 'when milestone is from an ancestor group' do
let(:old_group_ancestor) { create(:group) }
let(:old_group) { create(:group, parent: old_group_ancestor) }
let(:group_milestone) { create(:milestone, group: old_group_ancestor)}
it 'recreates the missing group milestones at project level' do
expect { service.execute }.to change(project.milestones, :count).by(1)
end
end
it 'deletes milestone issue counters cache for both milestones' do
new_milestone = create(:milestone, project: project, title: group_milestone.title)
 
Loading
Loading
# frozen_string_literal: true
 
RSpec.shared_examples 'CI variable' do
it { is_expected.to include_module(HasVariable) }
it { is_expected.to include_module(Ci::HasVariable) }
 
describe "variable type" do
it 'defines variable types' do
Loading
Loading
# frozen_string_literal: true
shared_examples 'include import workers modules' do
it { expect(described_class).to include_module(ApplicationWorker) }
it { expect(described_class).to include_module(Gitlab::JiraImport::QueueOptions) }
if described_class == Gitlab::JiraImport::Stage::StartImportWorker
it { expect(described_class).to include_module(ProjectStartImport) }
it { expect(described_class).to include_module(ProjectImportOptions) }
else
it { expect(described_class).to include_module(Gitlab::JiraImport::ImportWorker) }
end
end
shared_examples 'exit import not started' do
it 'does nothing, and exits' do
expect(Gitlab::JiraImport::AdvanceStageWorker).not_to receive(:perform_async)
worker.perform(project.id)
end
end
shared_examples 'advance to next stage' do |next_stage|
let(:job_waiter) { Gitlab::JobWaiter.new(2, 'some-job-key') }
it "advances to #{next_stage} stage" do
expect(Gitlab::JobWaiter).to receive(:new).and_return(job_waiter)
expect(Gitlab::JiraImport::AdvanceStageWorker).to receive(:perform_async).with(project.id, { job_waiter.key => job_waiter.jobs_remaining }, next_stage.to_sym)
worker.perform(project.id)
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::JiraImport::Stage::FinishImportWorker do
let(:project) { create(:project) }
let(:worker) { described_class.new }
describe 'modules' do
it_behaves_like 'include import workers modules'
end
describe '#perform' do
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: false)
end
it_behaves_like 'exit import not started'
end
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: true)
end
context 'when import did not start' do
let!(:import_state) { create(:import_state, project: project) }
it_behaves_like 'exit import not started'
end
context 'when import started' do
let(:imported_jira_project) do
JiraImportData::JiraProjectDetails.new('xx', Time.now.strftime('%Y-%m-%d %H:%M:%S'), { user_id: 1, name: 'root' })
end
let(:jira_import_data) do
data = JiraImportData.new
data << imported_jira_project
data.force_import!
data
end
let(:import_state) { create(:import_state, status: :started) }
let(:project) { create(:project, import_type: 'jira', import_data: jira_import_data, import_state: import_state) }
it 'changes import state to finished' do
worker.perform(project.id)
expect(project.reload.import_state.status).to eq "finished"
end
it 'removes force-import flag' do
expect(project.reload.import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be true
worker.perform(project.id)
expect(project.reload.import_data.data['jira'][JiraImportData::FORCE_IMPORT_KEY]).to be nil
expect(project.reload.import_data.data['jira']).not_to be nil
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::JiraImport::Stage::ImportAttachmentsWorker do
let(:project) { create(:project) }
let(:worker) { described_class.new }
describe 'modules' do
it_behaves_like 'include import workers modules'
end
describe '#perform' do
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: false)
end
it_behaves_like 'exit import not started'
end
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: true)
end
context 'when import did not start' do
let!(:import_state) { create(:import_state, project: project) }
it_behaves_like 'exit import not started'
end
context 'when import started' do
let!(:import_state) { create(:import_state, status: :started, project: project) }
it_behaves_like 'advance to next stage', :notes
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::JiraImport::Stage::ImportIssuesWorker do
let(:project) { create(:project) }
let(:worker) { described_class.new }
describe 'modules' do
it_behaves_like 'include import workers modules'
end
describe '#perform' do
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: false)
end
it_behaves_like 'exit import not started'
end
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: true)
end
context 'when import did not start' do
let!(:import_state) { create(:import_state, project: project) }
it_behaves_like 'exit import not started'
end
context 'when import started' do
let!(:import_state) { create(:import_state, status: :started, project: project) }
it_behaves_like 'advance to next stage', :attachments
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::JiraImport::Stage::ImportLabelsWorker do
let(:project) { create(:project) }
let(:worker) { described_class.new }
describe 'modules' do
it_behaves_like 'include import workers modules'
end
describe '#perform' do
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: false)
end
it_behaves_like 'exit import not started'
end
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: true)
end
context 'when import did not start' do
let!(:import_state) { create(:import_state, project: project) }
it_behaves_like 'exit import not started'
end
context 'when import started' do
let!(:import_state) { create(:import_state, status: :started, project: project) }
it_behaves_like 'advance to next stage', :issues
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::JiraImport::Stage::ImportNotesWorker do
let(:project) { create(:project) }
let(:worker) { described_class.new }
describe 'modules' do
it_behaves_like 'include import workers modules'
end
describe '#perform' do
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: false)
end
it_behaves_like 'exit import not started'
end
context 'when feature flag enabled' do
before do
stub_feature_flags(jira_issue_import: true)
end
context 'when import did not start' do
let!(:import_state) { create(:import_state, project: project) }
it_behaves_like 'exit import not started'
end
context 'when import started' do
let!(:import_state) { create(:import_state, status: :started, project: project) }
it_behaves_like 'advance to next stage', :finish
end
end
end
end
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