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
129
130
131
132
133
134
|
# frozen_string_literal: true
module QA
RSpec.shared_examples 'notifies on a pipeline' do |exit_code|
before do
push_commit(exit_code: exit_code)
end
it 'sends an email' do
meta = exit_code_meta(exit_code)
project.visit!
Flow::Pipeline.wait_for_latest_pipeline(status: meta[:status])
messages = mail_hog_messages(mail_hog)
subjects = messages.map(&:subject)
targets = messages.map(&:to)
aggregate_failures do
expect(subjects).to include(meta[:email_subject])
expect(subjects).to include(/#{Regexp.escape(project.name)}/)
expect(targets).to include(*emails)
end
end
end
RSpec.describe 'Manage', :orchestrated, :runner, :requires_admin, :smtp, product_group: :integrations do
describe 'Pipeline status emails' do
let(:executor) { "qa-runner-#{Time.now.to_i}" }
let(:emails) { %w[foo@bar.com baz@buzz.com] }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipeline-status-project'
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.project = project
runner.name = executor
runner.tags = [executor]
end
end
let(:mail_hog) { Vendor::MailHog::API.new }
before(:all) do
Runtime::ApplicationSettings.set_application_settings(allow_local_requests_from_web_hooks_and_services: true)
end
before do
setup_pipeline_emails(emails)
end
describe 'when pipeline passes', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366240' do
include_examples 'notifies on a pipeline', 0
end
describe 'when pipeline fails', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/366241' do
include_examples 'notifies on a pipeline', 1
end
def push_commit(exit_code: 0)
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
commit.add_files(
[
{
file_path: '.gitlab-ci.yml',
content: gitlab_ci_yaml(exit_code: exit_code)
}
]
)
end
end
def setup_pipeline_emails(emails)
page.visit Runtime::Scenario.gitlab_address
Flow::Login.sign_in_unless_signed_in
project.visit!
Page::Project::Menu.perform(&:go_to_integrations_settings)
QA::Page::Project::Settings::Integrations.perform(&:click_pipelines_email_link)
QA::Page::Project::Settings::Services::PipelineStatusEmails.perform do |pipeline_status_emails|
pipeline_status_emails.toggle_notify_broken_pipelines # notify on pass and fail
pipeline_status_emails.set_recipients(emails)
pipeline_status_emails.click_save_button
end
end
def gitlab_ci_yaml(exit_code: 0, tag: executor)
<<~YAML
test-pipeline-email:
tags:
- #{tag}
script: sleep 5; exit #{exit_code};
YAML
end
private
def exit_code_meta(exit_code)
{
0 => { status: 'passed', email_subject: /Successful pipeline/ },
1 => { status: 'failed', email_subject: /Failed pipeline/ }
}[exit_code]
end
def mail_hog_messages(mail_hog_api)
Support::Retrier.retry_until(sleep_interval: 1) do
Runtime::Logger.debug('Fetching email...')
messages = mail_hog_api.fetch_messages
logs = messages.map { |m| "#{m.to}: #{m.subject}" }
Runtime::Logger.debug("MailHog Logs: #{logs.join("\n")}")
# for failing pipelines we have three messages
# one for the owner
# and one for each recipient
messages if mail_hog_pipeline_count(messages) >= 2
end
end
def mail_hog_pipeline_count(messages)
messages.count { |message| message.subject.include?('pipeline') }
end
end
end
end
|