post_receive_spec.rb 8,0 КБ
Newer Older
Thong Kuah's avatar
Thong Kuah включено в состав коммита
1
2
# frozen_string_literal: true

Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
3
4
5
require 'spec_helper'

describe PostReceive do
Douwe Maan's avatar
Douwe Maan включено в состав коммита
6
7
8
  let(:changes) { "123456 789012 refs/heads/tést\n654321 210987 refs/tags/tag" }
  let(:wrongly_encoded_changes) { changes.encode("ISO-8859-1").force_encoding("UTF-8") }
  let(:base64_changes) { Base64.encode64(wrongly_encoded_changes) }
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
9
  let(:gl_repository) { "project-#{project.id}" }
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
10
  let(:key) { create(:key, user: project.owner) }
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
11
  let!(:key_id) { key.shell_id }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets включено в состав коммита
12

Lin Jen-Shin's avatar
Lin Jen-Shin включено в состав коммита
13
14
15
16
  let(:project) do
    create(:project, :repository, auto_cancel_pending_pipelines: 'disabled')
  end

Gabriel Mazetto's avatar
Gabriel Mazetto включено в состав коммита
17
  context "as a sidekiq worker" do
Lin Jen-Shin's avatar
Lin Jen-Shin включено в состав коммита
18
    it "responds to #perform" do
Robert Speicher's avatar
Robert Speicher включено в состав коммита
19
      expect(described_class.new).to respond_to(:perform)
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
20
21
22
    end
  end

Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
23
  context 'with a non-existing project' do
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
24
    let(:gl_repository) { "project-123456789" }
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
25
    let(:error_message) do
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
26
      "Triggered hook for non-existing project with gl_repository \"#{gl_repository}\""
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
27
28
29
30
    end

    it "returns false and logs an error" do
      expect(Gitlab::GitLogger).to receive(:error).with("POST-RECEIVE: #{error_message}")
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
31
      expect(described_class.new.perform(gl_repository, key_id, base64_changes)).to be(false)
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
32
33
34
    end
  end

Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
35
  describe "#process_project_changes" do
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
36
37
    context 'empty changes' do
      it "does not call any PushService but runs after project hooks" do
Nick Thomas's avatar
Nick Thomas включено в состав коммита
38
        expect(Git::BranchPushService).not_to receive(:new)
Nick Thomas's avatar
Nick Thomas включено в состав коммита
39
        expect(Git::TagPushService).not_to receive(:new)
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
40
41
42
43
        expect_next_instance_of(SystemHooksService) { |service| expect(service).to receive(:execute_hooks) }

        described_class.new.perform(gl_repository, key_id, "")
      end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
44
    end
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
45

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
46
47
48
49
    context 'unidentified user' do
      let!(:key_id) { "" }

      it 'returns false' do
Nick Thomas's avatar
Nick Thomas включено в состав коммита
50
        expect(Git::BranchPushService).not_to receive(:new)
Nick Thomas's avatar
Nick Thomas включено в состав коммита
51
        expect(Git::TagPushService).not_to receive(:new)
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
52
53
54
55
56

        expect(described_class.new.perform(gl_repository, key_id, base64_changes)).to be false
      end
    end

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
57
58
59
60
61
62
63
    context 'with changes' do
      before do
        allow_any_instance_of(Gitlab::GitPostReceive).to receive(:identify).and_return(project.owner)
      end

      context "branches" do
        let(:changes) { "123456 789012 refs/heads/tést" }
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
64

Nick Thomas's avatar
Nick Thomas включено в состав коммита
65
        it "calls Git::BranchPushService" do
Nick Thomas's avatar
Nick Thomas включено в состав коммита
66
67
68
69
70
71
          expect_next_instance_of(Git::BranchPushService) do |service|
            expect(service).to receive(:execute).and_return(true)
          end

          expect(Git::TagPushService).not_to receive(:new)

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
72
73
          described_class.new.perform(gl_repository, key_id, base64_changes)
        end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
74
75
      end

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
76
77
      context "tags" do
        let(:changes) { "123456 789012 refs/tags/tag" }
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
78

Nick Thomas's avatar
Nick Thomas включено в состав коммита
79
        it "calls Git::TagPushService" do
Nick Thomas's avatar
Nick Thomas включено в состав коммита
80
81
82
83
84
85
          expect(Git::BranchPushService).not_to receive(:execute)

          expect_next_instance_of(Git::TagPushService) do |service|
            expect(service).to receive(:execute).and_return(true)
          end

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
86
87
          described_class.new.perform(gl_repository, key_id, base64_changes)
        end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
88
89
      end

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
90
91
      context "merge-requests" do
        let(:changes) { "123456 789012 refs/merge-requests/123" }
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
92

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
93
        it "does not call any of the services" do
Nick Thomas's avatar
Nick Thomas включено в состав коммита
94
95
96
          expect(Git::BranchPushService).not_to receive(:new)
          expect(Git::TagPushService).not_to receive(:new)

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
97
98
          described_class.new.perform(gl_repository, key_id, base64_changes)
        end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
99
      end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
100

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
101
      context "gitlab-ci.yml" do
Kamil Trzciński's avatar
Kamil Trzciński включено в состав коммита
102
103
104
105
106
107
108
109
110
111
112
        let(:changes) do
          <<-EOF.strip_heredoc
            123456 789012 refs/heads/feature
            654321 210987 refs/tags/tag
            123456 789012 refs/heads/feature2
            123458 789013 refs/heads/feature3
            123459 789015 refs/heads/feature4
          EOF
        end

        let(:changes_count) { changes.lines.count }
Grzegorz Bizon's avatar
Grzegorz Bizon включено в состав коммита
113

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
114
        subject { described_class.new.perform(gl_repository, key_id, base64_changes) }
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
115

Kamil Trzciński's avatar
Kamil Trzciński включено в состав коммита
116
        context "with valid .gitlab-ci.yml" do
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
117
118
119
120
121
122
          before do
            stub_ci_pipeline_to_return_yaml_file

            allow_any_instance_of(Project)
              .to receive(:commit)
              .and_return(project.commit)
Grzegorz Bizon's avatar
Grzegorz Bizon включено в состав коммита
123

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
124
125
126
127
            allow_any_instance_of(Repository)
              .to receive(:branch_exists?)
              .and_return(true)
          end
Grzegorz Bizon's avatar
Grzegorz Bizon включено в состав коммита
128

Kamil Trzciński's avatar
Kamil Trzciński включено в состав коммита
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
          context 'when git_push_create_all_pipelines is disabled' do
            before do
              stub_feature_flags(git_push_create_all_pipelines: false)
            end

            it "creates pipeline for branches and tags" do
              subject

              expect(Ci::Pipeline.pluck(:ref)).to contain_exactly("feature", "tag", "feature2", "feature3")
            end

            it "creates exactly #{described_class::PIPELINE_PROCESS_LIMIT} pipelines" do
              expect(changes_count).to be > described_class::PIPELINE_PROCESS_LIMIT

              expect { subject }.to change { Ci::Pipeline.count }.by(described_class::PIPELINE_PROCESS_LIMIT)
            end
          end

          context 'when git_push_create_all_pipelines is enabled' do
            before do
              stub_feature_flags(git_push_create_all_pipelines: true)
            end

            it "creates all pipelines" do
              expect { subject }.to change { Ci::Pipeline.count }.by(changes_count)
            end
          end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
156
        end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
157

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
158
159
160
161
        context "does not create a Ci::Pipeline" do
          before do
            stub_ci_pipeline_yaml_file(nil)
          end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
162

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
163
          it { expect { subject }.not_to change { Ci::Pipeline.count } }
Robert Speicher's avatar
Robert Speicher включено в состав коммита
164
        end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
165
      end
Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
166

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
167
168
169
      context 'after project changes hooks' do
        let(:changes) { '123456 789012 refs/heads/tést' }
        let(:fake_hook_data) { Hash.new(event_name: 'repository_update') }
Gabriel Mazetto's avatar
Gabriel Mazetto включено в состав коммита
170

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
171
172
173
174
        before do
          allow_any_instance_of(Gitlab::DataBuilder::Repository).to receive(:update).and_return(fake_hook_data)
          # silence hooks so we can isolate
          allow_any_instance_of(Key).to receive(:post_create_hook).and_return(true)
Nick Thomas's avatar
Nick Thomas включено в состав коммита
175
176
177
          expect_next_instance_of(Git::BranchPushService) do |service|
            expect(service).to receive(:execute).and_return(true)
          end
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
178
        end
Gabriel Mazetto's avatar
Gabriel Mazetto включено в состав коммита
179

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
180
181
        it 'calls SystemHooksService' do
          expect_any_instance_of(SystemHooksService).to receive(:execute_hooks).with(fake_hook_data, :repository_update_hooks).and_return(true)
Gabriel Mazetto's avatar
Gabriel Mazetto включено в состав коммита
182

Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
183
184
          described_class.new.perform(gl_repository, key_id, base64_changes)
        end
Douglas Barbosa Alexandre's avatar
Douglas Barbosa Alexandre включено в состав коммита
185
      end
Gabriel Mazetto's avatar
Gabriel Mazetto включено в состав коммита
186
187
188
    end
  end

Douglas Barbosa Alexandre's avatar
Douglas Barbosa Alexandre включено в состав коммита
189
190
191
192
  describe '#process_wiki_changes' do
    let(:gl_repository) { "wiki-#{project.id}" }

    it 'updates project activity' do
Stan Hu's avatar
Stan Hu включено в состав коммита
193
194
      # Force Project#set_timestamps_for_create to initialize timestamps
      project
Douglas Barbosa Alexandre's avatar
Douglas Barbosa Alexandre включено в состав коммита
195

Stan Hu's avatar
Stan Hu включено в состав коммита
196
197
198
199
200
201
202
203
204
      # MySQL drops milliseconds in the timestamps, so advance at least
      # a second to ensure we see changes.
      Timecop.freeze(1.second.from_now) do
        expect do
          described_class.new.perform(gl_repository, key_id, base64_changes)
          project.reload
        end.to change(project, :last_activity_at)
           .and change(project, :last_repository_updated_at)
      end
Douglas Barbosa Alexandre's avatar
Douglas Barbosa Alexandre включено в состав коммита
205
206
207
    end
  end

Kamil Trzcinski's avatar
Kamil Trzcinski включено в состав коммита
208
  context "webhook" do
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
209
    it "fetches the correct project" do
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
210
      expect(Project).to receive(:find_by).with(id: project.id.to_s)
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
211
      described_class.new.perform(gl_repository, key_id, base64_changes)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets включено в состав коммита
212
    end
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
213

Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
214
    it "does not run if the author is not in the project" do
Grzegorz Bizon's avatar
Grzegorz Bizon включено в состав коммита
215
216
217
      allow_any_instance_of(Gitlab::GitPostReceive)
        .to receive(:identify_using_ssh_key)
        .and_return(nil)
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
218

Jeroen van Baarsen's avatar
Jeroen van Baarsen включено в состав коммита
219
      expect(project).not_to receive(:execute_hooks)
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
220

Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
221
      expect(described_class.new.perform(gl_repository, key_id, base64_changes)).to be_falsey
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
222
223
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets включено в состав коммита
224
    it "asks the project to trigger all hooks" do
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
225
      allow(Project).to receive(:find_by).and_return(project)
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
226

Douwe Maan's avatar
Douwe Maan включено в состав коммита
227
228
      expect(project).to receive(:execute_hooks).twice
      expect(project).to receive(:execute_services).twice
Paco Guzman's avatar
Paco Guzman включено в состав коммита
229

Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
230
      described_class.new.perform(gl_repository, key_id, base64_changes)
Paco Guzman's avatar
Paco Guzman включено в состав коммита
231
232
233
    end

    it "enqueues a UpdateMergeRequestsWorker job" do
Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
234
      allow(Project).to receive(:find_by).and_return(project)
Tiago Botelho's avatar
Tiago Botelho включено в состав коммита
235

Paco Guzman's avatar
Paco Guzman включено в состав коммита
236
      expect(UpdateMergeRequestsWorker).to receive(:perform_async).with(project.id, project.owner.id, any_args)
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
237

Alejandro Rodríguez's avatar
Alejandro Rodríguez включено в состав коммита
238
      described_class.new.perform(gl_repository, key_id, base64_changes)
Ariejan de Vroom's avatar
Ariejan de Vroom включено в состав коммита
239
240
241
    end
  end
end