summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/ci/config/external/context_spec.rb
blob: 610646ca85a74d0f93b0ab59959dc01dd11e0ac0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# frozen_string_literal: true

require 'fast_spec_helper'

describe Gitlab::Ci::Config::External::Context do
  let(:project) { double('Project') }
  let(:user) { double('User') }
  let(:sha) { '12345' }
  let(:attributes) { { project: project, user: user, sha: sha } }

  subject(:subject) { described_class.new(**attributes) }

  describe 'attributes' do
    context 'with values' do
      it { is_expected.to have_attributes(**attributes) }
      it { expect(subject.expandset).to eq(Set.new) }
      it { expect(subject.execution_deadline).to eq(0) }
    end

    context 'without values' do
      let(:attributes) { { project: nil, user: nil, sha: nil } }

      it { is_expected.to have_attributes(**attributes) }
      it { expect(subject.expandset).to eq(Set.new) }
      it { expect(subject.execution_deadline).to eq(0) }
    end
  end

  describe '#set_deadline' do
    let(:stubbed_time) { 1 }

    before do
      allow(subject).to receive(:current_monotonic_time).and_return(stubbed_time)
    end

    context 'with a float value' do
      let(:timeout_seconds) { 10.5.seconds }

      it 'updates execution_deadline' do
        expect { subject.set_deadline(timeout_seconds) }
          .to change { subject.execution_deadline }
          .to(timeout_seconds + stubbed_time)
      end
    end

    context 'with nil as a value' do
      let(:timeout_seconds) {}

      it 'updates execution_deadline' do
        expect { subject.set_deadline(timeout_seconds) }
          .to change { subject.execution_deadline }
          .to(stubbed_time)
      end
    end
  end

  describe '#check_execution_time!' do
    before do
      allow(subject).to receive(:current_monotonic_time).and_return(stubbed_time)
      allow(subject).to receive(:execution_deadline).and_return(stubbed_deadline)
    end

    context 'when execution is expired' do
      let(:stubbed_time) { 2 }
      let(:stubbed_deadline) { 1 }

      it 'raises an error' do
        expect { subject.check_execution_time! }
          .to raise_error(described_class::TimeoutError)
      end
    end

    context 'when execution is not expired' do
      let(:stubbed_time) { 1 }
      let(:stubbed_deadline) { 2 }

      it 'does not raises any errors' do
        expect { subject.check_execution_time! }.not_to raise_error
      end
    end

    context 'without setting a deadline' do
      let(:stubbed_time) { 2 }
      let(:stubbed_deadline) { 1 }

      before do
        allow(subject).to receive(:execution_deadline).and_call_original
      end

      it 'does not raises any errors' do
        expect { subject.check_execution_time! }.not_to raise_error
      end
    end
  end

  describe '#mutate' do
    shared_examples 'a mutated context' do
      let(:mutated) { subject.mutate(new_attributes) }

      before do
        subject.expandset << :a_file
        subject.set_deadline(15.seconds)
      end

      it { expect(mutated).not_to eq(subject) }
      it { expect(mutated).to be_a(described_class) }
      it { expect(mutated).to have_attributes(new_attributes) }
      it { expect(mutated.expandset).to eq(subject.expandset) }
      it { expect(mutated.execution_deadline).to eq(mutated.execution_deadline) }
    end

    context 'with attributes' do
      let(:new_attributes) { { project: double, user: double, sha: '56789' } }

      it_behaves_like 'a mutated context'
    end

    context 'without attributes' do
      let(:new_attributes) { {} }

      it_behaves_like 'a mutated context'
    end
  end

  describe '#sentry_payload' do
    it { expect(subject.sentry_payload).to match(a_hash_including(:project, :user)) }
  end
end