diff options
Diffstat (limited to 'spec/lib/gitlab')
354 files changed, 3406 insertions, 1272 deletions
diff --git a/spec/lib/gitlab/action_rate_limiter_spec.rb b/spec/lib/gitlab/action_rate_limiter_spec.rb index 542fc03e555..8dbad32dfb4 100644 --- a/spec/lib/gitlab/action_rate_limiter_spec.rb +++ b/spec/lib/gitlab/action_rate_limiter_spec.rb @@ -1,11 +1,11 @@ +# frozen_string_literal: true + require 'spec_helper' -describe Gitlab::ActionRateLimiter do +describe Gitlab::ActionRateLimiter, :clean_gitlab_redis_cache do let(:redis) { double('redis') } let(:user) { create(:user) } let(:project) { create(:project) } - let(:key) { [user, project] } - let(:cache_key) { "action_rate_limiter:test_action:user:#{user.id}:project:#{project.id}" } subject { described_class.new(action: :test_action, expiry_time: 100) } @@ -13,17 +13,98 @@ describe Gitlab::ActionRateLimiter do allow(Gitlab::Redis::Cache).to receive(:with).and_yield(redis) end - it 'increases the throttle count and sets the expire time' do - expect(redis).to receive(:incr).with(cache_key).and_return(1) - expect(redis).to receive(:expire).with(cache_key, 100) + shared_examples 'action rate limiter' do + it 'increases the throttle count and sets the expiration time' do + expect(redis).to receive(:incr).with(cache_key).and_return(1) + expect(redis).to receive(:expire).with(cache_key, 100) + + expect(subject.throttled?(key, 1)).to be_falsy + end + + it 'returns true if the key is throttled' do + expect(redis).to receive(:incr).with(cache_key).and_return(2) + expect(redis).not_to receive(:expire) - expect(subject.throttled?(key, 1)).to be false + expect(subject.throttled?(key, 1)).to be_truthy + end + + context 'when throttling is disabled' do + it 'returns false and does not set expiration time' do + expect(redis).not_to receive(:incr) + expect(redis).not_to receive(:expire) + + expect(subject.throttled?(key, 0)).to be_falsy + end + end end - it 'returns true if the key is throttled' do - expect(redis).to receive(:incr).with(cache_key).and_return(2) - expect(redis).not_to receive(:expire) + context 'when the key is an array of only ActiveRecord models' do + let(:key) { [user, project] } + + let(:cache_key) do + "action_rate_limiter:test_action:user:#{user.id}:project:#{project.id}" + end + + it_behaves_like 'action rate limiter' + end + + context 'when they key a combination of ActiveRecord models and strings' do + let(:project) { create(:project, :public, :repository) } + let(:commit) { project.repository.commit } + let(:path) { 'app/controllers/groups_controller.rb' } + let(:key) { [project, commit, path] } + + let(:cache_key) do + "action_rate_limiter:test_action:project:#{project.id}:commit:#{commit.sha}:#{path}" + end + + it_behaves_like 'action rate limiter' + end + + describe '#log_request' do + let(:file_path) { 'master/README.md' } + let(:type) { :raw_blob_request_limit } + let(:fullpath) { "/#{project.full_path}/raw/#{file_path}" } + + let(:request) do + double('request', ip: '127.0.0.1', request_method: 'GET', fullpath: fullpath) + end + + let(:base_attributes) do + { + message: 'Action_Rate_Limiter_Request', + env: type, + ip: '127.0.0.1', + request_method: 'GET', + fullpath: fullpath + } + end + + context 'without a current user' do + let(:current_user) { nil } + + it 'logs information to auth.log' do + expect(Gitlab::AuthLogger).to receive(:error).with(base_attributes).once + + subject.log_request(request, type, current_user) + end + end + + context 'with a current_user' do + let(:current_user) { create(:user) } + + let(:attributes) do + base_attributes.merge({ + user_id: current_user.id, + username: current_user.username + }) + end + + it 'logs information to auth.log' do + expect(Gitlab::AuthLogger).to receive(:error).with(attributes).once - expect(subject.throttled?(key, 1)).to be true + subject.log_request(request, type, current_user) + end + end end end diff --git a/spec/lib/gitlab/allowable_spec.rb b/spec/lib/gitlab/allowable_spec.rb index 9d80d480b52..4905cc4c3db 100644 --- a/spec/lib/gitlab/allowable_spec.rb +++ b/spec/lib/gitlab/allowable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Allowable do diff --git a/spec/lib/gitlab/app_logger_spec.rb b/spec/lib/gitlab/app_logger_spec.rb index c86d30ce6df..3b21104b15d 100644 --- a/spec/lib/gitlab/app_logger_spec.rb +++ b/spec/lib/gitlab/app_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::AppLogger, :request_store do diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb index 5293732ead1..7c65525b8dc 100644 --- a/spec/lib/gitlab/asciidoc_spec.rb +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'nokogiri' @@ -110,6 +112,56 @@ module Gitlab expect(render(input, context)).to include(output.strip) end + + it 'removes non footnote def ids' do + input = <<~ADOC + ++++ + <div id="def">Footnote definition</div> + ++++ + ADOC + + output = <<~HTML + <div>Footnote definition</div> + HTML + + expect(render(input, context)).to include(output.strip) + end + + it 'removes non footnote ref ids' do + input = <<~ADOC + ++++ + <a id="ref">Footnote reference</a> + ++++ + ADOC + + output = <<~HTML + <a>Footnote reference</a> + HTML + + expect(render(input, context)).to include(output.strip) + end + end + + context 'with footnotes' do + it 'preserves ids and links' do + input = <<~ADOC + This paragraph has a footnote.footnote:[This is the text of the footnote.] + ADOC + + output = <<~HTML + <div> + <p>This paragraph has a footnote.<sup>[<a id="_footnoteref_1" href="#_footnotedef_1" title="View footnote.">1</a>]</sup></p> + </div> + <div> + <hr> + <div id="_footnotedef_1"> + <a href="#_footnoteref_1">1</a>. This is the text of the footnote. + </div> + </div> + HTML + + expect(render(input, context)).to include(output.strip) + end end context 'with section anchors' do diff --git a/spec/lib/gitlab/auth/activity_spec.rb b/spec/lib/gitlab/auth/activity_spec.rb index 07854cb1eba..e03fafe3826 100644 --- a/spec/lib/gitlab/auth/activity_spec.rb +++ b/spec/lib/gitlab/auth/activity_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Auth::Activity do diff --git a/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb b/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb index f39863fdda1..52849f8c172 100644 --- a/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb +++ b/spec/lib/gitlab/auth/blocked_user_tracker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::BlockedUserTracker do diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb index 662f899180b..ecdd5b29986 100644 --- a/spec/lib/gitlab/auth/ldap/access_spec.rb +++ b/spec/lib/gitlab/auth/ldap/access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::Access do diff --git a/spec/lib/gitlab/auth/ldap/adapter_spec.rb b/spec/lib/gitlab/auth/ldap/adapter_spec.rb index 3eeaf3862f6..54486913b72 100644 --- a/spec/lib/gitlab/auth/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/auth/ldap/adapter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::Adapter do diff --git a/spec/lib/gitlab/auth/ldap/authentication_spec.rb b/spec/lib/gitlab/auth/ldap/authentication_spec.rb index 111572d043b..e68e83e4617 100644 --- a/spec/lib/gitlab/auth/ldap/authentication_spec.rb +++ b/spec/lib/gitlab/auth/ldap/authentication_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::Authentication do diff --git a/spec/lib/gitlab/auth/ldap/config_spec.rb b/spec/lib/gitlab/auth/ldap/config_spec.rb index b91a09e3137..577dfe51949 100644 --- a/spec/lib/gitlab/auth/ldap/config_spec.rb +++ b/spec/lib/gitlab/auth/ldap/config_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::Config do diff --git a/spec/lib/gitlab/auth/ldap/dn_spec.rb b/spec/lib/gitlab/auth/ldap/dn_spec.rb index f2983a02602..63656efba29 100644 --- a/spec/lib/gitlab/auth/ldap/dn_spec.rb +++ b/spec/lib/gitlab/auth/ldap/dn_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::DN do diff --git a/spec/lib/gitlab/auth/ldap/user_spec.rb b/spec/lib/gitlab/auth/ldap/user_spec.rb index 44bb9d20e47..bc09de7b525 100644 --- a/spec/lib/gitlab/auth/ldap/user_spec.rb +++ b/spec/lib/gitlab/auth/ldap/user_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::LDAP::User do diff --git a/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb index 40001cea22e..a2d9e27ea5b 100644 --- a/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/auth_hash_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::OAuth::AuthHash do @@ -13,13 +15,13 @@ describe Gitlab::Auth::OAuth::AuthHash do end let(:uid_raw) do - "CN=Onur K\xC3\xBC\xC3\xA7\xC3\xBCk,OU=Test,DC=example,DC=net" + +"CN=Onur K\xC3\xBC\xC3\xA7\xC3\xBCk,OU=Test,DC=example,DC=net" end - let(:email_raw) { "onur.k\xC3\xBC\xC3\xA7\xC3\xBCk_ABC-123@example.net" } - let(:nickname_raw) { "ok\xC3\xBC\xC3\xA7\xC3\xBCk" } - let(:first_name_raw) { 'Onur' } - let(:last_name_raw) { "K\xC3\xBC\xC3\xA7\xC3\xBCk" } - let(:name_raw) { "Onur K\xC3\xBC\xC3\xA7\xC3\xBCk" } + let(:email_raw) { +"onur.k\xC3\xBC\xC3\xA7\xC3\xBCk_ABC-123@example.net" } + let(:nickname_raw) { +"ok\xC3\xBC\xC3\xA7\xC3\xBCk" } + let(:first_name_raw) { +'Onur' } + let(:last_name_raw) { +"K\xC3\xBC\xC3\xA7\xC3\xBCk" } + let(:name_raw) { +"Onur K\xC3\xBC\xC3\xA7\xC3\xBCk" } let(:uid_ascii) { uid_raw.force_encoding(Encoding::ASCII_8BIT) } let(:email_ascii) { email_raw.force_encoding(Encoding::ASCII_8BIT) } @@ -40,7 +42,11 @@ describe Gitlab::Auth::OAuth::AuthHash do last_name: last_name_ascii, name: name_ascii, nickname: nickname_ascii, - uid: uid_ascii + uid: uid_ascii, + address: { + locality: 'some locality', + country: 'some country' + } } end @@ -51,6 +57,7 @@ describe Gitlab::Auth::OAuth::AuthHash do it { expect(auth_hash.username).to eql nickname_utf8 } it { expect(auth_hash.name).to eql name_utf8 } it { expect(auth_hash.password).not_to be_empty } + it { expect(auth_hash.location).to eq 'some locality, some country' } end context 'email not provided' do diff --git a/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb index bf810d72f0e..45c1baa4089 100644 --- a/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/identity_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::OAuth::IdentityLinker do diff --git a/spec/lib/gitlab/auth/o_auth/provider_spec.rb b/spec/lib/gitlab/auth/o_auth/provider_spec.rb index 80d702cf9dc..f46f9d76a1e 100644 --- a/spec/lib/gitlab/auth/o_auth/provider_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/provider_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::OAuth::Provider do diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb index b765c265e69..a9b15c411dc 100644 --- a/spec/lib/gitlab/auth/o_auth/user_spec.rb +++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::OAuth::User do diff --git a/spec/lib/gitlab/auth/request_authenticator_spec.rb b/spec/lib/gitlab/auth/request_authenticator_spec.rb index 3d979132880..f7fff389d88 100644 --- a/spec/lib/gitlab/auth/request_authenticator_spec.rb +++ b/spec/lib/gitlab/auth/request_authenticator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::RequestAuthenticator do diff --git a/spec/lib/gitlab/auth/saml/auth_hash_spec.rb b/spec/lib/gitlab/auth/saml/auth_hash_spec.rb index 3620e1afe25..13636a495d1 100644 --- a/spec/lib/gitlab/auth/saml/auth_hash_spec.rb +++ b/spec/lib/gitlab/auth/saml/auth_hash_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::Saml::AuthHash do diff --git a/spec/lib/gitlab/auth/saml/identity_linker_spec.rb b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb index f3305d574cc..89118ff05ba 100644 --- a/spec/lib/gitlab/auth/saml/identity_linker_spec.rb +++ b/spec/lib/gitlab/auth/saml/identity_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::Saml::IdentityLinker do diff --git a/spec/lib/gitlab/auth/saml/user_spec.rb b/spec/lib/gitlab/auth/saml/user_spec.rb index c523f5e177f..5546438b7ee 100644 --- a/spec/lib/gitlab/auth/saml/user_spec.rb +++ b/spec/lib/gitlab/auth/saml/user_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::Saml::User do diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb index 22708687a56..ebf7de9c701 100644 --- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb +++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::UniqueIpsLimiter, :clean_gitlab_redis_shared_state do diff --git a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb index 002ce776be9..8ec19c454d8 100644 --- a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb +++ b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::UserAccessDeniedReason do diff --git a/spec/lib/gitlab/auth/user_auth_finders_spec.rb b/spec/lib/gitlab/auth/user_auth_finders_spec.rb index 1e2aebdc84b..41265da97a4 100644 --- a/spec/lib/gitlab/auth/user_auth_finders_spec.rb +++ b/spec/lib/gitlab/auth/user_auth_finders_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth::UserAuthFinders do @@ -138,6 +140,20 @@ describe Gitlab::Auth::UserAuthFinders do expect { find_user_from_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError) end end + + context 'with OAuth headers' do + it 'returns user' do + env['HTTP_AUTHORIZATION'] = "Bearer #{personal_access_token.token}" + + expect(find_user_from_access_token).to eq user + end + + it 'returns exception if invalid personal_access_token' do + env['HTTP_AUTHORIZATION'] = 'Bearer invalid_20byte_token' + + expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError) + end + end end describe '#find_user_from_web_access_token' do diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index d9c73cff01e..edff38f05ec 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Auth do @@ -297,6 +299,70 @@ describe Gitlab::Auth do let(:project) { create(:project) } let(:auth_failure) { Gitlab::Auth::Result.new(nil, nil) } + context 'when deploy token and user have the same username' do + let(:username) { 'normal_user' } + let(:user) { create(:user, username: username, password: 'my-secret') } + let(:deploy_token) { create(:deploy_token, username: username, read_registry: false, projects: [project]) } + + before do + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: username) + end + + it 'succeeds for the token' do + auth_success = Gitlab::Auth::Result.new(deploy_token, project, :deploy_token, [:download_code]) + + expect(gl_auth.find_for_git_client(username, deploy_token.token, project: project, ip: 'ip')) + .to eq(auth_success) + end + + it 'succeeds for the user' do + auth_success = Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities) + + expect(gl_auth.find_for_git_client(username, 'my-secret', project: project, ip: 'ip')) + .to eq(auth_success) + end + end + + context 'when deploy tokens have the same username' do + context 'and belong to the same project' do + let!(:read_registry) { create(:deploy_token, username: 'deployer', read_repository: false, projects: [project]) } + let!(:read_repository) { create(:deploy_token, username: read_registry.username, read_registry: false, projects: [project]) } + + it 'succeeds for the right token' do + auth_success = Gitlab::Auth::Result.new(read_repository, project, :deploy_token, [:download_code]) + + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'deployer') + expect(gl_auth.find_for_git_client('deployer', read_repository.token, project: project, ip: 'ip')) + .to eq(auth_success) + end + + it 'fails for the wrong token' do + expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'deployer') + expect(gl_auth.find_for_git_client('deployer', read_registry.token, project: project, ip: 'ip')) + .to eq(auth_failure) + end + end + + context 'and belong to different projects' do + let!(:read_registry) { create(:deploy_token, username: 'deployer', read_repository: false, projects: [create(:project)]) } + let!(:read_repository) { create(:deploy_token, username: read_registry.username, read_registry: false, projects: [project]) } + + it 'succeeds for the right token' do + auth_success = Gitlab::Auth::Result.new(read_repository, project, :deploy_token, [:download_code]) + + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'deployer') + expect(gl_auth.find_for_git_client('deployer', read_repository.token, project: project, ip: 'ip')) + .to eq(auth_success) + end + + it 'fails for the wrong token' do + expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'deployer') + expect(gl_auth.find_for_git_client('deployer', read_registry.token, project: project, ip: 'ip')) + .to eq(auth_failure) + end + end + end + context 'when the deploy token has read_repository as scope' do let(:deploy_token) { create(:deploy_token, read_registry: false, projects: [project]) } let(:login) { deploy_token.username } diff --git a/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb b/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb index c43ed72038e..e299e2a366f 100644 --- a/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb +++ b/spec/lib/gitlab/background_migration/add_merge_request_diff_commits_count_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::AddMergeRequestDiffCommitsCount, :migration, schema: 20180105212544 do diff --git a/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb b/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb index 877c061d11b..2a7cffb2f3e 100644 --- a/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb +++ b/spec/lib/gitlab/background_migration/archive_legacy_traces_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::ArchiveLegacyTraces, :migration, schema: 20180529152628 do diff --git a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb index 1d9bac79dcd..3c2ed6d3a6d 100644 --- a/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb +++ b/spec/lib/gitlab/background_migration/encrypt_columns_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::EncryptColumns, :migration, schema: 20180910115836 do diff --git a/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb b/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb index 9d4921968b3..54af9807e7b 100644 --- a/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb +++ b/spec/lib/gitlab/background_migration/encrypt_runners_tokens_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::EncryptRunnersTokens, :migration, schema: 20181121111200 do diff --git a/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb b/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb index 20af63bc6c8..f3127cbf5df 100644 --- a/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb +++ b/spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, schema: 20180702120647 do @@ -75,7 +77,7 @@ describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, sch create_resource(target_type, 1, 2) end - it 'ignores label links referencing ancestor group labels', :nested_groups do + it 'ignores label links referencing ancestor group labels' do labels_table.create(id: 4, title: 'bug', color: 'red', project_id: 2, type: 'ProjectLabel') label_links_table.create(label_id: 4, target_type: target_type, target_id: 1) link = label_links_table.create(label_id: 1, target_type: target_type, target_id: 1) @@ -85,7 +87,7 @@ describe Gitlab::BackgroundMigration::FixCrossProjectLabelLinks, :migration, sch expect(link.reload.label_id).to eq(1) end - it 'checks also issues and MRs in subgroups', :nested_groups do + it 'checks also issues and MRs in subgroups' do link = label_links_table.create(label_id: 2, target_type: target_type, target_id: 1) subject.perform(1, 100) diff --git a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb index 582396275ed..a496f8416bf 100644 --- a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 20180212101928 do diff --git a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb b/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb index 2d1505dacfe..268626d58fd 100644 --- a/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::MigrateLegacyArtifacts, :migration, schema: 20180816161409 do diff --git a/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb b/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb index 4db829b1e7b..1a8b0355fd9 100644 --- a/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::MigrateStageIndex, :migration, schema: 20180420080616 do diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb index c76adcbe2f5..ea1eaa6417d 100644 --- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_untracked_uploads_dependencies/untracked_file_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' # Rollback DB to 10.5 (later than this was originally written for) because it still needs to work. diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb index 0dee683350f..44f537ca8dd 100644 --- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' # Rollback DB to 10.5 (later than this was originally written for) because it still needs to work. @@ -114,7 +116,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads, :sidekiq, :migra it 'does not drop the temporary tracking table after processing the batch, if there are still untracked rows' do subject.perform(1, untracked_files_for_uploads.last.id - 1) - expect(ActiveRecord::Base.connection.data_source_exists?(:untracked_files_for_uploads)).to be_truthy + expect(ActiveRecord::Base.connection.table_exists?(:untracked_files_for_uploads)).to be_truthy end it 'drops the temporary tracking table after processing the batch, if there are no untracked rows left' do diff --git a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb index 35750d89c35..591368ee98e 100644 --- a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb +++ b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' # Rollback DB to 10.5 (later than this was originally written for) because it still needs to work. diff --git a/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb b/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb index d494ce68c5b..f877e8cc1b8 100644 --- a/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb +++ b/spec/lib/gitlab/background_migration/schedule_calculate_wiki_sizes_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20190527194900_schedule_calculate_wiki_sizes.rb') diff --git a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb index 6f3fb994f17..3600755ada7 100644 --- a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb +++ b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnServices, :migration, schema: 20180122154930 do diff --git a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb index 82b484b7d5b..5cd9c02fd3f 100644 --- a/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb +++ b/spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration::SetConfidentialNoteEventsOnWebhooks, :migration, schema: 20180104131052 do diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb index 1d0ffb5e9df..8960ac706e6 100644 --- a/spec/lib/gitlab/background_migration_spec.rb +++ b/spec/lib/gitlab/background_migration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BackgroundMigration do diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb index 74eaf7eaf8b..2b87508bdef 100644 --- a/spec/lib/gitlab/badge/coverage/metadata_spec.rb +++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/badge/shared/metadata' diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb index da789bf3705..eee3f96ab85 100644 --- a/spec/lib/gitlab/badge/coverage/report_spec.rb +++ b/spec/lib/gitlab/badge/coverage/report_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Badge::Coverage::Report do diff --git a/spec/lib/gitlab/badge/coverage/template_spec.rb b/spec/lib/gitlab/badge/coverage/template_spec.rb index d9c21a22590..b51d707a61d 100644 --- a/spec/lib/gitlab/badge/coverage/template_spec.rb +++ b/spec/lib/gitlab/badge/coverage/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Badge::Coverage::Template do diff --git a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb index 9032a8e9016..b096803f921 100644 --- a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/badge/shared/metadata' diff --git a/spec/lib/gitlab/badge/pipeline/status_spec.rb b/spec/lib/gitlab/badge/pipeline/status_spec.rb index dc835375c66..684c6829879 100644 --- a/spec/lib/gitlab/badge/pipeline/status_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/status_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Badge::Pipeline::Status do diff --git a/spec/lib/gitlab/badge/pipeline/template_spec.rb b/spec/lib/gitlab/badge/pipeline/template_spec.rb index bcef0b7e120..c0aaa3d73e1 100644 --- a/spec/lib/gitlab/badge/pipeline/template_spec.rb +++ b/spec/lib/gitlab/badge/pipeline/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Badge::Pipeline::Template do diff --git a/spec/lib/gitlab/badge/shared/metadata.rb b/spec/lib/gitlab/badge/shared/metadata.rb index 63c7ca5a915..809fa54db02 100644 --- a/spec/lib/gitlab/badge/shared/metadata.rb +++ b/spec/lib/gitlab/badge/shared/metadata.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + shared_examples 'badge metadata' do describe '#to_html' do let(:html) { Nokogiri::HTML.parse(metadata.to_html) } diff --git a/spec/lib/gitlab/bare_repository_import/importer_spec.rb b/spec/lib/gitlab/bare_repository_import/importer_spec.rb index f4759b69538..0c1eedad7f4 100644 --- a/spec/lib/gitlab/bare_repository_import/importer_spec.rb +++ b/spec/lib/gitlab/bare_repository_import/importer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BareRepositoryImport::Importer, :seed_helper do @@ -103,7 +105,7 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do end end - context 'with subgroups', :nested_groups do + context 'with subgroups' do let(:project_path) { 'a-group/a-sub-group/a-project' } let(:existing_group) do @@ -188,20 +190,6 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do end end - context 'when subgroups are not available' do - let(:project_path) { 'a-group/a-sub-group/a-project' } - - before do - expect(Group).to receive(:supports_nested_objects?) { false } - end - - describe '#create_project_if_needed' do - it 'raises an error' do - expect { importer.create_project_if_needed }.to raise_error('Nested groups are not supported on MySQL') - end - end - end - def prepare_repository(project_path, source_project) repo_path = File.join(base_dir, project_path) diff --git a/spec/lib/gitlab/bare_repository_import/repository_spec.rb b/spec/lib/gitlab/bare_repository_import/repository_spec.rb index a07c5371134..0607e2232a1 100644 --- a/spec/lib/gitlab/bare_repository_import/repository_spec.rb +++ b/spec/lib/gitlab/bare_repository_import/repository_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe ::Gitlab::BareRepositoryImport::Repository do diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb index 35700e0b588..62b688d4d3e 100644 --- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BitbucketImport::Importer do diff --git a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb index e2bee22cf1f..0dd8547a925 100644 --- a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BitbucketImport::ProjectCreator do diff --git a/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb b/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb index 795fd069ab2..7b5c7847f2d 100644 --- a/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb +++ b/spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BitbucketImport::WikiFormatter do diff --git a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb index cc09804fd53..8ab7b2c5fa7 100644 --- a/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb +++ b/spec/lib/gitlab/bitbucket_server_import/importer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BitbucketServerImport::Importer do diff --git a/spec/lib/gitlab/blame_spec.rb b/spec/lib/gitlab/blame_spec.rb index 7cab04e9fc9..e1afd5b25bb 100644 --- a/spec/lib/gitlab/blame_spec.rb +++ b/spec/lib/gitlab/blame_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Blame do diff --git a/spec/lib/gitlab/build_access_spec.rb b/spec/lib/gitlab/build_access_spec.rb index 08f50bf4fac..b7af8ace5b5 100644 --- a/spec/lib/gitlab/build_access_spec.rb +++ b/spec/lib/gitlab/build_access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::BuildAccess do diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb index 972dd7e0d2b..91e7edaf704 100644 --- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb +++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do @@ -26,7 +28,6 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do end it 'loads 10 projects without hitting Gitaly call limit', :request_store do - allow(Gitlab::GitalyClient).to receive(:can_access_disk?).and_return(false) projects = Gitlab::GitalyClient.allow_n_plus_1_calls do (1..10).map { create(:project, :repository) } end diff --git a/spec/lib/gitlab/cache/request_cache_spec.rb b/spec/lib/gitlab/cache/request_cache_spec.rb index 5b82c216a13..70a7f090d0a 100644 --- a/spec/lib/gitlab/cache/request_cache_spec.rb +++ b/spec/lib/gitlab/cache/request_cache_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Cache::RequestCache do diff --git a/spec/lib/gitlab/changes_list_spec.rb b/spec/lib/gitlab/changes_list_spec.rb index 464508fcd73..911450f3a8b 100644 --- a/spec/lib/gitlab/changes_list_spec.rb +++ b/spec/lib/gitlab/changes_list_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" describe Gitlab::ChangesList do diff --git a/spec/lib/gitlab/chat_name_token_spec.rb b/spec/lib/gitlab/chat_name_token_spec.rb index 1e9fb9077fc..b2d4a466021 100644 --- a/spec/lib/gitlab/chat_name_token_spec.rb +++ b/spec/lib/gitlab/chat_name_token_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::ChatNameToken do diff --git a/spec/lib/gitlab/chat_spec.rb b/spec/lib/gitlab/chat_spec.rb index d61c4b36668..08cc16314c5 100644 --- a/spec/lib/gitlab/chat_spec.rb +++ b/spec/lib/gitlab/chat_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Chat, :use_clean_rails_memory_store_caching do diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb index 45fb33e9e4a..3a8e8f67e16 100644 --- a/spec/lib/gitlab/checks/change_access_spec.rb +++ b/spec/lib/gitlab/checks/change_access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Checks::ChangeAccess do diff --git a/spec/lib/gitlab/checks/force_push_spec.rb b/spec/lib/gitlab/checks/force_push_spec.rb index 0e0788ce974..9432be083d3 100644 --- a/spec/lib/gitlab/checks/force_push_spec.rb +++ b/spec/lib/gitlab/checks/force_push_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Checks::ForcePush do diff --git a/spec/lib/gitlab/checks/lfs_integrity_spec.rb b/spec/lib/gitlab/checks/lfs_integrity_spec.rb index 887ea8fc1e0..88e8f5d74d1 100644 --- a/spec/lib/gitlab/checks/lfs_integrity_spec.rb +++ b/spec/lib/gitlab/checks/lfs_integrity_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Checks::LfsIntegrity do diff --git a/spec/lib/gitlab/checks/project_created_spec.rb b/spec/lib/gitlab/checks/project_created_spec.rb index ac02007e111..14cb5e6ec66 100644 --- a/spec/lib/gitlab/checks/project_created_spec.rb +++ b/spec/lib/gitlab/checks/project_created_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do diff --git a/spec/lib/gitlab/checks/project_moved_spec.rb b/spec/lib/gitlab/checks/project_moved_spec.rb index 8e9386b1ba1..3ca977aa48d 100644 --- a/spec/lib/gitlab/checks/project_moved_spec.rb +++ b/spec/lib/gitlab/checks/project_moved_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do diff --git a/spec/lib/gitlab/ci/ansi2html_spec.rb b/spec/lib/gitlab/ci/ansi2html_spec.rb index 3d57ce431ab..eaf06ed8992 100644 --- a/spec/lib/gitlab/ci/ansi2html_spec.rb +++ b/spec/lib/gitlab/ci/ansi2html_spec.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Ansi2html do subject { described_class } it "prints non-ansi as-is" do - expect(convert_html("Hello")).to eq('<span class="">Hello</span>') + expect(convert_html("Hello")).to eq('<span>Hello</span>') end it "strips non-color-changing control sequences" do - expect(convert_html("Hello \e[2Kworld")).to eq('<span class="">Hello world</span>') + expect(convert_html("Hello \e[2Kworld")).to eq('<span>Hello world</span>') end it "prints simply red" do @@ -32,7 +34,7 @@ describe Gitlab::Ci::Ansi2html do end it "resets colors after red on blue" do - expect(convert_html("\e[31;44mHello\e[0m world")).to eq('<span class="term-fg-red term-bg-blue">Hello</span><span class=""> world</span>') + expect(convert_html("\e[31;44mHello\e[0m world")).to eq('<span class="term-fg-red term-bg-blue">Hello</span><span> world</span>') end it "performs color change from red/blue to yellow/blue" do @@ -44,11 +46,11 @@ describe Gitlab::Ci::Ansi2html do end it "performs color change from red/blue to reset to yellow/green" do - expect(convert_html("\e[31;44mHello\e[0m \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello</span><span class=""> </span><span class="term-fg-yellow term-bg-green">world</span>') + expect(convert_html("\e[31;44mHello\e[0m \e[33;42mworld")).to eq('<span class="term-fg-red term-bg-blue">Hello</span><span> </span><span class="term-fg-yellow term-bg-green">world</span>') end it "ignores unsupported codes" do - expect(convert_html("\e[51mHello\e[0m")).to eq('<span class="">Hello</span>') + expect(convert_html("\e[51mHello\e[0m")).to eq('<span>Hello</span>') end it "prints light red" do @@ -72,8 +74,8 @@ describe Gitlab::Ci::Ansi2html do end it "resets bold text" do - expect(convert_html("\e[1mHello\e[21m world")).to eq('<span class="term-bold">Hello</span><span class=""> world</span>') - expect(convert_html("\e[1mHello\e[22m world")).to eq('<span class="term-bold">Hello</span><span class=""> world</span>') + expect(convert_html("\e[1mHello\e[21m world")).to eq('<span class="term-bold">Hello</span><span> world</span>') + expect(convert_html("\e[1mHello\e[22m world")).to eq('<span class="term-bold">Hello</span><span> world</span>') end it "prints italic text" do @@ -81,7 +83,7 @@ describe Gitlab::Ci::Ansi2html do end it "resets italic text" do - expect(convert_html("\e[3mHello\e[23m world")).to eq('<span class="term-italic">Hello</span><span class=""> world</span>') + expect(convert_html("\e[3mHello\e[23m world")).to eq('<span class="term-italic">Hello</span><span> world</span>') end it "prints underlined text" do @@ -89,7 +91,7 @@ describe Gitlab::Ci::Ansi2html do end it "resets underlined text" do - expect(convert_html("\e[4mHello\e[24m world")).to eq('<span class="term-underline">Hello</span><span class=""> world</span>') + expect(convert_html("\e[4mHello\e[24m world")).to eq('<span class="term-underline">Hello</span><span> world</span>') end it "prints concealed text" do @@ -97,7 +99,7 @@ describe Gitlab::Ci::Ansi2html do end it "resets concealed text" do - expect(convert_html("\e[8mHello\e[28m world")).to eq('<span class="term-conceal">Hello</span><span class=""> world</span>') + expect(convert_html("\e[8mHello\e[28m world")).to eq('<span class="term-conceal">Hello</span><span> world</span>') end it "prints crossed-out text" do @@ -105,7 +107,7 @@ describe Gitlab::Ci::Ansi2html do end it "resets crossed-out text" do - expect(convert_html("\e[9mHello\e[29m world")).to eq('<span class="term-cross">Hello</span><span class=""> world</span>') + expect(convert_html("\e[9mHello\e[29m world")).to eq('<span class="term-cross">Hello</span><span> world</span>') end it "can print 256 xterm fg colors" do @@ -137,15 +139,15 @@ describe Gitlab::Ci::Ansi2html do end it "prints <" do - expect(convert_html("<")).to eq('<span class=""><</span>') + expect(convert_html("<")).to eq('<span><</span>') end it "replaces newlines with line break tags" do - expect(convert_html("\n")).to eq('<span class=""><br/><span class=""></span></span>') + expect(convert_html("\n")).to eq('<span><br/></span>') end it "groups carriage returns with newlines" do - expect(convert_html("\r\n")).to eq('<span class=""><br/><span class=""></span></span>') + expect(convert_html("\r\n")).to eq('<span><br/></span>') end describe "incremental update" do @@ -182,7 +184,7 @@ describe Gitlab::Ci::Ansi2html do context "with partial sequence" do let(:pre_text) { "Hello\e" } - let(:pre_html) { "<span class=\"\">Hello</span>" } + let(:pre_html) { "<span>Hello</span>" } let(:text) { "[1m World" } let(:html) { "<span class=\"term-bold\"> World</span>" } @@ -191,9 +193,9 @@ describe Gitlab::Ci::Ansi2html do context 'with new line' do let(:pre_text) { "Hello\r" } - let(:pre_html) { "<span class=\"\">Hello\r</span>" } + let(:pre_html) { "<span>Hello\r</span>" } let(:text) { "\nWorld" } - let(:html) { "<span class=\"\"><br/><span class=\"\">World</span></span>" } + let(:html) { "<span><br/>World</span>" } it_behaves_like 'stateable converter' end @@ -220,7 +222,7 @@ describe Gitlab::Ci::Ansi2html do text = "#{section_start}Some text#{section_end}" class_name_start = section_start.gsub("\033[0K", '').gsub('<', '<') class_name_end = section_end.gsub("\033[0K", '').gsub('<', '<') - html = %{<span class="">#{class_name_start}Some text#{class_name_end}</span>} + html = %{<span>#{class_name_start}Some text#{class_name_end}</span>} expect(convert_html(text)).to eq(html) end @@ -230,12 +232,11 @@ describe Gitlab::Ci::Ansi2html do let(:text) { "#{section_start}Some text#{section_end}" } it 'prints light red' do - text = "#{section_start}\e[91mHello\e[0m\n#{section_end}" + text = "#{section_start}\e[91mHello\e[0m\nLine 1\nLine 2\nLine 3\n#{section_end}" header = %{<span class="term-fg-l-red section js-section-header section-header js-s-#{class_name(section_name)}">Hello</span>} line_break = %{<span class="section js-section-header section-header js-s-#{class_name(section_name)}"><br/></span>} - line = %{<span class="section line s_#{class_name(section_name)}"></span>} - empty_line = %{<span class="section js-s-#{class_name(section_name)}"></span>} - html = "#{section_start_html}#{header}#{line_break}#{line}#{empty_line}#{section_end_html}" + output_line = %{<span class="section line js-s-#{class_name(section_name)}">Line 1<br/>Line 2<br/>Line 3<br/></span>} + html = "#{section_start_html}#{header}#{line_break}#{output_line}#{section_end_html}" expect(convert_html(text)).to eq(html) end diff --git a/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb index 987c6b37aaa..cec3e70bb9f 100644 --- a/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/adapters/gzip_stream_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Adapters::GzipStream do diff --git a/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb index ec2dd724b45..66a234232e1 100644 --- a/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/adapters/raw_stream_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Adapters::RawStream do diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb index 3b905611467..24d17eb0fb3 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb index a9a4af1f455..ff189c4701e 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Metadata do diff --git a/spec/lib/gitlab/ci/build/artifacts/path_spec.rb b/spec/lib/gitlab/ci/build/artifacts/path_spec.rb index 7bd6a2ead25..7bbef0f5197 100644 --- a/spec/lib/gitlab/ci/build/artifacts/path_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/path_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Artifacts::Path do diff --git a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb index d53db05e5e6..9148c0d579e 100644 --- a/spec/lib/gitlab/ci/build/credentials/factory_spec.rb +++ b/spec/lib/gitlab/ci/build/credentials/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Credentials::Factory do diff --git a/spec/lib/gitlab/ci/build/credentials/registry_spec.rb b/spec/lib/gitlab/ci/build/credentials/registry_spec.rb index c6054138cde..552580dcbbe 100644 --- a/spec/lib/gitlab/ci/build/credentials/registry_spec.rb +++ b/spec/lib/gitlab/ci/build/credentials/registry_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Credentials::Registry do diff --git a/spec/lib/gitlab/ci/build/image_spec.rb b/spec/lib/gitlab/ci/build/image_spec.rb index 6e20e0ef5c3..04bab9c58b8 100644 --- a/spec/lib/gitlab/ci/build/image_spec.rb +++ b/spec/lib/gitlab/ci/build/image_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Image do diff --git a/spec/lib/gitlab/ci/build/policy/changes_spec.rb b/spec/lib/gitlab/ci/build/policy/changes_spec.rb index 92cf0376c02..48ac2e4e657 100644 --- a/spec/lib/gitlab/ci/build/policy/changes_spec.rb +++ b/spec/lib/gitlab/ci/build/policy/changes_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Policy::Changes do diff --git a/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb b/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb index 4510b82ca9d..bc2e6fe6b8d 100644 --- a/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb +++ b/spec/lib/gitlab/ci/build/policy/kubernetes_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Policy::Kubernetes do diff --git a/spec/lib/gitlab/ci/build/policy/refs_spec.rb b/spec/lib/gitlab/ci/build/policy/refs_spec.rb index 22ca681cfd3..43c5d3ec980 100644 --- a/spec/lib/gitlab/ci/build/policy/refs_spec.rb +++ b/spec/lib/gitlab/ci/build/policy/refs_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Policy::Refs do diff --git a/spec/lib/gitlab/ci/build/policy/variables_spec.rb b/spec/lib/gitlab/ci/build/policy/variables_spec.rb index 9b016901a20..42a2a9fda2e 100644 --- a/spec/lib/gitlab/ci/build/policy/variables_spec.rb +++ b/spec/lib/gitlab/ci/build/policy/variables_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Policy::Variables do diff --git a/spec/lib/gitlab/ci/build/policy_spec.rb b/spec/lib/gitlab/ci/build/policy_spec.rb index 20ee3dd3e89..80d7b2e9dc8 100644 --- a/spec/lib/gitlab/ci/build/policy_spec.rb +++ b/spec/lib/gitlab/ci/build/policy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Policy do diff --git a/spec/lib/gitlab/ci/build/step_spec.rb b/spec/lib/gitlab/ci/build/step_spec.rb index e3136fc925e..84e6e0e177f 100644 --- a/spec/lib/gitlab/ci/build/step_spec.rb +++ b/spec/lib/gitlab/ci/build/step_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Build::Step do diff --git a/spec/lib/gitlab/ci/charts_spec.rb b/spec/lib/gitlab/ci/charts_spec.rb index 1668d3bbaac..cfb7a3f72fa 100644 --- a/spec/lib/gitlab/ci/charts_spec.rb +++ b/spec/lib/gitlab/ci/charts_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Charts do diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb index bd1f2c92844..a7f457e0f5e 100644 --- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Artifacts do diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index 8f711e02f9b..4cb63168ec7 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Cache do diff --git a/spec/lib/gitlab/ci/config/entry/commands_spec.rb b/spec/lib/gitlab/ci/config/entry/commands_spec.rb index 8934aeb83db..269a3406913 100644 --- a/spec/lib/gitlab/ci/config/entry/commands_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/commands_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Commands do diff --git a/spec/lib/gitlab/ci/config/entry/coverage_spec.rb b/spec/lib/gitlab/ci/config/entry/coverage_spec.rb index 4c6bd859552..48d0864cfca 100644 --- a/spec/lib/gitlab/ci/config/entry/coverage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/coverage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Coverage do diff --git a/spec/lib/gitlab/ci/config/entry/default_spec.rb b/spec/lib/gitlab/ci/config/entry/default_spec.rb index a901dd80c2c..27d63dbd407 100644 --- a/spec/lib/gitlab/ci/config/entry/default_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/default_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Default do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index 0bc9e8bd3cd..7b72b45fd8d 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Environment do diff --git a/spec/lib/gitlab/ci/config/entry/hidden_spec.rb b/spec/lib/gitlab/ci/config/entry/hidden_spec.rb index c88ee10550c..40b73352676 100644 --- a/spec/lib/gitlab/ci/config/entry/hidden_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/hidden_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Hidden do diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 1ebdda398b9..8de2e5de724 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Image do diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 25766d34c65..800ef122203 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Job do @@ -84,6 +86,22 @@ describe Gitlab::Ci::Config::Entry::Job do it { expect(entry).to be_valid } end end + + context 'when has needs' do + let(:config) do + { script: 'echo', needs: ['another-job'] } + end + + it { expect(entry).to be_valid } + + context 'when has dependencies' do + let(:config) do + { script: 'echo', dependencies: ['another-job'], needs: ['another-job'] } + end + + it { expect(entry).to be_valid } + end + end end context 'when entry value is not correct' do @@ -221,6 +239,43 @@ describe Gitlab::Ci::Config::Entry::Job do expect(entry.errors).to include 'job start in must be blank' end end + + context 'when has dependencies' do + context 'that are not a array of strings' do + let(:config) do + { script: 'echo', dependencies: 'build-job' } + end + + it 'returns error about invalid type' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job dependencies should be an array of strings' + end + end + end + + context 'when has needs' do + context 'that are not a array of strings' do + let(:config) do + { script: 'echo', needs: 'build-job' } + end + + it 'returns error about invalid type' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job needs should be an array of strings' + end + end + + context 'when have dependencies that are not subset of needs' do + let(:config) do + { script: 'echo', dependencies: ['another-job'], needs: ['build-job'] } + end + + it 'returns error about invalid data' do + expect(entry).not_to be_valid + expect(entry.errors).to include 'job dependencies the another-job should be part of needs' + end + end + end end end diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index 3e4137930dc..61c8956d41f 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Jobs do diff --git a/spec/lib/gitlab/ci/config/entry/key_spec.rb b/spec/lib/gitlab/ci/config/entry/key_spec.rb index 3cbf19bea8b..a7874447725 100644 --- a/spec/lib/gitlab/ci/config/entry/key_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/key_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Key do diff --git a/spec/lib/gitlab/ci/config/entry/paths_spec.rb b/spec/lib/gitlab/ci/config/entry/paths_spec.rb index 1d9c5ddee9b..221d5ae5863 100644 --- a/spec/lib/gitlab/ci/config/entry/paths_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/paths_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Paths do diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb index fba5671594d..266a27c1e47 100644 --- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require 'support/helpers/stub_feature_flags' require_dependency 'active_model' diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb index 38943138cbf..3c352c30e55 100644 --- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Reports do diff --git a/spec/lib/gitlab/ci/config/entry/retry_spec.rb b/spec/lib/gitlab/ci/config/entry/retry_spec.rb index 164a9ed4c3d..f9efd2e014d 100644 --- a/spec/lib/gitlab/ci/config/entry/retry_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/retry_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Retry do diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb index 7a252ed675a..968dbb9c7f2 100644 --- a/spec/lib/gitlab/ci/config/entry/root_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Root do diff --git a/spec/lib/gitlab/ci/config/entry/script_spec.rb b/spec/lib/gitlab/ci/config/entry/script_spec.rb index 069eaa26422..d523243d3b6 100644 --- a/spec/lib/gitlab/ci/config/entry/script_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/script_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Script do diff --git a/spec/lib/gitlab/ci/config/entry/service_spec.rb b/spec/lib/gitlab/ci/config/entry/service_spec.rb index d31866a1987..66cca100688 100644 --- a/spec/lib/gitlab/ci/config/entry/service_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Service do diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index d5a1316f665..764f783b083 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Services do diff --git a/spec/lib/gitlab/ci/config/entry/stage_spec.rb b/spec/lib/gitlab/ci/config/entry/stage_spec.rb index 70c8a0a355a..574fa00575a 100644 --- a/spec/lib/gitlab/ci/config/entry/stage_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Stage do diff --git a/spec/lib/gitlab/ci/config/entry/stages_spec.rb b/spec/lib/gitlab/ci/config/entry/stages_spec.rb index 182c8d867c7..97970522104 100644 --- a/spec/lib/gitlab/ci/config/entry/stages_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/stages_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Stages do diff --git a/spec/lib/gitlab/ci/config/entry/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/variables_spec.rb index 84bfef9e8ad..1320b366367 100644 --- a/spec/lib/gitlab/ci/config/entry/variables_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/variables_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config::Entry::Variables do diff --git a/spec/lib/gitlab/ci/config/extendable/entry_spec.rb b/spec/lib/gitlab/ci/config/extendable/entry_spec.rb index d63612053b6..e00104e3c68 100644 --- a/spec/lib/gitlab/ci/config/extendable/entry_spec.rb +++ b/spec/lib/gitlab/ci/config/extendable/entry_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Ci::Config::Extendable::Entry do diff --git a/spec/lib/gitlab/ci/config/extendable_spec.rb b/spec/lib/gitlab/ci/config/extendable_spec.rb index 90213f6603d..874b224067b 100644 --- a/spec/lib/gitlab/ci/config/extendable_spec.rb +++ b/spec/lib/gitlab/ci/config/extendable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Ci::Config::Extendable do diff --git a/spec/lib/gitlab/ci/config/normalizer_spec.rb b/spec/lib/gitlab/ci/config/normalizer_spec.rb index cd880177170..6b766cc37bf 100644 --- a/spec/lib/gitlab/ci/config/normalizer_spec.rb +++ b/spec/lib/gitlab/ci/config/normalizer_spec.rb @@ -49,37 +49,44 @@ describe Gitlab::Ci::Config::Normalizer do end end - context 'when jobs depend on parallelized jobs' do - let(:config) { { job_name => job_config, other_job: { script: 'echo 1', dependencies: [job_name.to_s] } } } - - it 'parallelizes dependencies' do - job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] - - expect(subject[:other_job][:dependencies]).to include(*job_names) + %i[dependencies needs].each do |context| + context "when job has #{context} on parallelized jobs" do + let(:config) do + { + job_name => job_config, + other_job: { script: 'echo 1', context => [job_name.to_s] } + } + end + + it "parallelizes #{context}" do + job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] + + expect(subject[:other_job][context]).to include(*job_names) + end + + it "does not include original job name in #{context}" do + expect(subject[:other_job][context]).not_to include(job_name) + end end - it 'does not include original job name in dependencies' do - expect(subject[:other_job][:dependencies]).not_to include(job_name) - end - end + context "when there are #{context} which are both parallelized and not" do + let(:config) do + { + job_name => job_config, + other_job: { script: 'echo 1' }, + final_job: { script: 'echo 1', context => [job_name.to_s, "other_job"] } + } + end - context 'when there are dependencies which are both parallelized and not' do - let(:config) do - { - job_name => job_config, - other_job: { script: 'echo 1' }, - final_job: { script: 'echo 1', dependencies: [job_name.to_s, "other_job"] } - } - end - - it 'parallelizes dependencies' do - job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] + it "parallelizes #{context}" do + job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] - expect(subject[:final_job][:dependencies]).to include(*job_names) - end + expect(subject[:final_job][context]).to include(*job_names) + end - it 'includes the regular job in dependencies' do - expect(subject[:final_job][:dependencies]).to include('other_job') + it "includes the regular job in #{context}" do + expect(subject[:final_job][context]).to include('other_job') + end end end end diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 4e8bff3d738..986cde3540a 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Config do diff --git a/spec/lib/gitlab/ci/cron_parser_spec.rb b/spec/lib/gitlab/ci/cron_parser_spec.rb index 491e3fba9d9..af4e9d687c4 100644 --- a/spec/lib/gitlab/ci/cron_parser_spec.rb +++ b/spec/lib/gitlab/ci/cron_parser_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::CronParser do diff --git a/spec/lib/gitlab/ci/mask_secret_spec.rb b/spec/lib/gitlab/ci/mask_secret_spec.rb index 3789a142248..6607aaae399 100644 --- a/spec/lib/gitlab/ci/mask_secret_spec.rb +++ b/spec/lib/gitlab/ci/mask_secret_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::MaskSecret do diff --git a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb index a49402c7398..8ff60710f67 100644 --- a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb +++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Ci::Parsers::Test::Junit do diff --git a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb index 50cb45c39d1..bf9ff922c05 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Build do diff --git a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb index 5181e9c1583..5775e934cfd 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/command_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Command do diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb index 0edc3f315bb..650ab193997 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Create do diff --git a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb index 0302e4090cf..9bccd5be4fe 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Populate do @@ -36,8 +38,8 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do it 'populates pipeline with stages' do expect(pipeline.stages).to be_one expect(pipeline.stages.first).not_to be_persisted - expect(pipeline.stages.first.builds).to be_one - expect(pipeline.stages.first.builds.first).not_to be_persisted + expect(pipeline.stages.first.statuses).to be_one + expect(pipeline.stages.first.statuses.first).not_to be_persisted end it 'correctly assigns user' do @@ -189,8 +191,8 @@ describe Gitlab::Ci::Pipeline::Chain::Populate do step.perform! expect(pipeline.stages.size).to eq 1 - expect(pipeline.stages.first.builds.size).to eq 1 - expect(pipeline.stages.first.builds.first.name).to eq 'rspec' + expect(pipeline.stages.first.statuses.size).to eq 1 + expect(pipeline.stages.first.statuses.first.name).to eq 'rspec' end end diff --git a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb index eca23694a2b..9cb59442dfd 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Sequence do diff --git a/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb index c7f4fc98ca3..fe46633ed1b 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Skip do diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb index b3e58c3dfdb..ac370433955 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb index 00bbc4c817a..79acd3e4f54 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Validate::Config do diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb index 2e8c9d70098..b866355906e 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/repository_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Chain::Validate::Repository do diff --git a/spec/lib/gitlab/ci/pipeline/duration_spec.rb b/spec/lib/gitlab/ci/pipeline/duration_spec.rb index 7c9836e2da6..a4984092f35 100644 --- a/spec/lib/gitlab/ci/pipeline/duration_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/duration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Duration do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb index 006ce4d8078..847d613dba3 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require 'rspec-parameterized' diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb index fcbd2863289..0e13681a4cf 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::Equals do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb index a6fdec832a3..4e4f1bf6ad3 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require_dependency 're2' diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb index 38d30c9035a..a3a48f83b27 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::NotEquals do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb index 99110ff8d88..6b81008ffb1 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require_dependency 're2' diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb index b5a59929e11..7013c6bacbb 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/null_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::Null do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb index d542eebc613..15505ebc82b 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require 'rspec-parameterized' diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb index 6ce4b321397..2cc25a07417 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/pattern_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::Pattern do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb index f54ef492e6d..2a6b90d127f 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/string_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::String do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb index 599a5411881..29e26930249 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexeme/variable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexeme::Variable do diff --git a/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb index 7c98e729b0b..2b0cee2d6f2 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/lexer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Expression::Lexer do diff --git a/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb index e88ec5561b6..10adfa18af6 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/parser_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Ci::Pipeline::Expression::Parser do diff --git a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb index b259ef711aa..79ee4d07e3a 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/statement_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' require 'rspec-parameterized' diff --git a/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb b/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb index cedfe270f9d..aa807cecb72 100644 --- a/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/expression/token_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'fast_spec_helper' describe Gitlab::Ci::Pipeline::Expression::Token do diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb index 7991e2f48b5..762025f9bd9 100644 --- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb @@ -1,32 +1,31 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Seed::Build do let(:project) { create(:project, :repository) } let(:pipeline) { create(:ci_empty_pipeline, project: project) } + let(:attributes) { { name: 'rspec', ref: 'master' } } + let(:previous_stages) { [] } - let(:attributes) do - { name: 'rspec', ref: 'master' } - end - - subject do - described_class.new(pipeline, attributes) - end + let(:seed_build) { described_class.new(pipeline, attributes, previous_stages) } describe '#attributes' do - it 'returns hash attributes of a build' do - expect(subject.attributes).to be_a Hash - expect(subject.attributes) - .to include(:name, :project, :ref) - end + subject { seed_build.attributes } + + it { is_expected.to be_a(Hash) } + it { is_expected.to include(:name, :project, :ref) } end describe '#bridge?' do + subject { seed_build.bridge? } + context 'when job is a bridge' do let(:attributes) do { name: 'rspec', ref: 'master', options: { trigger: 'my/project' } } end - it { is_expected.to be_bridge } + it { is_expected.to be_truthy } end context 'when trigger definition is empty' do @@ -34,20 +33,20 @@ describe Gitlab::Ci::Pipeline::Seed::Build do { name: 'rspec', ref: 'master', options: { trigger: '' } } end - it { is_expected.not_to be_bridge } + it { is_expected.to be_falsey } end context 'when job is not a bridge' do - it { is_expected.not_to be_bridge } + it { is_expected.to be_falsey } end end describe '#to_resource' do + subject { seed_build.to_resource } + context 'when job is not a bridge' do - it 'returns a valid build resource' do - expect(subject.to_resource).to be_a(::Ci::Build) - expect(subject.to_resource).to be_valid - end + it { is_expected.to be_a(::Ci::Build) } + it { is_expected.to be_valid } end context 'when job is a bridge' do @@ -55,71 +54,117 @@ describe Gitlab::Ci::Pipeline::Seed::Build do { name: 'rspec', ref: 'master', options: { trigger: 'my/project' } } end - it 'returns a valid bridge resource' do - expect(subject.to_resource).to be_a(::Ci::Bridge) - expect(subject.to_resource).to be_valid - end + it { is_expected.to be_a(::Ci::Bridge) } + it { is_expected.to be_valid } end it 'memoizes a resource object' do - build = subject.to_resource - - expect(build.object_id).to eq subject.to_resource.object_id + expect(subject.object_id).to eq seed_build.to_resource.object_id end it 'can not be persisted without explicit assignment' do - build = subject.to_resource - pipeline.save! - expect(build).not_to be_persisted + expect(subject).not_to be_persisted end end - describe 'applying only/except policies' do + describe 'applying job inclusion policies' do + subject { seed_build } + context 'when no branch policy is specified' do - let(:attributes) { { name: 'rspec' } } + let(:attributes) do + { name: 'rspec' } + end it { is_expected.to be_included } end context 'when branch policy does not match' do context 'when using only' do - let(:attributes) { { name: 'rspec', only: { refs: ['deploy'] } } } + let(:attributes) do + { name: 'rspec', only: { refs: ['deploy'] } } + end it { is_expected.not_to be_included } end context 'when using except' do - let(:attributes) { { name: 'rspec', except: { refs: ['deploy'] } } } + let(:attributes) do + { name: 'rspec', except: { refs: ['deploy'] } } + end it { is_expected.to be_included } end + + context 'with both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[deploy] }, + except: { refs: %w[deploy] } + } + end + + it { is_expected.not_to be_included } + end end context 'when branch regexp policy does not match' do context 'when using only' do - let(:attributes) { { name: 'rspec', only: { refs: ['/^deploy$/'] } } } + let(:attributes) do + { name: 'rspec', only: { refs: %w[/^deploy$/] } } + end it { is_expected.not_to be_included } end context 'when using except' do - let(:attributes) { { name: 'rspec', except: { refs: ['/^deploy$/'] } } } + let(:attributes) do + { name: 'rspec', except: { refs: %w[/^deploy$/] } } + end it { is_expected.to be_included } end + + context 'with both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[/^deploy$/] }, + except: { refs: %w[/^deploy$/] } + } + end + + it { is_expected.not_to be_included } + end end context 'when branch policy matches' do context 'when using only' do - let(:attributes) { { name: 'rspec', only: { refs: %w[deploy master] } } } + let(:attributes) do + { name: 'rspec', only: { refs: %w[deploy master] } } + end it { is_expected.to be_included } end context 'when using except' do - let(:attributes) { { name: 'rspec', except: { refs: %w[deploy master] } } } + let(:attributes) do + { name: 'rspec', except: { refs: %w[deploy master] } } + end + + it { is_expected.not_to be_included } + end + + context 'when using both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[deploy master] }, + except: { refs: %w[deploy master] } + } + end it { is_expected.not_to be_included } end @@ -127,13 +172,29 @@ describe Gitlab::Ci::Pipeline::Seed::Build do context 'when keyword policy matches' do context 'when using only' do - let(:attributes) { { name: 'rspec', only: { refs: ['branches'] } } } + let(:attributes) do + { name: 'rspec', only: { refs: %w[branches] } } + end it { is_expected.to be_included } end context 'when using except' do - let(:attributes) { { name: 'rspec', except: { refs: ['branches'] } } } + let(:attributes) do + { name: 'rspec', except: { refs: %w[branches] } } + end + + it { is_expected.not_to be_included } + end + + context 'when using both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[branches] }, + except: { refs: %w[branches] } + } + end it { is_expected.not_to be_included } end @@ -141,50 +202,78 @@ describe Gitlab::Ci::Pipeline::Seed::Build do context 'when keyword policy does not match' do context 'when using only' do - let(:attributes) { { name: 'rspec', only: { refs: ['tags'] } } } + let(:attributes) do + { name: 'rspec', only: { refs: %w[tags] } } + end it { is_expected.not_to be_included } end context 'when using except' do - let(:attributes) { { name: 'rspec', except: { refs: ['tags'] } } } + let(:attributes) do + { name: 'rspec', except: { refs: %w[tags] } } + end it { is_expected.to be_included } end + + context 'when using both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[tags] }, + except: { refs: %w[tags] } + } + end + + it { is_expected.not_to be_included } + end end context 'with source-keyword policy' do using RSpec::Parameterized - let(:pipeline) { build(:ci_empty_pipeline, ref: 'deploy', tag: false, source: source) } + let(:pipeline) do + build(:ci_empty_pipeline, ref: 'deploy', tag: false, source: source) + end context 'matches' do where(:keyword, :source) do [ - %w(pushes push), - %w(web web), - %w(triggers trigger), - %w(schedules schedule), - %w(api api), - %w(external external) + %w[pushes push], + %w[web web], + %w[triggers trigger], + %w[schedules schedule], + %w[api api], + %w[external external] ] end with_them do context 'using an only policy' do - let(:attributes) { { name: 'rspec', only: { refs: [keyword] } } } + let(:attributes) do + { name: 'rspec', only: { refs: [keyword] } } + end it { is_expected.to be_included } end context 'using an except policy' do - let(:attributes) { { name: 'rspec', except: { refs: [keyword] } } } + let(:attributes) do + { name: 'rspec', except: { refs: [keyword] } } + end it { is_expected.not_to be_included } end context 'using both only and except policies' do - let(:attributes) { { name: 'rspec', only: { refs: [keyword] }, except: { refs: [keyword] } } } + let(:attributes) do + { + name: 'rspec', + only: { refs: [keyword] }, + except: { refs: [keyword] } + } + end it { is_expected.not_to be_included } end @@ -193,29 +282,39 @@ describe Gitlab::Ci::Pipeline::Seed::Build do context 'non-matches' do where(:keyword, :source) do - %w(web trigger schedule api external).map { |source| ['pushes', source] } + - %w(push trigger schedule api external).map { |source| ['web', source] } + - %w(push web schedule api external).map { |source| ['triggers', source] } + - %w(push web trigger api external).map { |source| ['schedules', source] } + - %w(push web trigger schedule external).map { |source| ['api', source] } + - %w(push web trigger schedule api).map { |source| ['external', source] } + %w[web trigger schedule api external].map { |source| ['pushes', source] } + + %w[push trigger schedule api external].map { |source| ['web', source] } + + %w[push web schedule api external].map { |source| ['triggers', source] } + + %w[push web trigger api external].map { |source| ['schedules', source] } + + %w[push web trigger schedule external].map { |source| ['api', source] } + + %w[push web trigger schedule api].map { |source| ['external', source] } end with_them do context 'using an only policy' do - let(:attributes) { { name: 'rspec', only: { refs: [keyword] } } } + let(:attributes) do + { name: 'rspec', only: { refs: [keyword] } } + end it { is_expected.not_to be_included } end context 'using an except policy' do - let(:attributes) { { name: 'rspec', except: { refs: [keyword] } } } + let(:attributes) do + { name: 'rspec', except: { refs: [keyword] } } + end it { is_expected.to be_included } end context 'using both only and except policies' do - let(:attributes) { { name: 'rspec', only: { refs: [keyword] }, except: { refs: [keyword] } } } + let(:attributes) do + { + name: 'rspec', + only: { refs: [keyword] }, + except: { refs: [keyword] } + } + end it { is_expected.not_to be_included } end @@ -239,12 +338,24 @@ describe Gitlab::Ci::Pipeline::Seed::Build do it { is_expected.not_to be_included } end + + context 'when using both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: ["branches@#{pipeline.project_full_path}"] }, + except: { refs: ["branches@#{pipeline.project_full_path}"] } + } + end + + it { is_expected.not_to be_included } + end end context 'when repository path does not matches' do context 'when using only' do let(:attributes) do - { name: 'rspec', only: { refs: ['branches@fork'] } } + { name: 'rspec', only: { refs: %w[branches@fork] } } end it { is_expected.not_to be_included } @@ -252,11 +363,58 @@ describe Gitlab::Ci::Pipeline::Seed::Build do context 'when using except' do let(:attributes) do - { name: 'rspec', except: { refs: ['branches@fork'] } } + { name: 'rspec', except: { refs: %w[branches@fork] } } end it { is_expected.to be_included } end + + context 'when using both only and except policies' do + let(:attributes) do + { + name: 'rspec', + only: { refs: %w[branches@fork] }, + except: { refs: %w[branches@fork] } + } + end + + it { is_expected.not_to be_included } + end + end + end + + describe 'applying needs: dependency' do + subject { seed_build } + + let(:attributes) do + { + name: 'rspec', + needs_attributes: [{ + name: 'build' + }] + } + end + + context 'when build job is not present in prior stages' do + it { is_expected.not_to be_included } + end + + context 'when build job is part of prior stages' do + let(:stage_attributes) do + { + name: 'build', + index: 0, + builds: [{ name: 'build' }] + } + end + + let(:stage_seed) do + Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline, stage_attributes, []) + end + + let(:previous_stages) { [stage_seed] } + + it { is_expected.to be_included } end end end diff --git a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb index 493ca3cd7b5..6fba9f37d91 100644 --- a/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/seed/stage_spec.rb @@ -1,8 +1,11 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Pipeline::Seed::Stage do let(:project) { create(:project, :repository) } let(:pipeline) { create(:ci_empty_pipeline, project: project) } + let(:previous_stages) { [] } let(:attributes) do { name: 'test', @@ -13,7 +16,7 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do end subject do - described_class.new(pipeline, attributes) + described_class.new(pipeline, attributes, previous_stages) end describe '#size' do @@ -107,6 +110,17 @@ describe Gitlab::Ci::Pipeline::Seed::Stage do end end + describe '#seeds_names' do + it 'returns all job names' do + expect(subject.seeds_names).to contain_exactly( + 'rspec', 'spinach') + end + + it 'returns a set' do + expect(subject.seeds_names).to be_a(Set) + end + end + describe '#to_resource' do it 'builds a valid stage object with all builds' do subject.to_resource.save! diff --git a/spec/lib/gitlab/ci/reports/test_case_spec.rb b/spec/lib/gitlab/ci/reports/test_case_spec.rb index 6932f79f0ce..20c489ee94c 100644 --- a/spec/lib/gitlab/ci/reports/test_case_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_case_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Reports::TestCase do diff --git a/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb b/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb index 36582204cc1..48eef0643b2 100644 --- a/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_reports_comparer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Reports::TestReportsComparer do diff --git a/spec/lib/gitlab/ci/reports/test_reports_spec.rb b/spec/lib/gitlab/ci/reports/test_reports_spec.rb index 74ff134b239..0b5d05bada3 100644 --- a/spec/lib/gitlab/ci/reports/test_reports_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_reports_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Reports::TestReports do diff --git a/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb b/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb index 579b3e6fd24..cf4690bb334 100644 --- a/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_suite_comparer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Reports::TestSuiteComparer do diff --git a/spec/lib/gitlab/ci/reports/test_suite_spec.rb b/spec/lib/gitlab/ci/reports/test_suite_spec.rb index cd34dbaf62f..8646db43bc8 100644 --- a/spec/lib/gitlab/ci/reports/test_suite_spec.rb +++ b/spec/lib/gitlab/ci/reports/test_suite_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Reports::TestSuite do diff --git a/spec/lib/gitlab/ci/status/build/action_spec.rb b/spec/lib/gitlab/ci/status/build/action_spec.rb index bdec582b57b..3aae7e18d6d 100644 --- a/spec/lib/gitlab/ci/status/build/action_spec.rb +++ b/spec/lib/gitlab/ci/status/build/action_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Action do diff --git a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb index 78d6fa65b5a..3841dae91c7 100644 --- a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb +++ b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Cancelable do diff --git a/spec/lib/gitlab/ci/status/build/canceled_spec.rb b/spec/lib/gitlab/ci/status/build/canceled_spec.rb index c6b5cc68770..4b43c78f1a7 100644 --- a/spec/lib/gitlab/ci/status/build/canceled_spec.rb +++ b/spec/lib/gitlab/ci/status/build/canceled_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Canceled do diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index ca3c66f0152..5114540708f 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Common do diff --git a/spec/lib/gitlab/ci/status/build/created_spec.rb b/spec/lib/gitlab/ci/status/build/created_spec.rb index 8bdfe6ef7a2..6e3aa442810 100644 --- a/spec/lib/gitlab/ci/status/build/created_spec.rb +++ b/spec/lib/gitlab/ci/status/build/created_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Created do diff --git a/spec/lib/gitlab/ci/status/build/erased_spec.rb b/spec/lib/gitlab/ci/status/build/erased_spec.rb index 0acd271e375..af9c296da0c 100644 --- a/spec/lib/gitlab/ci/status/build/erased_spec.rb +++ b/spec/lib/gitlab/ci/status/build/erased_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Erased do diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index b6231510b91..de489fa4664 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Factory do diff --git a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb index 2a5915d75d0..01500689619 100644 --- a/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb +++ b/spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::FailedAllowed do diff --git a/spec/lib/gitlab/ci/status/build/failed_spec.rb b/spec/lib/gitlab/ci/status/build/failed_spec.rb index e424270f7c5..78f5214ca81 100644 --- a/spec/lib/gitlab/ci/status/build/failed_spec.rb +++ b/spec/lib/gitlab/ci/status/build/failed_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Failed do diff --git a/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb b/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb index a4854bdc6b9..19a3c82eac7 100644 --- a/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb +++ b/spec/lib/gitlab/ci/status/build/failed_unmet_prerequisites_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Gitlab::Ci::Status::Build::FailedUnmetPrerequisites do diff --git a/spec/lib/gitlab/ci/status/build/manual_spec.rb b/spec/lib/gitlab/ci/status/build/manual_spec.rb index 6386296f992..bffe2c10d12 100644 --- a/spec/lib/gitlab/ci/status/build/manual_spec.rb +++ b/spec/lib/gitlab/ci/status/build/manual_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Manual do diff --git a/spec/lib/gitlab/ci/status/build/pending_spec.rb b/spec/lib/gitlab/ci/status/build/pending_spec.rb index 4cf70828e53..64d57954c15 100644 --- a/spec/lib/gitlab/ci/status/build/pending_spec.rb +++ b/spec/lib/gitlab/ci/status/build/pending_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Pending do diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb index 02f8c4c114b..bb12a900b55 100644 --- a/spec/lib/gitlab/ci/status/build/play_spec.rb +++ b/spec/lib/gitlab/ci/status/build/play_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Play do diff --git a/spec/lib/gitlab/ci/status/build/retried_spec.rb b/spec/lib/gitlab/ci/status/build/retried_spec.rb index 76c2fb01e3f..fce497d40a1 100644 --- a/spec/lib/gitlab/ci/status/build/retried_spec.rb +++ b/spec/lib/gitlab/ci/status/build/retried_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Retried do diff --git a/spec/lib/gitlab/ci/status/build/retryable_spec.rb b/spec/lib/gitlab/ci/status/build/retryable_spec.rb index 84d98588f2d..5b0ae315927 100644 --- a/spec/lib/gitlab/ci/status/build/retryable_spec.rb +++ b/spec/lib/gitlab/ci/status/build/retryable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Retryable do diff --git a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb index 68b87fea75d..8f87da10815 100644 --- a/spec/lib/gitlab/ci/status/build/scheduled_spec.rb +++ b/spec/lib/gitlab/ci/status/build/scheduled_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Scheduled do diff --git a/spec/lib/gitlab/ci/status/build/skipped_spec.rb b/spec/lib/gitlab/ci/status/build/skipped_spec.rb index 46f6933025a..7ce5142da78 100644 --- a/spec/lib/gitlab/ci/status/build/skipped_spec.rb +++ b/spec/lib/gitlab/ci/status/build/skipped_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Skipped do diff --git a/spec/lib/gitlab/ci/status/build/stop_spec.rb b/spec/lib/gitlab/ci/status/build/stop_spec.rb index 5b7534c96c1..d3e98400a53 100644 --- a/spec/lib/gitlab/ci/status/build/stop_spec.rb +++ b/spec/lib/gitlab/ci/status/build/stop_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Stop do diff --git a/spec/lib/gitlab/ci/status/build/unschedule_spec.rb b/spec/lib/gitlab/ci/status/build/unschedule_spec.rb index ed046d66ca5..c18fc3252b4 100644 --- a/spec/lib/gitlab/ci/status/build/unschedule_spec.rb +++ b/spec/lib/gitlab/ci/status/build/unschedule_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Build::Unschedule do diff --git a/spec/lib/gitlab/ci/status/canceled_spec.rb b/spec/lib/gitlab/ci/status/canceled_spec.rb index dc74d7e28c5..6cfcea4fdde 100644 --- a/spec/lib/gitlab/ci/status/canceled_spec.rb +++ b/spec/lib/gitlab/ci/status/canceled_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Canceled do diff --git a/spec/lib/gitlab/ci/status/created_spec.rb b/spec/lib/gitlab/ci/status/created_spec.rb index ce4333f2aca..aeb41e9cfc3 100644 --- a/spec/lib/gitlab/ci/status/created_spec.rb +++ b/spec/lib/gitlab/ci/status/created_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Created do diff --git a/spec/lib/gitlab/ci/status/extended_spec.rb b/spec/lib/gitlab/ci/status/extended_spec.rb index 6eacb07078b..8accfc4a2f9 100644 --- a/spec/lib/gitlab/ci/status/extended_spec.rb +++ b/spec/lib/gitlab/ci/status/extended_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Extended do diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 0d02c371a92..983522fa2d6 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::External::Common do diff --git a/spec/lib/gitlab/ci/status/external/factory_spec.rb b/spec/lib/gitlab/ci/status/external/factory_spec.rb index 529d02a3e39..3b90fb60cca 100644 --- a/spec/lib/gitlab/ci/status/external/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/external/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::External::Factory do diff --git a/spec/lib/gitlab/ci/status/factory_spec.rb b/spec/lib/gitlab/ci/status/factory_spec.rb index bbf9c7c83a3..b51c0bec47e 100644 --- a/spec/lib/gitlab/ci/status/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Factory do diff --git a/spec/lib/gitlab/ci/status/failed_spec.rb b/spec/lib/gitlab/ci/status/failed_spec.rb index a4a92117c7f..5c7393fc8cf 100644 --- a/spec/lib/gitlab/ci/status/failed_spec.rb +++ b/spec/lib/gitlab/ci/status/failed_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Failed do diff --git a/spec/lib/gitlab/ci/status/group/common_spec.rb b/spec/lib/gitlab/ci/status/group/common_spec.rb index c0ca05881f5..35fff30ea9d 100644 --- a/spec/lib/gitlab/ci/status/group/common_spec.rb +++ b/spec/lib/gitlab/ci/status/group/common_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Group::Common do diff --git a/spec/lib/gitlab/ci/status/group/factory_spec.rb b/spec/lib/gitlab/ci/status/group/factory_spec.rb index 0cd83123938..be76a1d5a65 100644 --- a/spec/lib/gitlab/ci/status/group/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/group/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Group::Factory do diff --git a/spec/lib/gitlab/ci/status/manual_spec.rb b/spec/lib/gitlab/ci/status/manual_spec.rb index 0463f2e1aff..0839452ec22 100644 --- a/spec/lib/gitlab/ci/status/manual_spec.rb +++ b/spec/lib/gitlab/ci/status/manual_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Manual do diff --git a/spec/lib/gitlab/ci/status/pending_spec.rb b/spec/lib/gitlab/ci/status/pending_spec.rb index 0e25358dd8a..5f830e5bb56 100644 --- a/spec/lib/gitlab/ci/status/pending_spec.rb +++ b/spec/lib/gitlab/ci/status/pending_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Pending do diff --git a/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb index 1a2b952d374..876ba712d05 100644 --- a/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Pipeline::Blocked do diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index 57df8325635..d3251d138b8 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Pipeline::Common do diff --git a/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb b/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb index f89712d2b03..90b797965b3 100644 --- a/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Pipeline::Delayed do diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index 466087a0e31..8a36cd1b658 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Pipeline::Factory do diff --git a/spec/lib/gitlab/ci/status/running_spec.rb b/spec/lib/gitlab/ci/status/running_spec.rb index 9c9d431bb5d..75ff58c5c98 100644 --- a/spec/lib/gitlab/ci/status/running_spec.rb +++ b/spec/lib/gitlab/ci/status/running_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Running do diff --git a/spec/lib/gitlab/ci/status/scheduled_spec.rb b/spec/lib/gitlab/ci/status/scheduled_spec.rb index b8ca3caa1f7..a0374e1a87b 100644 --- a/spec/lib/gitlab/ci/status/scheduled_spec.rb +++ b/spec/lib/gitlab/ci/status/scheduled_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Scheduled do diff --git a/spec/lib/gitlab/ci/status/skipped_spec.rb b/spec/lib/gitlab/ci/status/skipped_spec.rb index 63694ca0ea6..7f68d4a2fa9 100644 --- a/spec/lib/gitlab/ci/status/skipped_spec.rb +++ b/spec/lib/gitlab/ci/status/skipped_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Skipped do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index bb2d0a2c75c..26ff0e901fd 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Stage::Common do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index 4b299170c87..8f5b1ff62a5 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Stage::Factory do diff --git a/spec/lib/gitlab/ci/status/success_spec.rb b/spec/lib/gitlab/ci/status/success_spec.rb index 2f67df71c4f..d4b3a9f12cc 100644 --- a/spec/lib/gitlab/ci/status/success_spec.rb +++ b/spec/lib/gitlab/ci/status/success_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::Success do diff --git a/spec/lib/gitlab/ci/status/success_warning_spec.rb b/spec/lib/gitlab/ci/status/success_warning_spec.rb index 9493b1d89f2..af952011e21 100644 --- a/spec/lib/gitlab/ci/status/success_warning_spec.rb +++ b/spec/lib/gitlab/ci/status/success_warning_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Status::SuccessWarning do diff --git a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb index 546a9e7d0cc..e0077a5280a 100644 --- a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb +++ b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do @@ -312,7 +314,7 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do end context 'when utf-8 is being used' do - let(:sample_trace_raw) { sample_trace_raw_utf8.force_encoding(Encoding::BINARY) } + let(:sample_trace_raw) { sample_trace_raw_utf8.dup.force_encoding(Encoding::BINARY) } let(:sample_trace_raw_utf8) { "😺\n😺\n😺\n😺" } before do @@ -442,5 +444,15 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do expect(Ci::BuildTraceChunk.where(build: build).count).to eq(0) end + + context 'when the job does not have archived trace' do + it 'leaves a message in sidekiq log' do + expect(Sidekiq.logger).to receive(:warn).with( + message: 'The job does not have archived trace but going to be destroyed.', + job_id: build.id).and_call_original + + subject + end + end end end diff --git a/spec/lib/gitlab/ci/trace/section_parser_spec.rb b/spec/lib/gitlab/ci/trace/section_parser_spec.rb index ca53ff87c6f..5e2efe083be 100644 --- a/spec/lib/gitlab/ci/trace/section_parser_spec.rb +++ b/spec/lib/gitlab/ci/trace/section_parser_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Trace::SectionParser do diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index 35250632e86..af519f4bae6 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -65,9 +65,9 @@ describe Gitlab::Ci::Trace::Stream, :clean_gitlab_redis_cache do result = stream.html expect(result).to eq( - "<span class=\"\">ヾ(´༎ຶД༎ຶ`)ノ<br/><span class=\"\"></span></span>"\ - "<span class=\"term-fg-green\">許功蓋</span><span class=\"\"><br/>"\ - "<span class=\"\"></span></span>") + "<span>ヾ(´༎ຶД༎ຶ`)ノ<br/></span>"\ + "<span class=\"term-fg-green\">許功蓋</span>"\ + "<span><br/></span>") expect(result.encoding).to eq(Encoding.default_external) end end @@ -253,7 +253,7 @@ describe Gitlab::Ci::Trace::Stream, :clean_gitlab_redis_cache do it 'returns html content with state' do result = stream.html_with_state - expect(result.html).to eq("<span class=\"\">1234</span>") + expect(result.html).to eq("<span>1234</span>") end context 'follow-up state' do @@ -269,7 +269,7 @@ describe Gitlab::Ci::Trace::Stream, :clean_gitlab_redis_cache do result = stream.html_with_state(last_result.state) expect(result.append).to be_truthy - expect(result.html).to eq("<span class=\"\">5678</span>") + expect(result.html).to eq("<span>5678</span>") end end end @@ -305,13 +305,11 @@ describe Gitlab::Ci::Trace::Stream, :clean_gitlab_redis_cache do describe '#html' do shared_examples_for 'htmls' do it "returns html" do - expect(stream.html).to eq( - "<span class=\"\">12<br/><span class=\"\">34<br/>"\ - "<span class=\"\">56</span></span></span>") + expect(stream.html).to eq("<span>12<br/>34<br/>56</span>") end it "returns html for last line only" do - expect(stream.html(last_lines: 1)).to eq("<span class=\"\">56</span>") + expect(stream.html(last_lines: 1)).to eq("<span>56</span>") end end diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb index d6510649dba..f7bc5686b68 100644 --- a/spec/lib/gitlab/ci/trace_spec.rb +++ b/spec/lib/gitlab/ci/trace_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Trace, :clean_gitlab_redis_shared_state do diff --git a/spec/lib/gitlab/ci/variables/collection/item_spec.rb b/spec/lib/gitlab/ci/variables/collection/item_spec.rb index 613814df23f..1bdca753cd3 100644 --- a/spec/lib/gitlab/ci/variables/collection/item_spec.rb +++ b/spec/lib/gitlab/ci/variables/collection/item_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Variables::Collection::Item do diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb index 8e732d44d5d..59b9f7d4fb9 100644 --- a/spec/lib/gitlab/ci/variables/collection_spec.rb +++ b/spec/lib/gitlab/ci/variables/collection_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Ci::Variables::Collection do diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index 789d6813d5b..4ffa1fc9fd8 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module Gitlab @@ -1083,6 +1085,111 @@ module Gitlab it { expect { subject }.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, 'test1 job: dependency deploy is not defined in prior stages') } end + + context 'when a job depends on another job that references a not-yet defined stage' do + let(:config) do + { + "stages" => [ + "version" + ], + "version" => { + "stage" => "version", + "dependencies" => ["release:components:versioning"], + "script" => ["./versioning/versioning"] + }, + ".release_go" => { + "stage" => "build", + "script" => ["cd versioning"] + }, + "release:components:versioning" => { + "stage" => "build", + "script" => ["cd versioning"] + } + } + end + + it { expect { subject }.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, /is not defined in prior stages/) } + end + end + + describe "Needs" do + let(:needs) { } + let(:dependencies) { } + + let(:config) do + { + build1: { stage: 'build', script: 'test' }, + build2: { stage: 'build', script: 'test' }, + test1: { stage: 'test', script: 'test', needs: needs, dependencies: dependencies }, + test2: { stage: 'test', script: 'test' }, + deploy: { stage: 'test', script: 'test' } + } + end + + subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)) } + + context 'no needs' do + it { expect { subject }.not_to raise_error } + end + + context 'needs to builds' do + let(:needs) { %w(build1 build2) } + + it "does create jobs with valid specification" do + expect(subject.builds.size).to eq(5) + expect(subject.builds[0]).to eq( + stage: "build", + stage_idx: 0, + name: "build1", + options: { + script: ["test"] + }, + when: "on_success", + allow_failure: false, + yaml_variables: [] + ) + expect(subject.builds[2]).to eq( + stage: "test", + stage_idx: 1, + name: "test1", + options: { + script: ["test"] + }, + needs_attributes: [ + { name: "build1" }, + { name: "build2" } + ], + when: "on_success", + allow_failure: false, + yaml_variables: [] + ) + end + end + + context 'needs to builds defined as symbols' do + let(:needs) { [:build1, :build2] } + + it { expect { subject }.not_to raise_error } + end + + context 'undefined need' do + let(:needs) { ['undefined'] } + + it { expect { subject }.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, 'test1 job: undefined need: undefined') } + end + + context 'needs to deploy' do + let(:needs) { ['deploy'] } + + it { expect { subject }.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, 'test1 job: need deploy is not defined in prior stages') } + end + + context 'needs and dependencies that are mismatching' do + let(:needs) { %w(build1) } + let(:dependencies) { %w(build2) } + + it { expect { subject }.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, 'jobs:test1 dependencies the build2 should be part of needs') } + end end describe "Hidden jobs" do diff --git a/spec/lib/gitlab/ci_access_spec.rb b/spec/lib/gitlab/ci_access_spec.rb index 75b90e76083..3c68d209eb6 100644 --- a/spec/lib/gitlab/ci_access_spec.rb +++ b/spec/lib/gitlab/ci_access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CiAccess do diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index 44568f2a653..fdd01f58c9d 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::ClosingIssueExtractor do diff --git a/spec/lib/gitlab/color_schemes_spec.rb b/spec/lib/gitlab/color_schemes_spec.rb index c7be45dbcd3..ba5573f6901 100644 --- a/spec/lib/gitlab/color_schemes_spec.rb +++ b/spec/lib/gitlab/color_schemes_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::ColorSchemes do diff --git a/spec/lib/gitlab/config/entry/attributable_spec.rb b/spec/lib/gitlab/config/entry/attributable_spec.rb index abb4fff3ad7..82614bb8238 100644 --- a/spec/lib/gitlab/config/entry/attributable_spec.rb +++ b/spec/lib/gitlab/config/entry/attributable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Attributable do diff --git a/spec/lib/gitlab/config/entry/boolean_spec.rb b/spec/lib/gitlab/config/entry/boolean_spec.rb index 1b7a3f850ec..0b8b720dd80 100644 --- a/spec/lib/gitlab/config/entry/boolean_spec.rb +++ b/spec/lib/gitlab/config/entry/boolean_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Boolean do diff --git a/spec/lib/gitlab/config/entry/configurable_spec.rb b/spec/lib/gitlab/config/entry/configurable_spec.rb index 62dbf20ddf8..8c3a4490d08 100644 --- a/spec/lib/gitlab/config/entry/configurable_spec.rb +++ b/spec/lib/gitlab/config/entry/configurable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Configurable do diff --git a/spec/lib/gitlab/config/entry/factory_spec.rb b/spec/lib/gitlab/config/entry/factory_spec.rb index 42f8be8e141..a614ef56a78 100644 --- a/spec/lib/gitlab/config/entry/factory_spec.rb +++ b/spec/lib/gitlab/config/entry/factory_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Factory do diff --git a/spec/lib/gitlab/config/entry/simplifiable_spec.rb b/spec/lib/gitlab/config/entry/simplifiable_spec.rb index bc8387ada67..65e18fe3f10 100644 --- a/spec/lib/gitlab/config/entry/simplifiable_spec.rb +++ b/spec/lib/gitlab/config/entry/simplifiable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Simplifiable do diff --git a/spec/lib/gitlab/config/entry/undefined_spec.rb b/spec/lib/gitlab/config/entry/undefined_spec.rb index 48f9d276c95..83c3a6aec72 100644 --- a/spec/lib/gitlab/config/entry/undefined_spec.rb +++ b/spec/lib/gitlab/config/entry/undefined_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Undefined do diff --git a/spec/lib/gitlab/config/entry/unspecified_spec.rb b/spec/lib/gitlab/config/entry/unspecified_spec.rb index 64421824a12..32c52594ecf 100644 --- a/spec/lib/gitlab/config/entry/unspecified_spec.rb +++ b/spec/lib/gitlab/config/entry/unspecified_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Unspecified do diff --git a/spec/lib/gitlab/config/entry/validatable_spec.rb b/spec/lib/gitlab/config/entry/validatable_spec.rb index 5a8f9766d23..925db3594ba 100644 --- a/spec/lib/gitlab/config/entry/validatable_spec.rb +++ b/spec/lib/gitlab/config/entry/validatable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Validatable do diff --git a/spec/lib/gitlab/config/entry/validator_spec.rb b/spec/lib/gitlab/config/entry/validator_spec.rb index efa16c4265c..7bf350912df 100644 --- a/spec/lib/gitlab/config/entry/validator_spec.rb +++ b/spec/lib/gitlab/config/entry/validator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Entry::Validator do diff --git a/spec/lib/gitlab/config/loader/yaml_spec.rb b/spec/lib/gitlab/config/loader/yaml_spec.rb index 0affeb01f6a..ccddf340c3d 100644 --- a/spec/lib/gitlab/config/loader/yaml_spec.rb +++ b/spec/lib/gitlab/config/loader/yaml_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Config::Loader::Yaml do diff --git a/spec/lib/gitlab/conflict/file_collection_spec.rb b/spec/lib/gitlab/conflict/file_collection_spec.rb index c93912db411..f3cdb1a9e59 100644 --- a/spec/lib/gitlab/conflict/file_collection_spec.rb +++ b/spec/lib/gitlab/conflict/file_collection_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Conflict::FileCollection do diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index a955ce54e85..adf5a232a75 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Conflict::File do diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb index 51e5bdc6307..1154f029a8d 100644 --- a/spec/lib/gitlab/contributions_calendar_spec.rb +++ b/spec/lib/gitlab/contributions_calendar_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::ContributionsCalendar do diff --git a/spec/lib/gitlab/cross_project_access/check_collection_spec.rb b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb index a9e7575240e..1aa5480b670 100644 --- a/spec/lib/gitlab/cross_project_access/check_collection_spec.rb +++ b/spec/lib/gitlab/cross_project_access/check_collection_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CrossProjectAccess::CheckCollection do diff --git a/spec/lib/gitlab/cross_project_access/check_info_spec.rb b/spec/lib/gitlab/cross_project_access/check_info_spec.rb index ea7393a7006..7d2471b6327 100644 --- a/spec/lib/gitlab/cross_project_access/check_info_spec.rb +++ b/spec/lib/gitlab/cross_project_access/check_info_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CrossProjectAccess::CheckInfo do diff --git a/spec/lib/gitlab/cross_project_access/class_methods_spec.rb b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb index 5349685e633..17d265542dd 100644 --- a/spec/lib/gitlab/cross_project_access/class_methods_spec.rb +++ b/spec/lib/gitlab/cross_project_access/class_methods_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CrossProjectAccess::ClassMethods do diff --git a/spec/lib/gitlab/cross_project_access_spec.rb b/spec/lib/gitlab/cross_project_access_spec.rb index 614b0473c7e..ce18d207413 100644 --- a/spec/lib/gitlab/cross_project_access_spec.rb +++ b/spec/lib/gitlab/cross_project_access_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CrossProjectAccess do diff --git a/spec/lib/gitlab/crypto_helper_spec.rb b/spec/lib/gitlab/crypto_helper_spec.rb index 05cc6cf15de..71bbeccb17b 100644 --- a/spec/lib/gitlab/crypto_helper_spec.rb +++ b/spec/lib/gitlab/crypto_helper_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CryptoHelper do diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb index db31e5280a3..2759412add8 100644 --- a/spec/lib/gitlab/current_settings_spec.rb +++ b/spec/lib/gitlab/current_settings_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CurrentSettings do diff --git a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb index 8b07da11c5d..3eea791d61a 100644 --- a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CycleAnalytics::BaseEventFetcher do @@ -9,12 +11,12 @@ describe Gitlab::CycleAnalytics::BaseEventFetcher do let(:options) do { start_time_attrs: start_time_attrs, end_time_attrs: end_time_attrs, - from: 30.days.ago } + from: 30.days.ago, + project: project } end subject do - described_class.new(project: project, - stage: :issue, + described_class.new(stage: :issue, options: options).fetch end diff --git a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb index 0267e8c2f69..b521ad0c6ea 100644 --- a/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/code_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb index c738cc49c1f..dd1d9ac0f16 100644 --- a/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/code_stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' @@ -5,40 +7,114 @@ describe Gitlab::CycleAnalytics::CodeStage do let(:stage_name) { :code } let(:project) { create(:project) } - let!(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } - let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:mr_1) { create(:merge_request, source_project: project, created_at: 15.minutes.ago) } - let!(:mr_2) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'A') } - let!(:mr_3) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } + let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:mr_1) { create(:merge_request, source_project: project, created_at: 15.minutes.ago) } + let(:mr_2) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'A') } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } before do issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 45.minutes.ago) issue_2.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) issue_3.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) + create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') create(:merge_requests_closing_issues, merge_request: mr_1, issue: issue_1) create(:merge_requests_closing_issues, merge_request: mr_2, issue: issue_2) end it_behaves_like 'base stage' - describe '#median' do + describe '#project_median' do around do |example| Timecop.freeze { example.run } end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end describe '#events' do + subject { stage.events } + it 'exposes merge requests that closes issues' do - result = stage.events + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(mr_1.title, mr_2.title) + end + end + + context 'when group is given' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project_2) { create(:project, group: group) } + let(:project_3) { create(:project, group: group) } + let(:issue_2_1) { create(:issue, project: project_2, created_at: 90.minutes.ago) } + let(:issue_2_2) { create(:issue, project: project_3, created_at: 60.minutes.ago) } + let(:issue_2_3) { create(:issue, project: project_2, created_at: 60.minutes.ago) } + let(:mr_2_1) { create(:merge_request, source_project: project_2, created_at: 15.minutes.ago) } + let(:mr_2_2) { create(:merge_request, source_project: project_3, created_at: 10.minutes.ago, source_branch: 'A') } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group }) } + + before do + group.add_owner(user) + issue_2_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 45.minutes.ago) + issue_2_2.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) + issue_2_3.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) + create(:merge_requests_closing_issues, merge_request: mr_2_1, issue: issue_2_1) + create(:merge_requests_closing_issues, merge_request: mr_2_2, issue: issue_2_2) + end + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(mr_2_1.title, mr_2_2.title) + end + end + + context 'when subgroup is given' do + let(:subgroup) { create(:group, parent: group) } + let(:project_4) { create(:project, group: subgroup) } + let(:project_5) { create(:project, group: subgroup) } + let(:issue_3_1) { create(:issue, project: project_4, created_at: 90.minutes.ago) } + let(:issue_3_2) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + let(:issue_3_3) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + let(:mr_3_1) { create(:merge_request, source_project: project_4, created_at: 15.minutes.ago) } + let(:mr_3_2) { create(:merge_request, source_project: project_5, created_at: 10.minutes.ago, source_branch: 'A') } + + before do + issue_3_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 45.minutes.ago) + issue_3_2.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) + issue_3_3.metrics.update!(first_added_to_board_at: 60.minutes.ago, first_mentioned_in_commit_at: 40.minutes.ago) + create(:merge_requests_closing_issues, merge_request: mr_3_1, issue: issue_3_1) + create(:merge_requests_closing_issues, merge_request: mr_3_2, issue: issue_3_2) + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(4) + expect(subject.map { |event| event[:title] }).to contain_exactly(mr_2_1.title, mr_2_2.title, mr_3_1.title, mr_3_2.title) + end - expect(result.count).to eq(2) - expect(result.map { |event| event[:title] }).to contain_exactly(mr_1.title, mr_2.title) + it 'exposes merge requests that close issues with full path for subgroup' do + expect(subject.count).to eq(4) + expect(subject.find { |event| event[:title] == mr_3_1.title }[:url]).to include("#{subgroup.full_path}") + end + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb index 5ee02650e49..a163de07967 100644 --- a/spec/lib/gitlab/cycle_analytics/events_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'cycle analytics events' do diff --git a/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb new file mode 100644 index 00000000000..d5c2f7cc579 --- /dev/null +++ b/spec/lib/gitlab/cycle_analytics/group_stage_summary_spec.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe Gitlab::CycleAnalytics::GroupStageSummary do + let(:group) { create(:group) } + let(:project) { create(:project, :repository, namespace: group) } + let(:project_2) { create(:project, :repository, namespace: group) } + let(:from) { 1.day.ago } + let(:user) { create(:user, :admin) } + + subject { described_class.new(group, options: { from: Time.now, current_user: user }).data } + + describe "#new_issues" do + context 'with from date' do + before do + Timecop.freeze(5.days.ago) { create(:issue, project: project) } + Timecop.freeze(5.days.ago) { create(:issue, project: project_2) } + Timecop.freeze(5.days.from_now) { create(:issue, project: project) } + Timecop.freeze(5.days.from_now) { create(:issue, project: project_2) } + end + + it "finds the number of issues created after it" do + expect(subject.first[:value]).to eq(2) + end + + context 'with subgroups' do + before do + Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project, namespace: create(:group, parent: group))) } + end + + it "finds issues from them" do + expect(subject.first[:value]).to eq(3) + end + end + + context 'with projects specified in options' do + before do + Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project, namespace: group)) } + end + + subject { described_class.new(group, options: { from: Time.now, current_user: user, projects: [project.id, project_2.id] }).data } + + it 'finds issues from those projects' do + expect(subject.first[:value]).to eq(2) + end + end + end + + context 'with other projects' do + before do + Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project, namespace: create(:group))) } + Timecop.freeze(5.days.from_now) { create(:issue, project: project) } + Timecop.freeze(5.days.from_now) { create(:issue, project: project_2) } + end + + it "doesn't find issues from them" do + expect(subject.first[:value]).to eq(2) + end + end + end + + describe "#deploys" do + context 'with from date' do + before do + Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project) } + Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project) } + Timecop.freeze(5.days.ago) { create(:deployment, :success, project: project_2) } + Timecop.freeze(5.days.from_now) { create(:deployment, :success, project: project_2) } + end + + it "finds the number of deploys made created after it" do + expect(subject.second[:value]).to eq(2) + end + + context 'with subgroups' do + before do + Timecop.freeze(5.days.from_now) do + create(:deployment, :success, project: create(:project, :repository, namespace: create(:group, parent: group))) + end + end + + it "finds deploys from them" do + expect(subject.second[:value]).to eq(3) + end + end + + context 'with projects specified in options' do + before do + Timecop.freeze(5.days.from_now) do + create(:deployment, :success, project: create(:project, :repository, namespace: group, name: 'not_applicable')) + end + end + + subject { described_class.new(group, options: { from: Time.now, current_user: user, projects: [project.id, project_2.id] }).data } + + it 'shows deploys from those projects' do + expect(subject.second[:value]).to eq(2) + end + end + end + + context 'with other projects' do + before do + Timecop.freeze(5.days.from_now) do + create(:deployment, :success, project: create(:project, :repository, namespace: create(:group))) + end + end + + it "doesn't find deploys from them" do + expect(subject.second[:value]).to eq(0) + end + end + end +end diff --git a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb index fd9fa2fee49..afb7b6a13b0 100644 --- a/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/issue_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb index 3b6af9cbaed..4dd21239cde 100644 --- a/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/issue_stage_spec.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::IssueStage do let(:stage_name) { :issue } let(:project) { create(:project) } - let!(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } - let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) } + let(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } + let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) } let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } before do issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago ) @@ -24,7 +26,7 @@ describe Gitlab::CycleAnalytics::IssueStage do end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end @@ -36,4 +38,90 @@ describe Gitlab::CycleAnalytics::IssueStage do expect(result.map { |event| event[:title] }).to contain_exactly(issue_1.title, issue_2.title, issue_3.title) end end + context 'when group is given' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project_2) { create(:project, group: group) } + let(:project_3) { create(:project, group: group) } + let(:issue_2_1) { create(:issue, project: project_2, created_at: 90.minutes.ago) } + let(:issue_2_2) { create(:issue, project: project_3, created_at: 60.minutes.ago) } + let(:issue_2_3) { create(:issue, project: project_2, created_at: 60.minutes.ago) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group }) } + + before do + group.add_owner(user) + issue_2_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago) + issue_2_2.metrics.update!(first_added_to_board_at: 30.minutes.ago) + end + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_2_1.title, issue_2_2.title) + end + end + + context 'when only part of projects is chosen' do + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group, projects: [project_2.id] }) } + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(1) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_2_1.title) + end + end + end + + context 'when subgroup is given' do + let(:subgroup) { create(:group, parent: group) } + let(:project_4) { create(:project, group: subgroup) } + let(:project_5) { create(:project, group: subgroup) } + let(:issue_3_1) { create(:issue, project: project_4, created_at: 90.minutes.ago) } + let(:issue_3_2) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + let(:issue_3_3) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + + before do + issue_3_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago) + issue_3_2.metrics.update!(first_added_to_board_at: 30.minutes.ago) + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(4) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_2_1.title, issue_2_2.title, issue_3_1.title, issue_3_2.title) + end + + it 'exposes merge requests that close issues with full path for subgroup' do + expect(subject.count).to eq(4) + expect(subject.find { |event| event[:title] == issue_3_1.title }[:url]).to include("#{subgroup.full_path}") + end + end + end + end end diff --git a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb index f670c7f6c75..2896e973a43 100644 --- a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CycleAnalytics::Permissions do diff --git a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb index 2e5dc5b5547..17786cd02c6 100644 --- a/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/plan_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb index 506a8160412..98d2593de66 100644 --- a/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/plan_stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' @@ -8,7 +10,7 @@ describe Gitlab::CycleAnalytics::PlanStage do let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } let!(:issue_3) { create(:issue, project: project, created_at: 30.minutes.ago) } let!(:issue_without_milestone) { create(:issue, project: project, created_at: 1.minute.ago) } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } before do issue_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 10.minutes.ago) @@ -18,22 +20,88 @@ describe Gitlab::CycleAnalytics::PlanStage do it_behaves_like 'base stage' - describe '#median' do + describe '#project_median' do around do |example| Timecop.freeze { example.run } end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end describe '#events' do + subject { stage.events } + it 'exposes issues with metrics' do - result = stage.events + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_1.title, issue_2.title) + end + end + + context 'when group is given' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project_2) { create(:project, group: group) } + let(:project_3) { create(:project, group: group) } + let(:issue_2_1) { create(:issue, project: project_2, created_at: 90.minutes.ago) } + let(:issue_2_2) { create(:issue, project: project_3, created_at: 60.minutes.ago) } + let(:issue_2_3) { create(:issue, project: project_2, created_at: 60.minutes.ago) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group }) } + + before do + group.add_owner(user) + issue_2_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 10.minutes.ago) + issue_2_2.metrics.update!(first_added_to_board_at: 30.minutes.ago, first_mentioned_in_commit_at: 20.minutes.ago) + issue_2_3.metrics.update!(first_added_to_board_at: 15.minutes.ago) + end + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_2_1.title, issue_2_2.title) + end + end + + context 'when subgroup is given' do + let(:subgroup) { create(:group, parent: group) } + let(:project_4) { create(:project, group: subgroup) } + let(:project_5) { create(:project, group: subgroup) } + let(:issue_3_1) { create(:issue, project: project_4, created_at: 90.minutes.ago) } + let(:issue_3_2) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + let(:issue_3_3) { create(:issue, project: project_5, created_at: 60.minutes.ago) } + + before do + issue_3_1.metrics.update!(first_associated_with_milestone_at: 60.minutes.ago, first_mentioned_in_commit_at: 10.minutes.ago) + issue_3_2.metrics.update!(first_added_to_board_at: 30.minutes.ago, first_mentioned_in_commit_at: 20.minutes.ago) + issue_3_3.metrics.update!(first_added_to_board_at: 15.minutes.ago) + end + + describe '#events' do + subject { stage.events } + + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(4) + expect(subject.map { |event| event[:title] }).to contain_exactly(issue_2_1.title, issue_2_2.title, issue_3_1.title, issue_3_2.title) + end - expect(result.count).to eq(2) - expect(result.map { |event| event[:title] }).to contain_exactly(issue_1.title, issue_2.title) + it 'exposes merge requests that close issues with full path for subgroup' do + expect(subject.count).to eq(4) + expect(subject.find { |event| event[:title] == issue_3_1.title }[:url]).to include("#{subgroup.full_path}") + end + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb index 74001181305..3ecfad49acd 100644 --- a/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/production_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb index 916684b81eb..4d0cc91a318 100644 --- a/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/production_stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' diff --git a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb index 4f67c95ed4c..2c2169be58c 100644 --- a/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/review_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb index f072a9644e8..0f36a8c5c36 100644 --- a/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/review_stage_spec.rb @@ -1,17 +1,19 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::ReviewStage do let(:stage_name) { :review } let(:project) { create(:project) } - let!(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } - let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:mr_1) { create(:merge_request, :closed, source_project: project, created_at: 60.minutes.ago) } - let!(:mr_2) { create(:merge_request, :closed, source_project: project, created_at: 40.minutes.ago, source_branch: 'A') } - let!(:mr_3) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') } + let(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } + let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:mr_1) { create(:merge_request, :closed, source_project: project, created_at: 60.minutes.ago) } + let(:mr_2) { create(:merge_request, :closed, source_project: project, created_at: 40.minutes.ago, source_branch: 'A') } + let(:mr_3) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') } let!(:mr_4) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'C') } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } before do mr_1.metrics.update!(merged_at: 30.minutes.ago) @@ -24,22 +26,66 @@ describe Gitlab::CycleAnalytics::ReviewStage do it_behaves_like 'base stage' - describe '#median' do + describe '#project_median' do around do |example| Timecop.freeze { example.run } end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end describe '#events' do + subject { stage.events } + it 'exposes merge requests that close issues' do - result = stage.events + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(mr_1.title, mr_2.title) + end + end + + context 'when group is given' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project_2) { create(:project, group: group) } + let(:project_3) { create(:project, group: group) } + let(:issue_2_1) { create(:issue, project: project_2, created_at: 90.minutes.ago) } + let(:issue_2_2) { create(:issue, project: project_3, created_at: 60.minutes.ago) } + let(:issue_2_3) { create(:issue, project: project_2, created_at: 60.minutes.ago) } + let(:mr_2_1) { create(:merge_request, :closed, source_project: project_2, created_at: 60.minutes.ago) } + let(:mr_2_2) { create(:merge_request, :closed, source_project: project_3, created_at: 40.minutes.ago, source_branch: 'A') } + let(:mr_2_3) { create(:merge_request, source_project: project_2, created_at: 10.minutes.ago, source_branch: 'B') } + let!(:mr_2_4) { create(:merge_request, source_project: project_3, created_at: 10.minutes.ago, source_branch: 'C') } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group }) } + + before do + group.add_owner(user) + mr_2_1.metrics.update!(merged_at: 30.minutes.ago) + mr_2_2.metrics.update!(merged_at: 10.minutes.ago) + + create(:merge_requests_closing_issues, merge_request: mr_2_1, issue: issue_2_1) + create(:merge_requests_closing_issues, merge_request: mr_2_2, issue: issue_2_2) + create(:merge_requests_closing_issues, merge_request: mr_2_3, issue: issue_2_3) + end + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } - expect(result.count).to eq(2) - expect(result.map { |event| event[:title] }).to contain_exactly(mr_1.title, mr_2.title) + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:title] }).to contain_exactly(mr_2_1.title, mr_2_2.title) + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb index c22d27f60d6..c053af010b3 100644 --- a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require 'spec_helper' shared_examples 'default query config' do let(:project) { create(:project) } - let(:event) { described_class.new(project: project, stage: stage_name, options: { from: 1.day.ago }) } + let(:event) { described_class.new(stage: stage_name, options: { from: 1.day.ago, project: project }) } it 'has the stage attribute' do expect(event.stage).not_to be_nil diff --git a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb index 1a4b572cc11..cf95741908f 100644 --- a/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/shared_stage_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'spec_helper' shared_examples 'base stage' do ISSUES_MEDIAN = 30.minutes.to_i - let(:stage) { described_class.new(project: double, options: {}) } + let(:stage) { described_class.new(options: { project: double }) } before do - allow(stage).to receive(:median).and_return(1.12) + allow(stage).to receive(:project_median).and_return(1.12) allow_any_instance_of(Gitlab::CycleAnalytics::BaseEventFetcher).to receive(:event_result).and_return({}) end diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb index f8009709ce2..778c2f479b5 100644 --- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CycleAnalytics::StageSummary do diff --git a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb index bbc82496340..016d2e8da5b 100644 --- a/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/staging_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb index 17d5fbb9733..bd64c4aca42 100644 --- a/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/staging_stage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' @@ -5,16 +7,16 @@ describe Gitlab::CycleAnalytics::StagingStage do let(:stage_name) { :staging } let(:project) { create(:project) } - let!(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } - let!(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } - let!(:mr_1) { create(:merge_request, :closed, source_project: project, created_at: 60.minutes.ago) } - let!(:mr_2) { create(:merge_request, :closed, source_project: project, created_at: 40.minutes.ago, source_branch: 'A') } - let!(:mr_3) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') } + let(:issue_1) { create(:issue, project: project, created_at: 90.minutes.ago) } + let(:issue_2) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:issue_3) { create(:issue, project: project, created_at: 60.minutes.ago) } + let(:mr_1) { create(:merge_request, :closed, source_project: project, created_at: 60.minutes.ago) } + let(:mr_2) { create(:merge_request, :closed, source_project: project, created_at: 40.minutes.ago, source_branch: 'A') } + let(:mr_3) { create(:merge_request, source_project: project, created_at: 10.minutes.ago, source_branch: 'B') } let(:build_1) { create(:ci_build, project: project) } let(:build_2) { create(:ci_build, project: project) } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } before do mr_1.metrics.update!(merged_at: 80.minutes.ago, first_deployed_to_production_at: 50.minutes.ago, pipeline_id: build_1.commit_id) @@ -28,22 +30,68 @@ describe Gitlab::CycleAnalytics::StagingStage do it_behaves_like 'base stage' - describe '#median' do + describe '#project_median' do around do |example| Timecop.freeze { example.run } end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end describe '#events' do + subject { stage.events } + it 'exposes builds connected to merge request' do - result = stage.events + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:name] }).to contain_exactly(build_1.name, build_2.name) + end + end + + context 'when group is given' do + let(:user) { create(:user) } + let(:group) { create(:group) } + let(:project_2) { create(:project, group: group) } + let(:project_3) { create(:project, group: group) } + let(:issue_2_1) { create(:issue, project: project_2, created_at: 90.minutes.ago) } + let(:issue_2_2) { create(:issue, project: project_3, created_at: 60.minutes.ago) } + let(:issue_2_3) { create(:issue, project: project_2, created_at: 60.minutes.ago) } + let(:mr_1) { create(:merge_request, :closed, source_project: project_2, created_at: 60.minutes.ago) } + let(:mr_2) { create(:merge_request, :closed, source_project: project_3, created_at: 40.minutes.ago, source_branch: 'A') } + let(:mr_3) { create(:merge_request, source_project: project_2, created_at: 10.minutes.ago, source_branch: 'B') } + let(:build_1) { create(:ci_build, project: project_2) } + let(:build_2) { create(:ci_build, project: project_3) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: user, group: group }) } + + before do + group.add_owner(user) + mr_1.metrics.update!(merged_at: 80.minutes.ago, first_deployed_to_production_at: 50.minutes.ago, pipeline_id: build_1.commit_id) + mr_2.metrics.update!(merged_at: 60.minutes.ago, first_deployed_to_production_at: 30.minutes.ago, pipeline_id: build_2.commit_id) + mr_3.metrics.update!(merged_at: 10.minutes.ago, first_deployed_to_production_at: 3.days.ago, pipeline_id: create(:ci_build, project: project_2).commit_id) + + create(:merge_requests_closing_issues, merge_request: mr_1, issue: issue_2_1) + create(:merge_requests_closing_issues, merge_request: mr_2, issue: issue_2_2) + create(:merge_requests_closing_issues, merge_request: mr_3, issue: issue_2_3) + end + + describe '#group_median' do + around do |example| + Timecop.freeze { example.run } + end + + it 'counts median from issues with metrics' do + expect(stage.group_median).to eq(ISSUES_MEDIAN) + end + end + + describe '#events' do + subject { stage.events } - expect(result.count).to eq(2) - expect(result.map { |event| event[:name] }).to contain_exactly(build_1.name, build_2.name) + it 'exposes merge requests that close issues' do + expect(subject.count).to eq(2) + expect(subject.map { |event| event[:name] }).to contain_exactly(build_1.name, build_2.name) + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb index 6639fa54e0e..be7c0e9dd59 100644 --- a/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/test_event_fetcher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_event_spec' diff --git a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb index 8633a63849f..9162686d17d 100644 --- a/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/test_stage_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'spec_helper' require 'lib/gitlab/cycle_analytics/shared_stage_spec' describe Gitlab::CycleAnalytics::TestStage do let(:stage_name) { :test } let(:project) { create(:project) } - let(:stage) { described_class.new(project: project, options: { from: 2.days.ago, current_user: project.creator }) } + let(:stage) { described_class.new(options: { from: 2.days.ago, current_user: project.creator, project: project }) } it_behaves_like 'base stage' @@ -36,7 +38,7 @@ describe Gitlab::CycleAnalytics::TestStage do end it 'counts median from issues with metrics' do - expect(stage.median).to eq(ISSUES_MEDIAN) + expect(stage.project_median).to eq(ISSUES_MEDIAN) end end end diff --git a/spec/lib/gitlab/cycle_analytics/updater_spec.rb b/spec/lib/gitlab/cycle_analytics/updater_spec.rb index eff54cd3692..67f386f9144 100644 --- a/spec/lib/gitlab/cycle_analytics/updater_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/updater_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CycleAnalytics::Updater do diff --git a/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb b/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb index 8122e85a981..e568ea633db 100644 --- a/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/usage_data_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::CycleAnalytics::UsageData do @@ -28,27 +30,7 @@ describe Gitlab::CycleAnalytics::UsageData do end end - shared_examples 'a valid usage data result' do - it 'returns the aggregated usage data of every selected project' do - result = subject.to_json - - expect(result).to have_key(:avg_cycle_analytics) - - CycleAnalytics::Base::STAGES.each do |stage| - expect(result[:avg_cycle_analytics]).to have_key(stage) - - stage_values = result[:avg_cycle_analytics][stage] - expected_values = expect_values_per_stage[stage] - - expected_values.each_pair do |op, value| - expect(stage_values).to have_key(op) - expect(stage_values[op]).to eq(value) - end - end - end - end - - context 'when using postgresql', :postgresql do + context 'a valid usage data result' do let(:expect_values_per_stage) do { issue: { @@ -89,51 +71,23 @@ describe Gitlab::CycleAnalytics::UsageData do } end - it_behaves_like 'a valid usage data result' - end + it 'returns the aggregated usage data of every selected project' do + result = subject.to_json - context 'when using mysql', :mysql do - let(:expect_values_per_stage) do - { - issue: { - average: nil, - sd: 0, - missing: 2 - }, - plan: { - average: nil, - sd: 0, - missing: 2 - }, - code: { - average: nil, - sd: 0, - missing: 2 - }, - test: { - average: nil, - sd: 0, - missing: 2 - }, - review: { - average: nil, - sd: 0, - missing: 2 - }, - staging: { - average: nil, - sd: 0, - missing: 2 - }, - production: { - average: nil, - sd: 0, - missing: 2 - } - } - end + expect(result).to have_key(:avg_cycle_analytics) + + CycleAnalytics::LevelBase::STAGES.each do |stage| + expect(result[:avg_cycle_analytics]).to have_key(stage) - it_behaves_like 'a valid usage data result' + stage_values = result[:avg_cycle_analytics][stage] + expected_values = expect_values_per_stage[stage] + + expected_values.each_pair do |op, value| + expect(stage_values).to have_key(op) + expect(stage_values[op]).to eq(value) + end + end + end end end end diff --git a/spec/lib/gitlab/daemon_spec.rb b/spec/lib/gitlab/daemon_spec.rb index 2bdb0dfc736..d3e73314b87 100644 --- a/spec/lib/gitlab/daemon_spec.rb +++ b/spec/lib/gitlab/daemon_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Daemon do diff --git a/spec/lib/gitlab/danger/helper_spec.rb b/spec/lib/gitlab/danger/helper_spec.rb index 92d90ac2fef..f11f68ab3c2 100644 --- a/spec/lib/gitlab/danger/helper_spec.rb +++ b/spec/lib/gitlab/danger/helper_spec.rb @@ -85,6 +85,20 @@ describe Gitlab::Danger::Helper do end end + describe '#markdown_list' do + it 'creates a markdown list of items' do + items = %w[a b] + + expect(helper.markdown_list(items)).to eq("* `a`\n* `b`") + end + + it 'wraps items in <details> when there are more than 10 items' do + items = ('a'..'k').to_a + + expect(helper.markdown_list(items)).to match(%r{<details>[^<]+</details>}) + end + end + describe '#changes_by_category' do it 'categorizes changed files' do expect(fake_git).to receive(:added_files) { %w[foo foo.md foo.rb foo.js db/foo lib/gitlab/database/foo.rb qa/foo ee/changelogs/foo.yml] } @@ -224,4 +238,20 @@ describe Gitlab::Danger::Helper do expect(teammates.map(&:username)).to eq(usernames) end end + + describe '#missing_database_labels' do + subject { helper.missing_database_labels(current_mr_labels) } + + context 'when current merge request has ~database::review pending' do + let(:current_mr_labels) { ['database::review pending', 'feature'] } + + it { is_expected.to match_array(['database']) } + end + + context 'when current merge request does not have ~database::review pending' do + let(:current_mr_labels) { ['feature'] } + + it { is_expected.to match_array(['database', 'database::review pending']) } + end + end end diff --git a/spec/lib/gitlab/danger/teammate_spec.rb b/spec/lib/gitlab/danger/teammate_spec.rb index 6a6cf1429c8..171f2344e82 100644 --- a/spec/lib/gitlab/danger/teammate_spec.rb +++ b/spec/lib/gitlab/danger/teammate_spec.rb @@ -40,6 +40,14 @@ describe Gitlab::Danger::Teammate do it '#maintainer? returns false' do expect(subject.maintainer?(project, :test, labels)).to be_falsey end + + context 'when hyperlink is mangled in the role' do + let(:role) { '<a href="#">Test Automation Engineer</a>, Create' } + + it '#reviewer? returns true' do + expect(subject.reviewer?(project, :test, labels)).to be_truthy + end + end end context 'when role is Test Automation Engineer, Manage' do diff --git a/spec/lib/gitlab/data_builder/build_spec.rb b/spec/lib/gitlab/data_builder/build_spec.rb index 14fe196a986..b170ef788d9 100644 --- a/spec/lib/gitlab/data_builder/build_spec.rb +++ b/spec/lib/gitlab/data_builder/build_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DataBuilder::Build do diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb index 1b5dd2538e0..3c26daba5a5 100644 --- a/spec/lib/gitlab/data_builder/note_spec.rb +++ b/spec/lib/gitlab/data_builder/note_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DataBuilder::Note do diff --git a/spec/lib/gitlab/data_builder/pipeline_spec.rb b/spec/lib/gitlab/data_builder/pipeline_spec.rb index 1f36fd5c6ef..4afb7195b7b 100644 --- a/spec/lib/gitlab/data_builder/pipeline_spec.rb +++ b/spec/lib/gitlab/data_builder/pipeline_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DataBuilder::Pipeline do diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb index 46ad674a1eb..cc31f88d365 100644 --- a/spec/lib/gitlab/data_builder/push_spec.rb +++ b/spec/lib/gitlab/data_builder/push_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DataBuilder::Push do diff --git a/spec/lib/gitlab/data_builder/wiki_page_spec.rb b/spec/lib/gitlab/data_builder/wiki_page_spec.rb index 9c8bdf4b032..404d54bf2da 100644 --- a/spec/lib/gitlab/data_builder/wiki_page_spec.rb +++ b/spec/lib/gitlab/data_builder/wiki_page_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DataBuilder::WikiPage do diff --git a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb index 3991c737a26..111833a506a 100644 --- a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb +++ b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::Count::ExactCountStrategy do @@ -23,18 +25,4 @@ describe Gitlab::Database::Count::ExactCountStrategy do expect(subject).to eq({}) end end - - describe '.enabled?' do - it 'is enabled for PostgreSQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - - expect(described_class.enabled?).to be_truthy - end - - it 'is enabled for MySQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(described_class.enabled?).to be_truthy - end - end end diff --git a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb index bd3c66d0548..08032d19d14 100644 --- a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb +++ b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::Count::ReltuplesCountStrategy do @@ -8,7 +10,7 @@ describe Gitlab::Database::Count::ReltuplesCountStrategy do subject { described_class.new(models).count } - describe '#count', :postgresql do + describe '#count' do let(:models) { [Project, Identity] } context 'when reltuples is up to date' do @@ -48,18 +50,4 @@ describe Gitlab::Database::Count::ReltuplesCountStrategy do end end end - - describe '.enabled?' do - it 'is enabled for PostgreSQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - - expect(described_class.enabled?).to be_truthy - end - - it 'is disabled for MySQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(described_class.enabled?).to be_falsey - end - end end diff --git a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb index 40d810b195b..0c480709c22 100644 --- a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb +++ b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::Count::TablesampleCountStrategy do @@ -12,7 +14,7 @@ describe Gitlab::Database::Count::TablesampleCountStrategy do subject { strategy.count } - describe '#count', :postgresql do + describe '#count' do let(:estimates) do { Project => threshold + 1, @@ -56,22 +58,4 @@ describe Gitlab::Database::Count::TablesampleCountStrategy do end end end - - describe '.enabled?' do - before do - stub_feature_flags(tablesample_counts: true) - end - - it 'is enabled for PostgreSQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - - expect(described_class.enabled?).to be_truthy - end - - it 'is disabled for MySQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(described_class.enabled?).to be_falsey - end - end end diff --git a/spec/lib/gitlab/database/count_spec.rb b/spec/lib/gitlab/database/count_spec.rb index 1d096b8fa7c..71c25f23b6b 100644 --- a/spec/lib/gitlab/database/count_spec.rb +++ b/spec/lib/gitlab/database/count_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::Count do @@ -9,24 +11,13 @@ describe Gitlab::Database::Count do let(:models) { [Project, Identity] } context '.approximate_counts' do - context 'selecting strategies' do - let(:strategies) { [double('s1', enabled?: true), double('s2', enabled?: false)] } - - it 'uses only enabled strategies' do - expect(strategies[0]).to receive(:new).and_return(double('strategy1', count: {})) - expect(strategies[1]).not_to receive(:new) - - described_class.approximate_counts(models, strategies: strategies) - end - end - context 'fallbacks' do subject { described_class.approximate_counts(models, strategies: strategies) } let(:strategies) do [ - double('s1', enabled?: true, new: first_strategy), - double('s2', enabled?: true, new: second_strategy) + double('s1', new: first_strategy), + double('s2', new: second_strategy) ] end diff --git a/spec/lib/gitlab/database/grant_spec.rb b/spec/lib/gitlab/database/grant_spec.rb index 5ebf3f399b6..02697eb2a16 100644 --- a/spec/lib/gitlab/database/grant_spec.rb +++ b/spec/lib/gitlab/database/grant_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::Grant do @@ -8,7 +10,7 @@ describe Gitlab::Database::Grant do expect(described_class.create_and_execute_trigger?('users')).to eq(true) end - it 'returns false when the user can not create and/or execute a trigger', :postgresql do + it 'returns false when the user can not create and/or execute a trigger' do # In case of MySQL the user may have SUPER permissions, making it # impossible to have `false` returned when running tests; hence we only # run these tests on PostgreSQL. diff --git a/spec/lib/gitlab/database/median_spec.rb b/spec/lib/gitlab/database/median_spec.rb deleted file mode 100644 index 1b5e30089ce..00000000000 --- a/spec/lib/gitlab/database/median_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Database::Median do - let(:dummy_class) do - Class.new do - include Gitlab::Database::Median - end - end - - subject(:median) { dummy_class.new } - - describe '#median_datetimes' do - it 'raises NotSupportedError', :mysql do - expect { median.median_datetimes(nil, nil, nil, :project_id) }.to raise_error(dummy_class::NotSupportedError, "partition_column is not supported for MySQL") - end - end -end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 7409572288c..2731fc8573f 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::MigrationHelpers do @@ -9,35 +11,87 @@ describe Gitlab::Database::MigrationHelpers do allow(model).to receive(:puts) end + describe '#remove_timestamps' do + it 'can remove the default timestamps' do + Gitlab::Database::MigrationHelpers::DEFAULT_TIMESTAMP_COLUMNS.each do |column_name| + expect(model).to receive(:remove_column).with(:foo, column_name) + end + + model.remove_timestamps(:foo) + end + + it 'can remove custom timestamps' do + expect(model).to receive(:remove_column).with(:foo, :bar) + + model.remove_timestamps(:foo, columns: [:bar]) + end + end + describe '#add_timestamps_with_timezone' do + let(:in_transaction) { false } + before do - allow(model).to receive(:transaction_open?).and_return(false) + allow(model).to receive(:transaction_open?).and_return(in_transaction) + allow(model).to receive(:disable_statement_timeout) end - context 'using PostgreSQL' do - before do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - allow(model).to receive(:disable_statement_timeout) + it 'adds "created_at" and "updated_at" fields with the "datetime_with_timezone" data type' do + Gitlab::Database::MigrationHelpers::DEFAULT_TIMESTAMP_COLUMNS.each do |column_name| + expect(model).to receive(:add_column).with(:foo, column_name, :datetime_with_timezone, { null: false }) end - it 'adds "created_at" and "updated_at" fields with the "datetime_with_timezone" data type' do - expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, { null: false }) - expect(model).to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, { null: false }) + model.add_timestamps_with_timezone(:foo) + end - model.add_timestamps_with_timezone(:foo) + it 'can disable the NOT NULL constraint' do + Gitlab::Database::MigrationHelpers::DEFAULT_TIMESTAMP_COLUMNS.each do |column_name| + expect(model).to receive(:add_column).with(:foo, column_name, :datetime_with_timezone, { null: true }) end + + model.add_timestamps_with_timezone(:foo, null: true) + end + + it 'can add just one column' do + expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, anything) + expect(model).not_to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, anything) + + model.add_timestamps_with_timezone(:foo, columns: [:created_at]) end - context 'using MySQL' do + it 'can add choice of acceptable columns' do + expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, anything) + expect(model).to receive(:add_column).with(:foo, :deleted_at, :datetime_with_timezone, anything) + expect(model).not_to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, anything) + + model.add_timestamps_with_timezone(:foo, columns: [:created_at, :deleted_at]) + end + + it 'cannot add unacceptable column names' do + expect do + model.add_timestamps_with_timezone(:foo, columns: [:bar]) + end.to raise_error %r/Illegal timestamp column name/ + end + + context 'in a transaction' do + let(:in_transaction) { true } + before do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) + allow(model).to receive(:add_column).with(any_args).and_call_original + allow(model).to receive(:add_column) + .with(:foo, anything, :datetime_with_timezone, anything) + .and_return(nil) end - it 'adds "created_at" and "updated_at" fields with "datetime_with_timezone" data type' do - expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, { null: false }) - expect(model).to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, { null: false }) + it 'cannot add a default value' do + expect do + model.add_timestamps_with_timezone(:foo, default: :i_cause_an_error) + end.to raise_error %r/add_timestamps_with_timezone/ + end - model.add_timestamps_with_timezone(:foo) + it 'can add columns without defaults' do + expect do + model.add_timestamps_with_timezone(:foo) + end.not_to raise_error end end end @@ -46,56 +100,29 @@ describe Gitlab::Database::MigrationHelpers do context 'outside a transaction' do before do allow(model).to receive(:transaction_open?).and_return(false) + allow(model).to receive(:disable_statement_timeout).and_call_original end - context 'using PostgreSQL', :postgresql do - before do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - allow(model).to receive(:disable_statement_timeout).and_call_original - end - - it 'creates the index concurrently' do - expect(model).to receive(:add_index) - .with(:users, :foo, algorithm: :concurrently) - - model.add_concurrent_index(:users, :foo) - end - - it 'creates unique index concurrently' do - expect(model).to receive(:add_index) - .with(:users, :foo, { algorithm: :concurrently, unique: true }) - - model.add_concurrent_index(:users, :foo, unique: true) - end + it 'creates the index concurrently' do + expect(model).to receive(:add_index) + .with(:users, :foo, algorithm: :concurrently) - it 'does nothing if the index exists already' do - expect(model).to receive(:index_exists?) - .with(:users, :foo, { algorithm: :concurrently, unique: true }).and_return(true) - expect(model).not_to receive(:add_index) - - model.add_concurrent_index(:users, :foo, unique: true) - end + model.add_concurrent_index(:users, :foo) end - context 'using MySQL' do - before do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) - end - - it 'creates a regular index' do - expect(model).to receive(:add_index) - .with(:users, :foo, {}) + it 'creates unique index concurrently' do + expect(model).to receive(:add_index) + .with(:users, :foo, { algorithm: :concurrently, unique: true }) - model.add_concurrent_index(:users, :foo) - end + model.add_concurrent_index(:users, :foo, unique: true) + end - it 'does nothing if the index exists already' do - expect(model).to receive(:index_exists?) - .with(:users, :foo, { unique: true }).and_return(true) - expect(model).not_to receive(:add_index) + it 'does nothing if the index exists already' do + expect(model).to receive(:index_exists?) + .with(:users, :foo, { algorithm: :concurrently, unique: true }).and_return(true) + expect(model).not_to receive(:add_index) - model.add_concurrent_index(:users, :foo, unique: true) - end + model.add_concurrent_index(:users, :foo, unique: true) end end @@ -115,28 +142,23 @@ describe Gitlab::Database::MigrationHelpers do allow(model).to receive(:transaction_open?).and_return(false) allow(model).to receive(:index_exists?).and_return(true) allow(model).to receive(:disable_statement_timeout).and_call_original + allow(model).to receive(:supports_drop_index_concurrently?).and_return(true) end - context 'using PostgreSQL' do - before do - allow(model).to receive(:supports_drop_index_concurrently?).and_return(true) - end - - describe 'by column name' do - it 'removes the index concurrently' do - expect(model).to receive(:remove_index) - .with(:users, { algorithm: :concurrently, column: :foo }) + describe 'by column name' do + it 'removes the index concurrently' do + expect(model).to receive(:remove_index) + .with(:users, { algorithm: :concurrently, column: :foo }) - model.remove_concurrent_index(:users, :foo) - end + model.remove_concurrent_index(:users, :foo) + end - it 'does nothing if the index does not exist' do - expect(model).to receive(:index_exists?) - .with(:users, :foo, { algorithm: :concurrently, unique: true }).and_return(false) - expect(model).not_to receive(:remove_index) + it 'does nothing if the index does not exist' do + expect(model).to receive(:index_exists?) + .with(:users, :foo, { algorithm: :concurrently, unique: true }).and_return(false) + expect(model).not_to receive(:remove_index) - model.remove_concurrent_index(:users, :foo, unique: true) - end + model.remove_concurrent_index(:users, :foo, unique: true) end describe 'by index name' do @@ -159,17 +181,6 @@ describe Gitlab::Database::MigrationHelpers do end end end - - context 'using MySQL' do - it 'removes an index' do - expect(Gitlab::Database).to receive(:postgresql?).and_return(false).twice - - expect(model).to receive(:remove_index) - .with(:users, { column: :foo }) - - model.remove_concurrent_index(:users, :foo) - end - end end context 'inside a transaction' do @@ -202,88 +213,44 @@ describe Gitlab::Database::MigrationHelpers do allow(model).to receive(:transaction_open?).and_return(false) end - context 'using MySQL' do - before do - allow(Gitlab::Database).to receive(:mysql?).and_return(true) - end - - it 'creates a regular foreign key' do - expect(model).to receive(:add_foreign_key) - .with(:projects, :users, column: :user_id, on_delete: :cascade) + it 'creates a concurrent foreign key and validates it' do + expect(model).to receive(:disable_statement_timeout).and_call_original + expect(model).to receive(:execute).with(/statement_timeout/) + expect(model).to receive(:execute).ordered.with(/NOT VALID/) + expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/) + expect(model).to receive(:execute).with(/RESET ALL/) - model.add_concurrent_foreign_key(:projects, :users, column: :user_id) - end - - it 'allows the use of a custom key name' do - expect(model).to receive(:add_foreign_key).with( - :projects, - :users, - column: :user_id, - on_delete: :cascade, - name: :foo - ) - - model.add_concurrent_foreign_key( - :projects, - :users, - column: :user_id, - name: :foo - ) - end - - it 'does not create a foreign key if it exists already' do - expect(model).to receive(:foreign_key_exists?).with(:projects, :users, column: :user_id).and_return(true) - expect(model).not_to receive(:add_foreign_key) - - model.add_concurrent_foreign_key(:projects, :users, column: :user_id) - end + model.add_concurrent_foreign_key(:projects, :users, column: :user_id) end - context 'using PostgreSQL' do - before do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - allow(Gitlab::Database).to receive(:mysql?).and_return(false) - end - - it 'creates a concurrent foreign key and validates it' do - expect(model).to receive(:disable_statement_timeout).and_call_original - expect(model).to receive(:execute).with(/statement_timeout/) - expect(model).to receive(:execute).ordered.with(/NOT VALID/) - expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/) - expect(model).to receive(:execute).with(/RESET ALL/) - - model.add_concurrent_foreign_key(:projects, :users, column: :user_id) - end - - it 'appends a valid ON DELETE statement' do - expect(model).to receive(:disable_statement_timeout).and_call_original - expect(model).to receive(:execute).with(/statement_timeout/) - expect(model).to receive(:execute).with(/ON DELETE SET NULL/) - expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/) - expect(model).to receive(:execute).with(/RESET ALL/) + it 'appends a valid ON DELETE statement' do + expect(model).to receive(:disable_statement_timeout).and_call_original + expect(model).to receive(:execute).with(/statement_timeout/) + expect(model).to receive(:execute).with(/ON DELETE SET NULL/) + expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/) + expect(model).to receive(:execute).with(/RESET ALL/) - model.add_concurrent_foreign_key(:projects, :users, - column: :user_id, - on_delete: :nullify) - end + model.add_concurrent_foreign_key(:projects, :users, + column: :user_id, + on_delete: :nullify) + end - it 'does not create a foreign key if it exists already' do - expect(model).to receive(:foreign_key_exists?).with(:projects, :users, column: :user_id).and_return(true) - expect(model).not_to receive(:execute).with(/ADD CONSTRAINT/) - expect(model).to receive(:execute).with(/VALIDATE CONSTRAINT/) + it 'does not create a foreign key if it exists already' do + expect(model).to receive(:foreign_key_exists?).with(:projects, :users, column: :user_id).and_return(true) + expect(model).not_to receive(:execute).with(/ADD CONSTRAINT/) + expect(model).to receive(:execute).with(/VALIDATE CONSTRAINT/) - model.add_concurrent_foreign_key(:projects, :users, column: :user_id) - end + model.add_concurrent_foreign_key(:projects, :users, column: :user_id) + end - it 'allows the use of a custom key name' do - expect(model).to receive(:disable_statement_timeout).and_call_original - expect(model).to receive(:execute).with(/statement_timeout/) - expect(model).to receive(:execute).ordered.with(/NOT VALID/) - expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT.+foo/) - expect(model).to receive(:execute).with(/RESET ALL/) + it 'allows the use of a custom key name' do + expect(model).to receive(:disable_statement_timeout).and_call_original + expect(model).to receive(:execute).with(/statement_timeout/) + expect(model).to receive(:execute).ordered.with(/NOT VALID/) + expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT.+foo/) + expect(model).to receive(:execute).with(/RESET ALL/) - model.add_concurrent_foreign_key(:projects, :users, column: :user_id, name: :foo) - end + model.add_concurrent_foreign_key(:projects, :users, column: :user_id, name: :foo) end end end @@ -322,48 +289,43 @@ describe Gitlab::Database::MigrationHelpers do end describe '#disable_statement_timeout' do - context 'using PostgreSQL' do - it 'disables statement timeouts to current transaction only' do - expect(Gitlab::Database).to receive(:postgresql?).and_return(true) + it 'disables statement timeouts to current transaction only' do + expect(model).to receive(:execute).with('SET LOCAL statement_timeout TO 0') - expect(model).to receive(:execute).with('SET LOCAL statement_timeout TO 0') + model.disable_statement_timeout + end - model.disable_statement_timeout + # this specs runs without an enclosing transaction (:delete truncation method for db_cleaner) + context 'with real environment', :delete do + before do + model.execute("SET statement_timeout TO '20000'") end - # this specs runs without an enclosing transaction (:delete truncation method for db_cleaner) - context 'with real environment', :postgresql, :delete do - before do - model.execute("SET statement_timeout TO '20000'") - end - - after do - model.execute('RESET ALL') - end - - it 'defines statement to 0 only for current transaction' do - expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s') + after do + model.execute('RESET ALL') + end - model.connection.transaction do - model.disable_statement_timeout - expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('0') - end + it 'defines statement to 0 only for current transaction' do + expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s') - expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s') + model.connection.transaction do + model.disable_statement_timeout + expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('0') end + + expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s') end context 'when passing a blocks' do it 'disables statement timeouts on session level and executes the block' do - expect(Gitlab::Database).to receive(:postgresql?).and_return(true) expect(model).to receive(:execute).with('SET statement_timeout TO 0') - expect(model).to receive(:execute).with('RESET ALL') + expect(model).to receive(:execute).with('RESET ALL').at_least(:once) expect { |block| model.disable_statement_timeout(&block) }.to yield_control end # this specs runs without an enclosing transaction (:delete truncation method for db_cleaner) - context 'with real environment', :postgresql, :delete do + context 'with real environment', :delete do before do model.execute("SET statement_timeout TO '20000'") end @@ -386,69 +348,17 @@ describe Gitlab::Database::MigrationHelpers do end end end - - context 'using MySQL' do - it 'does nothing' do - expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(model).not_to receive(:execute) - - model.disable_statement_timeout - end - - context 'when passing a blocks' do - it 'executes the block of code' do - expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(model).not_to receive(:execute) - - expect { |block| model.disable_statement_timeout(&block) }.to yield_control - end - end - end end describe '#true_value' do - context 'using PostgreSQL' do - before do - expect(Gitlab::Database).to receive(:postgresql?).and_return(true) - end - - it 'returns the appropriate value' do - expect(model.true_value).to eq("'t'") - end - end - - context 'using MySQL' do - before do - expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - end - - it 'returns the appropriate value' do - expect(model.true_value).to eq(1) - end + it 'returns the appropriate value' do + expect(model.true_value).to eq("'t'") end end describe '#false_value' do - context 'using PostgreSQL' do - before do - expect(Gitlab::Database).to receive(:postgresql?).and_return(true) - end - - it 'returns the appropriate value' do - expect(model.false_value).to eq("'f'") - end - end - - context 'using MySQL' do - before do - expect(Gitlab::Database).to receive(:postgresql?).and_return(false) - end - - it 'returns the appropriate value' do - expect(model.false_value).to eq(0) - end + it 'returns the appropriate value' do + expect(model.false_value).to eq("'f'") end end @@ -640,77 +550,37 @@ describe Gitlab::Database::MigrationHelpers do before do allow(model).to receive(:transaction_open?).and_return(false) allow(model).to receive(:column_for).and_return(old_column) - - # Since MySQL and PostgreSQL use different quoting styles we'll just - # stub the methods used for this to make testing easier. - allow(model).to receive(:quote_column_name) { |name| name.to_s } - allow(model).to receive(:quote_table_name) { |name| name.to_s } end - context 'using MySQL' do - it 'renames a column concurrently' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) + it 'renames a column concurrently' do + expect(model).to receive(:check_trigger_permissions!).with(:users) - expect(model).to receive(:check_trigger_permissions!).with(:users) + expect(model).to receive(:install_rename_triggers_for_postgresql) + .with(trigger_name, '"users"', '"old"', '"new"') - expect(model).to receive(:install_rename_triggers_for_mysql) - .with(trigger_name, 'users', 'old', 'new') + expect(model).to receive(:add_column) + .with(:users, :new, :integer, + limit: old_column.limit, + precision: old_column.precision, + scale: old_column.scale) - expect(model).to receive(:add_column) - .with(:users, :new, :integer, - limit: old_column.limit, - precision: old_column.precision, - scale: old_column.scale) + expect(model).to receive(:change_column_default) + .with(:users, :new, old_column.default) - expect(model).to receive(:change_column_default) - .with(:users, :new, old_column.default) + expect(model).to receive(:update_column_in_batches) - expect(model).to receive(:update_column_in_batches) + expect(model).to receive(:change_column_null).with(:users, :new, false) - expect(model).to receive(:change_column_null).with(:users, :new, false) + expect(model).to receive(:copy_indexes).with(:users, :old, :new) + expect(model).to receive(:copy_foreign_keys).with(:users, :old, :new) - expect(model).to receive(:copy_indexes).with(:users, :old, :new) - expect(model).to receive(:copy_foreign_keys).with(:users, :old, :new) - - model.rename_column_concurrently(:users, :old, :new) - end - end - - context 'using PostgreSQL' do - it 'renames a column concurrently' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - - expect(model).to receive(:check_trigger_permissions!).with(:users) - - expect(model).to receive(:install_rename_triggers_for_postgresql) - .with(trigger_name, 'users', 'old', 'new') - - expect(model).to receive(:add_column) - .with(:users, :new, :integer, - limit: old_column.limit, - precision: old_column.precision, - scale: old_column.scale) - - expect(model).to receive(:change_column_default) - .with(:users, :new, old_column.default) - - expect(model).to receive(:update_column_in_batches) - - expect(model).to receive(:change_column_null).with(:users, :new, false) - - expect(model).to receive(:copy_indexes).with(:users, :old, :new) - expect(model).to receive(:copy_foreign_keys).with(:users, :old, :new) - - model.rename_column_concurrently(:users, :old, :new) - end + model.rename_column_concurrently(:users, :old, :new) end end end describe '#cleanup_concurrent_column_rename' do - it 'cleans up the renaming procedure for PostgreSQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(true) - + it 'cleans up the renaming procedure' do expect(model).to receive(:check_trigger_permissions!).with(:users) expect(model).to receive(:remove_rename_triggers_for_postgresql) @@ -720,19 +590,6 @@ describe Gitlab::Database::MigrationHelpers do model.cleanup_concurrent_column_rename(:users, :old, :new) end - - it 'cleans up the renaming procedure for MySQL' do - allow(Gitlab::Database).to receive(:postgresql?).and_return(false) - - expect(model).to receive(:check_trigger_permissions!).with(:users) - - expect(model).to receive(:remove_rename_triggers_for_mysql) - .with(/trigger_.{12}/) - - expect(model).to receive(:remove_column).with(:users, :old) - - model.cleanup_concurrent_column_rename(:users, :old, :new) - end end describe '#change_column_type_concurrently' do @@ -768,18 +625,6 @@ describe Gitlab::Database::MigrationHelpers do end end - describe '#install_rename_triggers_for_mysql' do - it 'installs the triggers for MySQL' do - expect(model).to receive(:execute) - .with(/CREATE TRIGGER foo_insert.+ON users/m) - - expect(model).to receive(:execute) - .with(/CREATE TRIGGER foo_update.+ON users/m) - - model.install_rename_triggers_for_mysql('foo', :users, :old, :new) - end - end - describe '#remove_rename_triggers_for_postgresql' do it 'removes the function and trigger' do expect(model).to receive(:execute).with('DROP TRIGGER IF EXISTS foo ON bar') @@ -789,15 +634,6 @@ describe Gitlab::Database::MigrationHelpers do end end - describe '#remove_rename_triggers_for_mysql' do - it 'removes the triggers' do - expect(model).to receive(:execute).with('DROP TRIGGER IF EXISTS foo_insert') - expect(model).to receive(:execute).with('DROP TRIGGER IF EXISTS foo_update') - - model.remove_rename_triggers_for_mysql('foo') - end - end - describe '#rename_trigger_name' do it 'returns a String' do expect(model.rename_trigger_name(:users, :foo, :bar)) @@ -1017,26 +853,9 @@ describe Gitlab::Database::MigrationHelpers do end describe '#replace_sql' do - context 'using postgres' do - before do - allow(Gitlab::Database).to receive(:mysql?).and_return(false) - end - - it 'builds the sql with correct functions' do - expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s) - .to include('regexp_replace') - end - end - - context 'using mysql' do - before do - allow(Gitlab::Database).to receive(:mysql?).and_return(true) - end - - it 'builds the sql with the correct functions' do - expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s) - .to include('locate', 'insert') - end + it 'builds the sql with correct functions' do + expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s) + .to include('regexp_replace') end describe 'results' do @@ -1393,7 +1212,7 @@ describe Gitlab::Database::MigrationHelpers do .to be_falsy end - context 'when an index with a function exists', :postgresql do + context 'when an index with a function exists' do before do ActiveRecord::Base.connection.execute( 'CREATE INDEX test_index ON projects (LOWER(path));' diff --git a/spec/lib/gitlab/database/multi_threaded_migration_spec.rb b/spec/lib/gitlab/database/multi_threaded_migration_spec.rb index 6c45f13bb5a..53c001fbc1b 100644 --- a/spec/lib/gitlab/database/multi_threaded_migration_spec.rb +++ b/spec/lib/gitlab/database/multi_threaded_migration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::MultiThreadedMigration do diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb index 81419e51635..612c418e8bb 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :delete do diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb index b6096d4faf6..8c4d7e323fa 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :delete do diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb index d4d7a83921c..1ccdb1d9447 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :delete do diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb index ddd54a669a3..b09258ae227 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' shared_examples 'renames child namespaces' do |type| diff --git a/spec/lib/gitlab/database/sha_attribute_spec.rb b/spec/lib/gitlab/database/sha_attribute_spec.rb index 778bfa2cc47..c6fc55291f5 100644 --- a/spec/lib/gitlab/database/sha_attribute_spec.rb +++ b/spec/lib/gitlab/database/sha_attribute_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database::ShaAttribute do @@ -10,11 +12,7 @@ describe Gitlab::Database::ShaAttribute do end let(:binary_from_db) do - if Gitlab::Database.postgresql? - "\\x#{sha}" - else - binary_sha - end + "\\x#{sha}" end let(:attribute) { described_class.new } diff --git a/spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb b/spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb index 57c8bafd488..eed2a1b7b48 100644 --- a/spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb +++ b/spec/lib/gitlab/database_importers/common_metrics/importer_spec.rb @@ -7,8 +7,8 @@ describe Gitlab::DatabaseImporters::CommonMetrics::Importer do context "does import common_metrics.yml" do let(:groups) { subject.content['panel_groups'] } - let(:panels) { groups.map { |group| group['panels'] }.flatten } - let(:metrics) { panels.map { |group| group['metrics'] }.flatten } + let(:panels) { groups.flat_map { |group| group['panels'] } } + let(:metrics) { panels.flat_map { |group| group['metrics'] } } let(:metric_ids) { metrics.map { |metric| metric['id'] } } before do diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 5f57cd6b825..77e58b6d5c7 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Database do @@ -15,28 +17,18 @@ describe Gitlab::Database do it 'returns the name of the adapter' do expect(described_class.adapter_name).to be_an_instance_of(String) end - end - - describe '.human_adapter_name' do - it 'returns PostgreSQL when using PostgreSQL' do - allow(described_class).to receive(:postgresql?).and_return(true) - expect(described_class.human_adapter_name).to eq('PostgreSQL') - end - - it 'returns MySQL when using MySQL' do + it 'returns Unknown when using anything else' do allow(described_class).to receive(:postgresql?).and_return(false) - expect(described_class.human_adapter_name).to eq('MySQL') + expect(described_class.human_adapter_name).to eq('Unknown') end end - # These are just simple smoke tests to check if the methods work (regardless - # of what they may return). - describe '.mysql?' do - subject { described_class.mysql? } - - it { is_expected.to satisfy { |val| val == true || val == false } } + describe '.human_adapter_name' do + it 'returns PostgreSQL when using PostgreSQL' do + expect(described_class.human_adapter_name).to eq('PostgreSQL') + end end describe '.postgresql?' do @@ -52,15 +44,6 @@ describe Gitlab::Database do described_class.instance_variable_set(:@version, nil) end - context "on mysql" do - it "extracts the version number" do - allow(described_class).to receive(:database_version) - .and_return("5.7.12-standard") - - expect(described_class.version).to eq '5.7.12-standard' - end - end - context "on postgresql" do it "extracts the version number" do allow(described_class).to receive(:database_version) @@ -80,21 +63,18 @@ describe Gitlab::Database do end describe '.postgresql_9_or_less?' do - it 'returns false when using MySQL' do - allow(described_class).to receive(:postgresql?).and_return(false) - - expect(described_class.postgresql_9_or_less?).to eq(false) + it 'returns true when using postgresql 8.4' do + allow(described_class).to receive(:version).and_return('8.4') + expect(described_class.postgresql_9_or_less?).to eq(true) end it 'returns true when using PostgreSQL 9.6' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.6') expect(described_class.postgresql_9_or_less?).to eq(true) end it 'returns false when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('10') expect(described_class.postgresql_9_or_less?).to eq(false) @@ -102,53 +82,33 @@ describe Gitlab::Database do end describe '.postgresql_minimum_supported_version?' do - it 'returns false when not using PostgreSQL' do - allow(described_class).to receive(:postgresql?).and_return(false) + it 'returns false when using PostgreSQL 9.5' do + allow(described_class).to receive(:version).and_return('9.5') expect(described_class.postgresql_minimum_supported_version?).to eq(false) end - context 'when using PostgreSQL' do - before do - allow(described_class).to receive(:postgresql?).and_return(true) - end - - it 'returns false when using PostgreSQL 9.5' do - allow(described_class).to receive(:version).and_return('9.5') - - expect(described_class.postgresql_minimum_supported_version?).to eq(false) - end - - it 'returns true when using PostgreSQL 9.6' do - allow(described_class).to receive(:version).and_return('9.6') + it 'returns true when using PostgreSQL 9.6' do + allow(described_class).to receive(:version).and_return('9.6') - expect(described_class.postgresql_minimum_supported_version?).to eq(true) - end + expect(described_class.postgresql_minimum_supported_version?).to eq(true) + end - it 'returns true when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:version).and_return('10') + it 'returns true when using PostgreSQL 10 or newer' do + allow(described_class).to receive(:version).and_return('10') - expect(described_class.postgresql_minimum_supported_version?).to eq(true) - end + expect(described_class.postgresql_minimum_supported_version?).to eq(true) end end describe '.join_lateral_supported?' do - it 'returns false when using MySQL' do - allow(described_class).to receive(:postgresql?).and_return(false) - - expect(described_class.join_lateral_supported?).to eq(false) - end - it 'returns false when using PostgreSQL 9.2' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.2.1') expect(described_class.join_lateral_supported?).to eq(false) end it 'returns true when using PostgreSQL 9.3.0 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.3.0') expect(described_class.join_lateral_supported?).to eq(true) @@ -156,21 +116,13 @@ describe Gitlab::Database do end describe '.replication_slots_supported?' do - it 'returns false when using MySQL' do - allow(described_class).to receive(:postgresql?).and_return(false) - - expect(described_class.replication_slots_supported?).to eq(false) - end - it 'returns false when using PostgreSQL 9.3' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.3.1') expect(described_class.replication_slots_supported?).to eq(false) end it 'returns true when using PostgreSQL 9.4.0 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.4.0') expect(described_class.replication_slots_supported?).to eq(true) @@ -179,14 +131,12 @@ describe Gitlab::Database do describe '.pg_wal_lsn_diff' do it 'returns old name when using PostgreSQL 9.6' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.6') expect(described_class.pg_wal_lsn_diff).to eq('pg_xlog_location_diff') end it 'returns new name when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('10') expect(described_class.pg_wal_lsn_diff).to eq('pg_wal_lsn_diff') @@ -195,14 +145,12 @@ describe Gitlab::Database do describe '.pg_current_wal_insert_lsn' do it 'returns old name when using PostgreSQL 9.6' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.6') expect(described_class.pg_current_wal_insert_lsn).to eq('pg_current_xlog_insert_location') end it 'returns new name when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('10') expect(described_class.pg_current_wal_insert_lsn).to eq('pg_current_wal_insert_lsn') @@ -211,14 +159,12 @@ describe Gitlab::Database do describe '.pg_last_wal_receive_lsn' do it 'returns old name when using PostgreSQL 9.6' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.6') expect(described_class.pg_last_wal_receive_lsn).to eq('pg_last_xlog_receive_location') end it 'returns new name when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('10') expect(described_class.pg_last_wal_receive_lsn).to eq('pg_last_wal_receive_lsn') @@ -227,14 +173,12 @@ describe Gitlab::Database do describe '.pg_last_wal_replay_lsn' do it 'returns old name when using PostgreSQL 9.6' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('9.6') expect(described_class.pg_last_wal_replay_lsn).to eq('pg_last_xlog_replay_location') end it 'returns new name when using PostgreSQL 10 or newer' do - allow(described_class).to receive(:postgresql?).and_return(true) allow(described_class).to receive(:version).and_return('10') expect(described_class.pg_last_wal_replay_lsn).to eq('pg_last_wal_replay_lsn') @@ -248,43 +192,13 @@ describe Gitlab::Database do end describe '.nulls_last_order' do - context 'when using PostgreSQL' do - before do - expect(described_class).to receive(:postgresql?).and_return(true) - end - - it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'} - it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'} - end - - context 'when using MySQL' do - before do - expect(described_class).to receive(:postgresql?).and_return(false) - end - - it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column IS NULL, column ASC'} - it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC'} - end + it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'} + it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'} end describe '.nulls_first_order' do - context 'when using PostgreSQL' do - before do - expect(described_class).to receive(:postgresql?).and_return(true) - end - - it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'} - it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'} - end - - context 'when using MySQL' do - before do - expect(described_class).to receive(:postgresql?).and_return(false) - end - - it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC'} - it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column IS NULL, column DESC'} - end + it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'} + it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'} end describe '.with_connection_pool' do @@ -394,10 +308,6 @@ describe Gitlab::Database do end context 'when using PostgreSQL' do - before do - allow(described_class).to receive(:mysql?).and_return(false) - end - it 'allows the returning of the IDs of the inserted rows' do result = double(:result, values: [['10']]) @@ -463,31 +373,15 @@ describe Gitlab::Database do end describe '#true_value' do - it 'returns correct value for PostgreSQL' do - expect(described_class).to receive(:postgresql?).and_return(true) - + it 'returns correct value' do expect(described_class.true_value).to eq "'t'" end - - it 'returns correct value for MySQL' do - expect(described_class).to receive(:postgresql?).and_return(false) - - expect(described_class.true_value).to eq 1 - end end describe '#false_value' do - it 'returns correct value for PostgreSQL' do - expect(described_class).to receive(:postgresql?).and_return(true) - + it 'returns correct value' do expect(described_class.false_value).to eq "'f'" end - - it 'returns correct value for MySQL' do - expect(described_class).to receive(:postgresql?).and_return(false) - - expect(described_class.false_value).to eq 0 - end end describe '.read_only?' do @@ -497,43 +391,32 @@ describe Gitlab::Database do end describe '.db_read_only?' do - context 'when using PostgreSQL' do - before do - allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original - allow(described_class).to receive(:postgresql?).and_return(true) - end - - it 'detects a read only database' do - allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => "t" }]) - - expect(described_class.db_read_only?).to be_truthy - end + before do + allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original + end - it 'detects a read only database' do - allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => true }]) + it 'detects a read only database' do + allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => "t" }]) - expect(described_class.db_read_only?).to be_truthy - end + expect(described_class.db_read_only?).to be_truthy + end - it 'detects a read write database' do - allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => "f" }]) + it 'detects a read only database' do + allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => true }]) - expect(described_class.db_read_only?).to be_falsey - end + expect(described_class.db_read_only?).to be_truthy + end - it 'detects a read write database' do - allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => false }]) + it 'detects a read write database' do + allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => "f" }]) - expect(described_class.db_read_only?).to be_falsey - end + expect(described_class.db_read_only?).to be_falsey end - context 'when using MySQL' do - before do - expect(described_class).to receive(:postgresql?).and_return(false) - end + it 'detects a read write database' do + allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => false }]) - it { expect(described_class.db_read_only?).to be_falsey } + expect(described_class.db_read_only?).to be_falsey end end diff --git a/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb index 3a93d5e1e97..3eb5db51224 100644 --- a/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/cartfile_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::CartfileLinker do diff --git a/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb index 0ebd8994636..6bef6f57e64 100644 --- a/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::ComposerJsonLinker do diff --git a/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb index f00f6b47b94..6ecdb0d1247 100644 --- a/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::GemfileLinker do diff --git a/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb b/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb index 6c6a5d70576..256fe58925c 100644 --- a/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::GemspecLinker do diff --git a/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb index ae5ad39ad11..f620d1b590c 100644 --- a/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/godeps_json_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::GodepsJsonLinker do diff --git a/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb index 9050127af7f..71e9381eaad 100644 --- a/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::PackageJsonLinker do diff --git a/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb index 8f1b523653e..eb81bc07760 100644 --- a/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::PodfileLinker do diff --git a/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb index d4a398c5948..938726dd434 100644 --- a/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/podspec_json_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::PodspecJsonLinker do diff --git a/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb b/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb index bacec830103..540eb2fadfe 100644 --- a/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::PodspecLinker do diff --git a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb index ef952b3abd5..957a87985a2 100644 --- a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker::RequirementsTxtLinker do diff --git a/spec/lib/gitlab/dependency_linker_spec.rb b/spec/lib/gitlab/dependency_linker_spec.rb index 10d2f701298..98e46d62ca0 100644 --- a/spec/lib/gitlab/dependency_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Gitlab::DependencyLinker do diff --git a/spec/lib/gitlab/diff/diff_refs_spec.rb b/spec/lib/gitlab/diff/diff_refs_spec.rb index f9bfb4c469e..e12b46c15ad 100644 --- a/spec/lib/gitlab/diff/diff_refs_spec.rb +++ b/spec/lib/gitlab/diff/diff_refs_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::DiffRefs do diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb index 0697594c725..d89be6fef4e 100644 --- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb +++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::FileCollection::MergeRequestDiff do diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index cc36060f864..716fc8ae987 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::File do diff --git a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb index 2f99febe04e..2e6eb71d37d 100644 --- a/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb +++ b/spec/lib/gitlab/diff/formatters/image_formatter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::Formatters::ImageFormatter do diff --git a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb index 897dc917f6a..33d4994f5db 100644 --- a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb +++ b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::Formatters::TextFormatter do diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb index 5d0a603d11d..f5d3d14ccc5 100644 --- a/spec/lib/gitlab/diff/highlight_spec.rb +++ b/spec/lib/gitlab/diff/highlight_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::Highlight do diff --git a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb index 7e17437fa2a..a668bb464a4 100644 --- a/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb +++ b/spec/lib/gitlab/diff/inline_diff_markdown_marker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::InlineDiffMarkdownMarker do diff --git a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb index 97e65318059..26b99870b31 100644 --- a/spec/lib/gitlab/diff/inline_diff_marker_spec.rb +++ b/spec/lib/gitlab/diff/inline_diff_marker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::InlineDiffMarker do diff --git a/spec/lib/gitlab/diff/inline_diff_spec.rb b/spec/lib/gitlab/diff/inline_diff_spec.rb index 0a41362f606..fdbee3b4230 100644 --- a/spec/lib/gitlab/diff/inline_diff_spec.rb +++ b/spec/lib/gitlab/diff/inline_diff_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::InlineDiff do diff --git a/spec/lib/gitlab/diff/line_mapper_spec.rb b/spec/lib/gitlab/diff/line_mapper_spec.rb index 42750bf9ea1..1739bcd14a8 100644 --- a/spec/lib/gitlab/diff/line_mapper_spec.rb +++ b/spec/lib/gitlab/diff/line_mapper_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::LineMapper do diff --git a/spec/lib/gitlab/diff/line_spec.rb b/spec/lib/gitlab/diff/line_spec.rb index 76d411973c7..29b9951ba4c 100644 --- a/spec/lib/gitlab/diff/line_spec.rb +++ b/spec/lib/gitlab/diff/line_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe Gitlab::Diff::Line do describe '.init_from_hash' do it 'round-trips correctly with to_hash' do diff --git a/spec/lib/gitlab/diff/parallel_diff_spec.rb b/spec/lib/gitlab/diff/parallel_diff_spec.rb index e9fc7be366a..7540da71086 100644 --- a/spec/lib/gitlab/diff/parallel_diff_spec.rb +++ b/spec/lib/gitlab/diff/parallel_diff_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::ParallelDiff do diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb index 80c8c189665..00a446c4e20 100644 --- a/spec/lib/gitlab/diff/parser_spec.rb +++ b/spec/lib/gitlab/diff/parser_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::Parser do diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb index b755cd1aff0..399787635c0 100644 --- a/spec/lib/gitlab/diff/position_spec.rb +++ b/spec/lib/gitlab/diff/position_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::Position do diff --git a/spec/lib/gitlab/diff/position_tracer_spec.rb b/spec/lib/gitlab/diff/position_tracer_spec.rb index 79b33d4d276..47d78e0b18c 100644 --- a/spec/lib/gitlab/diff/position_tracer_spec.rb +++ b/spec/lib/gitlab/diff/position_tracer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Diff::PositionTracer do diff --git a/spec/lib/gitlab/downtime_check/message_spec.rb b/spec/lib/gitlab/downtime_check/message_spec.rb index a5a398abf78..2beb5a19a32 100644 --- a/spec/lib/gitlab/downtime_check/message_spec.rb +++ b/spec/lib/gitlab/downtime_check/message_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DowntimeCheck::Message do diff --git a/spec/lib/gitlab/downtime_check_spec.rb b/spec/lib/gitlab/downtime_check_spec.rb index 1f1e4e0216c..56ad49d528f 100644 --- a/spec/lib/gitlab/downtime_check_spec.rb +++ b/spec/lib/gitlab/downtime_check_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::DowntimeCheck do diff --git a/spec/lib/gitlab/email/attachment_uploader_spec.rb b/spec/lib/gitlab/email/attachment_uploader_spec.rb index 45c690842bc..d66a746284d 100644 --- a/spec/lib/gitlab/email/attachment_uploader_spec.rb +++ b/spec/lib/gitlab/email/attachment_uploader_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" describe Gitlab::Email::AttachmentUploader do diff --git a/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb b/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb index ae61ece8029..65e4e27d56f 100644 --- a/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb +++ b/spec/lib/gitlab/email/hook/additional_headers_interceptor_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Email::Hook::AdditionalHeadersInterceptor do diff --git a/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb b/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb index 4497d4002da..24da47c42ac 100644 --- a/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb +++ b/spec/lib/gitlab/email/hook/delivery_metrics_observer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Email::Hook::DeliveryMetricsObserver do diff --git a/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb b/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb index 91aa3bc7c2e..0c58cf088cc 100644 --- a/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb +++ b/spec/lib/gitlab/email/hook/disable_email_interceptor_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Email::Hook::DisableEmailInterceptor do diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb index 0ec1f931037..84c5b38127e 100644 --- a/spec/lib/gitlab/email/message/repository_push_spec.rb +++ b/spec/lib/gitlab/email/message/repository_push_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Email::Message::RepositoryPush do diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb index 0af978eced3..c9fde06cbae 100644 --- a/spec/lib/gitlab/email/receiver_spec.rb +++ b/spec/lib/gitlab/email/receiver_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::Email::Receiver do diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb index 376d3accd55..646575b2edd 100644 --- a/spec/lib/gitlab/email/reply_parser_spec.rb +++ b/spec/lib/gitlab/email/reply_parser_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" # Inspired in great part by Discourse's Email::Receiver diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb index 88ea98eb1e1..b24b71522ec 100644 --- a/spec/lib/gitlab/encoding_helper_spec.rb +++ b/spec/lib/gitlab/encoding_helper_spec.rb @@ -1,4 +1,6 @@ # coding: utf-8 +# frozen_string_literal: true + require "spec_helper" describe Gitlab::EncodingHelper do @@ -9,8 +11,8 @@ describe Gitlab::EncodingHelper do [ ["nil", nil, nil], ["empty string", "".encode("ASCII-8BIT"), "".encode("UTF-8")], - ["invalid utf-8 encoded string", "my bad string\xE5".force_encoding("UTF-8"), "my bad string"], - ["frozen non-ascii string", "é".force_encoding("ASCII-8BIT").freeze, "é".encode("UTF-8")], + ["invalid utf-8 encoded string", (+"my bad string\xE5").force_encoding("UTF-8"), "my bad string"], + ["frozen non-ascii string", (+"é").force_encoding("ASCII-8BIT").freeze, "é".encode("UTF-8")], [ 'leaves ascii only string as is', 'ascii only string', @@ -23,7 +25,7 @@ describe Gitlab::EncodingHelper do ], [ 'removes invalid bytes from ASCII-8bit encoded multibyte string. This can occur when a git diff match line truncates in the middle of a multibyte character. This occurs after the second word in this example. The test string is as short as we can get while still triggering the error condition when not looking at `detect[:confidence]`.', - "mu ns\xC3\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi ".force_encoding('ASCII-8BIT'), + (+"mu ns\xC3\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi ").force_encoding('ASCII-8BIT'), "mu ns\n Lorem ipsum dolor sit amet, consectetur adipisicing ut\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg kia elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non p\n {: .normal_pn}\n \n-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in\n# *Lorem ipsum\xC3\xB9l\xC3\xB9l\xC3\xA0 dolor\xC3\xB9k\xC3\xB9 sit\xC3\xA8b\xC3\xA8 N\xC3\xA8 amet b\xC3\xA0d\xC3\xAC*\n+# *consectetur\xC3\xB9l\xC3\xB9l\xC3\xA0 adipisicing\xC3\xB9k\xC3\xB9 elit\xC3\xA8b\xC3\xA8 N\xC3\xA8 sed do\xC3\xA0d\xC3\xAC*{: .italic .smcaps}\n \n \xEF\x9B\xA1 eiusmod tempor incididunt, ut\xC3\xAAn\xC3\xB9 labore et dolore. Tw\xC4\x83nj\xC3\xAC magna aliqua. Ut enim ad minim veniam\n {: .normal}\n@@ -9,5 +9,5 @@ quis nostrud\xC3\xAAt\xC3\xB9 exercitiation ullamco laboris m\xC3\xB9s\xC3\xB9k\xC3\xB9abc\xC3\xB9 nisi " ], [ @@ -93,7 +95,7 @@ describe Gitlab::EncodingHelper do [ ["nil", nil, nil], ["empty string", "".encode("ASCII-8BIT"), "".encode("UTF-8")], - ["invalid utf-8 encoded string", "my bad string\xE5".force_encoding("UTF-8"), "my bad stringå"], + ["invalid utf-8 encoded string", (+"my bad string\xE5").force_encoding("UTF-8"), "my bad stringå"], [ "encodes valid utf8 encoded string to utf8", "λ, λ, λ".encode("UTF-8"), @@ -160,12 +162,12 @@ describe Gitlab::EncodingHelper do ], [ 'removes invalid bytes from ASCII-8bit encoded multibyte string.', - "Lorem ipsum\xC3\n dolor sit amet, xy\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg".force_encoding('ASCII-8BIT'), + (+"Lorem ipsum\xC3\n dolor sit amet, xy\xC3\xA0y\xC3\xB9abcd\xC3\xB9efg").force_encoding('ASCII-8BIT'), "Lorem ipsum\n dolor sit amet, xyàyùabcdùefg" ], [ 'handles UTF-16BE encoded strings', - "\xFE\xFF\x00\x41".force_encoding('ASCII-8BIT'), # An "A" prepended with UTF-16 BOM + (+"\xFE\xFF\x00\x41").force_encoding('ASCII-8BIT'), # An "A" prepended with UTF-16 BOM "\xEF\xBB\xBFA" # An "A" prepended with UTF-8 BOM ] ].each do |description, test_string, xpect| diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb index 4a54d641b4e..9ead55075fa 100644 --- a/spec/lib/gitlab/etag_caching/middleware_spec.rb +++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::EtagCaching::Middleware do diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb index a7cb0bb2a87..fbc49d894a6 100644 --- a/spec/lib/gitlab/etag_caching/router_spec.rb +++ b/spec/lib/gitlab/etag_caching/router_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe Gitlab::EtagCaching::Router do diff --git a/spec/lib/gitlab/exclusive_lease_helpers_spec.rb b/spec/lib/gitlab/exclusive_lease_helpers_spec.rb index 5107e1efbbd..c3b706fc538 100644 --- a/spec/lib/gitlab/exclusive_lease_helpers_spec.rb +++ b/spec/lib/gitlab/exclusive_lease_helpers_spec.rb @@ -25,13 +25,13 @@ describe Gitlab::ExclusiveLeaseHelpers, :clean_gitlab_redis_shared_state do end it 'calls the given block' do - expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_control.once + expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_with_args(false) end it 'calls the given block continuously' do - expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_control.once - expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_control.once - expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_control.once + expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_with_args(false) + expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_with_args(false) + expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_with_args(false) end it 'cancels the exclusive lease after the block' do @@ -68,6 +68,15 @@ describe Gitlab::ExclusiveLeaseHelpers, :clean_gitlab_redis_shared_state do expect { subject }.to raise_error('Failed to obtain a lock') end + + context 'when lease is granted after retry' do + it 'yields block with true' do + expect(lease).to receive(:try_obtain).exactly(3).times { nil } + expect(lease).to receive(:try_obtain).once { unique_key } + + expect { |b| class_instance.in_lock(unique_key, &b) }.to yield_with_args(true) + end + end end context 'when sleep second is specified' do diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index a28b95e5bff..dccd50bc472 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -186,6 +186,12 @@ describe Gitlab::Git::Repository, :seed_helper do it { is_expected.to be < 2 } end + describe '#to_s' do + subject { repository.to_s } + + it { is_expected.to eq("<Gitlab::Git::Repository: group/project>") } + end + describe '#object_directory_size' do before do allow(repository.gitaly_repository_client) @@ -256,6 +262,22 @@ describe Gitlab::Git::Repository, :seed_helper do end end + describe '#submodule_urls_for' do + let(:ref) { 'master' } + + it 'returns url mappings for submodules' do + urls = repository.submodule_urls_for(ref) + + expect(urls).to eq({ + "deeper/nested/six" => "git://github.com/randx/six.git", + "gitlab-grack" => "https://gitlab.com/gitlab-org/gitlab-grack.git", + "gitlab-shell" => "https://github.com/gitlabhq/gitlab-shell.git", + "nested/six" => "git://github.com/randx/six.git", + "six" => "git://github.com/randx/six.git" + }) + end + end + describe '#commit_count' do it { expect(repository.commit_count("master")).to eq(25) } it { expect(repository.commit_count("feature")).to eq(9) } diff --git a/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb b/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb index e7ef9d08f80..1a4168f7317 100644 --- a/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb +++ b/spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb @@ -16,21 +16,44 @@ describe Gitlab::Git::RuggedImpl::UseRugged, :seed_helper do end subject(:wrapper) do - klazz = Class.new { include Gitlab::Git::RuggedImpl::UseRugged } + klazz = Class.new do + include Gitlab::Git::RuggedImpl::UseRugged + + def rugged_test(ref, test_number) + end + end + klazz.new end before do + allow(Gitlab::GitalyClient).to receive(:can_use_disk?).and_call_original Gitlab::GitalyClient.instance_variable_set(:@can_use_disk, {}) end + context '#execute_rugged_call', :request_store do + let(:args) { ['refs/heads/master', 1] } + + before do + allow(Gitlab::RuggedInstrumentation).to receive(:peek_enabled?).and_return(true) + end + + it 'instruments Rugged call' do + expect(subject).to receive(:rugged_test).with(args) + + subject.execute_rugged_call(:rugged_test, args) + + expect(Gitlab::RuggedInstrumentation.query_count).to eq(1) + expect(Gitlab::RuggedInstrumentation.list_call_details.count).to eq(1) + end + end + context 'when feature flag is not persisted' do before do allow(Feature).to receive(:persisted?).with(feature_flag).and_return(false) end it 'returns true when gitaly matches disk' do - pending('temporary disabled because of https://gitlab.com/gitlab-org/gitlab-ce/issues/64338') expect(subject.use_rugged?(repository, feature_flag_name)).to be true end @@ -49,7 +72,6 @@ describe Gitlab::Git::RuggedImpl::UseRugged, :seed_helper do end it "doesn't lead to a second rpc call because gitaly client should use the cached value" do - pending('temporary disabled because of https://gitlab.com/gitlab-org/gitlab-ce/issues/64338') expect(subject.use_rugged?(repository, feature_flag_name)).to be true expect(Gitlab::GitalyClient).not_to receive(:filesystem_id) diff --git a/spec/lib/gitlab/git_spec.rb b/spec/lib/gitlab/git_spec.rb index ce15057dd7d..6515be85ae3 100644 --- a/spec/lib/gitlab/git_spec.rb +++ b/spec/lib/gitlab/git_spec.rb @@ -39,6 +39,26 @@ describe Gitlab::Git do end end + describe '.commit_id?' do + using RSpec::Parameterized::TableSyntax + + where(:sha, :result) do + '' | false + 'foobar' | false + '4b825dc' | false + 'zzz25dc642cb6eb9a060e54bf8d69288fbee4904' | false + + '4b825dc642cb6eb9a060e54bf8d69288fbee4904' | true + Gitlab::Git::BLANK_SHA | true + end + + with_them do + it 'returns the expected result' do + expect(described_class.commit_id?(sha)).to eq(result) + end + end + end + describe '.shas_eql?' do using RSpec::Parameterized::TableSyntax diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb index b8debee3b58..e9fb6c0125c 100644 --- a/spec/lib/gitlab/gitaly_client_spec.rb +++ b/spec/lib/gitlab/gitaly_client_spec.rb @@ -17,6 +17,16 @@ describe Gitlab::GitalyClient do }) end + describe '.filesystem_id_from_disk' do + it 'catches errors' do + [Errno::ENOENT, Errno::EACCES, JSON::ParserError].each do |error| + allow(File).to receive(:read).with(described_class.storage_metadata_file_path('default')).and_raise(error) + + expect(described_class.filesystem_id_from_disk('default')).to be_nil + end + end + end + describe '.stub_class' do it 'returns the gRPC health check stub' do expect(described_class.stub_class(:health_check)).to eq(::Grpc::Health::V1::Health::Stub) @@ -119,6 +129,19 @@ describe Gitlab::GitalyClient do end end + describe '.can_use_disk?' do + it 'properly caches a false result' do + # spec_helper stubs this globally + allow(described_class).to receive(:can_use_disk?).and_call_original + expect(described_class).to receive(:filesystem_id).once + expect(described_class).to receive(:filesystem_id_from_disk).once + + 2.times do + described_class.can_use_disk?('unknown') + end + end + end + describe '.connection_data' do it 'returns connection data' do address = 'tcp://localhost:9876' diff --git a/spec/lib/gitlab/graphql/representation/submodule_tree_entry_spec.rb b/spec/lib/gitlab/graphql/representation/submodule_tree_entry_spec.rb new file mode 100644 index 00000000000..28056a6085d --- /dev/null +++ b/spec/lib/gitlab/graphql/representation/submodule_tree_entry_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Graphql::Representation::SubmoduleTreeEntry do + let(:project) { create(:project, :repository) } + let(:repository) { project.repository } + + describe '.decorate' do + let(:submodules) { repository.tree.submodules } + + it 'returns array of SubmoduleTreeEntry' do + entries = described_class.decorate(submodules, repository.tree) + + expect(entries.first).to be_a(described_class) + + expect(entries.map(&:web_url)).to contain_exactly( + "https://gitlab.com/gitlab-org/gitlab-grack", + "https://github.com/gitlabhq/gitlab-shell", + "https://github.com/randx/six" + ) + + expect(entries.map(&:tree_url)).to contain_exactly( + "https://gitlab.com/gitlab-org/gitlab-grack/tree/645f6c4c82fd3f5e06f67134450a570b795e55a6", + "https://github.com/gitlabhq/gitlab-shell/tree/79bceae69cb5750d6567b223597999bfa91cb3b9", + "https://github.com/randx/six/tree/409f37c4f05865e4fb208c771485f211a22c4c2d" + ) + end + end +end diff --git a/spec/lib/gitlab/group_search_results_spec.rb b/spec/lib/gitlab/group_search_results_spec.rb index 2734fcef0a0..53a91a35ec9 100644 --- a/spec/lib/gitlab/group_search_results_spec.rb +++ b/spec/lib/gitlab/group_search_results_spec.rb @@ -20,7 +20,7 @@ describe Gitlab::GroupSearchResults do expect(result).to eq [user1] end - it 'returns the user belonging to the subgroup matching the search query', :nested_groups do + it 'returns the user belonging to the subgroup matching the search query' do user1 = create(:user, username: 'gob_bluth') subgroup = create(:group, parent: group) create(:group_member, :developer, user: user1, group: subgroup) @@ -32,7 +32,7 @@ describe Gitlab::GroupSearchResults do expect(result).to eq [user1] end - it 'returns the user belonging to the parent group matching the search query', :nested_groups do + it 'returns the user belonging to the parent group matching the search query' do user1 = create(:user, username: 'gob_bluth') parent_group = create(:group, children: [group]) create(:group_member, :developer, user: user1, group: parent_group) @@ -44,7 +44,7 @@ describe Gitlab::GroupSearchResults do expect(result).to eq [user1] end - it 'does not return the user belonging to the private subgroup', :nested_groups do + it 'does not return the user belonging to the private subgroup' do user1 = create(:user, username: 'gob_bluth') subgroup = create(:group, :private, parent: group) create(:group_member, :developer, user: user1, group: subgroup) diff --git a/spec/lib/gitlab/http_connection_adapter_spec.rb b/spec/lib/gitlab/http_connection_adapter_spec.rb index 930d1f62272..1532fd1103e 100644 --- a/spec/lib/gitlab/http_connection_adapter_spec.rb +++ b/spec/lib/gitlab/http_connection_adapter_spec.rb @@ -3,7 +3,13 @@ require 'spec_helper' describe Gitlab::HTTPConnectionAdapter do + include StubRequests + describe '#connection' do + before do + stub_all_dns('https://example.org', ip_address: '93.184.216.34') + end + context 'when local requests are not allowed' do it 'sets up the connection' do uri = URI('https://example.org') diff --git a/spec/lib/gitlab/http_spec.rb b/spec/lib/gitlab/http_spec.rb index 158f77cab2c..d3f9be845dd 100644 --- a/spec/lib/gitlab/http_spec.rb +++ b/spec/lib/gitlab/http_spec.rb @@ -23,14 +23,14 @@ describe Gitlab::HTTP do end end - describe 'allow_local_requests_from_hooks_and_services is' do + describe 'allow_local_requests_from_web_hooks_and_services is' do before do WebMock.stub_request(:get, /.*/).to_return(status: 200, body: 'Success') end context 'disabled' do before do - allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(false) + allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(false) end it 'deny requests to localhost' do @@ -52,7 +52,7 @@ describe Gitlab::HTTP do context 'enabled' do before do - allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(true) + allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_web_hooks_and_services?).and_return(true) end it 'allow requests to localhost' do diff --git a/spec/lib/gitlab/import/database_helpers_spec.rb b/spec/lib/gitlab/import/database_helpers_spec.rb index e716155b7d5..3ac34455177 100644 --- a/spec/lib/gitlab/import/database_helpers_spec.rb +++ b/spec/lib/gitlab/import/database_helpers_spec.rb @@ -15,32 +15,15 @@ describe Gitlab::Import::DatabaseHelpers do let(:attributes) { { iid: 1, title: 'foo' } } let(:project) { create(:project) } - context 'on PostgreSQL' do - it 'returns the ID returned by the query' do - expect(Gitlab::Database) - .to receive(:bulk_insert) - .with(Issue.table_name, [attributes], return_ids: true) - .and_return([10]) + it 'returns the ID returned by the query' do + expect(Gitlab::Database) + .to receive(:bulk_insert) + .with(Issue.table_name, [attributes], return_ids: true) + .and_return([10]) - id = subject.insert_and_return_id(attributes, project.issues) + id = subject.insert_and_return_id(attributes, project.issues) - expect(id).to eq(10) - end - end - - context 'on MySQL' do - it 'uses a separate query to retrieve the ID' do - issue = create(:issue, project: project, iid: attributes[:iid]) - - expect(Gitlab::Database) - .to receive(:bulk_insert) - .with(Issue.table_name, [attributes], return_ids: true) - .and_return([]) - - id = subject.insert_and_return_id(attributes, project.issues) - - expect(id).to eq(issue.id) - end + expect(id).to eq(10) end end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 7baa52ffb4f..929b6222900 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -343,7 +343,6 @@ project: - fork_network_member - fork_network - custom_attributes -- prometheus_metrics - lfs_file_locks - project_badges - source_of_merge_requests diff --git a/spec/lib/gitlab/import_export/lfs_restorer_spec.rb b/spec/lib/gitlab/import_export/lfs_restorer_spec.rb index 70eeb9ee66b..2b0bdb909ae 100644 --- a/spec/lib/gitlab/import_export/lfs_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/lfs_restorer_spec.rb @@ -6,6 +6,7 @@ describe Gitlab::ImportExport::LfsRestorer do let(:export_path) { "#{Dir.tmpdir}/lfs_object_restorer_spec" } let(:project) { create(:project) } let(:shared) { project.import_export_shared } + let(:saver) { Gitlab::ImportExport::LfsSaver.new(project: project, shared: shared) } subject(:restorer) { described_class.new(project: project, shared: shared) } before do @@ -19,49 +20,98 @@ describe Gitlab::ImportExport::LfsRestorer do describe '#restore' do context 'when the archive contains lfs files' do - let(:dummy_lfs_file_path) { File.join(shared.export_path, 'lfs-objects', 'dummy') } - - def create_lfs_object_with_content(content) - dummy_lfs_file = Tempfile.new('existing') - File.write(dummy_lfs_file.path, content) - size = dummy_lfs_file.size - oid = LfsObject.calculate_oid(dummy_lfs_file.path) - LfsObject.create!(oid: oid, size: size, file: dummy_lfs_file) + let(:lfs_object) { create(:lfs_object, :correct_oid, :with_file) } + + # Use the LfsSaver to save data to be restored + def save_lfs_data + %w(project wiki).each do |repository_type| + create( + :lfs_objects_project, + project: project, + repository_type: repository_type, + lfs_object: lfs_object + ) + end + + saver.save + + project.lfs_objects.delete_all end before do - FileUtils.mkdir_p(File.dirname(dummy_lfs_file_path)) - File.write(dummy_lfs_file_path, 'not very large') - allow(restorer).to receive(:lfs_file_paths).and_return([dummy_lfs_file_path]) + save_lfs_data + project.reload end - it 'creates an lfs object for the project' do - expect { restorer.restore }.to change { project.reload.lfs_objects.size }.by(1) + it 'succeeds' do + expect(restorer.restore).to eq(true) + expect(shared.errors).to be_empty end - it 'assigns the file correctly' do + it 'does not create a new `LfsObject` records, as one already exists' do + expect { restorer.restore }.not_to change { LfsObject.count } + end + + it 'creates new `LfsObjectsProject` records in order to link the project to the existing `LfsObject`' do + expect { restorer.restore }.to change { LfsObjectsProject.count }.by(2) + end + + it 'restores the correct `LfsObject` records' do restorer.restore - expect(project.lfs_objects.first.file.read).to eq('not very large') + expect(project.lfs_objects).to contain_exactly(lfs_object) end - it 'links an existing LFS object if it existed' do - lfs_object = create_lfs_object_with_content('not very large') + it 'restores the correct `LfsObjectsProject` records for the project' do + restorer.restore + expect( + project.lfs_objects_projects.pluck(:repository_type) + ).to contain_exactly('project', 'wiki') + end + + it 'assigns the file correctly' do restorer.restore - expect(project.lfs_objects).to include(lfs_object) + expect(project.lfs_objects.first.file.read).to eq(lfs_object.file.read) end - it 'succeeds' do - expect(restorer.restore).to be_truthy - expect(shared.errors).to be_empty + context 'when there is not an existing `LfsObject`' do + before do + lfs_object.destroy + end + + it 'creates a new lfs object' do + expect { restorer.restore }.to change { LfsObject.count }.by(1) + end + + it 'stores the upload' do + expect_any_instance_of(LfsObjectUploader).to receive(:store!) + + restorer.restore + end end - it 'stores the upload' do - expect_any_instance_of(LfsObjectUploader).to receive(:store!) + context 'when there is no lfs-objects.json file' do + before do + json_file = File.join(shared.export_path, ::Gitlab::ImportExport.lfs_objects_filename) - restorer.restore + FileUtils.rm_rf(json_file) + end + + it 'restores the correct `LfsObject` records' do + restorer.restore + + expect(project.lfs_objects).to contain_exactly(lfs_object) + end + + it 'restores a single `LfsObjectsProject` record for the project with "project" for the `repository_type`' do + restorer.restore + + expect( + project.lfs_objects_projects.pluck(:repository_type) + ).to contain_exactly('project') + end end end diff --git a/spec/lib/gitlab/import_export/lfs_saver_spec.rb b/spec/lib/gitlab/import_export/lfs_saver_spec.rb index 9b0e21deb2e..c3c88486e16 100644 --- a/spec/lib/gitlab/import_export/lfs_saver_spec.rb +++ b/spec/lib/gitlab/import_export/lfs_saver_spec.rb @@ -19,6 +19,11 @@ describe Gitlab::ImportExport::LfsSaver do describe '#save' do context 'when the project has LFS objects locally stored' do let(:lfs_object) { create(:lfs_object, :with_file) } + let(:lfs_json_file) { File.join(shared.export_path, Gitlab::ImportExport.lfs_objects_filename) } + + def lfs_json + JSON.parse(IO.read(lfs_json_file)) + end before do project.lfs_objects << lfs_object @@ -35,6 +40,45 @@ describe Gitlab::ImportExport::LfsSaver do expect(File).to exist("#{shared.export_path}/lfs-objects/#{lfs_object.oid}") end + + describe 'saving a json file' do + before do + # Create two more LfsObjectProject records with different `repository_type`s + %w(wiki design).each do |repository_type| + create( + :lfs_objects_project, + project: project, + repository_type: repository_type, + lfs_object: lfs_object + ) + end + + FileUtils.rm_rf(lfs_json_file) + end + + it 'saves a json file correctly' do + saver.save + + expect(File.exist?(lfs_json_file)).to eq(true) + expect(lfs_json).to eq( + { + lfs_object.oid => [ + LfsObjectsProject.repository_types['wiki'], + LfsObjectsProject.repository_types['design'], + nil + ] + } + ) + end + + it 'does not save a json file if feature is disabled' do + stub_feature_flags(export_lfs_objects_projects: false) + + saver.save + + expect(File.exist?(lfs_json_file)).to eq(false) + end + end end context 'when the LFS objects are stored in object storage' do @@ -42,8 +86,11 @@ describe Gitlab::ImportExport::LfsSaver do before do allow(LfsObjectUploader).to receive(:object_store_enabled?).and_return(true) - allow(lfs_object.file).to receive(:url).and_return('http://my-object-storage.local') project.lfs_objects << lfs_object + + expect_next_instance_of(LfsObjectUploader) do |instance| + expect(instance).to receive(:url).and_return('http://my-object-storage.local') + end end it 'downloads the file to include in an archive' do diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb index b95b5dfe791..a9e8431acba 100644 --- a/spec/lib/gitlab/import_export/members_mapper_spec.rb +++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb @@ -154,5 +154,15 @@ describe Gitlab::ImportExport::MembersMapper do expect(members_mapper.map[exported_user_id]).to eq(user2.id) end end + + context 'when importer mapping fails' do + let(:exception_message) { 'Something went wrong' } + + it 'includes importer specific error message' do + expect(ProjectMember).to receive(:create!).and_raise(StandardError.new(exception_message)) + + expect { members_mapper.map }.to raise_error(StandardError, "Error adding importer user to project members. #{exception_message}") + end + end end end diff --git a/spec/lib/gitlab/import_export/project.group.json b/spec/lib/gitlab/import_export/project.group.json index 1a561e81e4a..66f5bb4c87b 100644 --- a/spec/lib/gitlab/import_export/project.group.json +++ b/spec/lib/gitlab/import_export/project.group.json @@ -19,7 +19,7 @@ "labels": [ { "id": 2, - "title": "project label", + "title": "A project label", "color": "#428bca", "project_id": 8, "created_at": "2016-07-22T08:55:44.161Z", @@ -105,7 +105,7 @@ "updated_at": "2017-08-15T18:37:40.795Z", "label": { "id": 6, - "title": "project label", + "title": "A project label", "color": "#A8D695", "project_id": null, "created_at": "2017-08-15T18:37:19.698Z", @@ -162,7 +162,7 @@ "updated_at": "2017-08-15T18:37:40.795Z", "label": { "id": 2, - "title": "project label", + "title": "A project label", "color": "#A8D695", "project_id": null, "created_at": "2017-08-15T18:37:19.698Z", diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json index c0b97486eeb..9e54ca28e58 100644 --- a/spec/lib/gitlab/import_export/project.json +++ b/spec/lib/gitlab/import_export/project.json @@ -2775,7 +2775,8 @@ "action": 1, "author_id": 1 } - ] + ], + "approvals_before_merge": 1 }, { "id": 26, diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb index e6ce3f1bcea..b9f6595762b 100644 --- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb @@ -272,7 +272,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do end it 'has label priorities' do - expect(project.labels.first.priorities).not_to be_empty + expect(project.labels.find_by(title: 'A project label').priorities).not_to be_empty end it 'has milestones' do @@ -325,7 +325,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do it_behaves_like 'restores project correctly', issues: 1, - labels: 1, + labels: 2, milestones: 1, first_issue_labels: 1, services: 1 @@ -402,7 +402,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do it_behaves_like 'restores project successfully' it_behaves_like 'restores project correctly', issues: 2, - labels: 1, + labels: 2, milestones: 2, first_issue_labels: 1 @@ -496,6 +496,18 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do end end + context 'with restricted internal visibility' do + describe 'internal project' do + let(:visibility) { Gitlab::VisibilityLevel::INTERNAL } + + it 'uses private visibility' do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) + + expect(restorer.restored_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end + end + context 'with group visibility' do before do group = create(:group, visibility_level: group_visibility) @@ -528,6 +540,14 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do it 'uses the group visibility' do expect(restorer.restored_project.visibility_level).to eq(group_visibility) end + + context 'with restricted internal visibility' do + it 'sets private visibility' do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) + + expect(restorer.restored_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end end end end diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb index bc4f867e891..1ff2eb9210f 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -42,6 +42,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do expect(saved_project_json).to include({ 'description' => 'description', 'visibility_level' => 20 }) end + it 'has approvals_before_merge set' do + expect(saved_project_json['approvals_before_merge']).to eq(1) + end + it 'has milestones' do expect(saved_project_json['milestones']).not_to be_empty end @@ -175,9 +179,9 @@ describe Gitlab::ImportExport::ProjectTreeSaver do end it 'has priorities associated to labels' do - priorities = saved_project_json['issues'].first['label_links'].map { |link| link['label']['priorities'] } + priorities = saved_project_json['issues'].first['label_links'].flat_map { |link| link['label']['priorities'] } - expect(priorities.flatten).not_to be_empty + expect(priorities).not_to be_empty end it 'has issue resource label events' do @@ -287,7 +291,8 @@ describe Gitlab::ImportExport::ProjectTreeSaver do issues: [issue], snippets: [snippet], releases: [release], - group: group + group: group, + approvals_before_merge: 1 ) project_label = create(:label, project: project) group_label = create(:group_label, group: group) diff --git a/spec/lib/gitlab/import_export/relation_rename_service_spec.rb b/spec/lib/gitlab/import_export/relation_rename_service_spec.rb index a20a844a492..15748407f0c 100644 --- a/spec/lib/gitlab/import_export/relation_rename_service_spec.rb +++ b/spec/lib/gitlab/import_export/relation_rename_service_spec.rb @@ -28,6 +28,7 @@ describe Gitlab::ImportExport::RelationRenameService do before do allow(shared).to receive(:export_path).and_return(import_path) + allow(ActiveSupport::JSON).to receive(:decode).and_call_original allow(ActiveSupport::JSON).to receive(:decode).with(file_content).and_return(json_file) end diff --git a/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb new file mode 100644 index 00000000000..d49d4779735 --- /dev/null +++ b/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Kubernetes::Helm::ResetCommand do + let(:rbac) { true } + let(:name) { 'helm' } + let(:files) { {} } + let(:reset_command) { described_class.new(name: name, rbac: rbac, files: files) } + + subject { reset_command } + + it_behaves_like 'helm commands' do + let(:commands) do + <<~EOS + helm reset + kubectl delete replicaset -n gitlab-managed-apps -l name\\=tiller + EOS + end + end + + context 'when there is a ca.pem file' do + let(:files) { { 'ca.pem': 'some file content' } } + + it_behaves_like 'helm commands' do + let(:commands) do + <<~EOS1.squish + "\n" + <<~EOS2 + helm reset + --tls + --tls-ca-cert /data/helm/helm/config/ca.pem + --tls-cert /data/helm/helm/config/cert.pem + --tls-key /data/helm/helm/config/key.pem + EOS1 + kubectl delete replicaset -n gitlab-managed-apps -l name\\=tiller + EOS2 + end + end + end + + describe '#pod_resource' do + subject { reset_command.pod_resource } + + context 'rbac is enabled' do + let(:rbac) { true } + + it 'generates a pod that uses the tiller serviceAccountName' do + expect(subject.spec.serviceAccountName).to eq('tiller') + end + end + + context 'rbac is not enabled' do + let(:rbac) { false } + + it 'generates a pod that uses the default serviceAccountName' do + expect(subject.spec.serviceAcccountName).to be_nil + end + end + end + + describe '#pod_name' do + subject { reset_command.pod_name } + + it { is_expected.to eq('uninstall-helm') } + end +end diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb index 97ebb5f1554..f49d4e23e39 100644 --- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb +++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb @@ -58,7 +58,7 @@ describe Gitlab::Kubernetes::KubeClient do context 'when local requests are allowed' do before do - stub_application_setting(allow_local_requests_from_hooks_and_services: true) + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) end it 'allows local addresses' do diff --git a/spec/lib/gitlab/manifest_import/manifest_spec.rb b/spec/lib/gitlab/manifest_import/manifest_spec.rb index ab305fb2316..ded93e23c08 100644 --- a/spec/lib/gitlab/manifest_import/manifest_spec.rb +++ b/spec/lib/gitlab/manifest_import/manifest_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::ManifestImport::Manifest, :postgresql do +describe Gitlab::ManifestImport::Manifest do let(:file) { File.open(Rails.root.join('spec/fixtures/aosp_manifest.xml')) } let(:manifest) { described_class.new(file) } diff --git a/spec/lib/gitlab/manifest_import/project_creator_spec.rb b/spec/lib/gitlab/manifest_import/project_creator_spec.rb index 1d01d437535..a7487972f51 100644 --- a/spec/lib/gitlab/manifest_import/project_creator_spec.rb +++ b/spec/lib/gitlab/manifest_import/project_creator_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::ManifestImport::ProjectCreator, :postgresql do +describe Gitlab::ManifestImport::ProjectCreator do let(:group) { create(:group) } let(:user) { create(:user) } let(:repository) do diff --git a/spec/lib/gitlab/metrics/dashboard/dynamic_dashboard_service_spec.rb b/spec/lib/gitlab/metrics/dashboard/dynamic_dashboard_service_spec.rb deleted file mode 100644 index 79a78df44ae..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/dynamic_dashboard_service_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Metrics::Dashboard::DynamicDashboardService, :use_clean_rails_memory_store_caching do - include MetricsDashboardHelpers - - set(:project) { build(:project) } - set(:user) { create(:user) } - set(:environment) { create(:environment, project: project) } - - before do - project.add_maintainer(user) - end - - describe '#get_dashboard' do - let(:service_params) { [project, user, { environment: environment, dashboard_path: nil }] } - let(:service_call) { described_class.new(*service_params).get_dashboard } - - it_behaves_like 'valid embedded dashboard service response' - it_behaves_like 'raises error for users with insufficient permissions' - - it 'caches the unprocessed dashboard for subsequent calls' do - expect(YAML).to receive(:safe_load).once.and_call_original - - described_class.new(*service_params).get_dashboard - described_class.new(*service_params).get_dashboard - end - - context 'when called with a non-system dashboard' do - let(:dashboard_path) { 'garbage/dashboard/path' } - - it_behaves_like 'valid embedded dashboard service response' - end - end -end diff --git a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb index d8ed54c0248..e57c7326320 100644 --- a/spec/lib/gitlab/metrics/dashboard/finder_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/finder_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::Metrics::Dashboard::Finder, :use_clean_rails_memory_store_cachi set(:project) { build(:project) } set(:user) { create(:user) } set(:environment) { create(:environment, project: project) } - let(:system_dashboard_path) { Gitlab::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH} + let(:system_dashboard_path) { ::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH} before do project.add_maintainer(user) diff --git a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb index 797d4daabe3..d7891e69dd0 100644 --- a/spec/lib/gitlab/metrics/dashboard/processor_spec.rb +++ b/spec/lib/gitlab/metrics/dashboard/processor_spec.rb @@ -101,9 +101,9 @@ describe Gitlab::Metrics::Dashboard::Processor do private def all_metrics - dashboard[:panel_groups].map do |group| - group[:panels].map { |panel| panel[:metrics] } - end.flatten + dashboard[:panel_groups].flat_map do |group| + group[:panels].flat_map { |panel| panel[:metrics] } + end end def get_metric_details(metric) diff --git a/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb b/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb deleted file mode 100644 index 468e8ec9ef2..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/project_dashboard_service_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Gitlab::Metrics::Dashboard::ProjectDashboardService, :use_clean_rails_memory_store_caching do - include MetricsDashboardHelpers - - set(:user) { create(:user) } - set(:project) { create(:project) } - set(:environment) { create(:environment, project: project) } - - before do - project.add_maintainer(user) - end - - describe 'get_dashboard' do - let(:dashboard_path) { '.gitlab/dashboards/test.yml' } - let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] } - let(:service_call) { described_class.new(*service_params).get_dashboard } - - context 'when the dashboard does not exist' do - it_behaves_like 'misconfigured dashboard service response', :not_found - end - - it_behaves_like 'raises error for users with insufficient permissions' - - context 'when the dashboard exists' do - let(:project) { project_with_dashboard(dashboard_path) } - - it_behaves_like 'valid dashboard service response' - - it 'caches the unprocessed dashboard for subsequent calls' do - expect_any_instance_of(described_class) - .to receive(:get_raw_dashboard) - .once - .and_call_original - - described_class.new(*service_params).get_dashboard - described_class.new(*service_params).get_dashboard - end - - context 'and the dashboard is then deleted' do - it 'does not return the previously cached dashboard' do - described_class.new(*service_params).get_dashboard - - delete_project_dashboard(project, user, dashboard_path) - - expect_any_instance_of(described_class) - .to receive(:get_raw_dashboard) - .once - .and_call_original - - described_class.new(*service_params).get_dashboard - end - end - end - - context 'when the dashboard is configured incorrectly' do - let(:project) { project_with_dashboard(dashboard_path, {}) } - - it_behaves_like 'misconfigured dashboard service response', :unprocessable_entity - end - end - - describe '::all_dashboard_paths' do - let(:all_dashboards) { described_class.all_dashboard_paths(project) } - - context 'when there are no project dashboards' do - it 'returns an empty array' do - expect(all_dashboards).to be_empty - end - end - - context 'when there are project dashboards available' do - let(:dashboard_path) { '.gitlab/dashboards/test.yml' } - let(:project) { project_with_dashboard(dashboard_path) } - - it 'returns the dashboard attributes' do - expect(all_dashboards).to eq( - [{ - path: dashboard_path, - display_name: 'test.yml', - default: false - }] - ) - end - end - end -end diff --git a/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb b/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb deleted file mode 100644 index 13f22dd01c5..00000000000 --- a/spec/lib/gitlab/metrics/dashboard/system_dashboard_service_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_store_caching do - include MetricsDashboardHelpers - - set(:user) { create(:user) } - set(:project) { create(:project) } - set(:environment) { create(:environment, project: project) } - - before do - project.add_maintainer(user) - end - - describe 'get_dashboard' do - let(:dashboard_path) { described_class::SYSTEM_DASHBOARD_PATH } - let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] } - let(:service_call) { described_class.new(*service_params).get_dashboard } - - it_behaves_like 'valid dashboard service response' - it_behaves_like 'raises error for users with insufficient permissions' - - it 'caches the unprocessed dashboard for subsequent calls' do - expect(YAML).to receive(:safe_load).once.and_call_original - - described_class.new(*service_params).get_dashboard - described_class.new(*service_params).get_dashboard - end - - context 'when called with a non-system dashboard' do - let(:dashboard_path) { 'garbage/dashboard/path' } - - # We want to alwaus return the system dashboard. - it_behaves_like 'valid dashboard service response' - end - end - - describe '::all_dashboard_paths' do - it 'returns the dashboard attributes' do - all_dashboards = described_class.all_dashboard_paths(project) - - expect(all_dashboards).to eq( - [{ - path: described_class::SYSTEM_DASHBOARD_PATH, - display_name: described_class::SYSTEM_DASHBOARD_NAME, - default: true - }] - ) - end - end -end diff --git a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb index 81954fcf8c5..2923048f742 100644 --- a/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/influx_sampler_spec.rb @@ -17,18 +17,10 @@ describe Gitlab::Metrics::Samplers::InfluxSampler do it 'samples various statistics' do expect(sampler).to receive(:sample_memory_usage) expect(sampler).to receive(:sample_file_descriptors) - expect(sampler).to receive(:sample_gc) expect(sampler).to receive(:flush) sampler.sample end - - it 'clears any GC profiles' do - expect(sampler).to receive(:flush) - expect(GC::Profiler).to receive(:clear) - - sampler.sample - end end describe '#flush' do @@ -67,18 +59,6 @@ describe Gitlab::Metrics::Samplers::InfluxSampler do end end - describe '#sample_gc' do - it 'adds a metric containing garbage collection statistics' do - expect(GC::Profiler).to receive(:total_time).and_return(0.24) - - expect(sampler).to receive(:add_metric) - .with(/gc_statistics/, an_instance_of(Hash)) - .and_call_original - - sampler.sample_gc - end - end - describe '#add_metric' do it 'prefixes the series name for a Rails process' do expect(sampler).to receive(:sidekiq?).and_return(false) diff --git a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb index 4d93b70e6e3..5005a5d9ebc 100644 --- a/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb +++ b/spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb @@ -59,17 +59,29 @@ describe Gitlab::Metrics::Samplers::RubySampler do end it 'clears any GC profiles' do - expect(GC::Profiler).to receive(:clear) + expect(GC::Profiler).to receive(:clear).at_least(:once) sampler.sample end end describe '#sample_gc' do - it 'adds a metric containing garbage collection time statistics' do - expect(GC::Profiler).to receive(:total_time).and_return(0.24) + let!(:sampler) { described_class.new(5) } - expect(sampler.metrics[:total_time]).to receive(:increment).with({}, 0.24) + let(:gc_reports) { [{ GC_TIME: 0.1 }, { GC_TIME: 0.2 }, { GC_TIME: 0.3 }] } + + it 're-enables GC::Profiler if needed' do + expect(GC::Profiler).to receive(:enable) + + sampler.sample + end + + it 'observes GC cycles time' do + expect(sampler).to receive(:sample_gc_reports).and_return(gc_reports) + + expect(sampler.metrics[:gc_duration_seconds]).to receive(:observe).with({}, 0.1).ordered + expect(sampler.metrics[:gc_duration_seconds]).to receive(:observe).with({}, 0.2).ordered + expect(sampler.metrics[:gc_duration_seconds]).to receive(:observe).with({}, 0.3).ordered sampler.sample end diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb index 6795c1ab56b..e04056b3450 100644 --- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb +++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb @@ -201,7 +201,15 @@ describe Gitlab::Metrics::Subscribers::RailsCache do it 'observes cache metric' do expect(subscriber.send(:metric_cache_operation_duration_seconds)) .to receive(:observe) - .with(transaction.labels.merge(operation: :delete), event.duration / 1000.0) + .with({ operation: :delete }, event.duration / 1000.0) + + subscriber.observe(:delete, event.duration) + end + + it 'increments the operations total' do + expect(subscriber.send(:metric_cache_operations_total)) + .to receive(:increment) + .with(transaction.labels.merge(operation: :delete)) subscriber.observe(:delete, event.duration) end diff --git a/spec/lib/gitlab/object_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb index e6e9ae3223e..bfd456cdd7e 100644 --- a/spec/lib/gitlab/object_hierarchy_spec.rb +++ b/spec/lib/gitlab/object_hierarchy_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::ObjectHierarchy, :postgresql do +describe Gitlab::ObjectHierarchy do let!(:parent) { create(:group) } let!(:child1) { create(:group, parent: parent) } let!(:child2) { create(:group, parent: child1) } diff --git a/spec/lib/gitlab/octokit/middleware_spec.rb b/spec/lib/gitlab/octokit/middleware_spec.rb new file mode 100644 index 00000000000..43f6d13f7ba --- /dev/null +++ b/spec/lib/gitlab/octokit/middleware_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe Gitlab::Octokit::Middleware do + let(:app) { double(:app) } + let(:middleware) { described_class.new(app) } + + shared_examples 'Public URL' do + it 'does not raise an error' do + expect(app).to receive(:call).with(env) + + expect { middleware.call(env) }.not_to raise_error + end + end + + shared_examples 'Local URL' do + it 'raises an error' do + expect { middleware.call(env) }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError) + end + end + + describe '#call' do + context 'when the URL is a public URL' do + let(:env) { { url: 'https://public-url.com' } } + + it_behaves_like 'Public URL' + end + + context 'when the URL is a localhost adresss' do + let(:env) { { url: 'http://127.0.0.1' } } + + context 'when localhost requests are not allowed' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) + end + + it_behaves_like 'Local URL' + end + + context 'when localhost requests are allowed' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + end + + it_behaves_like 'Public URL' + end + end + + context 'when the URL is a local network address' do + let(:env) { { url: 'http://172.16.0.0' } } + + context 'when local network requests are not allowed' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) + end + + it_behaves_like 'Local URL' + end + + context 'when local network requests are allowed' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + end + + it_behaves_like 'Public URL' + end + end + end +end diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb index ee3c571c9c0..71c109db1f1 100644 --- a/spec/lib/gitlab/performance_bar_spec.rb +++ b/spec/lib/gitlab/performance_bar_spec.rb @@ -96,7 +96,7 @@ describe Gitlab::PerformanceBar do end end - context 'when allowed group is nested', :nested_groups do + context 'when allowed group is nested' do let!(:nested_my_group) { create(:group, parent: create(:group, path: 'my-org'), path: 'my-group') } before do @@ -110,7 +110,7 @@ describe Gitlab::PerformanceBar do end end - context 'when a nested group has the same path', :nested_groups do + context 'when a nested group has the same path' do before do create(:group, :nested, path: 'my-group').add_developer(user) end diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb index bd0bc2c9044..75e2d5e1319 100644 --- a/spec/lib/gitlab/project_authorizations_spec.rb +++ b/spec/lib/gitlab/project_authorizations_spec.rb @@ -20,13 +20,7 @@ describe Gitlab::ProjectAuthorizations do end let(:authorizations) do - klass = if Group.supports_nested_objects? - Gitlab::ProjectAuthorizations::WithNestedGroups - else - Gitlab::ProjectAuthorizations::WithoutNestedGroups - end - - klass.new(user).calculate + described_class.new(user).calculate end it 'returns the correct number of authorizations' do @@ -46,28 +40,26 @@ describe Gitlab::ProjectAuthorizations do expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER) end - if Group.supports_nested_objects? - context 'with nested groups' do - let!(:nested_group) { create(:group, parent: group) } - let!(:nested_project) { create(:project, namespace: nested_group) } + context 'with nested groups' do + let!(:nested_group) { create(:group, parent: group) } + let!(:nested_project) { create(:project, namespace: nested_group) } - it 'includes nested groups' do - expect(authorizations.pluck(:project_id)).to include(nested_project.id) - end + it 'includes nested groups' do + expect(authorizations.pluck(:project_id)).to include(nested_project.id) + end - it 'inherits access levels when the user is not a member of a nested group' do - mapping = map_access_levels(authorizations) + it 'inherits access levels when the user is not a member of a nested group' do + mapping = map_access_levels(authorizations) - expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER) - end + expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER) + end - it 'uses the greatest access level when a user is a member of a nested group' do - nested_group.add_maintainer(user) + it 'uses the greatest access level when a user is a member of a nested group' do + nested_group.add_maintainer(user) - mapping = map_access_levels(authorizations) + mapping = map_access_levels(authorizations) - expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER) - end + expect(mapping[nested_project.id]).to eq(Gitlab::Access::MAINTAINER) end end end diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb index 8c2fc048a54..8b82ea7faa5 100644 --- a/spec/lib/gitlab/project_template_spec.rb +++ b/spec/lib/gitlab/project_template_spec.rb @@ -44,6 +44,12 @@ describe Gitlab::ProjectTemplate do end end + describe '.archive_directory' do + subject { described_class.archive_directory } + + it { is_expected.to be_a Pathname } + end + describe 'instance methods' do subject { described_class.new('phoenix', 'Phoenix Framework', 'Phoenix description', 'link-to-template') } diff --git a/spec/lib/gitlab/prometheus/metric_group_spec.rb b/spec/lib/gitlab/prometheus/metric_group_spec.rb index 5cc6827488b..a45dd0af91e 100644 --- a/spec/lib/gitlab/prometheus/metric_group_spec.rb +++ b/spec/lib/gitlab/prometheus/metric_group_spec.rb @@ -17,7 +17,7 @@ describe Gitlab::Prometheus::MetricGroup do end it 'returns exactly three metric queries' do - expect(subject.map(&:metrics).flatten.map(&:id)).to contain_exactly( + expect(subject.flat_map(&:metrics).map(&:id)).to contain_exactly( common_metric_group_a.id, common_metric_group_b_q1.id, common_metric_group_b_q2.id) end @@ -37,7 +37,7 @@ describe Gitlab::Prometheus::MetricGroup do subject do described_class.for_project(other_project) - .map(&:metrics).flatten + .flat_map(&:metrics) .map(&:id) end diff --git a/spec/lib/gitlab/quick_actions/command_definition_spec.rb b/spec/lib/gitlab/quick_actions/command_definition_spec.rb index b6e0adbc1c2..21f2c87a755 100644 --- a/spec/lib/gitlab/quick_actions/command_definition_spec.rb +++ b/spec/lib/gitlab/quick_actions/command_definition_spec.rb @@ -219,6 +219,52 @@ describe Gitlab::QuickActions::CommandDefinition do end end + describe "#execute_message" do + context "when the command is a noop" do + it 'returns nil' do + expect(subject.execute_message({}, nil)).to be_nil + end + end + + context "when the command is not a noop" do + before do + subject.action_block = proc { self.run = true } + end + + context "when the command is not available" do + before do + subject.condition_block = proc { false } + end + + it 'returns nil' do + expect(subject.execute_message({}, nil)).to be_nil + end + end + + context "when the command is available" do + context 'when the execution_message is a static string' do + before do + subject.execution_message = 'Assigned jacopo' + end + + it 'returns this static string' do + expect(subject.execute_message({}, nil)).to eq('Assigned jacopo') + end + end + + context 'when the explanation is dynamic' do + before do + subject.execution_message = proc { |arg| "Assigned #{arg}" } + end + + it 'invokes the proc' do + expect(subject.execute_message({}, 'Jacopo')).to eq('Assigned Jacopo') + end + end + end + end + end + describe '#explain' do context 'when the command is not available' do before do diff --git a/spec/lib/gitlab/quick_actions/dsl_spec.rb b/spec/lib/gitlab/quick_actions/dsl_spec.rb index 185adab1ff6..78b9b3804c3 100644 --- a/spec/lib/gitlab/quick_actions/dsl_spec.rb +++ b/spec/lib/gitlab/quick_actions/dsl_spec.rb @@ -20,6 +20,9 @@ describe Gitlab::QuickActions::Dsl do desc do "A dynamic description for #{noteable.upcase}" end + execution_message do |arg| + "A dynamic execution message for #{noteable.upcase} passing #{arg}" + end params 'The first argument', 'The second argument' command :dynamic_description do |args| args.split @@ -30,6 +33,7 @@ describe Gitlab::QuickActions::Dsl do explanation do |arg| "Action does something with #{arg}" end + execution_message 'Command applied correctly' condition do project == 'foo' end @@ -67,6 +71,7 @@ describe Gitlab::QuickActions::Dsl do expect(no_args_def.aliases).to eq([:none]) expect(no_args_def.description).to eq('A command with no args') expect(no_args_def.explanation).to eq('') + expect(no_args_def.execution_message).to eq('') expect(no_args_def.params).to eq([]) expect(no_args_def.condition_block).to be_nil expect(no_args_def.types).to eq([]) @@ -78,6 +83,8 @@ describe Gitlab::QuickActions::Dsl do expect(explanation_with_aliases_def.aliases).to eq([:once, :first]) expect(explanation_with_aliases_def.description).to eq('') expect(explanation_with_aliases_def.explanation).to eq('Static explanation') + expect(explanation_with_aliases_def.execution_message).to eq('') + expect(no_args_def.params).to eq([]) expect(explanation_with_aliases_def.params).to eq(['The first argument']) expect(explanation_with_aliases_def.condition_block).to be_nil expect(explanation_with_aliases_def.types).to eq([]) @@ -88,7 +95,7 @@ describe Gitlab::QuickActions::Dsl do expect(dynamic_description_def.name).to eq(:dynamic_description) expect(dynamic_description_def.aliases).to eq([]) expect(dynamic_description_def.to_h(OpenStruct.new(noteable: 'issue'))[:description]).to eq('A dynamic description for ISSUE') - expect(dynamic_description_def.explanation).to eq('') + expect(dynamic_description_def.execute_message(OpenStruct.new(noteable: 'issue'), 'arg')).to eq('A dynamic execution message for ISSUE passing arg') expect(dynamic_description_def.params).to eq(['The first argument', 'The second argument']) expect(dynamic_description_def.condition_block).to be_nil expect(dynamic_description_def.types).to eq([]) @@ -100,6 +107,7 @@ describe Gitlab::QuickActions::Dsl do expect(cc_def.aliases).to eq([]) expect(cc_def.description).to eq('') expect(cc_def.explanation).to eq('') + expect(cc_def.execution_message).to eq('') expect(cc_def.params).to eq([]) expect(cc_def.condition_block).to be_nil expect(cc_def.types).to eq([]) @@ -111,6 +119,7 @@ describe Gitlab::QuickActions::Dsl do expect(cond_action_def.aliases).to eq([]) expect(cond_action_def.description).to eq('') expect(cond_action_def.explanation).to be_a_kind_of(Proc) + expect(cond_action_def.execution_message).to eq('Command applied correctly') expect(cond_action_def.params).to eq([]) expect(cond_action_def.condition_block).to be_a_kind_of(Proc) expect(cond_action_def.types).to eq([]) @@ -122,6 +131,7 @@ describe Gitlab::QuickActions::Dsl do expect(with_params_parsing_def.aliases).to eq([]) expect(with_params_parsing_def.description).to eq('') expect(with_params_parsing_def.explanation).to eq('') + expect(with_params_parsing_def.execution_message).to eq('') expect(with_params_parsing_def.params).to eq([]) expect(with_params_parsing_def.condition_block).to be_nil expect(with_params_parsing_def.types).to eq([]) @@ -133,6 +143,7 @@ describe Gitlab::QuickActions::Dsl do expect(substitution_def.aliases).to eq([]) expect(substitution_def.description).to eq('') expect(substitution_def.explanation).to eq('') + expect(substitution_def.execution_message).to eq('') expect(substitution_def.params).to eq(['<Comment>']) expect(substitution_def.condition_block).to be_nil expect(substitution_def.types).to eq([]) @@ -144,6 +155,7 @@ describe Gitlab::QuickActions::Dsl do expect(has_types.aliases).to eq([]) expect(has_types.description).to eq('A command with types') expect(has_types.explanation).to eq('') + expect(has_types.execution_message).to eq('') expect(has_types.params).to eq([]) expect(has_types.condition_block).to be_nil expect(has_types.types).to eq([Issue, Commit]) diff --git a/spec/lib/gitlab/request_profiler/profile_spec.rb b/spec/lib/gitlab/request_profiler/profile_spec.rb new file mode 100644 index 00000000000..b37ee558e1a --- /dev/null +++ b/spec/lib/gitlab/request_profiler/profile_spec.rb @@ -0,0 +1,59 @@ +require 'fast_spec_helper' + +describe Gitlab::RequestProfiler::Profile do + let(:profile) { described_class.new(filename) } + + describe '.new' do + context 'using old filename' do + let(:filename) { '|api|v4|version.txt_1562854738.html' } + + it 'returns valid data' do + expect(profile).to be_valid + expect(profile.request_path).to eq('/api/v4/version.txt') + expect(profile.time).to eq(Time.at(1562854738).utc) + expect(profile.type).to eq('html') + end + end + + context 'using new filename' do + let(:filename) { '|api|v4|version.txt_1563547949_execution.html' } + + it 'returns valid data' do + expect(profile).to be_valid + expect(profile.request_path).to eq('/api/v4/version.txt') + expect(profile.profile_mode).to eq('execution') + expect(profile.time).to eq(Time.at(1563547949).utc) + expect(profile.type).to eq('html') + end + end + end + + describe '#content_type' do + context 'when using html file' do + let(:filename) { '|api|v4|version.txt_1562854738_memory.html' } + + it 'returns valid data' do + expect(profile).to be_valid + expect(profile.content_type).to eq('text/html') + end + end + + context 'when using text file' do + let(:filename) { '|api|v4|version.txt_1562854738_memory.txt' } + + it 'returns valid data' do + expect(profile).to be_valid + expect(profile.content_type).to eq('text/plain') + end + end + + context 'when file is unknown' do + let(:filename) { '|api|v4|version.txt_1562854738_memory.xxx' } + + it 'returns valid data' do + expect(profile).not_to be_valid + expect(profile.content_type).to be_nil + end + end + end +end diff --git a/spec/lib/gitlab/request_profiler_spec.rb b/spec/lib/gitlab/request_profiler_spec.rb index fd8cbf39bce..498c045b6cd 100644 --- a/spec/lib/gitlab/request_profiler_spec.rb +++ b/spec/lib/gitlab/request_profiler_spec.rb @@ -13,15 +13,42 @@ describe Gitlab::RequestProfiler do end end - describe '.remove_all_profiles' do - it 'removes Gitlab::RequestProfiler::PROFILES_DIR directory' do - dir = described_class::PROFILES_DIR - FileUtils.mkdir_p(dir) + context 'with temporary PROFILES_DIR' do + let(:tmpdir) { Dir.mktmpdir('profiler-test') } + let(:profile_name) { '|api|v4|version.txt_1562854738_memory.html' } + let(:profile_path) { File.join(tmpdir, profile_name) } - expect(Dir.exist?(dir)).to be true + before do + stub_const('Gitlab::RequestProfiler::PROFILES_DIR', tmpdir) + FileUtils.touch(profile_path) + end + + after do + FileUtils.rm_rf(tmpdir) + end + + describe '.remove_all_profiles' do + it 'removes Gitlab::RequestProfiler::PROFILES_DIR directory' do + described_class.remove_all_profiles + + expect(Dir.exist?(tmpdir)).to be false + end + end + + describe '.all' do + subject { described_class.all } + + it 'returns all profiles' do + expect(subject.map(&:name)).to contain_exactly(profile_name) + end + end + + describe '.find' do + subject { described_class.find(profile_name) } - described_class.remove_all_profiles - expect(Dir.exist?(dir)).to be false + it 'returns all profiles' do + expect(subject.name).to eq(profile_name) + end end end end diff --git a/spec/lib/gitlab/rugged_instrumentation_spec.rb b/spec/lib/gitlab/rugged_instrumentation_spec.rb new file mode 100644 index 00000000000..4dcc8ae514a --- /dev/null +++ b/spec/lib/gitlab/rugged_instrumentation_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::RuggedInstrumentation, :request_store do + subject { described_class } + + describe '.query_time' do + it 'increments query times' do + subject.query_time += 0.451 + subject.query_time += 0.322 + + expect(subject.query_time).to be_within(0.001).of(0.773) + expect(subject.query_time_ms).to eq(773.0) + end + end + + context '.increment_query_count' do + it 'tracks query counts' do + expect(subject.query_count).to eq(0) + + 2.times { subject.increment_query_count } + + expect(subject.query_count).to eq(2) + end + end +end diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb index 7bc4599e20f..98286eb432d 100644 --- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb +++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb @@ -2,7 +2,10 @@ require 'spec_helper' describe Gitlab::SidekiqLogging::StructuredLogger do describe '#call' do - let(:timestamp) { Time.new('2018-01-01 12:00:00').utc } + let(:timestamp) { Time.iso8601('2018-01-01T12:00:00Z') } + let(:created_at) { timestamp } + let(:scheduling_latency_s) { 0.0 } + let(:job) do { "class" => "TestWorker", @@ -11,19 +14,21 @@ describe Gitlab::SidekiqLogging::StructuredLogger do "queue" => "cronjob:test_queue", "queue_namespace" => "cronjob", "jid" => "da883554ee4fe414012f5f42", - "created_at" => timestamp.to_f, - "enqueued_at" => timestamp.to_f, + "created_at" => created_at.to_f, + "enqueued_at" => created_at.to_f, "correlation_id" => 'cid' } end + let(:logger) { double } let(:start_payload) do job.merge( 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: start', 'job_status' => 'start', 'pid' => Process.pid, - 'created_at' => timestamp.iso8601(3), - 'enqueued_at' => timestamp.iso8601(3) + 'created_at' => created_at.iso8601(3), + 'enqueued_at' => created_at.iso8601(3), + 'scheduling_latency_s' => scheduling_latency_s ) end let(:end_payload) do @@ -118,6 +123,35 @@ describe Gitlab::SidekiqLogging::StructuredLogger do subject.call(job, 'test_queue') { } end end + + it 'logs without created_at and enqueued_at fields' do + Timecop.freeze(timestamp) do + excluded_fields = %w(created_at enqueued_at args scheduling_latency_s) + + expect(logger).to receive(:info).with(start_payload.except(*excluded_fields)).ordered + expect(logger).to receive(:info).with(end_payload.except(*excluded_fields)).ordered + expect(subject).to receive(:log_job_start).and_call_original + expect(subject).to receive(:log_job_done).and_call_original + + subject.call(job.except("created_at", "enqueued_at"), 'test_queue') { } + end + end + end + + context 'with latency' do + let(:created_at) { Time.iso8601('2018-01-01T10:00:00Z') } + let(:scheduling_latency_s) { 7200.0 } + + it 'logs with scheduling latency' do + Timecop.freeze(timestamp) do + expect(logger).to receive(:info).with(start_payload.except('args')).ordered + expect(logger).to receive(:info).with(end_payload.except('args')).ordered + expect(subject).to receive(:log_job_start).and_call_original + expect(subject).to receive(:log_job_done).and_call_original + + subject.call(job, 'test_queue') { } + end + end end end end diff --git a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb index 1a5a38b5d99..1de9a644610 100644 --- a/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::SidekiqMiddleware::MemoryKiller do subject { described_class.new } let(:pid) { 999 } - let(:worker) { double(:worker, class: 'TestWorker') } + let(:worker) { double(:worker, class: ProjectCacheWorker) } let(:job) { { 'jid' => 123 } } let(:queue) { 'test_queue' } @@ -45,6 +45,12 @@ describe Gitlab::SidekiqMiddleware::MemoryKiller do expect(subject).to receive(:sleep).with(10).ordered expect(Process).to receive(:kill).with('SIGKILL', pid).ordered + expect(Sidekiq.logger) + .to receive(:warn).with(class: 'ProjectCacheWorker', + message: anything, + pid: pid, + signal: anything).at_least(:once) + run end diff --git a/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb new file mode 100644 index 00000000000..c6df1c6a0d8 --- /dev/null +++ b/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::SidekiqMiddleware::Metrics do + describe '#call' do + let(:middleware) { described_class.new } + let(:worker) { double(:worker) } + + let(:completion_seconds_metric) { double('completion seconds metric') } + let(:failed_total_metric) { double('failed total metric') } + let(:retried_total_metric) { double('retried total metric') } + let(:running_jobs_metric) { double('running jobs metric') } + + before do + allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything).and_return(completion_seconds_metric) + allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_failed_total, anything).and_return(failed_total_metric) + allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_retried_total, anything).and_return(retried_total_metric) + allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_running_jobs, anything, {}, :livesum).and_return(running_jobs_metric) + + allow(running_jobs_metric).to receive(:increment) + end + + it 'yields block' do + allow(completion_seconds_metric).to receive(:observe) + + expect { |b| middleware.call(worker, {}, :test, &b) }.to yield_control.once + end + + it 'sets metrics' do + labels = { queue: :test } + + expect(running_jobs_metric).to receive(:increment).with(labels, 1) + expect(running_jobs_metric).to receive(:increment).with(labels, -1) + expect(completion_seconds_metric).to receive(:observe).with(labels, kind_of(Numeric)) + + middleware.call(worker, {}, :test) { nil } + end + + context 'when job is retried' do + it 'sets sidekiq_jobs_retried_total metric' do + allow(completion_seconds_metric).to receive(:observe) + + expect(retried_total_metric).to receive(:increment) + + middleware.call(worker, { 'retry_count' => 1 }, :test) { nil } + end + end + + context 'when error is raised' do + it 'sets sidekiq_jobs_failed_total and reraises' do + expect(failed_total_metric).to receive(:increment) + expect { middleware.call(worker, {}, :test) { raise } }.to raise_error + end + end + end +end diff --git a/spec/lib/gitlab/slug/environment_spec.rb b/spec/lib/gitlab/slug/environment_spec.rb new file mode 100644 index 00000000000..7dc583a94b8 --- /dev/null +++ b/spec/lib/gitlab/slug/environment_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Slug::Environment do + describe '#generate' do + { + "staging-12345678901234567" => "staging-123456789-q517sa", + "9-staging-123456789012345" => "env-9-staging-123-q517sa", + "staging-1234567890123456" => "staging-1234567890123456", + "staging-1234567890123456-" => "staging-123456789-q517sa", + "production" => "production", + "PRODUCTION" => "production-q517sa", + "review/1-foo" => "review-1-foo-q517sa", + "1-foo" => "env-1-foo-q517sa", + "1/foo" => "env-1-foo-q517sa", + "foo-" => "foo", + "foo--bar" => "foo-bar-q517sa", + "foo**bar" => "foo-bar-q517sa", + "*-foo" => "env-foo-q517sa", + "staging-12345678-" => "staging-12345678", + "staging-12345678-01234567" => "staging-12345678-q517sa", + "" => "env-q517sa", + nil => "env-q517sa" + }.each do |name, matcher| + before do + # ('a' * 64).to_i(16).to_s(36).last(6) gives 'q517sa' + allow(Digest::SHA2).to receive(:hexdigest).with(name).and_return('a' * 64) + end + + it "returns a slug matching #{matcher}, given #{name}" do + slug = described_class.new(name).generate + + expect(slug).to match(/\A#{matcher}\z/) + end + end + end +end diff --git a/spec/lib/gitlab/sql/cte_spec.rb b/spec/lib/gitlab/sql/cte_spec.rb index d6763c7b2e1..5d2164491b5 100644 --- a/spec/lib/gitlab/sql/cte_spec.rb +++ b/spec/lib/gitlab/sql/cte_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::SQL::CTE, :postgresql do +describe Gitlab::SQL::CTE do describe '#to_arel' do it 'generates an Arel relation for the CTE body' do relation = User.where(id: 1) diff --git a/spec/lib/gitlab/sql/recursive_cte_spec.rb b/spec/lib/gitlab/sql/recursive_cte_spec.rb index 7fe39dd5a96..407a4d8a247 100644 --- a/spec/lib/gitlab/sql/recursive_cte_spec.rb +++ b/spec/lib/gitlab/sql/recursive_cte_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::SQL::RecursiveCTE, :postgresql do +describe Gitlab::SQL::RecursiveCTE do let(:cte) { described_class.new(:cte_name) } describe '#to_arel' do diff --git a/spec/lib/gitlab/submodule_links_spec.rb b/spec/lib/gitlab/submodule_links_spec.rb new file mode 100644 index 00000000000..a84602cd07d --- /dev/null +++ b/spec/lib/gitlab/submodule_links_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::SubmoduleLinks do + let(:submodule_item) { double(id: 'hash', path: 'gitlab-ce') } + let(:repo) { double } + let(:links) { described_class.new(repo) } + + describe '#for' do + subject { links.for(submodule_item, 'ref') } + + context 'when there is no .gitmodules file' do + before do + stub_urls(nil) + end + + it 'returns no links' do + expect(subject).to eq([nil, nil]) + end + end + + context 'when the submodule is unknown' do + before do + stub_urls({ 'path' => 'url' }) + end + + it 'returns no links' do + expect(subject).to eq([nil, nil]) + end + end + + context 'when the submodule is known' do + before do + stub_urls({ 'gitlab-ce' => 'git@gitlab.com:gitlab-org/gitlab-ce.git' }) + end + + it 'returns links' do + expect(subject).to eq(['https://gitlab.com/gitlab-org/gitlab-ce', 'https://gitlab.com/gitlab-org/gitlab-ce/tree/hash']) + end + end + end + + def stub_urls(urls) + allow(repo).to receive(:submodule_urls_for).and_return(urls) + end +end diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb index f8b0cbfb6f6..45d9022abeb 100644 --- a/spec/lib/gitlab/url_blocker_spec.rb +++ b/spec/lib/gitlab/url_blocker_spec.rb @@ -68,6 +68,16 @@ describe Gitlab::UrlBlocker do expect(uri).to eq(Addressable::URI.parse('https://example.org')) expect(hostname).to eq(nil) end + + context 'when it cannot be resolved' do + let(:import_url) { 'http://foobar.x' } + + it 'raises error' do + stub_env('RSPEC_ALLOW_INVALID_URLS', 'false') + + expect { described_class.validate!(import_url) }.to raise_error(described_class::BlockedUrlError) + end + end end context 'when the URL hostname is an IP address' do @@ -79,6 +89,16 @@ describe Gitlab::UrlBlocker do expect(uri).to eq(Addressable::URI.parse('https://93.184.216.34')) expect(hostname).to be(nil) end + + context 'when it is invalid' do + let(:import_url) { 'http://1.1.1.1.1' } + + it 'raises an error' do + stub_env('RSPEC_ALLOW_INVALID_URLS', 'false') + + expect { described_class.validate!(import_url) }.to raise_error(described_class::BlockedUrlError) + end + end end end end @@ -180,8 +200,6 @@ describe Gitlab::UrlBlocker do end it 'returns true for a non-alphanumeric hostname' do - stub_resolv - aggregate_failures do expect(described_class).to be_blocked_url('ssh://-oProxyCommand=whoami/a') @@ -220,53 +238,53 @@ describe Gitlab::UrlBlocker do end let(:fake_domain) { 'www.fakedomain.fake' } - context 'true (default)' do + shared_examples 'allows local requests' do |url_blocker_attributes| it 'does not block urls from private networks' do local_ips.each do |ip| - stub_domain_resolv(fake_domain, ip) - - expect(described_class).not_to be_blocked_url("http://#{fake_domain}") - - unstub_domain_resolv + stub_domain_resolv(fake_domain, ip) do + expect(described_class).not_to be_blocked_url("http://#{fake_domain}", url_blocker_attributes) + end - expect(described_class).not_to be_blocked_url("http://#{ip}") + expect(described_class).not_to be_blocked_url("http://#{ip}", url_blocker_attributes) end end it 'allows localhost endpoints' do - expect(described_class).not_to be_blocked_url('http://0.0.0.0', allow_localhost: true) - expect(described_class).not_to be_blocked_url('http://localhost', allow_localhost: true) - expect(described_class).not_to be_blocked_url('http://127.0.0.1', allow_localhost: true) + expect(described_class).not_to be_blocked_url('http://0.0.0.0', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://localhost', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://127.0.0.1', url_blocker_attributes) end it 'allows loopback endpoints' do - expect(described_class).not_to be_blocked_url('http://127.0.0.2', allow_localhost: true) + expect(described_class).not_to be_blocked_url('http://127.0.0.2', url_blocker_attributes) end it 'allows IPv4 link-local endpoints' do - expect(described_class).not_to be_blocked_url('http://169.254.169.254') - expect(described_class).not_to be_blocked_url('http://169.254.168.100') + expect(described_class).not_to be_blocked_url('http://169.254.169.254', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://169.254.168.100', url_blocker_attributes) end it 'allows IPv6 link-local endpoints' do - expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.169.254]') - expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.169.254]') - expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a9fe]') - expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.168.100]') - expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.168.100]') - expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a864]') - expect(described_class).not_to be_blocked_url('http://[fe80::c800:eff:fe74:8]') + expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.169.254]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.169.254]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a9fe]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.168.100]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.168.100]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a864]', url_blocker_attributes) + expect(described_class).not_to be_blocked_url('http://[fe80::c800:eff:fe74:8]', url_blocker_attributes) end end + context 'true (default)' do + it_behaves_like 'allows local requests', { allow_localhost: true, allow_local_network: true } + end + context 'false' do it 'blocks urls from private networks' do local_ips.each do |ip| - stub_domain_resolv(fake_domain, ip) - - expect(described_class).to be_blocked_url("http://#{fake_domain}", allow_local_network: false) - - unstub_domain_resolv + stub_domain_resolv(fake_domain, ip) do + expect(described_class).to be_blocked_url("http://#{fake_domain}", allow_local_network: false) + end expect(described_class).to be_blocked_url("http://#{ip}", allow_local_network: false) end @@ -286,24 +304,174 @@ describe Gitlab::UrlBlocker do expect(described_class).to be_blocked_url('http://[::ffff:a9fe:a864]', allow_local_network: false) expect(described_class).to be_blocked_url('http://[fe80::c800:eff:fe74:8]', allow_local_network: false) end + + context 'when local domain/IP is whitelisted' do + let(:url_blocker_attributes) do + { + allow_localhost: false, + allow_local_network: false + } + end + + before do + stub_application_setting(outbound_local_requests_whitelist: whitelist) + end + + context 'with IPs in whitelist' do + let(:whitelist) do + [ + '0.0.0.0', + '127.0.0.1', + '127.0.0.2', + '192.168.1.1', + '192.168.1.2', + '0:0:0:0:0:ffff:192.168.1.2', + '::ffff:c0a8:102', + '10.0.0.2', + '0:0:0:0:0:ffff:10.0.0.2', + '::ffff:a00:2', + '172.16.0.2', + '0:0:0:0:0:ffff:172.16.0.2', + '::ffff:ac10:20', + 'feef::1', + 'fee2::', + 'fc00:bf8b:e62c:abcd:abcd:aaaa:aaaa:aaaa', + '0:0:0:0:0:ffff:169.254.169.254', + '::ffff:a9fe:a9fe', + '::ffff:169.254.168.100', + '::ffff:a9fe:a864', + 'fe80::c800:eff:fe74:8', + + # garbage IPs + '45645632345', + 'garbage456:more345gar:bage' + ] + end + + it_behaves_like 'allows local requests', { allow_localhost: false, allow_local_network: false } + + it 'whitelists IP when dns_rebind_protection is disabled' do + stub_domain_resolv('example.com', '192.168.1.1') do + expect(described_class).not_to be_blocked_url("http://example.com", + url_blocker_attributes.merge(dns_rebind_protection: false)) + end + end + end + + context 'with domains in whitelist' do + let(:whitelist) do + [ + 'www.example.com', + 'example.com', + 'xn--itlab-j1a.com', + 'garbage$^$%#$^&$' + ] + end + + it 'allows domains present in whitelist' do + domain = 'example.com' + subdomain1 = 'www.example.com' + subdomain2 = 'subdomain.example.com' + + stub_domain_resolv(domain, '192.168.1.1') do + expect(described_class).not_to be_blocked_url("http://#{domain}", + url_blocker_attributes) + end + + stub_domain_resolv(subdomain1, '192.168.1.1') do + expect(described_class).not_to be_blocked_url("http://#{subdomain1}", + url_blocker_attributes) + end + + # subdomain2 is not part of the whitelist so it should be blocked + stub_domain_resolv(subdomain2, '192.168.1.1') do + expect(described_class).to be_blocked_url("http://#{subdomain2}", + url_blocker_attributes) + end + end + + it 'works with unicode and idna encoded domains' do + unicode_domain = 'ğitlab.com' + idna_encoded_domain = 'xn--itlab-j1a.com' + + stub_domain_resolv(unicode_domain, '192.168.1.1') do + expect(described_class).not_to be_blocked_url("http://#{unicode_domain}", + url_blocker_attributes) + end + + stub_domain_resolv(idna_encoded_domain, '192.168.1.1') do + expect(described_class).not_to be_blocked_url("http://#{idna_encoded_domain}", + url_blocker_attributes) + end + end + end + + context 'with ip ranges in whitelist' do + let(:ipv4_range) { '127.0.0.0/28' } + let(:ipv6_range) { 'fd84:6d02:f6d8:c89e::/124' } + + let(:whitelist) do + [ + ipv4_range, + ipv6_range + ] + end + + it 'blocks ipv4 range when not in whitelist' do + stub_application_setting(outbound_local_requests_whitelist: []) + + IPAddr.new(ipv4_range).to_range.to_a.each do |ip| + expect(described_class).to be_blocked_url("http://#{ip}", + url_blocker_attributes) + end + end + + it 'allows all ipv4s in the range when in whitelist' do + IPAddr.new(ipv4_range).to_range.to_a.each do |ip| + expect(described_class).not_to be_blocked_url("http://#{ip}", + url_blocker_attributes) + end + end + + it 'blocks ipv6 range when not in whitelist' do + stub_application_setting(outbound_local_requests_whitelist: []) + + IPAddr.new(ipv6_range).to_range.to_a.each do |ip| + expect(described_class).to be_blocked_url("http://[#{ip}]", + url_blocker_attributes) + end + end + + it 'allows all ipv6s in the range when in whitelist' do + IPAddr.new(ipv6_range).to_range.to_a.each do |ip| + expect(described_class).not_to be_blocked_url("http://[#{ip}]", + url_blocker_attributes) + end + end + + it 'blocks IPs outside the range' do + expect(described_class).to be_blocked_url("http://[fd84:6d02:f6d8:c89e:0:0:1:f]", + url_blocker_attributes) + + expect(described_class).to be_blocked_url("http://127.0.1.15", + url_blocker_attributes) + end + end + end end - def stub_domain_resolv(domain, ip) + def stub_domain_resolv(domain, ip, &block) address = double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false, ipv4_loopback?: false, ipv6_loopback?: false, ipv4?: false) allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([address]) allow(address).to receive(:ipv6_v4mapped?).and_return(false) - end - def unstub_domain_resolv + yield + allow(Addrinfo).to receive(:getaddrinfo).and_call_original end end context 'when enforce_user is' do - before do - stub_resolv - end - context 'false (default)' do it 'does not block urls with a non-alphanumeric username' do expect(described_class).not_to be_blocked_url('ssh://-oProxyCommand=whoami@example.com/a') @@ -351,6 +519,18 @@ describe Gitlab::UrlBlocker do expect(described_class.blocked_url?('https://gitlab.com/foo/foo.bar', ascii_only: true)).to be true end end + + it 'blocks urls with invalid ip address' do + stub_env('RSPEC_ALLOW_INVALID_URLS', 'false') + + expect(described_class).to be_blocked_url('http://8.8.8.8.8') + end + + it 'blocks urls whose hostname cannot be resolved' do + stub_env('RSPEC_ALLOW_INVALID_URLS', 'false') + + expect(described_class).to be_blocked_url('http://foobar.x') + end end describe '#validate_hostname' do @@ -382,10 +562,4 @@ describe Gitlab::UrlBlocker do end end end - - # Resolv does not support resolving UTF-8 domain names - # See https://bugs.ruby-lang.org/issues/4270 - def stub_resolv - allow(Resolv).to receive(:getaddresses).and_return([]) - end end diff --git a/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb new file mode 100644 index 00000000000..c34ac7867ab --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UsageDataCounters::RedisCounter, :clean_gitlab_redis_shared_state do + let(:redis_key) { 'foobar' } + + subject { Class.new.extend(described_class) } + + before do + stub_application_setting(usage_ping_enabled: setting_value) + end + + context 'when usage_ping is disabled' do + let(:setting_value) { false } + + it 'counter is not increased' do + expect do + subject.increment(redis_key) + end.not_to change { subject.total_count(redis_key) } + end + end + + context 'when usage_ping is enabled' do + let(:setting_value) { true } + + it 'counter is increased' do + expect do + subject.increment(redis_key) + end.to change { subject.total_count(redis_key) }.by(1) + end + end +end diff --git a/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb new file mode 100644 index 00000000000..50a9f980dc7 --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/search_counter_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UsageDataCounters::SearchCounter, :clean_gitlab_redis_shared_state do + it 'increments counter and return the total count' do + expect(described_class.total_navbar_searches_count).to eq(0) + + 2.times { described_class.increment_navbar_searches_count } + + expect(described_class.total_navbar_searches_count).to eq(2) + end +end diff --git a/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb new file mode 100644 index 00000000000..7a01f7d1de8 --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UsageDataCounters::WebIdeCounter, :clean_gitlab_redis_shared_state do + shared_examples 'counter examples' do + it 'increments counter and return the total count' do + expect(described_class.public_send(total_counter_method)).to eq(0) + + 2.times { described_class.public_send(increment_counter_method) } + + expect(described_class.public_send(total_counter_method)).to eq(2) + end + end + + describe 'commits counter' do + let(:increment_counter_method) { :increment_commits_count } + let(:total_counter_method) { :total_commits_count } + + it_behaves_like 'counter examples' + end + + describe 'merge requests counter' do + let(:increment_counter_method) { :increment_merge_requests_count } + let(:total_counter_method) { :total_merge_requests_count } + + it_behaves_like 'counter examples' + end + + describe 'views counter' do + let(:increment_counter_method) { :increment_views_count } + let(:total_counter_method) { :total_views_count } + + it_behaves_like 'counter examples' + end + + describe '.totals' do + commits = 5 + merge_requests = 3 + views = 2 + + before do + commits.times { described_class.increment_commits_count } + merge_requests.times { described_class.increment_merge_requests_count } + views.times { described_class.increment_views_count } + end + + it 'can report all totals' do + expect(described_class.totals).to include( + web_ide_commits: commits, + web_ide_views: views, + web_ide_merge_requests: merge_requests + ) + end + end +end diff --git a/spec/lib/gitlab/usage_data_counters/wiki_page_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/wiki_page_counter_spec.rb new file mode 100644 index 00000000000..4e8ae35187e --- /dev/null +++ b/spec/lib/gitlab/usage_data_counters/wiki_page_counter_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UsageDataCounters::WikiPageCounter do + it_behaves_like 'a redis usage counter', 'Wiki Page', :create + it_behaves_like 'a redis usage counter', 'Wiki Page', :update + it_behaves_like 'a redis usage counter', 'Wiki Page', :delete + + it_behaves_like 'a redis usage counter with totals', :wiki_pages, + create: 5, + update: 3, + delete: 2 +end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 90a534de202..297c4f0b683 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -24,7 +24,7 @@ describe Gitlab::UsageData do create(:cluster, :group, :disabled) create(:clusters_applications_helm, :installed, cluster: gcp_cluster) create(:clusters_applications_ingress, :installed, cluster: gcp_cluster) - create(:clusters_applications_cert_managers, :installed, cluster: gcp_cluster) + create(:clusters_applications_cert_manager, :installed, cluster: gcp_cluster) create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster) create(:clusters_applications_runner, :installed, cluster: gcp_cluster) create(:clusters_applications_knative, :installed, cluster: gcp_cluster) @@ -57,10 +57,19 @@ describe Gitlab::UsageData do gitaly database avg_cycle_analytics - web_ide_commits influxdb_metrics_enabled prometheus_metrics_enabled )) + + expect(subject).to include( + wiki_pages_create: a_kind_of(Integer), + wiki_pages_update: a_kind_of(Integer), + wiki_pages_delete: a_kind_of(Integer), + web_ide_views: a_kind_of(Integer), + web_ide_commits: a_kind_of(Integer), + web_ide_merge_requests: a_kind_of(Integer), + navbar_searches: a_kind_of(Integer) + ) end it "gathers usage counts" do @@ -182,6 +191,28 @@ describe Gitlab::UsageData do end end + describe '#usage_data_counters' do + subject { described_class.usage_data_counters } + + it { is_expected.to all(respond_to :totals) } + + describe 'the results of calling #totals on all objects in the array' do + subject { described_class.usage_data_counters.map(&:totals) } + + it do + is_expected + .to all(be_a Hash) + .and all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) + end + end + + it 'does not have any conflicts' do + all_keys = subject.flat_map { |counter| counter.totals.keys } + + expect(all_keys.size).to eq all_keys.to_set.size + end + end + describe '#features_usage_data_ce' do subject { described_class.features_usage_data_ce } diff --git a/spec/lib/gitlab/utils/sanitize_node_link_spec.rb b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb new file mode 100644 index 00000000000..064c2707d06 --- /dev/null +++ b/spec/lib/gitlab/utils/sanitize_node_link_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe Gitlab::Utils::SanitizeNodeLink do + let(:klass) do + struct = Struct.new(:value) + struct.include(described_class) + + struct + end + + subject(:object) { klass.new(:value) } + + invalid_schemes = [ + "javascript:", + "JaVaScRiPt:", + "\u0001java\u0003script:", + "javascript :", + "javascript: ", + "javascript : ", + ":javascript:", + "javascript:", + "javascript:", + "  javascript:" + ] + + invalid_schemes.each do |scheme| + context "with the scheme: #{scheme}" do + describe "#remove_unsafe_links" do + tags = { + a: { + doc: HTML::Pipeline.parse("<a href='#{scheme}alert(1);'>foo</a>"), + attr: "href", + node_to_check: -> (doc) { doc.children.first } + }, + img: { + doc: HTML::Pipeline.parse("<img src='#{scheme}alert(1);'>"), + attr: "src", + node_to_check: -> (doc) { doc.children.first } + }, + video: { + doc: HTML::Pipeline.parse("<video><source src='#{scheme}alert(1);'></video>"), + attr: "src", + node_to_check: -> (doc) { doc.children.first.children.filter("source").first } + } + } + + tags.each do |tag, opts| + context "<#{tag}> tags" do + it "removes the unsafe link" do + node = opts[:node_to_check].call(opts[:doc]) + + expect { object.remove_unsafe_links({ node: node }, remove_invalid_links: true) } + .to change { node[opts[:attr]] } + + expect(node[opts[:attr]]).to be_blank + end + end + end + end + + describe "#safe_protocol?" do + let(:doc) { HTML::Pipeline.parse("<a href='#{scheme}alert(1);'>foo</a>") } + let(:node) { doc.children.first } + let(:uri) { Addressable::URI.parse(node['href'])} + + it "returns false" do + expect(object.safe_protocol?(scheme)).to be_falsy + end + end + end + end +end diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb index 4645339f439..0c20b3aa4c8 100644 --- a/spec/lib/gitlab/utils_spec.rb +++ b/spec/lib/gitlab/utils_spec.rb @@ -231,4 +231,23 @@ describe Gitlab::Utils do end end end + + describe '.string_to_ip_object' do + it 'returns nil when string is nil' do + expect(described_class.string_to_ip_object(nil)).to eq(nil) + end + + it 'returns nil when string is invalid IP' do + expect(described_class.string_to_ip_object('invalid ip')).to eq(nil) + expect(described_class.string_to_ip_object('')).to eq(nil) + end + + it 'returns IP object when string is valid IP' do + expect(described_class.string_to_ip_object('192.168.1.1')).to eq(IPAddr.new('192.168.1.1')) + expect(described_class.string_to_ip_object('::ffff:a9fe:a864')).to eq(IPAddr.new('::ffff:a9fe:a864')) + expect(described_class.string_to_ip_object('[::ffff:a9fe:a864]')).to eq(IPAddr.new('::ffff:a9fe:a864')) + expect(described_class.string_to_ip_object('127.0.0.0/28')).to eq(IPAddr.new('127.0.0.0/28')) + expect(described_class.string_to_ip_object('1:0:0:0:0:0:0:0/124')).to eq(IPAddr.new('1:0:0:0:0:0:0:0/124')) + end + end end diff --git a/spec/lib/gitlab/web_ide_commits_counter_spec.rb b/spec/lib/gitlab/web_ide_commits_counter_spec.rb deleted file mode 100644 index c51889a1c63..00000000000 --- a/spec/lib/gitlab/web_ide_commits_counter_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Gitlab::WebIdeCommitsCounter, :clean_gitlab_redis_shared_state do - describe '.increment' do - it 'increments the web ide commits counter by 1' do - expect do - described_class.increment - end.to change { described_class.total_count }.from(0).to(1) - end - end - - describe '.total_count' do - it 'returns the total amount of web ide commits' do - expect(described_class.total_count).to eq(0) - end - end -end diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb index f8332757fcd..451e18ed91b 100644 --- a/spec/lib/gitlab/workhorse_spec.rb +++ b/spec/lib/gitlab/workhorse_spec.rb @@ -404,6 +404,7 @@ describe Gitlab::Workhorse do end it 'set and notify' do + expect(Gitlab::Redis::SharedState).to receive(:with).and_call_original expect_any_instance_of(::Redis).to receive(:publish) .with(described_class::NOTIFICATION_CHANNEL, "test-key=test-value") diff --git a/spec/lib/gitlab/zoom_link_extractor_spec.rb b/spec/lib/gitlab/zoom_link_extractor_spec.rb new file mode 100644 index 00000000000..c3d1679d031 --- /dev/null +++ b/spec/lib/gitlab/zoom_link_extractor_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::ZoomLinkExtractor do + describe "#links" do + using RSpec::Parameterized::TableSyntax + + where(:text, :links) do + 'issue text https://zoom.us/j/123 and https://zoom.us/s/1123433' | %w[https://zoom.us/j/123 https://zoom.us/s/1123433] + 'https://zoom.us/j/1123433 issue text' | %w[https://zoom.us/j/1123433] + 'issue https://zoom.us/my/1123433 text' | %w[https://zoom.us/my/1123433] + 'issue https://gitlab.com and https://gitlab.zoom.us/s/1123433' | %w[https://gitlab.zoom.us/s/1123433] + 'https://gitlab.zoom.us/j/1123433' | %w[https://gitlab.zoom.us/j/1123433] + 'https://gitlab.zoom.us/my/1123433' | %w[https://gitlab.zoom.us/my/1123433] + end + + with_them do + subject { described_class.new(text).links } + + it { is_expected.to eq(links) } + end + + describe '#match?' do + it 'is true when a zoom link found' do + expect(described_class.new('issue text https://zoom.us/j/123')).to be_match + end + + it 'is false when no zoom link found' do + expect(described_class.new('issue text')).not_to be_match + end + end + end +end |