Skip to content
Snippets Groups Projects
Commit 4061d291 authored by Lin Jen-Shin's avatar Lin Jen-Shin
Browse files

Merge remote-tracking branch 'upstream/master' into qa-allow-setting-sandbox-group

* upstream/master: (27 commits)
  Set initial password for instance in LDAP QA test
  Backport EE changes to some hashed storage documentation to CE
  Remove allow_n_plus_1 from Git::Repository#branches_filter
  Bumps Gitlab Shell version to 6.0.3
  Make resetting column information overridable in EE
  Added 'clear' button to ci lint editor
  Issues and merge requests in subgroups docs
  Update docs labels CE
  Refactored merge_requests/show path in dispatcher.js
  wording
  don't check against a hardcoded user name
  10.5 Update the dependencies license list
  10.5 Update the .gitignore, .gitlab-ci.yml, and Dockerfile templates
  Create update guide for 10.5
  Update 10.5 source install guide
  Add docs for MR link in commit page
  Add groups to OpenID Connect claims
  Replaced $.get with axois.get
  Memoize MergeRequest#rebase_in_progress? to prevent N+1 queries in Gitaly
  [docs] Info rescheduling background migrations
  ...
parents 5f62a935 7534f7a8
No related branches found
No related tags found
No related merge requests found
Showing
with 223 additions and 150 deletions
Loading
Loading
@@ -81,8 +81,10 @@ FactoryBot.define do
archived true
end
 
trait :hashed do
storage_version Project::LATEST_STORAGE_VERSION
storage_version Project::LATEST_STORAGE_VERSION
trait :legacy_storage do
storage_version nil
end
 
trait :access_requestable do
Loading
Loading
Loading
Loading
@@ -3,16 +3,19 @@ require 'spec_helper'
describe 'CI Lint', :js do
before do
sign_in(create(:user))
visit ci_lint_path
find('#ci-editor')
execute_script("ace.edit('ci-editor').setValue(#{yaml_content.to_json});")
# Ace editor updates a hidden textarea and it happens asynchronously
wait_for('YAML content') do
find('.ace_content').text.present?
end
end
 
describe 'YAML parsing' do
before do
visit ci_lint_path
# Ace editor updates a hidden textarea and it happens asynchronously
# `sleep 0.1` is actually needed here because of this
find('#ci-editor')
execute_script("ace.edit('ci-editor').setValue(" + yaml_content.to_json + ");")
sleep 0.1
click_on 'Validate'
end
 
Loading
Loading
@@ -32,11 +35,10 @@ describe 'CI Lint', :js do
end
 
context 'YAML is incorrect' do
let(:yaml_content) { '' }
let(:yaml_content) { 'value: cannot have :' }
 
it 'displays information about an error' do
expect(page).to have_content('Status: syntax is incorrect')
expect(page).to have_content('Error: Please provide content of .gitlab-ci.yml')
end
end
 
Loading
Loading
@@ -48,4 +50,20 @@ describe 'CI Lint', :js do
end
end
end
describe 'YAML clearing' do
before do
click_on 'Clear'
end
context 'YAML is present' do
let(:yaml_content) do
File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
end
it 'YAML content is cleared' do
expect(page).to have_field('content', with: '', visible: false, type: 'textarea')
end
end
end
end
require 'spec_helper'
 
feature 'Import/Export - Namespace export file cleanup', :js do
describe 'Import/Export - Namespace export file cleanup', :js do
let(:export_path) { Dir.mktmpdir('namespace_export_file_spec') }
 
before do
Loading
Loading
@@ -42,13 +42,13 @@ feature 'Import/Export - Namespace export file cleanup', :js do
end
 
describe 'legacy storage' do
let(:project) { create(:project) }
let(:project) { create(:project, :legacy_storage) }
 
it_behaves_like 'handling project exports on namespace change'
end
 
describe 'hashed storage' do
let(:project) { create(:project, :hashed) }
let(:project) { create(:project) }
 
it_behaves_like 'handling project exports on namespace change'
end
Loading
Loading
import Autosize from 'autosize';
import autosize from 'autosize';
import GLForm from '~/gl_form';
import '~/lib/utils/text_utility';
import '~/lib/utils/common_utils';
 
window.autosize = Autosize;
describe('GLForm', () => {
describe('when instantiated', function () {
beforeEach((done) => {
Loading
Loading
@@ -13,14 +11,12 @@ describe('GLForm', () => {
spyOn($.prototype, 'off').and.returnValue(this.textarea);
spyOn($.prototype, 'on').and.returnValue(this.textarea);
spyOn($.prototype, 'css');
spyOn(window, 'autosize');
 
this.glForm = new GLForm(this.form);
this.glForm = new GLForm(this.form, false);
setTimeout(() => {
$.prototype.off.calls.reset();
$.prototype.on.calls.reset();
$.prototype.css.calls.reset();
window.autosize.calls.reset();
done();
});
});
Loading
Loading
@@ -43,10 +39,6 @@ describe('GLForm', () => {
expect($.prototype.on).toHaveBeenCalledWith('mouseup.autosize', jasmine.any(Function));
});
 
it('should autosize the textarea', () => {
expect(window.autosize).toHaveBeenCalledWith(jasmine.any(Object));
});
it('should set the resize css property to vertical', () => {
expect($.prototype.css).toHaveBeenCalledWith('resize', 'vertical');
});
Loading
Loading
@@ -74,7 +66,7 @@ describe('GLForm', () => {
spyOn($.prototype, 'data');
spyOn($.prototype, 'outerHeight').and.returnValue(200);
spyOn(window, 'outerHeight').and.returnValue(400);
spyOn(window.autosize, 'destroy');
spyOn(autosize, 'destroy');
 
this.glForm.destroyAutosize();
});
Loading
Loading
@@ -88,7 +80,7 @@ describe('GLForm', () => {
});
 
it('should call autosize destroy', () => {
expect(window.autosize.destroy).toHaveBeenCalledWith(this.textarea);
expect(autosize.destroy).toHaveBeenCalledWith(this.textarea);
});
 
it('should set the data-height attribute', () => {
Loading
Loading
@@ -107,9 +99,9 @@ describe('GLForm', () => {
it('should return undefined if the data-height equals the outerHeight', () => {
spyOn($.prototype, 'outerHeight').and.returnValue(200);
spyOn($.prototype, 'data').and.returnValue(200);
spyOn(window.autosize, 'destroy');
spyOn(autosize, 'destroy');
expect(this.glForm.destroyAutosize()).toBeUndefined();
expect(window.autosize.destroy).not.toHaveBeenCalled();
expect(autosize.destroy).not.toHaveBeenCalled();
});
});
});
Loading
Loading
Loading
Loading
@@ -33,10 +33,22 @@ describe Backup::Repository do
allow(Gitlab::Popen).to receive(:popen).and_return(['error', 1])
end
 
it 'shows the appropriate error' do
described_class.new.restore
context 'hashed storage' do
it 'shows the appropriate error' do
described_class.new.restore
 
expect(progress).to have_received(:puts).with("Ignoring error on #{project.full_path} - error")
expect(progress).to have_received(:puts).with("Ignoring error on #{project.full_path} (#{project.disk_path}) - error")
end
end
context 'legacy storage' do
let!(:project) { create(:project, :legacy_storage) }
it 'shows the appropriate error' do
described_class.new.restore
expect(progress).to have_received(:puts).with("Ignoring error on #{project.full_path} - error")
end
end
end
end
Loading
Loading
Loading
Loading
@@ -23,8 +23,8 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads, :sidekiq do
let!(:appearance) { create_or_update_appearance(logo: uploaded_file, header_logo: uploaded_file) }
let!(:user1) { create(:user, :with_avatar) }
let!(:user2) { create(:user, :with_avatar) }
let!(:project1) { create(:project, :with_avatar) }
let!(:project2) { create(:project, :with_avatar) }
let!(:project1) { create(:project, :legacy_storage, :with_avatar) }
let!(:project2) { create(:project, :legacy_storage, :with_avatar) }
 
before do
UploadService.new(project1, uploaded_file, FileUploader).execute # Markdown upload
Loading
Loading
@@ -48,7 +48,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads, :sidekiq do
 
it 'adds untracked files to the uploads table' do
expect do
subject.perform(1, untracked_files_for_uploads.last.id)
subject.perform(1, untracked_files_for_uploads.reorder(:id).last.id)
end.to change { uploads.count }.from(4).to(8)
 
expect(user2.uploads.count).to eq(1)
Loading
Loading
@@ -213,13 +213,13 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads, :sidekiq do
end
 
context 'for a project avatar file path' do
let(:model) { create(:project, :with_avatar) }
let(:model) { create(:project, :legacy_storage, :with_avatar) }
 
it_behaves_like 'non_markdown_file'
end
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
let(:model) { create(:project) }
let(:model) { create(:project, :legacy_storage) }
 
before do
# Upload the file
Loading
Loading
@@ -304,7 +304,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
it 'returns the file path relative to the project directory in uploads' do
project = create(:project)
project = create(:project, :legacy_storage)
random_hex = SecureRandom.hex
 
assert_upload_path("/#{project.full_path}/#{random_hex}/Some file.jpg", "#{random_hex}/Some file.jpg")
Loading
Loading
@@ -357,7 +357,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
it 'returns FileUploader as a string' do
project = create(:project)
project = create(:project, :legacy_storage)
 
assert_uploader("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", 'FileUploader')
end
Loading
Loading
@@ -409,7 +409,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
it 'returns Project as a string' do
project = create(:project)
project = create(:project, :legacy_storage)
 
assert_model_type("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", 'Project')
end
Loading
Loading
@@ -461,7 +461,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
it 'returns the ID as a string' do
project = create(:project)
project = create(:project, :legacy_storage)
 
assert_model_id("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", project.id)
end
Loading
Loading
@@ -483,7 +483,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
end
 
context 'for a project avatar file path' do
let(:project) { create(:project, avatar: uploaded_file) }
let(:project) { create(:project, :legacy_storage, avatar: uploaded_file) }
let(:untracked_file) { described_class.create!(path: project.uploads.first.path) }
 
it 'returns the file size' do
Loading
Loading
@@ -496,7 +496,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do
end
 
context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do
let(:project) { create(:project) }
let(:project) { create(:project, :legacy_storage) }
let(:untracked_file) { create_untracked_file("/#{project.full_path}/#{project.uploads.first.path}") }
 
before do
Loading
Loading
Loading
Loading
@@ -77,7 +77,7 @@ describe Gitlab::BackgroundMigration::PrepareUntrackedUploads, :sidekiq do
context 'when files were uploaded before and after hashed storage was enabled' do
let!(:appearance) { create_or_update_appearance(logo: uploaded_file, header_logo: uploaded_file) }
let!(:user) { create(:user, :with_avatar) }
let!(:project1) { create(:project, :with_avatar) }
let!(:project1) { create(:project, :with_avatar, :legacy_storage) }
let(:project2) { create(:project) } # instantiate after enabling hashed_storage
 
before do
Loading
Loading
@@ -149,7 +149,7 @@ describe Gitlab::BackgroundMigration::PrepareUntrackedUploads, :sidekiq do
context 'when files were uploaded before and after hashed storage was enabled' do
let!(:appearance) { create_or_update_appearance(logo: uploaded_file, header_logo: uploaded_file) }
let!(:user) { create(:user, :with_avatar) }
let!(:project1) { create(:project, :with_avatar) }
let!(:project1) { create(:project, :with_avatar, :legacy_storage) }
let(:project2) { create(:project) } # instantiate after enabling hashed_storage
 
before do
Loading
Loading
Loading
Loading
@@ -8,11 +8,15 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
subject(:importer) { described_class.new(admin, bare_repository) }
 
before do
@rainbow = Rainbow.enabled
Rainbow.enabled = false
allow(described_class).to receive(:log)
end
 
after do
FileUtils.rm_rf(base_dir)
Rainbow.enabled = @rainbow
end
 
shared_examples 'importing a repository' do
Loading
Loading
@@ -148,7 +152,7 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
# This is a quick way to get a valid repository instead of copying an
# existing one. Since it's not persisted, the importer will try to
# create the project.
project = build(:project, :repository)
project = build(:project, :legacy_storage, :repository)
original_commit_count = project.repository.commit_count
 
bare_repo = Gitlab::BareRepositoryImport::Repository.new(project.repository_storage_path, project.repository.path)
Loading
Loading
Loading
Loading
@@ -94,7 +94,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
describe '#move_repositories' do
let(:namespace) { create(:group, name: 'hello-group') }
it 'moves a project for a namespace' do
create(:project, :repository, namespace: namespace, path: 'hello-project')
create(:project, :repository, :legacy_storage, namespace: namespace, path: 'hello-project')
expected_path = File.join(TestEnv.repos_path, 'bye-group', 'hello-project.git')
 
subject.move_repositories(namespace, 'hello-group', 'bye-group')
Loading
Loading
@@ -104,7 +104,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
 
it 'moves a namespace in a subdirectory correctly' do
child_namespace = create(:group, name: 'sub-group', parent: namespace)
create(:project, :repository, namespace: child_namespace, path: 'hello-project')
create(:project, :repository, :legacy_storage, namespace: child_namespace, path: 'hello-project')
 
expected_path = File.join(TestEnv.repos_path, 'hello-group', 'renamed-sub-group', 'hello-project.git')
 
Loading
Loading
@@ -115,7 +115,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
 
it 'moves a parent namespace with subdirectories' do
child_namespace = create(:group, name: 'sub-group', parent: namespace)
create(:project, :repository, namespace: child_namespace, path: 'hello-project')
create(:project, :repository, :legacy_storage, namespace: child_namespace, path: 'hello-project')
expected_path = File.join(TestEnv.repos_path, 'renamed-group', 'sub-group', 'hello-project.git')
 
subject.move_repositories(child_namespace, 'hello-group', 'renamed-group')
Loading
Loading
@@ -166,7 +166,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
 
describe '#rename_namespace_dependencies' do
it "moves the the repository for a project in the namespace" do
create(:project, :repository, namespace: namespace, path: "the-path-project")
create(:project, :repository, :legacy_storage, namespace: namespace, path: "the-path-project")
expected_repo = File.join(TestEnv.repos_path, "the-path0", "the-path-project.git")
 
subject.rename_namespace_dependencies(namespace, 'the-path', 'the-path0')
Loading
Loading
@@ -187,7 +187,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
end
 
it 'invalidates the markdown cache of related projects' do
project = create(:project, namespace: namespace, path: "the-path-project")
project = create(:project, :legacy_storage, namespace: namespace, path: "the-path-project")
 
expect(subject).to receive(:remove_cached_html_for_projects).with([project.id])
 
Loading
Loading
@@ -243,7 +243,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
 
describe '#revert_renames', :redis do
it 'renames the routes back to the previous values' do
project = create(:project, :repository, path: 'a-project', namespace: namespace)
project = create(:project, :legacy_storage, :repository, path: 'a-project', namespace: namespace)
subject.rename_namespace(namespace)
 
expect(subject).to receive(:perform_rename)
Loading
Loading
@@ -261,7 +261,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
end
 
it 'moves the repositories back to their original place' do
project = create(:project, :repository, path: 'a-project', namespace: namespace)
project = create(:project, :repository, :legacy_storage, path: 'a-project', namespace: namespace)
project.create_repository
subject.rename_namespace(namespace)
 
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :de
let(:subject) { described_class.new(['the-path'], migration) }
let(:project) do
create(:project,
:legacy_storage,
path: 'the-path',
namespace: create(:namespace, path: 'known-parent' ))
end
Loading
Loading
@@ -17,7 +18,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :de
describe '#projects_for_paths' do
it 'searches using nested paths' do
namespace = create(:namespace, path: 'hello')
project = create(:project, path: 'THE-path', namespace: namespace)
project = create(:project, :legacy_storage, path: 'THE-path', namespace: namespace)
 
result_ids = described_class.new(['Hello/the-path'], migration)
.projects_for_paths.map(&:id)
Loading
Loading
@@ -26,8 +27,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :de
end
 
it 'includes the correct projects' do
project = create(:project, path: 'THE-path')
_other_project = create(:project)
project = create(:project, :legacy_storage, path: 'THE-path')
_other_project = create(:project, :legacy_storage)
 
result_ids = subject.projects_for_paths.map(&:id)
 
Loading
Loading
@@ -36,7 +37,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :de
end
 
describe '#rename_projects' do
let!(:projects) { create_list(:project, 2, path: 'the-path') }
let!(:projects) { create_list(:project, 2, :legacy_storage, path: 'the-path') }
 
it 'renames each project' do
expect(subject).to receive(:rename_project).twice
Loading
Loading
@@ -120,7 +121,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :de
 
describe '#move_repository' do
let(:known_parent) { create(:namespace, path: 'known-parent') }
let(:project) { create(:project, :repository, path: 'the-path', namespace: known_parent) }
let(:project) { create(:project, :repository, :legacy_storage, path: 'the-path', namespace: known_parent) }
 
it 'moves the repository for a project' do
expected_path = File.join(TestEnv.repos_path, 'known-parent', 'new-repo.git')
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@ require "spec_helper"
 
describe Gitlab::Email::AttachmentUploader do
describe "#execute" do
let(:project) { build(:project) }
let(:project) { create(:project) }
let(:message_raw) { fixture_file("emails/attachment.eml") }
let(:message) { Mail::Message.new(message_raw) }
 
Loading
Loading
Loading
Loading
@@ -39,8 +39,8 @@ describe Gitlab::Gfm::UploadsRewriter do
it 'copies files' do
expect(new_files).to all(exist)
expect(old_paths).not_to match_array new_paths
expect(old_paths).to all(include(old_project.full_path))
expect(new_paths).to all(include(new_project.full_path))
expect(old_paths).to all(include(old_project.disk_path))
expect(new_paths).to all(include(new_project.disk_path))
end
 
it 'does not remove old files' do
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@ describe Gitlab::ImportExport::UploadsRestorer do
end
 
describe 'legacy storage' do
let(:project) { create(:project) }
let(:project) { create(:project, :legacy_storage) }
 
subject(:restorer) { described_class.new(project: project, shared: shared) }
 
Loading
Loading
@@ -34,7 +34,7 @@ describe Gitlab::ImportExport::UploadsRestorer do
end
 
describe 'hashed storage' do
let(:project) { create(:project, :hashed) }
let(:project) { create(:project) }
 
subject(:restorer) { described_class.new(project: project, shared: shared) }
 
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ describe Gitlab::ImportExport::UploadsSaver do
end
 
describe 'legacy storage' do
let(:project) { create(:project) }
let(:project) { create(:project, :legacy_storage) }
 
subject(:saver) { described_class.new(shared: shared, project: project) }
 
Loading
Loading
@@ -37,7 +37,7 @@ describe Gitlab::ImportExport::UploadsSaver do
end
 
describe 'hashed storage' do
let(:project) { create(:project, :hashed) }
let(:project) { create(:project) }
 
subject(:saver) { described_class.new(shared: shared, project: project) }
 
Loading
Loading
Loading
Loading
@@ -6,11 +6,11 @@ describe ::Gitlab::RepoPath do
 
context 'a repository storage path' do
it 'parses a full repository path' do
expect(described_class.parse(project.repository.path)).to eq([project, false, nil])
expect(described_class.parse(project.repository.full_path)).to eq([project, false, nil])
end
 
it 'parses a full wiki path' do
expect(described_class.parse(project.wiki.repository.path)).to eq([project, true, nil])
expect(described_class.parse(project.wiki.repository.full_path)).to eq([project, true, nil])
end
end
 
Loading
Loading
Loading
Loading
@@ -443,7 +443,7 @@ describe Gitlab::Shell do
end
 
describe '#remove_repository' do
let!(:project) { create(:project, :repository) }
let!(:project) { create(:project, :repository, :legacy_storage) }
let(:disk_path) { "#{project.disk_path}.git" }
 
it 'returns true when the command succeeds' do
Loading
Loading
Loading
Loading
@@ -324,7 +324,7 @@ describe Gitlab::Workhorse do
it 'includes a Repository param' do
repo_param = {
storage_name: 'default',
relative_path: project.full_path + '.git',
relative_path: project.disk_path + '.git',
gl_repository: "project-#{project.id}"
}
 
Loading
Loading
Loading
Loading
@@ -4,7 +4,7 @@ require 'spec_helper'
require Rails.root.join('db', 'migrate', '20161124141322_migrate_process_commit_worker_jobs.rb')
 
describe MigrateProcessCommitWorkerJobs do
let(:project) { create(:project, :repository) }
let(:project) { create(:project, :legacy_storage, :repository) }
let(:user) { create(:user) }
let(:commit) { project.commit.raw.rugged_commit }
 
Loading
Loading
Loading
Loading
@@ -4,7 +4,7 @@ require Rails.root.join('db', 'migrate', '20170503140202_turn_nested_groups_into
describe TurnNestedGroupsIntoRegularGroupsForMysql do
let!(:parent_group) { create(:group) }
let!(:child_group) { create(:group, parent: parent_group) }
let!(:project) { create(:project, :empty_repo, namespace: child_group) }
let!(:project) { create(:project, :legacy_storage, :empty_repo, namespace: child_group) }
let!(:member) { create(:user) }
let(:migration) { described_class.new }
 
Loading
Loading
Loading
Loading
@@ -168,84 +168,105 @@ describe Namespace do
end
 
describe '#move_dir', :request_store do
let(:namespace) { create(:namespace) }
let!(:project) { create(:project_empty_repo, namespace: namespace) }
shared_examples "namespace restrictions" do
context "when any project has container images" do
let(:container_repository) { create(:container_repository) }
 
it "raises error when directory exists" do
expect { namespace.move_dir }.to raise_error("namespace directory cannot be moved")
end
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: ['tag'])
 
it "moves dir if path changed" do
namespace.update_attributes(path: namespace.full_path + '_new')
create(:project, namespace: namespace, container_repositories: [container_repository])
 
expect(gitlab_shell.exists?(project.repository_storage_path, "#{namespace.path}/#{project.path}.git")).to be_truthy
end
allow(namespace).to receive(:path_was).and_return(namespace.path)
allow(namespace).to receive(:path).and_return('new_path')
end
 
context "when any project has container images" do
let(:container_repository) { create(:container_repository) }
it 'raises an error about not movable project' do
expect { namespace.move_dir }.to raise_error(/Namespace cannot be moved/)
end
end
end
 
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: ['tag'])
context 'legacy storage' do
let(:namespace) { create(:namespace) }
let!(:project) { create(:project_empty_repo, :legacy_storage, namespace: namespace) }
 
create(:project, namespace: namespace, container_repositories: [container_repository])
it_behaves_like 'namespace restrictions'
 
allow(namespace).to receive(:path_was).and_return(namespace.path)
allow(namespace).to receive(:path).and_return('new_path')
it "raises error when directory exists" do
expect { namespace.move_dir }.to raise_error("namespace directory cannot be moved")
end
 
it 'raises an error about not movable project' do
expect { namespace.move_dir }.to raise_error(/Namespace cannot be moved/)
it "moves dir if path changed" do
namespace.update_attributes(path: namespace.full_path + '_new')
expect(gitlab_shell.exists?(project.repository_storage_path, "#{namespace.path}/#{project.path}.git")).to be_truthy
end
end
 
context 'with subgroups' do
let(:parent) { create(:group, name: 'parent', path: 'parent') }
let(:child) { create(:group, name: 'child', path: 'child', parent: parent) }
let!(:project) { create(:project_empty_repo, path: 'the-project', namespace: child, skip_disk_validation: true) }
let(:uploads_dir) { FileUploader.root }
let(:pages_dir) { File.join(TestEnv.pages_path) }
context 'with subgroups' do
let(:parent) { create(:group, name: 'parent', path: 'parent') }
let(:child) { create(:group, name: 'child', path: 'child', parent: parent) }
let!(:project) { create(:project_empty_repo, :legacy_storage, path: 'the-project', namespace: child, skip_disk_validation: true) }
let(:uploads_dir) { FileUploader.root }
let(:pages_dir) { File.join(TestEnv.pages_path) }
 
before do
FileUtils.mkdir_p(File.join(uploads_dir, 'parent', 'child', 'the-project'))
FileUtils.mkdir_p(File.join(pages_dir, 'parent', 'child', 'the-project'))
end
before do
FileUtils.mkdir_p(File.join(uploads_dir, project.full_path))
FileUtils.mkdir_p(File.join(pages_dir, project.full_path))
end
context 'renaming child' do
it 'correctly moves the repository, uploads and pages' do
expected_repository_path = File.join(TestEnv.repos_path, 'parent', 'renamed', 'the-project.git')
expected_upload_path = File.join(uploads_dir, 'parent', 'renamed', 'the-project')
expected_pages_path = File.join(pages_dir, 'parent', 'renamed', 'the-project')
 
context 'renaming child' do
it 'correctly moves the repository, uploads and pages' do
expected_repository_path = File.join(TestEnv.repos_path, 'parent', 'renamed', 'the-project.git')
expected_upload_path = File.join(uploads_dir, 'parent', 'renamed', 'the-project')
expected_pages_path = File.join(pages_dir, 'parent', 'renamed', 'the-project')
child.update_attributes!(path: 'renamed')
 
child.update_attributes!(path: 'renamed')
expect(File.directory?(expected_repository_path)).to be(true)
expect(File.directory?(expected_upload_path)).to be(true)
expect(File.directory?(expected_pages_path)).to be(true)
end
end
context 'renaming parent' do
it 'correctly moves the repository, uploads and pages' do
expected_repository_path = File.join(TestEnv.repos_path, 'renamed', 'child', 'the-project.git')
expected_upload_path = File.join(uploads_dir, 'renamed', 'child', 'the-project')
expected_pages_path = File.join(pages_dir, 'renamed', 'child', 'the-project')
 
expect(File.directory?(expected_repository_path)).to be(true)
expect(File.directory?(expected_upload_path)).to be(true)
expect(File.directory?(expected_pages_path)).to be(true)
parent.update_attributes!(path: 'renamed')
expect(File.directory?(expected_repository_path)).to be(true)
expect(File.directory?(expected_upload_path)).to be(true)
expect(File.directory?(expected_pages_path)).to be(true)
end
end
end
end
 
context 'renaming parent' do
it 'correctly moves the repository, uploads and pages' do
expected_repository_path = File.join(TestEnv.repos_path, 'renamed', 'child', 'the-project.git')
expected_upload_path = File.join(uploads_dir, 'renamed', 'child', 'the-project')
expected_pages_path = File.join(pages_dir, 'renamed', 'child', 'the-project')
context 'hashed storage' do
let(:namespace) { create(:namespace) }
let!(:project) { create(:project_empty_repo, namespace: namespace) }
 
parent.update_attributes!(path: 'renamed')
it_behaves_like 'namespace restrictions'
 
expect(File.directory?(expected_repository_path)).to be(true)
expect(File.directory?(expected_upload_path)).to be(true)
expect(File.directory?(expected_pages_path)).to be(true)
end
it "repository directory remains unchanged if path changed" do
before_disk_path = project.disk_path
namespace.update_attributes(path: namespace.full_path + '_new')
expect(before_disk_path).to eq(project.disk_path)
expect(gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_truthy
end
end
 
it 'updates project full path in .git/config for each project inside namespace' do
parent = create(:group, name: 'mygroup', path: 'mygroup')
subgroup = create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent)
project_in_parent_group = create(:project, :repository, namespace: parent, name: 'foo1')
hashed_project_in_subgroup = create(:project, :repository, :hashed, namespace: subgroup, name: 'foo2')
legacy_project_in_subgroup = create(:project, :repository, namespace: subgroup, name: 'foo3')
project_in_parent_group = create(:project, :legacy_storage, :repository, namespace: parent, name: 'foo1')
hashed_project_in_subgroup = create(:project, :repository, namespace: subgroup, name: 'foo2')
legacy_project_in_subgroup = create(:project, :legacy_storage, :repository, namespace: subgroup, name: 'foo3')
 
parent.update(path: 'mygroup_new')
 
Loading
Loading
@@ -260,38 +281,18 @@ describe Namespace do
end
 
describe '#rm_dir', 'callback' do
let!(:project) { create(:project_empty_repo, namespace: namespace) }
let(:repository_storage_path) { Gitlab.config.repositories.storages.default['path'] }
let(:path_in_dir) { File.join(repository_storage_path, namespace.full_path) }
let(:deleted_path) { namespace.full_path.gsub(namespace.path, "#{namespace.full_path}+#{namespace.id}+deleted") }
let(:deleted_path_in_dir) { File.join(repository_storage_path, deleted_path) }
 
it 'renames its dirs when deleted' do
allow(GitlabShellWorker).to receive(:perform_in)
namespace.destroy
expect(File.exist?(deleted_path_in_dir)).to be(true)
end
it 'schedules the namespace for deletion' do
expect(GitlabShellWorker).to receive(:perform_in).with(5.minutes, :rm_namespace, repository_storage_path, deleted_path)
namespace.destroy
end
context 'in sub-groups' do
let(:parent) { create(:group, path: 'parent') }
let(:child) { create(:group, parent: parent, path: 'child') }
let!(:project) { create(:project_empty_repo, namespace: child) }
let(:path_in_dir) { File.join(repository_storage_path, 'parent', 'child') }
let(:deleted_path) { File.join('parent', "child+#{child.id}+deleted") }
let(:deleted_path_in_dir) { File.join(repository_storage_path, deleted_path) }
context 'legacy storage' do
let!(:project) { create(:project_empty_repo, :legacy_storage, namespace: namespace) }
 
it 'renames its dirs when deleted' do
allow(GitlabShellWorker).to receive(:perform_in)
 
child.destroy
namespace.destroy
 
expect(File.exist?(deleted_path_in_dir)).to be(true)
end
Loading
Loading
@@ -299,14 +300,57 @@ describe Namespace do
it 'schedules the namespace for deletion' do
expect(GitlabShellWorker).to receive(:perform_in).with(5.minutes, :rm_namespace, repository_storage_path, deleted_path)
 
child.destroy
namespace.destroy
end
context 'in sub-groups' do
let(:parent) { create(:group, path: 'parent') }
let(:child) { create(:group, parent: parent, path: 'child') }
let!(:project) { create(:project_empty_repo, :legacy_storage, namespace: child) }
let(:path_in_dir) { File.join(repository_storage_path, 'parent', 'child') }
let(:deleted_path) { File.join('parent', "child+#{child.id}+deleted") }
let(:deleted_path_in_dir) { File.join(repository_storage_path, deleted_path) }
it 'renames its dirs when deleted' do
allow(GitlabShellWorker).to receive(:perform_in)
child.destroy
expect(File.exist?(deleted_path_in_dir)).to be(true)
end
it 'schedules the namespace for deletion' do
expect(GitlabShellWorker).to receive(:perform_in).with(5.minutes, :rm_namespace, repository_storage_path, deleted_path)
child.destroy
end
end
it 'removes the exports folder' do
expect(namespace).to receive(:remove_exports!)
namespace.destroy
end
end
 
it 'removes the exports folder' do
expect(namespace).to receive(:remove_exports!)
context 'hashed storage' do
let!(:project) { create(:project_empty_repo, namespace: namespace) }
it 'has no repositories base directories to remove' do
allow(GitlabShellWorker).to receive(:perform_in)
expect(File.exist?(path_in_dir)).to be(false)
 
namespace.destroy
namespace.destroy
expect(File.exist?(deleted_path_in_dir)).to be(false)
end
it 'removes the exports folder' do
expect(namespace).to receive(:remove_exports!)
namespace.destroy
end
end
end
 
Loading
Loading
@@ -567,8 +611,8 @@ describe Namespace do
end
 
describe '#remove_exports' do
let(:legacy_project) { create(:project, :with_export, namespace: namespace) }
let(:hashed_project) { create(:project, :with_export, :hashed, namespace: namespace) }
let(:legacy_project) { create(:project, :with_export, :legacy_storage, namespace: namespace) }
let(:hashed_project) { create(:project, :with_export, namespace: namespace) }
let(:export_path) { Dir.mktmpdir('namespace_remove_exports_spec') }
let(:legacy_export) { legacy_project.export_project_path }
let(:hashed_export) { hashed_project.export_project_path }
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment