From 9e41159a6d2eb0d7409fe7188f8eedddbef0136b Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Thu, 16 Mar 2017 10:47:01 +0000 Subject: adds timeout option to push branches and respective test suite --- CHANGELOG | 3 ++ VERSION | 2 +- lib/gitlab_projects.rb | 17 ++++++---- spec/gitlab_projects_spec.rb | 80 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8622707..05d0981 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +v5.0.2 + - Adds timeout option to push branches + v5.0.1 - Fetch repositories with `--quiet` option by default diff --git a/VERSION b/VERSION index 0062ac9..a1ef0ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.0 +5.0.2 diff --git a/lib/gitlab_projects.rb b/lib/gitlab_projects.rb index eec8a2b..0b11ce3 100644 --- a/lib/gitlab_projects.rb +++ b/lib/gitlab_projects.rb @@ -113,16 +113,21 @@ class GitlabProjects def push_branches remote_name = ARGV.shift + # timeout for push + timeout = (ARGV.shift || 120).to_i + $logger.info "Pushing branches from #{full_path} to remote #{remote_name}: #{ARGV}" cmd = %W(git --git-dir=#{full_path} push -- #{remote_name}).concat(ARGV) pid = Process.spawn(*cmd) begin - Process.wait(pid) + Timeout.timeout(timeout) do + Process.wait(pid) + end $?.exitstatus.zero? rescue => exception - $logger.error "Pushing branches to remote #{remote_name} failed due to: #{exception.message}" + $logger.error "Pushing branches to remote #{remote_name} failed due to: #{exception.message}." Process.kill('KILL', pid) Process.wait @@ -204,10 +209,8 @@ class GitlabProjects tags_option = ARGV.include?('--no-tags') ? '--no-tags' : '--tags' $logger.info "Fetching remote #{@name} for project #{@project_name}." - cmd = %W(git --git-dir=#{full_path} fetch #{@name}) - cmd << '--prune' + cmd = %W(git --git-dir=#{full_path} fetch #{@name} --prune --quiet) cmd << '--force' if forced - cmd << '--quiet' cmd << tags_option pid = Process.spawn(*cmd) @@ -217,8 +220,8 @@ class GitlabProjects end $?.exitstatus.zero? - rescue Timeout::Error - $logger.error "Fetching remote #{@name} for project #{@project_name} failed due to timeout." + rescue => exception + $logger.error "Fetching remote #{@name} for project #{@project_name} failed due to: #{exception.message}." Process.kill('KILL', pid) Process.wait diff --git a/spec/gitlab_projects_spec.rb b/spec/gitlab_projects_spec.rb index 175c929..7f80cbd 100644 --- a/spec/gitlab_projects_spec.rb +++ b/spec/gitlab_projects_spec.rb @@ -287,6 +287,86 @@ describe GitlabProjects do end end + describe :push_branches do + let(:repos_path) { 'current/storage' } + let(:project_name) { 'project/path.git' } + let(:full_path) { File.join(repos_path, project_name) } + let(:remote_name) { 'new/storage' } + let(:pid) { 1234 } + let(:branch_name) { 'master' } + let(:cmd) { %W(git --git-dir=#{full_path} push -- #{remote_name} #{branch_name}) } + let(:gl_projects) { build_gitlab_projects('push-branches', repos_path, project_name, remote_name, '600', 'master') } + + it 'executes the command' do + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait).with(pid) + + expect(gl_projects.exec).to be true + end + + it 'raises timeout' do + expect(Timeout).to receive(:timeout).with(600).and_raise(Timeout::Error) + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait) + expect(Process).to receive(:kill).with('KILL', pid) + + expect(gl_projects.exec).to be false + end + end + + describe :fetch_remote do + let(:repos_path) { 'current/storage' } + let(:project_name) { 'project.git' } + let(:full_path) { File.join(repos_path, project_name) } + let(:remote_name) { 'new/storage' } + let(:pid) { 1234 } + let(:branch_name) { 'master' } + + describe 'with default args' do + let(:gl_projects) { build_gitlab_projects('fetch-remote', repos_path, project_name, remote_name, '600') } + let(:cmd) { %W(git --git-dir=#{full_path} fetch #{remote_name} --prune --quiet --tags) } + + it 'executes the command' do + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait).with(pid) + + expect(gl_projects.exec).to be true + end + + it 'raises timeout' do + expect(Timeout).to receive(:timeout).with(600).and_raise(Timeout::Error) + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait) + expect(Process).to receive(:kill).with('KILL', pid) + expect(gl_projects.exec).to be false + end + end + + describe 'with --force' do + let(:gl_projects) { build_gitlab_projects('fetch-remote', repos_path, project_name, remote_name, '600', '--force') } + let(:cmd) { %W(git --git-dir=#{full_path} fetch #{remote_name} --prune --quiet --force --tags) } + + it 'executes the command with forced option' do + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait).with(pid) + + expect(gl_projects.exec).to be true + end + end + + describe 'with --no-tags' do + let(:gl_projects) { build_gitlab_projects('fetch-remote', repos_path, project_name, remote_name, '600', '--no-tags') } + let(:cmd) { %W(git --git-dir=#{full_path} fetch #{remote_name} --prune --quiet --no-tags) } + + it 'executes the command' do + expect(Process).to receive(:spawn).with(*cmd).and_return(pid) + expect(Process).to receive(:wait).with(pid) + + expect(gl_projects.exec).to be true + end + end + end + describe :import_project do context 'success import' do let(:gl_projects) { build_gitlab_projects('import-project', tmp_repos_path, repo_name, 'https://github.com/randx/six.git') } -- cgit v1.2.1