Commit 3a2aa432 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into ce-to-ee-2017-10-13

* ee/master:
  Port of fl-autodevops-fix to EE
  Port Git alternate dirs fix to EE
  Fix default crontab for Geo::FileDownloadDispatchWorker
  Allow the default branch as branch name
  Geo: Don't sync disabled project wikis
parents d08b1ed8 03208c31
......@@ -192,9 +192,6 @@ import initGroupAnalytics from './init_group_analytics';
const filteredSearchManager = new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests');
filteredSearchManager.setup();
}
if (page === 'projects:merge_requests:index') {
new UserCallout({ setCalloutPerProject: true });
}
const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_';
IssuableIndex.init(pagePrefix);
......@@ -382,7 +379,10 @@ import initGroupAnalytics from './init_group_analytics';
case 'projects:show':
shortcut_handler = new ShortcutsNavigation();
new NotificationsForm();
new UserCallout({ setCalloutPerProject: true });
new UserCallout({
setCalloutPerProject: true,
className: 'js-autodevops-banner',
});
if ($('#tree-slider').length) new TreeView();
if ($('.blob-viewer').length) new BlobViewer();
......@@ -409,9 +409,6 @@ import initGroupAnalytics from './init_group_analytics';
case 'projects:pipelines:new':
new NewBranchForm($('.js-new-pipeline-form'));
break;
case 'projects:pipelines:index':
new UserCallout({ setCalloutPerProject: true });
break;
case 'projects:pipelines:builds':
case 'projects:pipelines:failures':
case 'projects:pipelines:show':
......@@ -477,7 +474,6 @@ import initGroupAnalytics from './init_group_analytics';
);
}
new UserCallout({ setCalloutPerProject: true });
$('#tree-slider').waitForImages(function() {
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
});
......
......@@ -6,6 +6,7 @@
@import "framework/animations";
@import "framework/avatar";
@import "framework/asciidoctor";
@import "framework/banner";
@import "framework/blocks";
@import "framework/buttons";
@import "framework/badges";
......
.banner-callout {
display: flex;
position: relative;
flex-wrap: wrap;
.banner-close {
position: absolute;
top: 10px;
right: 10px;
opacity: 1;
.dismiss-icon {
color: $gl-text-color;
font-size: $gl-font-size;
}
}
.banner-graphic {
margin: 20px auto;
}
&.banner-non-empty-state {
border-bottom: 1px solid $border-color;
}
}
......@@ -20,19 +20,29 @@ class Geo::ProjectRegistry < Geo::BaseRegistry
.where(resync_repository: false, resync_wiki: false)
end
def resync_repository?
resync_repository || last_repository_successful_sync_at.nil?
def repository_sync_due?(scheduled_time)
never_synced_repository? || repository_sync_needed?(scheduled_time)
end
def resync_wiki?
resync_wiki || last_wiki_successful_sync_at.nil?
def wiki_sync_due?(scheduled_time)
project.wiki_enabled? && (never_synced_wiki? || wiki_sync_needed?(scheduled_time))
end
def repository_synced_since?(timestamp)
last_repository_synced_at && last_repository_synced_at > timestamp
private
def never_synced_repository?
last_repository_successful_sync_at.nil?
end
def never_synced_wiki?
last_wiki_successful_sync_at.nil?
end
def repository_sync_needed?(timestamp)
resync_repository? && (last_repository_synced_at.nil? || timestamp > last_repository_synced_at)
end
def wiki_synced_since?(timestamp)
last_wiki_synced_at && last_wiki_synced_at > timestamp
def wiki_sync_needed?(timestamp)
resync_wiki? && (last_wiki_synced_at.nil? || timestamp > last_wiki_synced_at)
end
end
......@@ -10,7 +10,7 @@ module Geo
repository_storage_name: project.repository.storage,
repository_storage_path: project.repository_storage_path,
repo_path: project.disk_path,
wiki_path: "#{project.disk_path}.wiki",
wiki_path: ("#{project.disk_path}.wiki" if project.wiki_enabled?),
project_name: project.name
)
end
......
......@@ -24,10 +24,15 @@
%p
You will need to be owner or have the master permission level for the initial push, as the master branch is automatically protected.
- if show_auto_devops_callout?(@project)
%p
- link = link_to(s_('AutoDevOps|Auto DevOps (Beta)'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'))
= s_('AutoDevOps|You can activate %{link_to_settings} for this project.').html_safe % { link_to_settings: link }
%p
= s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
- if can?(current_user, :push_code, @project)
%div{ class: container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
.prepend-top-20
.empty_wrapper
%h3.page-title-empty
......
......@@ -13,8 +13,6 @@
- if @project.merge_requests.exists?
%div{ class: container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
.top-area
= render 'shared/issuable/nav', type: :merge_requests
.nav-controls
......
......@@ -5,8 +5,6 @@
= render 'shared/shared_runners_minutes_limit', project: @project
%div{ 'class' => container_class }
- if show_auto_devops_callout?(@project)
= render 'shared/auto_devops_callout'
#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json),
"help-page-path" => help_page_path('ci/quick_start/README'),
"help-auto-devops-path" => help_page_path('topics/autodevops/index.md'),
......
......@@ -12,7 +12,5 @@
= webpack_bundle_tag 'repo'
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
- if show_auto_devops_callout?(@project) && !show_new_repo?
= render 'shared/auto_devops_callout'
= render 'projects/last_push'
= render 'projects/files', commit: @last_commit, project: @project, ref: @ref, content_url: project_tree_path(@project, @id)
.user-callout{ data: { uid: 'auto_devops_settings_dismissed', project_path: project_path(@project) } }
.bordered-box.landing.content-block
%button.btn.btn-default.close.js-close-callout{ type: 'button',
'aria-label' => 'Dismiss Auto DevOps box' }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
.svg-container
= custom_icon('icon_autodevops')
.user-callout-copy
%h4= s_('AutoDevOps|Auto DevOps (Beta)')
%p= s_('AutoDevOps|Auto DevOps can be activated for this project. It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
%p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer')
= s_('AutoDevOps|Learn more in the %{link_to_documentation}').html_safe % { link_to_documentation: link }
.js-autodevops-banner.banner-callout.banner-non-empty-state.append-bottom-20{ data: { uid: 'auto_devops_settings_dismissed', project_path: project_path(@project) } }
.banner-graphic
= custom_icon('icon_autodevops')
= link_to s_('AutoDevOps|Enable in settings'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'), class: 'btn btn-primary js-close-callout'
.prepend-top-10.prepend-left-10.append-bottom-10
%h5= s_('AutoDevOps|Auto DevOps (Beta)')
%p= s_('AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration.')
%p
- link = link_to(s_('AutoDevOps|Auto DevOps documentation'), help_page_path('topics/autodevops/index.md'), target: '_blank', rel: 'noopener noreferrer')
= s_('AutoDevOps|Learn more in the %{link_to_documentation}').html_safe % { link_to_documentation: link }
.prepend-top-10
= link_to s_('AutoDevOps|Enable in settings'), project_settings_ci_cd_path(@project, anchor: 'js-general-pipeline-settings'), class: 'btn js-close-callout'
%button.btn-transparent.banner-close.close.js-close-callout{ type: 'button',
'aria-label' => 'Dismiss Auto DevOps box' }
= icon('times', class: 'dismiss-icon', 'aria-hidden' => 'true')
<svg xmlns="http://www.w3.org/2000/svg" width="189" height="179" viewBox="0 0 189 179">
<svg xmlns="http://www.w3.org/2000/svg" width="189" height="110" viewBox="0 0 189 179">
<g fill="none" fill-rule="evenodd">
<path fill="#FFFFFF" fill-rule="nonzero" d="M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/>
<path fill="#EEEEEE" fill-rule="nonzero" d="M110.160166,51.6956996 C106.846457,51.6956996 104.160166,54.3819911 104.160166,57.6956996 L104.160166,117.6957 C104.160166,121.009408 106.846457,123.6957 110.160166,123.6957 L160.160166,123.6957 C163.473874,123.6957 166.160166,121.009408 166.160166,117.6957 L166.160166,57.6956996 C166.160166,54.3819911 163.473874,51.6956996 160.160166,51.6956996 L110.160166,51.6956996 Z M110.160166,47.6956996 L160.160166,47.6956996 C165.683013,47.6956996 170.160166,52.1728521 170.160166,57.6956996 L170.160166,117.6957 C170.160166,123.218547 165.683013,127.6957 160.160166,127.6957 L110.160166,127.6957 C104.637318,127.6957 100.160166,123.218547 100.160166,117.6957 L100.160166,57.6956996 C100.160166,52.1728521 104.637318,47.6956996 110.160166,47.6956996 Z" transform="rotate(10 135.16 87.696)"/>
......
......@@ -11,30 +11,16 @@ module Geo
end
def perform(project_id, scheduled_time)
project = Project.find(project_id)
registry = Geo::ProjectRegistry.find_or_initialize_by(project_id: project_id)
project = registry.project
Geo::RepositorySyncService.new(project).execute if sync_repository?(registry, scheduled_time)
Geo::WikiSyncService.new(project).execute if sync_wiki?(registry, scheduled_time)
rescue ActiveRecord::RecordNotFound => e
Gitlab::Geo::Logger.error(
class: self.class.name,
message: "Couldn't find project, skipping syncing",
project_id: project_id,
error: e
)
end
private
def sync_repository?(registry, scheduled_time)
!registry.repository_synced_since?(scheduled_time) &&
registry.resync_repository?
end
if project.nil?
Gitlab::Geo::Logger.error(class: self.class.name, message: "Couldn't find project, skipping syncing", project_id: project_id)
return
end
def sync_wiki?(registry, scheduled_time)
!registry.wiki_synced_since?(scheduled_time) &&
registry.resync_wiki?
Geo::RepositorySyncService.new(project).execute if registry.repository_sync_due?(scheduled_time)
Geo::WikiSyncService.new(project).execute if registry.wiki_sync_due?(scheduled_time)
end
end
end
---
title: 'Geo: Don''t sync disabled project wikis'
merge_request: 3109
author:
type: fixed
---
title: Always allow the default branch as a branch name
merge_request: 3154
author:
type: fixed
---
title: Improve autodevops banner UX and render it only in project page
merge_request:
author:
type: fixed
......@@ -445,7 +445,7 @@ Settings.cron_jobs['geo_repository_sync_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_repository_sync_worker']['cron'] ||= '*/5 * * * *'
Settings.cron_jobs['geo_repository_sync_worker']['job_class'] ||= 'Geo::RepositorySyncWorker'
Settings.cron_jobs['geo_file_download_dispatch_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '5 * * * *'
Settings.cron_jobs['geo_file_download_dispatch_worker']['cron'] ||= '*/5 * * * *'
Settings.cron_jobs['geo_file_download_dispatch_worker']['job_class'] ||= 'Geo::FileDownloadDispatchWorker'
Settings.cron_jobs['import_export_project_cleanup_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['import_export_project_cleanup_worker']['cron'] ||= '0 * * * *'
......
......@@ -185,6 +185,7 @@ module Gitlab
def branch_name_allowed_by_push_rule?(push_rule)
return true unless push_rule
return true if @branch_name.blank?
return true if @branch_name == @project.default_branch
push_rule.branch_name_allowed?(@branch_name)
end
......
......@@ -19,9 +19,7 @@ module Gitlab
full_scan! if options[:full_scan]
until exit?
Events.fetch_in_batches do |batch|
handle_events(batch)
end
run_once!
return if exit?
......@@ -30,6 +28,10 @@ module Gitlab
end
end
def run_once!
Events.fetch_in_batches { |batch| handle_events(batch) }
end
# Execute routines to verify the required initial data is available
# and mark non-replicated data as requiring replication.
def full_scan!
......
......@@ -30,6 +30,17 @@ module Gitlab
RequestStore.fetch(:gitlab_git_env) { {} }
end
def self.to_env_hash
env = {}
all.compact.each do |key, value|
value = value.join(File::PATH_SEPARATOR) if value.is_a?(Array)
env[key.to_s] = value
end
env
end
def self.[](key)
all[key]
end
......
......@@ -28,7 +28,7 @@ module Gitlab
private
def execute(args)
output, status = popen(args, nil, Gitlab::Git::Env.all.stringify_keys)
output, status = popen(args, nil, Gitlab::Git::Env.to_env_hash)
unless status.zero?
raise "Got a non-zero exit code while calling out `#{args.join(' ')}`: #{output}"
......
......@@ -24,7 +24,7 @@ FactoryGirl.define do
repository_storage_path { project.repository_storage_path }
add_attribute(:repo_path) { project.disk_path }
project_name { project.name }
wiki_path { "{project.disk_path}.wiki" }
wiki_path { "#{project.disk_path}.wiki" }
end
factory :geo_repository_updated_event, class: Geo::RepositoryUpdatedEvent do
......
......@@ -266,6 +266,15 @@ describe Gitlab::Checks::ChangeAccess do
expect { subject }.to raise_error(Gitlab::GitAccess::UnauthorizedError, "Branch name does not follow the pattern '^(w*)$'")
end
end
context 'when the default branch does not match the push rules' do
let(:push_rule) { create(:push_rule, branch_name_regex: 'not-master') }
let(:ref) { "refs/heads/#{project.default_branch}" }
it 'allows the default branch even if it does not match push rule' do
expect { subject }.not_to raise_error
end
end
end
context 'existing member rules' do
......
......@@ -3,48 +3,70 @@ require 'spec_helper'
describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
include ::EE::GeoHelpers
set(:primary) { create(:geo_node, :primary) }
set(:secondary) { create(:geo_node) }
let(:options) { {} }
subject(:daemon) { described_class.new(options) }
around do |example|
Sidekiq::Testing.fake! { example.run }
end
before do
stub_current_geo_node(secondary)
stub_env("::#{described_class}::POOL_WAIT", 0.1)
allow(daemon).to receive(:trap_signals)
end
describe '#run!' do
set(:geo_node) { create(:geo_node, :primary) }
it 'traps signals' do
is_expected.to receive(:exit?).and_return(true)
is_expected.to receive(:trap_signals)
before do
stub_current_geo_node(geo_node)
daemon.run!
end
it 'traps signals' do
allow(subject).to receive(:exit?) { true }
expect(subject).to receive(:trap_signals)
it 'does not perform a full scan by default' do
is_expected.to receive(:exit?).and_return(true)
is_expected.not_to receive(:full_scan!)
subject.run!
daemon.run!
end
context 'when the command-line defines full_scan: true' do
subject { described_class.new(full_scan: true) }
context 'the command-line defines full_scan: true' do
let(:options) { { full_scan: true } }
it 'executes a full-scan' do
allow(subject).to receive(:exit?) { true }
is_expected.to receive(:exit?).and_return(true)
is_expected.to receive(:full_scan!)
expect(subject).to receive(:full_scan!)
subject.run!
daemon.run!
end
end
it 'delegates to #run_once! in a loop' do
is_expected.to receive(:exit?).and_return(false, false, false, true)
is_expected.to receive(:run_once!).twice
daemon.run!
end
end
describe '#run_once!' do
context 'when replaying a repository created event' do
let(:project) { create(:project) }
let(:repository_created_event) { create(:geo_repository_created_event, project: project) }
let(:event_log) { create(:geo_event_log, repository_created_event: repository_created_event) }
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
before do
allow(subject).to receive(:exit?).and_return(false, true)
end
it 'creates a new project registry' do
expect { subject.run! }.to change(Geo::ProjectRegistry, :count).by(1)
expect { daemon.run_once! }.to change(Geo::ProjectRegistry, :count).by(1)
end
it 'sets resync attributes to true' do
subject.run!
daemon.run_once!
registry = Geo::ProjectRegistry.last
......@@ -52,9 +74,9 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
end
it 'sets resync_wiki to false if wiki_path is nil' do
repository_created_event.update_attribute(:wiki_path, nil)
repository_created_event.update!(wiki_path: nil)
subject.run!
daemon.run_once!
registry = Geo::ProjectRegistry.last
......@@ -65,7 +87,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
expect(Geo::ProjectSyncWorker).to receive(:perform_async)
.with(project.id, anything).once
subject.run!
daemon.run_once!
end
end
......@@ -75,28 +97,24 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
let(:event_log) { create(:geo_event_log, repository_updated_event: repository_updated_event) }
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
before do
allow(subject).to receive(:exit?).and_return(false, true)
end
it 'creates a new project registry if it does not exist' do
expect { subject.run! }.to change(Geo::ProjectRegistry, :count).by(1)
expect { daemon.run_once! }.to change(Geo::ProjectRegistry, :count).by(1)
end
it 'sets resync_repository to true if event source is repository' do
repository_updated_event.update_attribute(:source, Geo::RepositoryUpdatedEvent::REPOSITORY)
repository_updated_event.update!(source: Geo::RepositoryUpdatedEvent::REPOSITORY)
registry = create(:geo_project_registry, :synced, project: repository_updated_event.project)
subject.run!
daemon.run_once!
expect(registry.reload.resync_repository).to be true
end
it 'sets resync_wiki to true if event source is wiki' do
repository_updated_event.update_attribute(:source, Geo::RepositoryUpdatedEvent::WIKI)
repository_updated_event.update!(source: Geo::RepositoryUpdatedEvent::WIKI)
registry = create(:geo_project_registry, :synced, project: repository_updated_event.project)
subject.run!
daemon.run_once!
expect(registry.reload.resync_wiki).to be true
end
......@@ -105,7 +123,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
expect(Geo::ProjectSyncWorker).to receive(:perform_async)
.with(project.id, anything).once
subject.run!
daemon.run_once!
end
end
......@@ -115,12 +133,8 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
let(:repository_deleted_event) { event_log.repository_deleted_event }
before do
allow(subject).to receive(:exit?).and_return(false, true)
end
it 'does not create a new project registry' do
expect { subject.run! }.not_to change(Geo::ProjectRegistry, :count)
expect { daemon.run_once! }.not_to change(Geo::ProjectRegistry, :count)
end
it 'schedules a GeoRepositoryDestroyWorker' do
......@@ -132,24 +146,19 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
expect(::GeoRepositoryDestroyWorker).to receive(:perform_async)
.with(project_id, project_name, full_path, project.repository_storage)
subject.run!
daemon.run_once!
end
end
context 'when replaying a repositories changed event' do
let(:geo_node) { create(:geo_node) }
let(:repositories_changed_event) { create(:geo_repositories_changed_event, geo_node: geo_node) }
let(:repositories_changed_event) { create(:geo_repositories_changed_event, geo_node: secondary) }
let(:event_log) { create(:geo_event_log, repositories_changed_event: repositories_changed_event) }
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
before do
allow(subject).to receive(:exit?).and_return(false, true)
end
it 'schedules a GeoRepositoryDestroyWorker when event node is the current node' do
expect(Geo::RepositoriesCleanUpWorker).to receive(:perform_in).with(within(5.minutes).of(1.hour), geo_node.id)
expect(Geo::RepositoriesCleanUpWorker).to receive(:perform_in).with(within(5.minutes).of(1.hour), secondary.id)
subject.run!
daemon.run_once!
end
it 'does not schedule a GeoRepositoryDestroyWorker when event node is not the current node' do
......@@ -157,7 +166,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
expect(Geo::RepositoriesCleanUpWorker).not_to receive(:perform_in)
subject.run!
daemon.run_once!
end
end
......@@ -170,36 +179,19 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
before do
allow(subject).to receive(:exit?).and_return(false, true)
allow(Geo::ProjectSyncWorker).to receive(:perform_async)
end
it 'replays events for projects that belong to selected namespaces to replicate' do
geo_node.update_attribute(:namespaces, [group_1])
secondary.update!(namespaces: [group_1])
expect { subject.run! }.to change(Geo::ProjectRegistry, :count).by(1)
expect { daemon.run_once! }.to change(Geo::ProjectRegistry, :count).by(1)
end
it 'does not replay events for projects that do not belong to selected namespaces to replicate' do
geo_node.update_attribute(:namespaces, [group_2])
secondary.update!(namespaces: [group_2])
expect { subject.run! }.not_to change(Geo::ProjectRegistry, :count)
end
context 'when performing a full scan' do
subject { described_class.new(full_scan: true) }
it 'creates registries for missing projects that belong to selected namespaces' do
geo_node.update_attribute(:namespaces, [group_1])
expect { subject.run! }.to change(Geo::ProjectRegistry, :count).by(1)
end
it 'does not create registries for missing projects that do not belong to selected namespaces' do
geo_node.update_attribute(:namespaces, [group_2])
expect { subject.run! }.not_to change(Geo::ProjectRegistry, :count)
end
expect { daemon.run_once! }.not_to change(Geo::ProjectRegistry, :count)
end
end
......@@ -209,12 +201,8 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
let!(:event_log_state) { create(:geo_event_log_state, event_id: event_log.id - 1) }
let(:repository_rename_event) { event_log.repository_renamed_event }
before do
allow(subject).to receive(:exit?).and_return(false, true)
end
it 'does not create a new project registry' do
expect { subject.run! }.not_to change(Geo::ProjectRegistry, :count)
expect { daemon.run_once! }.not_to change(Geo::ProjectRegistry, :count)
end
it 'schedules a GeoRepositoryDestroyWorker' do
......@@ -225,7 +213,25 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
expect(::GeoRepositoryMoveWorker).to receive(:perform_async)
.with(project_id, '', old_path_with_namespace, new_path_with_namespace)
subject.run!
daemon.run_once!
end
end
end
describe '#full_scan!' do
let(:project) { create(:project) }
context 'with selective sync enabled' do
it 'creates registries for missing projects that belong to selected namespaces' do
secondary.update!(namespaces: [project.namespace])
expect { daemon.full_scan! }.to change(Geo::ProjectRegistry, :count).by(1)
end
it 'does not create registries for missing projects that do not belong to selected namespaces' do
secondary.update!(namespaces: [create(:group)])
expect { daemon.full_scan! }.not_to change(Geo::ProjectRegistry, :count)
end
end
end
......
require 'spec_helper'
describe Gitlab::Git::Env do
describe "#set" do
describe ".set" do
context 'with RequestStore.store disabled' do
before do
allow(RequestStore).to receive(:active?).and_return(false)
......@@ -34,25 +34,57 @@ describe Gitlab::Git::Env do
end
end
describe "#all" do
describe ".all" do
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
described_class.set(
GIT_OBJECT_DIRECTORY: 'foo',
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar')
GIT_ALTERNATE_OBJECT_DIRECTORIES: ['bar'])
end
it 'returns an env hash' do
expect(described_class.all).to eq({
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => ['bar']
})
end
end
end
describe "#[]" do
describe ".to_env_hash" do
context 'with RequestStore.store enabled' do
using RSpec::Parameterized::TableSyntax
let(:key) { 'GIT_OBJECT_DIRECTORY' }
subject { described_class.to_env_hash }
where(:input, :output) do
nil | nil
'foo' | 'foo'
[] | ''
['foo'] | 'foo'
%w[foo bar] | 'foo:bar'
end
with_them do
before do
allow(RequestStore).to receive(:active?).and_return(true)
described_class.set(key.to_sym => input)
end
it 'puts the right value in the hash' do
if output
expect(subject.fetch(key)).to eq(output)
else
expect(subject.has_key?(key)).to eq(false)
end
end
end
end
end
describe ".[]" do
context 'with RequestStore.store enabled' do
before do
allow(RequestStore).to receive(:active?).and_return(true)
......
require 'spec_helper'
describe Geo::ProjectRegistry do
subject { create(:geo_project_registry) }
using RSpec::Parameterized::TableSyntax
set(:project) { create(:project) }
set(:registry) { create(:geo_project_registry, project_id: project.id) }
subject { registry }
describe 'relationships' do
it { is_expected.to belong_to(:project) }
......@@ -33,85 +38,79 @@ describe Geo::ProjectRegistry do
end
end
describe '#resync_repository?' do
it 'returns true when resync_repository is true' do
subject.resync_repository = true
expect(subject.resync_repository).to be true
end
it 'returns true when last_repository_successful_sync_at is nil' do
subject.last_repository_successful_sync_at = nil
expect(subject.resync_repository).to be true
end
it 'returns false when resync_repository is false and last_repository_successful_sync_at is present' do
subject.resync_repository = false
subject.last_repository_successful_sync_at = Time.now
expect(subject.resync_repository).to be false
end
end
describe '#resync_wiki?' do
it 'returns true when resync_wiki is true' do
subject.resync_wiki = true
expect(subject.resync_wiki).to be true
describe '#repository_sync_due?' do
where(:resync_repository, :last_successful_sync, :last_sync, :expected) do
now = Time.now
past = now - 1.year
future = now + 1.year
true | nil | nil | true
true | now | nil | true
false | nil | nil | true
false | now | nil | false
true | nil | past | true
true | now | past | true
false | nil | past | true
false | now | past | false
true | nil | future | true
true | now | future | false
false | nil | future | true
false | now | future | false
end
it 'returns true when last_wiki_successful_sync_at is nil' do
subject.last_wiki_successful_sync_at = nil
with_them do
before do
registry.update!(resync_repository: resync_repository, last_repository_successful_sync_at: last_successful_sync, last_repository_synced_at: last_sync)
end
expect(subject.resync_wiki).to be true
end
it 'returns false when resync_wiki is false and last_wiki_successful_sync_at is present' do
subject.resync_wiki = false
subject.last_wiki_successful_sync_at = Time.now
subject { registry.repository_sync_due?(Time.now) }
expect(subject.resync_wiki).to be false
it { is_expected.to eq(expected) }
end
end
describe '#repository_synced_since?' do
it 'returns false when last_repository_synced_at is nil' do
subject.last_repository_synced_at = nil
expect(subject.repository_synced_since?(Time.now)).to be_nil
describe '#wiki_sync_due?' do
where(:resync_wiki, :last_successful_sync, :last_sync, :expected) do
now = Time.now
past = now - 1.year
future = now + 1.year
true | nil | nil | true
true | now | nil | true
false | nil | nil | true
false | now | nil | false
true | nil | past | true
true | now | past | true
false | nil | past | true
false | now | past | false
true | nil | future | true
true | now | future | false
false | nil | future | true
false | now | future | false
end
it 'returns false when last_repository_synced_at before timestamp' do
subject.last_repository_synced_at = Time.now - 2.hours
with_them do
before do
registry.update!(resync_wiki: resync_wiki, last_wiki_successful_sync_at: last_successful_sync, last_wiki_synced_at: last_sync)
end
expect(subject.repository_synced_since?(Time.now)).to be false
end
subject { registry.wiki_sync_due?(Time.now) }
it 'returns true when last_repository_synced_at after timestamp' do
subject.last_repository_synced_at = Time.now + 2.hours
expect(subject.repository_synced_since?(Time.now)).to be true
end
end
describe '#wiki_synced_since?' do
it 'returns false when last_wiki_synced_at is nil' do
subject.last_wiki_synced_at = nil
expect(subject.wiki_synced_since?(Time.now)).to be_nil
end
it 'returns false when last_wiki_synced_at before timestamp' do
subject.last_wiki_synced_at = Time.now - 2.hours
expect(subject.wiki_synced_since?(Time.now)).to be false
end
context 'wiki enabled' do
it { is_expected.to eq(expected) }
end
it 'returns true when last_wiki_synced_at after timestamp' do
subject.last_wiki_synced_at = Time.now + 2.hours
context 'wiki disabled' do
before do
project.update!(wiki_enabled: false)
end
expect(subject.wiki_synced_since?(Time.now)).to be true
it { is_expected.to be_falsy }
end
end
end
end
require 'spec_helper'
describe Geo::RepositoryCreatedEventStore do
let(:project) { create(:project) }
set(:project) { create(:project) }
subject(:event) { described_class.new(project) }
subject(:create!) { described_class.new(project).create }
describe '#create' do
it 'does not create an event when not running on a primary node' do
allow(Gitlab::Geo).to receive(:primary?) { false }
expect { event.create }.not_to change(Geo::RepositoryCreatedEvent, :count)
expect { create! }.not_to change(Geo::RepositoryCreatedEvent, :count)
end
context 'when running on a primary node' do
context 'running on a primary node' do
before do
allow(Gitlab::Geo).to receive(:primary?) { true }
end
it 'creates a created event' do
expect { event.create }.to change(Geo::RepositoryCreatedEvent, :count).by(1)
expect { create! }.to change(Geo::RepositoryCreatedEvent, :count).by(1)
end
it 'tracks information for the created project' do
event.create
create!
event = Geo::RepositoryCreatedEvent.last
......@@ -35,6 +35,15 @@ describe Geo::RepositoryCreatedEventStore do
repository_storage_path: project.repository_storage_path
)
end
it 'does not set a wiki path if the wiki is disabled' do
project.update!(wiki_enabled: false)
create!
event = Geo::RepositoryCreatedEvent.last
expect(event.wiki_path).to be_nil
end
end
end
end
......@@ -102,6 +102,23 @@ RSpec.describe Geo::ProjectSyncWorker do
end
end
context 'wiki is not enabled for project' do
let!(:registry) { create(:geo_project_registry, resync_repository: true, resync_wiki: true, project: project) }
before do
project.update!(wiki_enabled: false)
subject.perform(project.id, Time.now)
end
it 'syncs the project repository' do
expect(repository_sync_service).to have_received(:execute)
end
it 'does not sync the project wiki' do
expect(wiki_sync_service).not_to have_received(:execute)
end
end
context 'when project repository was synced after the time the job was scheduled in' do
it 'does not perform Geo::RepositorySyncService for the given project' do
create(:geo_project_registry, :synced, :repository_dirty, project: project, last_repository_synced_at: Time.now)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment