diff options
Diffstat (limited to 'spec/models/ci')
-rw-r--r-- | spec/models/ci/commit_spec.rb | 422 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 403 | ||||
-rw-r--r-- | spec/models/ci/runner_project_spec.rb | 17 | ||||
-rw-r--r-- | spec/models/ci/runner_spec.rb | 51 | ||||
-rw-r--r-- | spec/models/ci/trigger_spec.rb | 13 | ||||
-rw-r--r-- | spec/models/ci/variable_spec.rb | 16 |
6 files changed, 435 insertions, 487 deletions
diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb deleted file mode 100644 index a747aa08447..00000000000 --- a/spec/models/ci/commit_spec.rb +++ /dev/null @@ -1,422 +0,0 @@ -# == Schema Information -# -# Table name: ci_commits -# -# id :integer not null, primary key -# project_id :integer -# ref :string(255) -# sha :string(255) -# before_sha :string(255) -# push_data :text -# created_at :datetime -# updated_at :datetime -# tag :boolean default(FALSE) -# yaml_errors :text -# committed_at :datetime -# gl_project_id :integer -# - -require 'spec_helper' - -describe Ci::Commit, models: true do - let(:project) { FactoryGirl.create :empty_project } - let(:commit) { FactoryGirl.create :ci_commit, project: project } - - it { is_expected.to belong_to(:project) } - it { is_expected.to have_many(:statuses) } - it { is_expected.to have_many(:trigger_requests) } - it { is_expected.to have_many(:builds) } - it { is_expected.to validate_presence_of :sha } - it { is_expected.to validate_presence_of :status } - it { is_expected.to delegate_method(:stages).to(:statuses) } - - it { is_expected.to respond_to :git_author_name } - it { is_expected.to respond_to :git_author_email } - it { is_expected.to respond_to :short_sha } - - describe :valid_commit_sha do - context 'commit.sha can not start with 00000000' do - before do - commit.sha = '0' * 40 - commit.valid_commit_sha - end - - it('commit errors should not be empty') { expect(commit.errors).not_to be_empty } - end - end - - describe :short_sha do - subject { commit.short_sha } - - it 'has 8 items' do - expect(subject.size).to eq(8) - end - it { expect(commit.sha).to start_with(subject) } - end - - describe :create_next_builds do - end - - describe :retried do - subject { commit.retried } - - before do - @commit1 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy' - @commit2 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy' - end - - it 'returns old builds' do - is_expected.to contain_exactly(@commit1) - end - end - - describe :create_builds do - let!(:commit) { FactoryGirl.create :ci_commit, project: project, ref: 'master', tag: false } - - def create_builds(trigger_request = nil) - commit.create_builds(nil, trigger_request) - end - - def create_next_builds - commit.create_next_builds(commit.builds.order(:id).last) - end - - it 'creates builds' do - expect(create_builds).to be_truthy - commit.builds.update_all(status: "success") - expect(commit.builds.count(:all)).to eq(2) - - expect(create_next_builds).to be_truthy - commit.builds.update_all(status: "success") - expect(commit.builds.count(:all)).to eq(4) - - expect(create_next_builds).to be_truthy - commit.builds.update_all(status: "success") - expect(commit.builds.count(:all)).to eq(5) - - expect(create_next_builds).to be_falsey - end - - context 'custom stage with first job allowed to fail' do - let(:yaml) do - { - stages: ['clean', 'test'], - clean_job: { - stage: 'clean', - allow_failure: true, - script: 'BUILD', - }, - test_job: { - stage: 'test', - script: 'TEST', - }, - } - end - - before do - stub_ci_commit_yaml_file(YAML.dump(yaml)) - create_builds - end - - it 'properly schedules builds' do - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:drop) - expect(commit.builds.pluck(:status)).to contain_exactly('pending', 'failed') - end - end - - context 'properly creates builds when "when" is defined' do - let(:yaml) do - { - stages: ["build", "test", "test_failure", "deploy", "cleanup"], - build: { - stage: "build", - script: "BUILD", - }, - test: { - stage: "test", - script: "TEST", - }, - test_failure: { - stage: "test_failure", - script: "ON test failure", - when: "on_failure", - }, - deploy: { - stage: "deploy", - script: "PUBLISH", - }, - cleanup: { - stage: "cleanup", - script: "TIDY UP", - when: "always", - } - } - end - - before do - stub_ci_commit_yaml_file(YAML.dump(yaml)) - end - - context 'when builds are successful' do - it 'properly creates builds' do - expect(create_builds).to be_truthy - expect(commit.builds.pluck(:name)).to contain_exactly('build') - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'success') - commit.reload - expect(commit.status).to eq('success') - end - end - - context 'when test job fails' do - it 'properly creates builds' do - expect(create_builds).to be_truthy - expect(commit.builds.pluck(:name)).to contain_exactly('build') - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending') - commit.builds.running_or_pending.each(&:drop) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'success') - commit.reload - expect(commit.status).to eq('failed') - end - end - - context 'when test and test_failure jobs fail' do - it 'properly creates builds' do - expect(create_builds).to be_truthy - expect(commit.builds.pluck(:name)).to contain_exactly('build') - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending') - commit.builds.running_or_pending.each(&:drop) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending') - commit.builds.running_or_pending.each(&:drop) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'success') - commit.reload - expect(commit.status).to eq('failed') - end - end - - context 'when deploy job fails' do - it 'properly creates builds' do - expect(create_builds).to be_truthy - expect(commit.builds.pluck(:name)).to contain_exactly('build') - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending') - commit.builds.running_or_pending.each(&:drop) - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'success') - commit.reload - expect(commit.status).to eq('failed') - end - end - - context 'when build is canceled in the second stage' do - it 'does not schedule builds after build has been canceled' do - expect(create_builds).to be_truthy - expect(commit.builds.pluck(:name)).to contain_exactly('build') - expect(commit.builds.pluck(:status)).to contain_exactly('pending') - commit.builds.running_or_pending.each(&:success) - - expect(commit.builds.running_or_pending).to_not be_empty - - expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test') - expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending') - commit.builds.running_or_pending.each(&:cancel) - - expect(commit.builds.running_or_pending).to be_empty - expect(commit.reload.status).to eq('canceled') - end - end - end - end - - describe "#finished_at" do - let(:commit) { FactoryGirl.create :ci_commit } - - it "returns finished_at of latest build" do - build = FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 60 - FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 120 - - expect(commit.finished_at.to_i).to eq(build.finished_at.to_i) - end - - it "returns nil if there is no finished build" do - FactoryGirl.create :ci_not_started_build, commit: commit - - expect(commit.finished_at).to be_nil - end - end - - describe "coverage" do - let(:project) { FactoryGirl.create :empty_project, build_coverage_regex: "/.*/" } - let(:commit) { FactoryGirl.create :ci_commit, project: project } - - it "calculates average when there are two builds with coverage" do - FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit - FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit - expect(commit.coverage).to eq("35.00") - end - - it "calculates average when there are two builds with coverage and one with nil" do - FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit - FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit - FactoryGirl.create :ci_build, commit: commit - expect(commit.coverage).to eq("35.00") - end - - it "calculates average when there are two builds with coverage and one is retried" do - FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit - FactoryGirl.create :ci_build, name: "rubocop", coverage: 30, commit: commit - FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit - expect(commit.coverage).to eq("35.00") - end - - it "calculates average when there is one build without coverage" do - FactoryGirl.create :ci_build, commit: commit - expect(commit.coverage).to be_nil - end - end - - describe '#retryable?' do - subject { commit.retryable? } - - context 'no failed builds' do - before do - FactoryGirl.create :ci_build, name: "rspec", commit: commit, status: 'success' - end - - it 'be not retryable' do - is_expected.to be_falsey - end - end - - context 'with failed builds' do - before do - FactoryGirl.create :ci_build, name: "rspec", commit: commit, status: 'running' - FactoryGirl.create :ci_build, name: "rubocop", commit: commit, status: 'failed' - end - - it 'be retryable' do - is_expected.to be_truthy - end - end - end - - describe '#stages' do - let(:commit2) { FactoryGirl.create :ci_commit, project: project } - subject { CommitStatus.where(commit: [commit, commit2]).stages } - - before do - FactoryGirl.create :ci_build, commit: commit2, stage: 'test', stage_idx: 1 - FactoryGirl.create :ci_build, commit: commit, stage: 'build', stage_idx: 0 - end - - it 'return all stages' do - is_expected.to eq(%w(build test)) - end - end - - describe '#update_state' do - it 'execute update_state after touching object' do - expect(commit).to receive(:update_state).and_return(true) - commit.touch - end - - context 'dependent objects' do - let(:commit_status) { build :commit_status, commit: commit } - - it 'execute update_state after saving dependent object' do - expect(commit).to receive(:update_state).and_return(true) - commit_status.save - end - end - - context 'update state' do - let(:current) { Time.now.change(usec: 0) } - let(:build) { FactoryGirl.create :ci_build, :success, commit: commit, started_at: current - 120, finished_at: current - 60 } - - before do - build - end - - [:status, :started_at, :finished_at, :duration].each do |param| - it "update #{param}" do - expect(commit.send(param)).to eq(build.send(param)) - end - end - end - end - - describe '#branch?' do - subject { commit.branch? } - - context 'is not a tag' do - before do - commit.tag = false - end - - it 'return true when tag is set to false' do - is_expected.to be_truthy - end - end - - context 'is not a tag' do - before do - commit.tag = true - end - - it 'return false when tag is set to true' do - is_expected.to be_falsey - end - end - end -end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb new file mode 100644 index 00000000000..0d769ed7324 --- /dev/null +++ b/spec/models/ci/pipeline_spec.rb @@ -0,0 +1,403 @@ +require 'spec_helper' + +describe Ci::Pipeline, models: true do + let(:project) { FactoryGirl.create :empty_project } + let(:pipeline) { FactoryGirl.create :ci_pipeline, project: project } + + it { is_expected.to belong_to(:project) } + it { is_expected.to have_many(:statuses) } + it { is_expected.to have_many(:trigger_requests) } + it { is_expected.to have_many(:builds) } + it { is_expected.to validate_presence_of :sha } + it { is_expected.to validate_presence_of :status } + + it { is_expected.to respond_to :git_author_name } + it { is_expected.to respond_to :git_author_email } + it { is_expected.to respond_to :short_sha } + + describe :valid_commit_sha do + context 'commit.sha can not start with 00000000' do + before do + pipeline.sha = '0' * 40 + pipeline.valid_commit_sha + end + + it('commit errors should not be empty') { expect(pipeline.errors).not_to be_empty } + end + end + + describe :short_sha do + subject { pipeline.short_sha } + + it 'has 8 items' do + expect(subject.size).to eq(8) + end + it { expect(pipeline.sha).to start_with(subject) } + end + + describe :create_next_builds do + end + + describe :retried do + subject { pipeline.retried } + + before do + @build1 = FactoryGirl.create :ci_build, pipeline: pipeline, name: 'deploy' + @build2 = FactoryGirl.create :ci_build, pipeline: pipeline, name: 'deploy' + end + + it 'returns old builds' do + is_expected.to contain_exactly(@build1) + end + end + + describe :create_builds do + let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project, ref: 'master', tag: false } + + def create_builds(trigger_request = nil) + pipeline.create_builds(nil, trigger_request) + end + + def create_next_builds + pipeline.create_next_builds(pipeline.builds.order(:id).last) + end + + it 'creates builds' do + expect(create_builds).to be_truthy + pipeline.builds.update_all(status: "success") + expect(pipeline.builds.count(:all)).to eq(2) + + expect(create_next_builds).to be_truthy + pipeline.builds.update_all(status: "success") + expect(pipeline.builds.count(:all)).to eq(4) + + expect(create_next_builds).to be_truthy + pipeline.builds.update_all(status: "success") + expect(pipeline.builds.count(:all)).to eq(5) + + expect(create_next_builds).to be_falsey + end + + context 'custom stage with first job allowed to fail' do + let(:yaml) do + { + stages: ['clean', 'test'], + clean_job: { + stage: 'clean', + allow_failure: true, + script: 'BUILD', + }, + test_job: { + stage: 'test', + script: 'TEST', + }, + } + end + + before do + stub_ci_pipeline_yaml_file(YAML.dump(yaml)) + create_builds + end + + it 'properly schedules builds' do + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:drop) + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending', 'failed') + end + end + + context 'properly creates builds when "when" is defined' do + let(:yaml) do + { + stages: ["build", "test", "test_failure", "deploy", "cleanup"], + build: { + stage: "build", + script: "BUILD", + }, + test: { + stage: "test", + script: "TEST", + }, + test_failure: { + stage: "test_failure", + script: "ON test failure", + when: "on_failure", + }, + deploy: { + stage: "deploy", + script: "PUBLISH", + }, + cleanup: { + stage: "cleanup", + script: "TIDY UP", + when: "always", + } + } + end + + before do + stub_ci_pipeline_yaml_file(YAML.dump(yaml)) + end + + context 'when builds are successful' do + it 'properly creates builds' do + expect(create_builds).to be_truthy + expect(pipeline.builds.pluck(:name)).to contain_exactly('build') + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'success') + pipeline.reload + expect(pipeline.status).to eq('success') + end + end + + context 'when test job fails' do + it 'properly creates builds' do + expect(create_builds).to be_truthy + expect(pipeline.builds.pluck(:name)).to contain_exactly('build') + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending') + pipeline.builds.running_or_pending.each(&:drop) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'success') + pipeline.reload + expect(pipeline.status).to eq('failed') + end + end + + context 'when test and test_failure jobs fail' do + it 'properly creates builds' do + expect(create_builds).to be_truthy + expect(pipeline.builds.pluck(:name)).to contain_exactly('build') + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending') + pipeline.builds.running_or_pending.each(&:drop) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending') + pipeline.builds.running_or_pending.each(&:drop) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'success') + pipeline.reload + expect(pipeline.status).to eq('failed') + end + end + + context 'when deploy job fails' do + it 'properly creates builds' do + expect(create_builds).to be_truthy + expect(pipeline.builds.pluck(:name)).to contain_exactly('build') + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending') + pipeline.builds.running_or_pending.each(&:drop) + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'success') + pipeline.reload + expect(pipeline.status).to eq('failed') + end + end + + context 'when build is canceled in the second stage' do + it 'does not schedule builds after build has been canceled' do + expect(create_builds).to be_truthy + expect(pipeline.builds.pluck(:name)).to contain_exactly('build') + expect(pipeline.builds.pluck(:status)).to contain_exactly('pending') + pipeline.builds.running_or_pending.each(&:success) + + expect(pipeline.builds.running_or_pending).not_to be_empty + + expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test') + expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending') + pipeline.builds.running_or_pending.each(&:cancel) + + expect(pipeline.builds.running_or_pending).to be_empty + expect(pipeline.reload.status).to eq('canceled') + end + end + end + end + + describe "#finished_at" do + let(:pipeline) { FactoryGirl.create :ci_pipeline } + + it "returns finished_at of latest build" do + build = FactoryGirl.create :ci_build, pipeline: pipeline, finished_at: Time.now - 60 + FactoryGirl.create :ci_build, pipeline: pipeline, finished_at: Time.now - 120 + + expect(pipeline.finished_at.to_i).to eq(build.finished_at.to_i) + end + + it "returns nil if there is no finished build" do + FactoryGirl.create :ci_not_started_build, pipeline: pipeline + + expect(pipeline.finished_at).to be_nil + end + end + + describe "coverage" do + let(:project) { FactoryGirl.create :empty_project, build_coverage_regex: "/.*/" } + let(:pipeline) { FactoryGirl.create :ci_pipeline, project: project } + + it "calculates average when there are two builds with coverage" do + FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline + FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline + expect(pipeline.coverage).to eq("35.00") + end + + it "calculates average when there are two builds with coverage and one with nil" do + FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline + FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline + FactoryGirl.create :ci_build, pipeline: pipeline + expect(pipeline.coverage).to eq("35.00") + end + + it "calculates average when there are two builds with coverage and one is retried" do + FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline + FactoryGirl.create :ci_build, name: "rubocop", coverage: 30, pipeline: pipeline + FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline + expect(pipeline.coverage).to eq("35.00") + end + + it "calculates average when there is one build without coverage" do + FactoryGirl.create :ci_build, pipeline: pipeline + expect(pipeline.coverage).to be_nil + end + end + + describe '#retryable?' do + subject { pipeline.retryable? } + + context 'no failed builds' do + before do + FactoryGirl.create :ci_build, name: "rspec", pipeline: pipeline, status: 'success' + end + + it 'be not retryable' do + is_expected.to be_falsey + end + end + + context 'with failed builds' do + before do + FactoryGirl.create :ci_build, name: "rspec", pipeline: pipeline, status: 'running' + FactoryGirl.create :ci_build, name: "rubocop", pipeline: pipeline, status: 'failed' + end + + it 'be retryable' do + is_expected.to be_truthy + end + end + end + + describe '#stages' do + let(:pipeline2) { FactoryGirl.create :ci_pipeline, project: project } + subject { CommitStatus.where(pipeline: [pipeline, pipeline2]).stages } + + before do + FactoryGirl.create :ci_build, pipeline: pipeline2, stage: 'test', stage_idx: 1 + FactoryGirl.create :ci_build, pipeline: pipeline, stage: 'build', stage_idx: 0 + end + + it 'return all stages' do + is_expected.to eq(%w(build test)) + end + end + + describe '#update_state' do + it 'execute update_state after touching object' do + expect(pipeline).to receive(:update_state).and_return(true) + pipeline.touch + end + + context 'dependent objects' do + let(:commit_status) { build :commit_status, pipeline: pipeline } + + it 'execute update_state after saving dependent object' do + expect(pipeline).to receive(:update_state).and_return(true) + commit_status.save + end + end + + context 'update state' do + let(:current) { Time.now.change(usec: 0) } + let(:build) { FactoryGirl.create :ci_build, :success, pipeline: pipeline, started_at: current - 120, finished_at: current - 60 } + + before do + build + end + + [:status, :started_at, :finished_at, :duration].each do |param| + it "update #{param}" do + expect(pipeline.send(param)).to eq(build.send(param)) + end + end + end + end + + describe '#branch?' do + subject { pipeline.branch? } + + context 'is not a tag' do + before do + pipeline.tag = false + end + + it 'return true when tag is set to false' do + is_expected.to be_truthy + end + end + + context 'is not a tag' do + before do + pipeline.tag = true + end + + it 'return false when tag is set to true' do + is_expected.to be_falsey + end + end + end +end diff --git a/spec/models/ci/runner_project_spec.rb b/spec/models/ci/runner_project_spec.rb deleted file mode 100644 index 000a732db77..00000000000 --- a/spec/models/ci/runner_project_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# == Schema Information -# -# Table name: ci_runner_projects -# -# id :integer not null, primary key -# runner_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - -require 'spec_helper' - -describe Ci::RunnerProject, models: true do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 25e9e5eca48..5d04d8ffcff 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -1,25 +1,24 @@ -# == Schema Information -# -# Table name: ci_runners -# -# id :integer not null, primary key -# token :string(255) -# created_at :datetime -# updated_at :datetime -# description :string(255) -# contacted_at :datetime -# active :boolean default(TRUE), not null -# is_shared :boolean default(FALSE) -# name :string(255) -# version :string(255) -# revision :string(255) -# platform :string(255) -# architecture :string(255) -# - require 'spec_helper' describe Ci::Runner, models: true do + describe 'validation' do + context 'when runner is not allowed to pick untagged jobs' do + context 'when runner does not have tags' do + it 'is not valid' do + runner = build(:ci_runner, tag_list: [], run_untagged: false) + expect(runner).to be_invalid + end + end + + context 'when runner has tags' do + it 'is valid' do + runner = build(:ci_runner, tag_list: ['tag'], run_untagged: false) + expect(runner).to be_valid + end + end + end + end + describe '#display_name' do it 'should return the description if it has a value' do runner = FactoryGirl.build(:ci_runner, description: 'Linux/Ruby-1.9.3-p448') @@ -133,7 +132,19 @@ describe Ci::Runner, models: true do end end - describe '#search' do + describe '#has_tags?' do + context 'when runner has tags' do + subject { create(:ci_runner, tag_list: ['tag']) } + it { is_expected.to have_tags } + end + + context 'when runner does not have tags' do + subject { create(:ci_runner, tag_list: []) } + it { is_expected.not_to have_tags } + end + end + + describe '.search' do let(:runner) { create(:ci_runner, token: '123abc') } it 'returns runners with a matching token' do diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb index 159be939300..474b0b1621d 100644 --- a/spec/models/ci/trigger_spec.rb +++ b/spec/models/ci/trigger_spec.rb @@ -1,16 +1,3 @@ -# == Schema Information -# -# Table name: ci_triggers -# -# id :integer not null, primary key -# token :string(255) -# project_id :integer -# deleted_at :datetime -# created_at :datetime -# updated_at :datetime -# gl_project_id :integer -# - require 'spec_helper' describe Ci::Trigger, models: true do diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index 71e84091cb7..98f60087cf5 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -1,17 +1,3 @@ -# == Schema Information -# -# Table name: ci_variables -# -# id :integer not null, primary key -# project_id :integer -# key :string(255) -# value :text -# encrypted_value :text -# encrypted_value_salt :string(255) -# encrypted_value_iv :string(255) -# gl_project_id :integer -# - require 'spec_helper' describe Ci::Variable, models: true do @@ -37,7 +23,7 @@ describe Ci::Variable, models: true do end it 'fails to decrypt if iv is incorrect' do - subject.encrypted_value_iv = nil + subject.encrypted_value_iv = SecureRandom.hex subject.instance_variable_set(:@value, nil) expect { subject.value }. to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt') |