BigW Consortium Gitlab

commit_status_spec.rb 10.7 KB
Newer Older
1 2
require 'spec_helper'

3
describe CommitStatus, :models do
4
  let(:project) { create(:project, :repository) }
5 6 7 8 9

  let(:pipeline) do
    create(:ci_pipeline, project: project, sha: project.commit.id)
  end

10 11 12 13 14
  let(:commit_status) { create_status }

  def create_status(args = {})
    create(:commit_status, args.merge(pipeline: pipeline))
  end
15

16
  it { is_expected.to belong_to(:pipeline) }
17
  it { is_expected.to belong_to(:user) }
Kamil Trzcinski committed
18
  it { is_expected.to belong_to(:project) }
19
  it { is_expected.to belong_to(:auto_canceled_by) }
Kamil Trzcinski committed
20

21 22 23
  it { is_expected.to validate_presence_of(:name) }
  it { is_expected.to validate_inclusion_of(:status).in_array(%w(pending running failed success canceled)) }

24 25
  it { is_expected.to delegate_method(:sha).to(:pipeline) }
  it { is_expected.to delegate_method(:short_sha).to(:pipeline) }
26

27 28 29 30 31
  it { is_expected.to respond_to :success? }
  it { is_expected.to respond_to :failed? }
  it { is_expected.to respond_to :running? }
  it { is_expected.to respond_to :pending? }

32
  describe '#author' do
33 34 35 36 37 38
    subject { commit_status.author }
    before { commit_status.author = User.new }

    it { is_expected.to eq(commit_status.user) }
  end

39
  describe '#started?' do
40 41 42 43 44 45 46 47
    subject { commit_status.started? }

    context 'without started_at' do
      before { commit_status.started_at = nil }

      it { is_expected.to be_falsey }
    end

Lin Jen-Shin committed
48
    %w[running success failed].each do |status|
49 50 51 52 53 54 55
      context "if commit status is #{status}" do
        before { commit_status.status = status }

        it { is_expected.to be_truthy }
      end
    end

Lin Jen-Shin committed
56
    %w[pending canceled].each do |status|
57 58 59 60 61 62 63 64
      context "if commit status is #{status}" do
        before { commit_status.status = status }

        it { is_expected.to be_falsey }
      end
    end
  end

65
  describe '#active?' do
66 67
    subject { commit_status.active? }

Lin Jen-Shin committed
68
    %w[pending running].each do |state|
69 70 71 72 73 74 75
      context "if commit_status.status is #{state}" do
        before { commit_status.status = state }

        it { is_expected.to be_truthy }
      end
    end

Lin Jen-Shin committed
76
    %w[success failed canceled].each do |state|
77 78 79 80 81 82 83 84
      context "if commit_status.status is #{state}" do
        before { commit_status.status = state }

        it { is_expected.to be_falsey }
      end
    end
  end

85
  describe '#complete?' do
86 87
    subject { commit_status.complete? }

Lin Jen-Shin committed
88
    %w[success failed canceled].each do |state|
89 90 91 92 93 94 95
      context "if commit_status.status is #{state}" do
        before { commit_status.status = state }

        it { is_expected.to be_truthy }
      end
    end

Lin Jen-Shin committed
96
    %w[pending running].each do |state|
97 98 99 100 101 102 103 104
      context "if commit_status.status is #{state}" do
        before { commit_status.status = state }

        it { is_expected.to be_falsey }
      end
    end
  end

105 106 107 108 109
  describe '#auto_canceled?' do
    subject { commit_status.auto_canceled? }

    context 'when it is canceled' do
      before do
110
        commit_status.update(status: 'canceled')
111 112 113 114
      end

      context 'when there is auto_canceled_by' do
        before do
Lin Jen-Shin committed
115
          commit_status.update(auto_canceled_by: create(:ci_empty_pipeline))
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
        end

        it 'is auto canceled' do
          is_expected.to be_truthy
        end
      end

      context 'when there is no auto_canceled_by' do
        it 'is not auto canceled' do
          is_expected.to be_falsey
        end
      end
    end
  end

131
  describe '#duration' do
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    subject { commit_status.duration }

    it { is_expected.to eq(120.0) }

    context 'if the building process has not started yet' do
      before do
        commit_status.started_at = nil
        commit_status.finished_at = nil
      end

      it { is_expected.to be_nil }
    end

    context 'if the building process has started' do
      before do
        commit_status.started_at = Time.now - 1.minute
        commit_status.finished_at = nil
      end

      it { is_expected.to be_a(Float) }
      it { is_expected.to be > 0.0 }
    end
  end
155

156
  describe '.latest' do
157
    subject { described_class.latest.order(:id) }
158

159
    let(:statuses) do
160 161 162
      [create_status(name: 'aa', ref: 'bb', status: 'running', retried: true),
       create_status(name: 'cc', ref: 'cc', status: 'pending', retried: true),
       create_status(name: 'aa', ref: 'cc', status: 'success', retried: true),
163 164
       create_status(name: 'cc', ref: 'bb', status: 'success'),
       create_status(name: 'aa', ref: 'bb', status: 'success')]
165 166
    end

167
    it 'returns unique statuses' do
168
      is_expected.to eq(statuses.values_at(3, 4))
169 170 171
    end
  end

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
  describe '.retried' do
    subject { described_class.retried.order(:id) }

    let(:statuses) do
      [create_status(name: 'aa', ref: 'bb', status: 'running', retried: true),
       create_status(name: 'cc', ref: 'cc', status: 'pending', retried: true),
       create_status(name: 'aa', ref: 'cc', status: 'success', retried: true),
       create_status(name: 'cc', ref: 'bb', status: 'success'),
       create_status(name: 'aa', ref: 'bb', status: 'success')]
    end

    it 'returns unique statuses' do
      is_expected.to contain_exactly(*statuses.values_at(0, 1, 2))
    end
  end

188
  describe '.running_or_pending' do
189
    subject { described_class.running_or_pending.order(:id) }
190

191 192 193 194 195 196
    let(:statuses) do
      [create_status(name: 'aa', ref: 'bb', status: 'running'),
       create_status(name: 'cc', ref: 'cc', status: 'pending'),
       create_status(name: 'aa', ref: nil, status: 'success'),
       create_status(name: 'dd', ref: nil, status: 'failed'),
       create_status(name: 'ee', ref: nil, status: 'canceled')]
197 198
    end

199
    it 'returns statuses that are running or pending' do
200
      is_expected.to contain_exactly(*statuses.values_at(0, 1))
201 202 203
    end
  end

204
  describe '.after_stage' do
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
    subject { described_class.after_stage(0) }

    let(:statuses) do
      [create_status(name: 'aa', stage_idx: 0),
       create_status(name: 'cc', stage_idx: 1),
       create_status(name: 'aa', stage_idx: 2)]
    end

    it 'returns statuses from second and third stage' do
      is_expected.to eq(statuses.values_at(1, 2))
    end
  end

  describe '.exclude_ignored' do
    subject { described_class.exclude_ignored.order(:id) }
220 221 222 223 224 225 226 227 228 229 230

    let(:statuses) do
      [create_status(when: 'manual', status: 'skipped'),
       create_status(when: 'manual', status: 'success'),
       create_status(when: 'manual', status: 'failed'),
       create_status(when: 'on_failure', status: 'skipped'),
       create_status(when: 'on_failure', status: 'success'),
       create_status(when: 'on_failure', status: 'failed'),
       create_status(allow_failure: true, status: 'success'),
       create_status(allow_failure: true, status: 'failed'),
       create_status(allow_failure: false, status: 'success'),
231 232 233
       create_status(allow_failure: false, status: 'failed'),
       create_status(allow_failure: true, status: 'manual'),
       create_status(allow_failure: false, status: 'manual')]
234 235 236
    end

    it 'returns statuses without what we want to ignore' do
237
      is_expected.to eq(statuses.values_at(0, 1, 2, 3, 4, 5, 6, 8, 9, 11))
238 239
    end
  end
240

241 242 243 244
  describe '.failed_but_allowed' do
    subject { described_class.failed_but_allowed.order(:id) }

    let(:statuses) do
245 246 247 248 249 250 251 252
      [create_status(allow_failure: true, status: 'success'),
       create_status(allow_failure: true, status: 'failed'),
       create_status(allow_failure: false, status: 'success'),
       create_status(allow_failure: false, status: 'failed'),
       create_status(allow_failure: true, status: 'canceled'),
       create_status(allow_failure: false, status: 'canceled'),
       create_status(allow_failure: true, status: 'manual'),
       create_status(allow_failure: false, status: 'manual')]
253 254 255 256 257 258 259
    end

    it 'returns statuses without what we want to ignore' do
      is_expected.to eq(statuses.values_at(1, 4))
    end
  end

260 261 262
  describe '#before_sha' do
    subject { commit_status.before_sha }

263 264
    context 'when no before_sha is set for pipeline' do
      before { pipeline.before_sha = nil }
265

266
      it 'returns blank sha' do
267 268 269 270
        is_expected.to eq(Gitlab::Git::BLANK_SHA)
      end
    end

271
    context 'for before_sha set for pipeline' do
272
      let(:value) { '1234' }
273
      before { pipeline.before_sha = value }
274

275
      it 'returns the set value' do
276 277 278 279 280
        is_expected.to eq(value)
      end
    end
  end

281 282 283 284 285
  describe '#commit' do
    it 'returns commit pipeline has been created for' do
      expect(commit_status.commit).to eq project.commit
    end
  end
Kamil Trzcinski committed
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

  describe '#group_name' do
    subject { commit_status.group_name }

    tests = {
      'rspec:windows' => 'rspec:windows',
      'rspec:windows 0' => 'rspec:windows 0',
      'rspec:windows 0 test' => 'rspec:windows 0 test',
      'rspec:windows 0 1' => 'rspec:windows',
      'rspec:windows 0 1 name' => 'rspec:windows name',
      'rspec:windows 0/1' => 'rspec:windows',
      'rspec:windows 0/1 name' => 'rspec:windows name',
      'rspec:windows 0:1' => 'rspec:windows',
      'rspec:windows 0:1 name' => 'rspec:windows name',
      'rspec:windows 10000 20000' => 'rspec:windows',
      'rspec:windows 0 : / 1' => 'rspec:windows',
      'rspec:windows 0 : / 1 name' => 'rspec:windows name',
303 304
      '0 1 name ruby' => 'name ruby',
      '0 :/ 1 name ruby' => 'name ruby'
Kamil Trzcinski committed
305 306 307 308 309 310 311 312 313 314
    }

    tests.each do |name, group_name|
      it "'#{name}' puts in '#{group_name}'" do
        commit_status.name = name

        is_expected.to eq(group_name)
      end
    end
  end
315 316 317 318 319 320 321 322 323

  describe '#detailed_status' do
    let(:user) { create(:user) }

    it 'returns a detailed status' do
      expect(commit_status.detailed_status(user))
        .to be_a Gitlab::Ci::Status::Success
    end
  end
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338

  describe '#sortable_name' do
    tests = {
      'karma' => ['karma'],
      'karma 0 20' => ['karma ', 0, ' ', 20],
      'karma 10 20' => ['karma ', 10, ' ', 20],
      'karma 50:100' => ['karma ', 50, ':', 100],
      'karma 1.10' => ['karma ', 1, '.', 10],
      'karma 1.5.1' => ['karma ', 1, '.', 5, '.', 1],
      'karma 1 a' => ['karma ', 1, ' a']
    }

    tests.each do |name, sortable_name|
      it "'#{name}' sorts as '#{sortable_name}'" do
        commit_status.name = name
339
        expect(commit_status.sortable_name).to eq(sortable_name)
340 341 342
      end
    end
  end
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378

  describe '#locking_enabled?' do
    before do
      commit_status.lock_version = 100
    end

    subject { commit_status.locking_enabled? }

    context "when changing status" do
      before do
        commit_status.status = "running"
      end

      it "lock" do
        is_expected.to be true
      end

      it "raise exception when trying to update" do
        expect{ commit_status.save }.to raise_error(ActiveRecord::StaleObjectError)
      end
    end

    context "when changing description" do
      before do
        commit_status.description = "test"
      end

      it "do not lock" do
        is_expected.to be false
      end

      it "save correctly" do
        expect(commit_status.save).to be true
      end
    end
  end
379
end