summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-10-22 12:09:12 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-10-22 12:09:12 +0000
commitfaec73b0fe1b2f19646363e4359f302fc1b9414c (patch)
tree09e887c8737a516926917fc0c0e8b675bf6fcac4
parente9a834ee298801dec92de77783fffa0cea9deb34 (diff)
downloadgitlab-ce-faec73b0fe1b2f19646363e4359f302fc1b9414c.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml1
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml1
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--README.md2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue10
-rw-r--r--app/controllers/admin/runners_controller.rb1
-rw-r--r--app/models/ci/runner.rb1
-rw-r--r--app/models/project.rb2
-rw-r--r--app/services/spam/spam_verdict_service.rb12
-rw-r--r--lib/api/helpers.rb6
-rw-r--r--lib/api/namespaces.rb2
-rw-r--r--lib/gitlab/database/migration_helpers.rb31
-rw-r--r--lib/gitlab/setup_helper.rb7
-rw-r--r--lib/tasks/gitlab/gitaly.rake2
-rwxr-xr-xscripts/security-harness3
-rw-r--r--spec/finders/branches_finder_spec.rb8
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_options_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js27
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js5
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb90
-rw-r--r--spec/requests/api/namespaces_spec.rb54
-rw-r--r--spec/services/spam/spam_verdict_service_spec.rb4
-rw-r--r--spec/support/database/cross-join-allowlist.yml7
-rw-r--r--spec/support/helpers/gitaly_setup.rb2
-rw-r--r--spec/tasks/gitlab/gitaly_rake_spec.rb6
27 files changed, 225 insertions, 74 deletions
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index d0c26d60066..d2a460bf8b7 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -44,6 +44,7 @@
prefix: "gitaly-binaries"
paths:
- tmp/tests/gitaly/_build/bin/
+ - tmp/tests/gitaly/_build/deps/git/install/
- tmp/tests/gitaly/config.toml
- tmp/tests/gitaly/gitaly2.config.toml
- tmp/tests/gitaly/internal/
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index 00f65ab7ca8..e82068092e0 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -181,6 +181,7 @@ setup-test-env:
paths:
- config/secrets.yml
- tmp/tests/gitaly/_build/bin/
+ - tmp/tests/gitaly/_build/deps/git/install
- tmp/tests/gitaly/config.toml
- tmp/tests/gitaly/gitaly2.config.toml
- tmp/tests/gitaly/internal/
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index c98aa0f5258..05f9d7573ba 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-4f0a07ba39f14adacf7d482128a5de2bb84f0eac
+ee4b20cc318876c4b237e277fefd9d75186a085c
diff --git a/README.md b/README.md
index f5ec329cd9e..64f19939ec2 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ To work on GitLab itself, we recommend setting up your development environment w
If you do not use the GitLab Development Kit you need to install and configure all the dependencies yourself, this is a lot of work and error prone.
One small thing you also have to do when installing it yourself is to copy the example development Puma configuration file:
- cp config/puma.rb.example.development config/puma.rb
+ cp config/puma.example.development.rb config/puma.rb
Instructions on how to start GitLab and how to run the tests can be found in the [getting started section of the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit#getting-started).
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
index 023367a794e..6483875a3d0 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/actions.vue
@@ -30,7 +30,7 @@ export default {
<template>
<div>
<gl-dropdown
- v-if="tertiaryButtons"
+ v-if="tertiaryButtons.length"
:text="dropdownLabel"
icon="ellipsis_v"
no-caret
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index 298f7c7ad8c..8dafdec0e92 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -143,7 +143,10 @@ export default {
:is-loading="isLoadingSummary"
:icon-name="statusIconName"
/>
- <div class="media-body gl-display-flex gl-flex-direction-row!">
+ <div
+ class="media-body gl-display-flex gl-flex-direction-row!"
+ data-testid="widget-extension-top-level"
+ >
<div class="gl-flex-grow-1">
<template v-if="isLoadingSummary">{{ widgetLoadingText }}</template>
<div v-else v-safe-html="summary(collapsedData)"></div>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
index 9dc5c5db276..7c1828f2294 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue
@@ -171,15 +171,17 @@ export default {
* This watcher listens for updates to `filterValue` on
* such instances. :(
*/
- filterValue(value) {
- const [firstVal] = value;
+ filterValue(newValue, oldValue) {
+ const [firstVal] = newValue;
if (
!this.initialRender &&
- value.length === 1 &&
+ newValue.length === 1 &&
firstVal.type === 'filtered-search-term' &&
!firstVal.value.data
) {
- this.$emit('onFilter', []);
+ const filtersCleared =
+ oldValue[0].type !== 'filtered-search-term' || oldValue[0].value.data !== '';
+ this.$emit('onFilter', [], filtersCleared);
}
// Set initial render flag to false
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 2dd6de971cc..76e86f15da8 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -88,6 +88,7 @@ class Admin::RunnersController < Admin::ApplicationController
::Gitlab::Database.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338659') do
@projects = @projects.where.not(id: runner.projects.select(:id)) if runner.projects.any?
+ @projects = @projects.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338659')
@projects = @projects.inc_routes
@projects = @projects.page(params[:page]).per(30).without_count
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 2f8a04eefb3..e86c5ad9d38 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -96,6 +96,7 @@ module Ci
union_sql = ::Gitlab::SQL::Union.new([group_runners, project_runners]).to_sql
from("(#{union_sql}) #{table_name}")
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/336433')
}
scope :belonging_to_parent_group_of_project, -> (project_id) {
diff --git a/app/models/project.rb b/app/models/project.rb
index cb58fee206b..7bc0efa1d3f 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1780,10 +1780,12 @@ class Project < ApplicationRecord
def all_runners
Ci::Runner.from_union([runners, group_runners, shared_runners])
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937')
end
def all_available_runners
Ci::Runner.from_union([runners, group_runners, available_shared_runners])
+ .allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/339937')
end
# Once issue 339937 is fixed, please search for all mentioned of
diff --git a/app/services/spam/spam_verdict_service.rb b/app/services/spam/spam_verdict_service.rb
index 8d995631db6..c8bdcf4310b 100644
--- a/app/services/spam/spam_verdict_service.rb
+++ b/app/services/spam/spam_verdict_service.rb
@@ -73,18 +73,12 @@ module Spam
begin
result, attribs, _error = spamcheck_client.issue_spam?(spam_issue: target, user: user, context: context)
- return [nil, attribs] unless result
-
# @TODO log if error is not nil https://gitlab.com/gitlab-org/gitlab/-/issues/329545
- return [result, attribs] if result == NOOP || attribs["monitorMode"] == "true"
+ return [nil, attribs] unless result
+
+ [result, attribs]
- # Duplicate logic with Akismet logic in #akismet_verdict
- if Gitlab::Recaptcha.enabled? && result != ALLOW
- [CONDITIONAL_ALLOW, attribs]
- else
- [result, attribs]
- end
rescue StandardError => e
Gitlab::ErrorTracking.log_exception(e)
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index f9ba5ba8186..ac57094a1ef 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -174,9 +174,9 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
def find_namespace(id)
if id.to_s =~ /^\d+$/
- Namespace.find_by(id: id)
+ Namespace.without_project_namespaces.find_by(id: id)
else
- Namespace.find_by_full_path(id)
+ find_namespace_by_path(id)
end
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -186,7 +186,7 @@ module API
end
def find_namespace_by_path(path)
- Namespace.find_by_full_path(path)
+ Namespace.without_project_namespaces.find_by_full_path(path)
end
def find_namespace_by_path!(path)
diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb
index c2d839571a6..2cdb3e2cd07 100644
--- a/lib/api/namespaces.rb
+++ b/lib/api/namespaces.rb
@@ -37,7 +37,7 @@ module API
namespaces = current_user.admin ? Namespace.all : current_user.namespaces(owned_only: owned_only)
- namespaces = namespaces.include_route
+ namespaces = namespaces.without_project_namespaces.include_route
namespaces = namespaces.include_gitlab_subscription_with_hosted_plan if Gitlab.ee?
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 9968096b1f6..7a7906a42d0 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -147,8 +147,18 @@ module Gitlab
options = options.merge({ algorithm: :concurrently })
if index_exists?(table_name, column_name, **options)
- Gitlab::AppLogger.warn "Index not created because it already exists (this may be due to an aborted migration or similar): table_name: #{table_name}, column_name: #{column_name}"
- return
+ name = options[:name] || index_name(table_name, column_name)
+ _, schema = table_name.to_s.split('.').reverse
+
+ if index_invalid?(name, schema: schema)
+ say "Index being recreated because the existing version was INVALID: table_name: #{table_name}, column_name: #{column_name}"
+
+ remove_concurrent_index_by_name(table_name, name)
+ else
+ say "Index not created because it already exists (this may be due to an aborted migration or similar): table_name: #{table_name}, column_name: #{column_name}"
+
+ return
+ end
end
disable_statement_timeout do
@@ -159,6 +169,23 @@ module Gitlab
unprepare_async_index(table_name, column_name, **options)
end
+ def index_invalid?(index_name, schema: nil)
+ index_name = connection.quote(index_name)
+ schema = connection.quote(schema) if schema
+ schema ||= 'current_schema()'
+
+ connection.select_value(<<~SQL)
+ select not i.indisvalid
+ from pg_class c
+ inner join pg_index i
+ on c.oid = i.indexrelid
+ inner join pg_namespace n
+ on n.oid = c.relnamespace
+ where n.nspname = #{schema}
+ and c.relname = #{index_name}
+ SQL
+ end
+
# Removes an existed index, concurrently
#
# Example:
diff --git a/lib/gitlab/setup_helper.rb b/lib/gitlab/setup_helper.rb
index 751405f1045..3a31f651714 100644
--- a/lib/gitlab/setup_helper.rb
+++ b/lib/gitlab/setup_helper.rb
@@ -104,9 +104,6 @@ module Gitlab
socket_filename = options[:gitaly_socket] || "gitaly.socket"
prometheus_listen_addr = options[:prometheus_listen_addr]
- git_bin_path = File.expand_path('../gitaly/_build/deps/git/install/bin/git')
- git_bin_path = nil unless File.exist?(git_bin_path)
-
config = {
# Override the set gitaly_address since Praefect is in the loop
socket_path: File.join(gitaly_dir, socket_filename),
@@ -116,8 +113,8 @@ module Gitlab
# sidekiq jobs, and concurrency will be low anyway in test.
git: {
catfile_cache_size: 5,
- bin_path: git_bin_path
- }.compact,
+ bin_path: File.expand_path(File.join(gitaly_dir, '_build', 'deps', 'git', 'install', 'bin', 'git'))
+ },
prometheus_listen_addr: prometheus_listen_addr
}.compact
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
index ef58c9339f1..ea17d25ee62 100644
--- a/lib/tasks/gitlab/gitaly.rake
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -67,7 +67,7 @@ Usage: rake "gitlab:gitaly:install[/installation/dir,/storage/path]")
env["BUNDLE_DEPLOYMENT"] = 'false'
end
- Gitlab::Popen.popen([make_cmd], nil, env)
+ Gitlab::Popen.popen([make_cmd, 'all', 'git'], nil, env)
end
end
end
diff --git a/scripts/security-harness b/scripts/security-harness
index ec062fc17cc..df499be23f5 100755
--- a/scripts/security-harness
+++ b/scripts/security-harness
@@ -4,7 +4,6 @@
require 'digest'
require 'fileutils'
-require 'open3'
if ENV['NO_COLOR']
SHELL_RED = ''
@@ -19,7 +18,7 @@ else
end
LEFTHOOK_GLOBAL_CONFIG_PATH = File.expand_path("../lefthook.yml", __dir__)
-HOOK_PATH = Open3.capture3("git rev-parse --path-format=absolute --git-path hooks/pre-push")[0].strip
+HOOK_PATH = `git rev-parse --path-format=absolute --git-path hooks/pre-push`.split.last
HOOK_DATA = <<~HOOK
#!/usr/bin/env bash
diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb
index f9d525c33a4..11b7ab08fb2 100644
--- a/spec/finders/branches_finder_spec.rb
+++ b/spec/finders/branches_finder_spec.rb
@@ -208,10 +208,10 @@ RSpec.describe BranchesFinder do
context 'by page_token only' do
let(:params) { { page_token: 'feature' } }
- it 'returns nothing' do
- result = subject
-
- expect(result.count).to eq(0)
+ it 'raises an error' do
+ expect do
+ subject
+ end.to raise_error(Gitlab::Git::CommandError, '13:could not find page token.')
end
end
diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
index 5aba6982886..8a99d83237e 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
@@ -1,4 +1,4 @@
-import { GlBadge, GlLink, GlIcon } from '@gitlab/ui';
+import { GlBadge, GlLink, GlIcon, GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
@@ -913,6 +913,10 @@ describe('MrWidgetOptions', () => {
await Vue.nextTick();
+ expect(
+ wrapper.find('[data-testid="widget-extension-top-level"]').find(GlDropdown).exists(),
+ ).toBe(false);
+
const collapsedSection = wrapper.find('[data-testid="widget-extension-collapsed-section"]');
expect(collapsedSection.exists()).toBe(true);
expect(collapsedSection.text()).toContain('Hello world');
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
index 8e931aebfe0..64d15884333 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/filtered_search_bar_root_spec.js
@@ -25,6 +25,7 @@ import {
tokenValueMilestone,
tokenValueMembership,
tokenValueConfidential,
+ tokenValueEmpty,
} from './mock_data';
jest.mock('~/vue_shared/components/filtered_search_bar/filtered_search_utils', () => ({
@@ -43,6 +44,7 @@ const createComponent = ({
recentSearchesStorageKey = 'requirements',
tokens = mockAvailableTokens,
sortOptions,
+ initialFilterValue = [],
showCheckbox = false,
checkboxChecked = false,
searchInputPlaceholder = 'Filter requirements',
@@ -55,6 +57,7 @@ const createComponent = ({
recentSearchesStorageKey,
tokens,
sortOptions,
+ initialFilterValue,
showCheckbox,
checkboxChecked,
searchInputPlaceholder,
@@ -193,19 +196,27 @@ describe('FilteredSearchBarRoot', () => {
describe('watchers', () => {
describe('filterValue', () => {
- it('emits component event `onFilter` with empty array when `filterValue` is cleared by GlFilteredSearch', () => {
+ it('emits component event `onFilter` with empty array and false when filter was never selected', () => {
+ wrapper = createComponent({ initialFilterValue: [tokenValueEmpty] });
wrapper.setData({
initialRender: false,
- filterValue: [
- {
- type: 'filtered-search-term',
- value: { data: '' },
- },
- ],
+ filterValue: [tokenValueEmpty],
+ });
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.emitted('onFilter')[0]).toEqual([[], false]);
+ });
+ });
+
+ it('emits component event `onFilter` with empty array and true when initially selected filter value was cleared', () => {
+ wrapper = createComponent({ initialFilterValue: [tokenValueLabel] });
+ wrapper.setData({
+ initialRender: false,
+ filterValue: [tokenValueEmpty],
});
return wrapper.vm.$nextTick(() => {
- expect(wrapper.emitted('onFilter')[0]).toEqual([[]]);
+ expect(wrapper.emitted('onFilter')[0]).toEqual([[], true]);
});
});
});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
index ae02c554e13..c2462d90a63 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/mock_data.js
@@ -282,6 +282,11 @@ export const tokenValuePlain = {
value: { data: 'foo' },
};
+export const tokenValueEmpty = {
+ type: 'filtered-search-term',
+ value: { data: '' },
+};
+
export const tokenValueEpic = {
type: 'epic_iid',
value: {
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index d89af1521a2..7b128fb49db 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -271,12 +271,92 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
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, { algorithm: :concurrently, unique: true }).and_return(true)
- expect(model).not_to receive(:add_index)
+ context 'when the index exists and is valid' do
+ before do
+ model.add_index :users, :id, unique: true
+ end
- model.add_concurrent_index(:users, :foo, unique: true)
+ it 'does leaves the existing index' do
+ expect(model).to receive(:index_exists?)
+ .with(:users, :id, { algorithm: :concurrently, unique: true }).and_call_original
+
+ expect(model).not_to receive(:remove_index)
+ expect(model).not_to receive(:add_index)
+
+ model.add_concurrent_index(:users, :id, unique: true)
+ end
+ end
+
+ context 'when an invalid copy of the index exists' do
+ before do
+ model.add_index :users, :id, unique: true, name: index_name
+
+ model.connection.execute(<<~SQL)
+ UPDATE pg_index
+ SET indisvalid = false
+ WHERE indexrelid = '#{index_name}'::regclass
+ SQL
+ end
+
+ context 'when the default name is used' do
+ let(:index_name) { model.index_name(:users, :id) }
+
+ it 'drops and recreates the index' do
+ expect(model).to receive(:index_exists?)
+ .with(:users, :id, { algorithm: :concurrently, unique: true }).and_call_original
+ expect(model).to receive(:index_invalid?).with(index_name, schema: nil).and_call_original
+
+ expect(model).to receive(:remove_concurrent_index_by_name).with(:users, index_name)
+
+ expect(model).to receive(:add_index)
+ .with(:users, :id, { algorithm: :concurrently, unique: true })
+
+ model.add_concurrent_index(:users, :id, unique: true)
+ end
+ end
+
+ context 'when a custom name is used' do
+ let(:index_name) { 'my_test_index' }
+
+ it 'drops and recreates the index' do
+ expect(model).to receive(:index_exists?)
+ .with(:users, :id, { algorithm: :concurrently, unique: true, name: index_name }).and_call_original
+ expect(model).to receive(:index_invalid?).with(index_name, schema: nil).and_call_original
+
+ expect(model).to receive(:remove_concurrent_index_by_name).with(:users, index_name)
+
+ expect(model).to receive(:add_index)
+ .with(:users, :id, { algorithm: :concurrently, unique: true, name: index_name })
+
+ model.add_concurrent_index(:users, :id, unique: true, name: index_name)
+ end
+ end
+
+ context 'when a qualified table name is used' do
+ let(:other_schema) { 'foo_schema' }
+ let(:index_name) { 'my_test_index' }
+ let(:table_name) { "#{other_schema}.users" }
+
+ before do
+ model.connection.execute(<<~SQL)
+ CREATE SCHEMA #{other_schema};
+ ALTER TABLE users SET SCHEMA #{other_schema};
+ SQL
+ end
+
+ it 'drops and recreates the index' do
+ expect(model).to receive(:index_exists?)
+ .with(table_name, :id, { algorithm: :concurrently, unique: true, name: index_name }).and_call_original
+ expect(model).to receive(:index_invalid?).with(index_name, schema: other_schema).and_call_original
+
+ expect(model).to receive(:remove_concurrent_index_by_name).with(table_name, index_name)
+
+ expect(model).to receive(:add_index)
+ .with(table_name, :id, { algorithm: :concurrently, unique: true, name: index_name })
+
+ model.add_concurrent_index(table_name, :id, unique: true, name: index_name)
+ end
+ end
end
it 'unprepares the async index creation' do
diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb
index 222d8992d1b..0a569819205 100644
--- a/spec/requests/api/namespaces_spec.rb
+++ b/spec/requests/api/namespaces_spec.rb
@@ -3,10 +3,12 @@
require 'spec_helper'
RSpec.describe API::Namespaces do
- let(:admin) { create(:admin) }
- let(:user) { create(:user) }
- let!(:group1) { create(:group, name: 'group.one') }
- let!(:group2) { create(:group, :nested) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group1) { create(:group, name: 'group.one') }
+ let_it_be(:group2) { create(:group, :nested) }
+ let_it_be(:project) { create(:project, namespace: group2, name: group2.name, path: group2.path) }
+ let_it_be(:project_namespace) { create(:project_namespace, project: project) }
describe "GET /namespaces" do
context "when unauthenticated" do
@@ -26,7 +28,7 @@ RSpec.describe API::Namespaces do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(group_kind_json_response.keys).to include('id', 'kind', 'name', 'path', 'full_path',
- 'parent_id', 'members_count_with_descendants')
+ 'parent_id', 'members_count_with_descendants')
expect(user_kind_json_response.keys).to include('id', 'kind', 'name', 'path', 'full_path', 'parent_id')
end
@@ -37,7 +39,8 @@ RSpec.describe API::Namespaces do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
- expect(json_response.length).to eq(Namespace.count)
+ # project namespace is excluded
+ expect(json_response.length).to eq(Namespace.count - 1)
end
it "admin: returns an array of matched namespaces" do
@@ -61,7 +64,7 @@ RSpec.describe API::Namespaces do
owned_group_response = json_response.find { |resource| resource['id'] == group1.id }
expect(owned_group_response.keys).to include('id', 'kind', 'name', 'path', 'full_path',
- 'parent_id', 'members_count_with_descendants')
+ 'parent_id', 'members_count_with_descendants')
end
it "returns correct attributes when user cannot admin group" do
@@ -109,7 +112,8 @@ RSpec.describe API::Namespaces do
describe 'GET /namespaces/:id' do
let(:owned_group) { group1 }
- let(:user2) { create(:user) }
+
+ let_it_be(:user2) { create(:user) }
shared_examples 'can access namespace' do
it 'returns namespace details' do
@@ -144,6 +148,16 @@ RSpec.describe API::Namespaces do
it_behaves_like 'can access namespace'
end
+
+ context 'when requesting project_namespace' do
+ let(:namespace_id) { project_namespace.id }
+
+ it 'returns not-found' do
+ get api("/namespaces/#{namespace_id}", request_actor)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
context 'when requested by path' do
@@ -159,6 +173,16 @@ RSpec.describe API::Namespaces do
it_behaves_like 'can access namespace'
end
+
+ context 'when requesting project_namespace' do
+ let(:namespace_id) { project_namespace.full_path }
+
+ it 'returns not-found' do
+ get api("/namespaces/#{namespace_id}", request_actor)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
end
@@ -177,6 +201,12 @@ RSpec.describe API::Namespaces do
expect(response).to have_gitlab_http_status(:unauthorized)
end
+
+ it 'returns authentication error' do
+ get api("/namespaces/#{project_namespace.id}")
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
end
context 'when authenticated as regular user' do
@@ -231,10 +261,10 @@ RSpec.describe API::Namespaces do
end
describe 'GET /namespaces/:namespace/exists' do
- let!(:namespace1) { create(:group, name: 'Namespace 1', path: 'namespace-1') }
- let!(:namespace2) { create(:group, name: 'Namespace 2', path: 'namespace-2') }
- let!(:namespace1sub) { create(:group, name: 'Sub Namespace 1', path: 'sub-namespace-1', parent: namespace1) }
- let!(:namespace2sub) { create(:group, name: 'Sub Namespace 2', path: 'sub-namespace-2', parent: namespace2) }
+ let_it_be(:namespace1) { create(:group, name: 'Namespace 1', path: 'namespace-1') }
+ let_it_be(:namespace2) { create(:group, name: 'Namespace 2', path: 'namespace-2') }
+ let_it_be(:namespace1sub) { create(:group, name: 'Sub Namespace 1', path: 'sub-namespace-1', parent: namespace1) }
+ let_it_be(:namespace2sub) { create(:group, name: 'Sub Namespace 2', path: 'sub-namespace-2', parent: namespace2) }
context 'when unauthenticated' do
it 'returns authentication error' do
diff --git a/spec/services/spam/spam_verdict_service_spec.rb b/spec/services/spam/spam_verdict_service_spec.rb
index 659c21b7d4f..99047f3233b 100644
--- a/spec/services/spam/spam_verdict_service_spec.rb
+++ b/spec/services/spam/spam_verdict_service_spec.rb
@@ -267,8 +267,8 @@ RSpec.describe Spam::SpamVerdictService do
where(:verdict_value, :expected) do
::Spam::SpamConstants::ALLOW | ::Spam::SpamConstants::ALLOW
::Spam::SpamConstants::CONDITIONAL_ALLOW | ::Spam::SpamConstants::CONDITIONAL_ALLOW
- ::Spam::SpamConstants::DISALLOW | ::Spam::SpamConstants::CONDITIONAL_ALLOW
- ::Spam::SpamConstants::BLOCK_USER | ::Spam::SpamConstants::CONDITIONAL_ALLOW
+ ::Spam::SpamConstants::DISALLOW | ::Spam::SpamConstants::DISALLOW
+ ::Spam::SpamConstants::BLOCK_USER | ::Spam::SpamConstants::BLOCK_USER
end
# rubocop: enable Lint/BinaryOperatorWithIdenticalOperands
diff --git a/spec/support/database/cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml
index 65b5f9cf1e6..eefae6d69fc 100644
--- a/spec/support/database/cross-join-allowlist.yml
+++ b/spec/support/database/cross-join-allowlist.yml
@@ -8,22 +8,17 @@
- "./ee/spec/models/security/scan_spec.rb"
- "./ee/spec/requests/api/ci/minutes_spec.rb"
- "./ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb"
-- "./ee/spec/requests/api/namespaces_spec.rb"
- "./ee/spec/services/ci/minutes/additional_packs/change_namespace_service_spec.rb"
- "./ee/spec/services/ci/minutes/additional_packs/create_service_spec.rb"
- "./ee/spec/services/ci/minutes/refresh_cached_data_service_spec.rb"
-- "./spec/controllers/admin/runners_controller_spec.rb"
- "./spec/controllers/groups/settings/ci_cd_controller_spec.rb"
- "./spec/controllers/projects/settings/ci_cd_controller_spec.rb"
-- "./spec/features/admin/admin_runners_spec.rb"
- "./spec/features/groups/packages_spec.rb"
- "./spec/features/ide/user_opens_merge_request_spec.rb"
- "./spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb"
- "./spec/features/projects/infrastructure_registry_spec.rb"
- "./spec/features/projects/packages_spec.rb"
- "./spec/finders/ci/pipelines_for_merge_request_finder_spec.rb"
-- "./spec/finders/ci/runners_finder_spec.rb"
-- "./spec/frontend/fixtures/runner.rb"
- "./spec/graphql/resolvers/ci/group_runners_resolver_spec.rb"
- "./spec/lib/api/entities/package_spec.rb"
- "./spec/lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans_spec.rb"
@@ -36,13 +31,11 @@
- "./spec/models/ci/pipeline_spec.rb"
- "./spec/models/ci/runner_spec.rb"
- "./spec/models/merge_request_spec.rb"
-- "./spec/models/project_spec.rb"
- "./spec/models/user_spec.rb"
- "./spec/presenters/packages/detail/package_presenter_spec.rb"
- "./spec/requests/api/ci/runner/runners_post_spec.rb"
- "./spec/requests/api/graphql/ci/runner_spec.rb"
- "./spec/requests/api/graphql/group/packages_spec.rb"
-- "./spec/requests/api/graphql/group_query_spec.rb"
- "./spec/requests/api/graphql/packages/composer_spec.rb"
- "./spec/requests/api/graphql/packages/conan_spec.rb"
- "./spec/requests/api/graphql/packages/maven_spec.rb"
diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb
index 5cfd03ecea8..8a329c2f9dd 100644
--- a/spec/support/helpers/gitaly_setup.rb
+++ b/spec/support/helpers/gitaly_setup.rb
@@ -98,7 +98,7 @@ module GitalySetup
end
def build_gitaly
- system(env, 'make', chdir: tmp_tests_gitaly_dir) # rubocop:disable GitlabSecurity/SystemCommandInjection
+ system(env.merge({ 'GIT_VERSION' => nil }), 'make all git', chdir: tmp_tests_gitaly_dir) # rubocop:disable GitlabSecurity/SystemCommandInjection
end
def start_gitaly
diff --git a/spec/tasks/gitlab/gitaly_rake_spec.rb b/spec/tasks/gitlab/gitaly_rake_spec.rb
index 5adea832995..22bd9414925 100644
--- a/spec/tasks/gitlab/gitaly_rake_spec.rb
+++ b/spec/tasks/gitlab/gitaly_rake_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe 'gitlab:gitaly namespace rake task', :silence_stdout do
it 'calls gmake in the gitaly directory' do
expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0])
- expect(Gitlab::Popen).to receive(:popen).with(%w[gmake], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
+ expect(Gitlab::Popen).to receive(:popen).with(%w[gmake all git], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
subject
end
@@ -81,13 +81,13 @@ RSpec.describe 'gitlab:gitaly namespace rake task', :silence_stdout do
end
it 'calls make in the gitaly directory' do
- expect(Gitlab::Popen).to receive(:popen).with(%w[make], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
+ expect(Gitlab::Popen).to receive(:popen).with(%w[make all git], nil, { "BUNDLE_GEMFILE" => nil, "RUBYOPT" => nil }).and_return(true)
subject
end
context 'when Rails.env is test' do
- let(:command) { %w[make] }
+ let(:command) { %w[make all git] }
before do
stub_rails_env('test')