Commit 7ab55880 authored by Sofia Vistas's avatar Sofia Vistas Committed by Dan Davison

Add e2e test for incidents management

Add runner to the test

Fix test structure and logic
parent e47f8abd
...@@ -345,6 +345,7 @@ export default { ...@@ -345,6 +345,7 @@ export default {
ref="copyChartLink" ref="copyChartLink"
v-track-event="generateLinkToChartOptions(clipboardText)" v-track-event="generateLinkToChartOptions(clipboardText)"
:data-clipboard-text="clipboardText" :data-clipboard-text="clipboardText"
data-qa-selector="generate_chart_link_menu_item"
@click="showToast(clipboardText)" @click="showToast(clipboardText)"
> >
{{ __('Copy link to chart') }} {{ __('Copy link to chart') }}
......
...@@ -203,7 +203,7 @@ ...@@ -203,7 +203,7 @@
- if project_nav_tab? :operations - if project_nav_tab? :operations
= nav_link(controller: sidebar_operations_paths) do = nav_link(controller: sidebar_operations_paths) do
= link_to sidebar_operations_link_path, class: 'shortcuts-operations qa-link-operations' do = link_to sidebar_operations_link_path, class: 'shortcuts-operations', data: { qa_selector: 'operations_link' } do
.nav-icon-container .nav-icon-container
= sprite_icon('cloud-gear') = sprite_icon('cloud-gear')
%span.nav-item-name %span.nav-item-name
...@@ -375,7 +375,7 @@ ...@@ -375,7 +375,7 @@
= _('CI / CD') = _('CI / CD')
- if !@project.archived? && settings_operations_available? - if !@project.archived? && settings_operations_available?
= nav_link(controller: [:operations]) do = nav_link(controller: [:operations]) do
= link_to project_settings_operations_path(@project), title: _('Operations') do = link_to project_settings_operations_path(@project), title: _('Operations'), data: { qa_selector: 'operations_settings_link' } do
= _('Operations') = _('Operations')
- if @project.pages_available? - if @project.pages_available?
= nav_link(controller: :pages) do = nav_link(controller: :pages) do
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- setting = project_incident_management_setting - setting = project_incident_management_setting
- templates = setting.available_issue_templates.map { |t| [t.name, t.key] } - templates = setting.available_issue_templates.map { |t| [t.name, t.key] }
%section.settings.no-animate.qa-incident-management-settings %section.settings.no-animate.qa-incident-management-settings{ data: { qa_selector: 'incidents_settings_content' } }
.settings-header .settings-header
%h3{ :class => "h4" }= _('Incidents') %h3{ :class => "h4" }= _('Incidents')
%button.btn.js-settings-toggle{ type: 'button' } %button.btn.js-settings-toggle{ type: 'button' }
...@@ -17,16 +17,16 @@ ...@@ -17,16 +17,16 @@
.form-group .form-group
= f.fields_for :incident_management_setting_attributes, setting do |form| = f.fields_for :incident_management_setting_attributes, setting do |form|
.form-group .form-group
= form.check_box :create_issue = form.check_box :create_issue, data: { qa_selector: 'create_issue_checkbox' }
= form.label :create_issue, _('Create an issue. Issues are created for each alert triggered.'), class: 'form-check-label' = form.label :create_issue, _('Create an issue. Issues are created for each alert triggered.'), class: 'form-check-label'
.form-group.col-sm-8 .form-group.col-sm-8
= form.label :issue_template_key, class: 'label-bold' do = form.label :issue_template_key, class: 'label-bold' do
= _('Issue template (optional)') = _('Issue template (optional)')
= link_to icon('question-circle'), help_page_path('user/project/description_templates', anchor: 'creating-issue-templates'), target: '_blank', rel: 'noopener noreferrer' = link_to icon('question-circle'), help_page_path('user/project/description_templates', anchor: 'creating-issue-templates'), target: '_blank', rel: 'noopener noreferrer'
.select-wrapper .select-wrapper
= form.select :issue_template_key, templates, {include_blank: 'No template selected'}, class: "form-control select-control" = form.select :issue_template_key, templates, {include_blank: 'No template selected'}, class: "form-control select-control", data: { qa_selector: 'incident_templates_dropdown' }
= icon('chevron-down') = icon('chevron-down')
.form-group .form-group
= form.check_box :send_email = form.check_box :send_email
= form.label :send_email, _('Send a separate email notification to Developers.'), class: 'form-check-label' = form.label :send_email, _('Send a separate email notification to Developers.'), class: 'form-check-label'
= f.submit _('Save changes'), class: 'btn btn-success' = f.submit _('Save changes'), class: 'btn btn-success', data: { qa_selector: 'save_changes_button' }
...@@ -262,6 +262,8 @@ module QA ...@@ -262,6 +262,8 @@ module QA
autoload :Members, 'qa/page/project/settings/members' autoload :Members, 'qa/page/project/settings/members'
autoload :MirroringRepositories, 'qa/page/project/settings/mirroring_repositories' autoload :MirroringRepositories, 'qa/page/project/settings/mirroring_repositories'
autoload :VisibilityFeaturesPermissions, 'qa/page/project/settings/visibility_features_permissions' autoload :VisibilityFeaturesPermissions, 'qa/page/project/settings/visibility_features_permissions'
autoload :Operations, 'qa/page/project/settings/operations'
autoload :Incidents, 'qa/page/project/settings/incidents'
end end
module SubMenus module SubMenus
......
...@@ -22,10 +22,12 @@ variables: ...@@ -22,10 +22,12 @@ variables:
stages: stages:
- production - production
# This job continuously deploys to staging/production on every push to `master`. # This job continuously deploys to production on every push to `master`.
production: production:
stage: production stage: production
tags:
- qa
script: script:
- check_kube_domain - check_kube_domain
- install_dependencies - install_dependencies
...@@ -34,7 +36,6 @@ production: ...@@ -34,7 +36,6 @@ production:
- initialize_tiller - initialize_tiller
- create_secret - create_secret
- deploy - deploy
- persist_environment_url
environment: environment:
name: production name: production
url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN url: http://$CI_PROJECT_PATH_SLUG.$AUTO_DEVOPS_DOMAIN
......
...@@ -17,6 +17,10 @@ module QA ...@@ -17,6 +17,10 @@ module QA
def has_cluster?(cluster) def has_cluster?(cluster)
has_element?(:cluster, cluster_name: cluster.to_s) has_element?(:cluster, cluster_name: cluster.to_s)
end end
def click_on_cluster(cluster)
click_on cluster.cluster_name
end
end end
end end
end end
......
...@@ -25,6 +25,7 @@ module QA ...@@ -25,6 +25,7 @@ module QA
element :prometheus_graph_widgets element :prometheus_graph_widgets
element :prometheus_widgets_dropdown element :prometheus_widgets_dropdown
element :alert_widget_menu_item element :alert_widget_menu_item
element :generate_chart_link_menu_item
end end
def wait_for_metrics def wait_for_metrics
...@@ -72,6 +73,11 @@ module QA ...@@ -72,6 +73,11 @@ module QA
end end
end end
def copy_link_to_first_chart
all_elements(:prometheus_widgets_dropdown, minimum: 1).first.click
find_element(:generate_chart_link_menu_item)['data-clipboard-text']
end
private private
def wait_for_data def wait_for_data
......
# frozen_string_literal: true
module QA
module Page
module Project
module Settings
class Incidents < Page::Base
view 'app/views/projects/settings/operations/_incidents.html.haml' do
element :create_issue_checkbox
element :incident_templates_dropdown
element :save_changes_button
end
def enable_issues_for_incidents
check_element :create_issue_checkbox
end
def select_issue_template(template)
within_element :incident_templates_dropdown do
find(:option, template).select_option
end
end
def save_incident_settings
click_element :save_changes_button
end
def has_template?(template)
within_element :incident_templates_dropdown do
has_text?(template)
end
end
end
end
end
end
end
# frozen_string_literal: true
module QA
module Page
module Project
module Settings
class Operations < Page::Base
include Common
view 'app/views/projects/settings/operations/_incidents.html.haml' do
element :incidents_settings_content
end
def expand_incidents(&block)
expand_section(:incidents_settings_content) do
Settings::Incidents.perform(&block)
end
end
end
end
end
end
end
...@@ -10,7 +10,7 @@ module QA ...@@ -10,7 +10,7 @@ module QA
def self.included(base) def self.included(base)
base.class_eval do base.class_eval do
view 'app/views/layouts/nav/sidebar/_project.html.haml' do view 'app/views/layouts/nav/sidebar/_project.html.haml' do
element :link_operations element :operations_link
element :operations_environments_link element :operations_environments_link
element :operations_metrics_link element :operations_metrics_link
end end
...@@ -45,8 +45,8 @@ module QA ...@@ -45,8 +45,8 @@ module QA
def hover_operations def hover_operations
within_sidebar do within_sidebar do
scroll_to_element(:link_operations) scroll_to_element(:operations_link)
find_element(:link_operations).hover find_element(:operations_link).hover
yield yield
end end
......
...@@ -14,6 +14,7 @@ module QA ...@@ -14,6 +14,7 @@ module QA
element :link_members_settings element :link_members_settings
element :general_settings_link element :general_settings_link
element :integrations_settings_link element :integrations_settings_link
element :operations_settings_link
end end
end end
end end
...@@ -64,6 +65,14 @@ module QA ...@@ -64,6 +65,14 @@ module QA
end end
end end
def go_to_operations_settings
hover_settings do
within_submenu do
click_element :operations_settings_link
end
end
end
private private
def hover_settings def hover_settings
......
...@@ -2,21 +2,39 @@ ...@@ -2,21 +2,39 @@
module QA module QA
context 'Monitor' do context 'Monitor' do
describe 'Alerts', :orchestrated, :kubernetes do describe 'with Prometheus Gitlab-managed cluster', :orchestrated, :kubernetes, :docker do
before do before :all do
@cluster = Service::KubernetesCluster.new.create! @cluster = Service::KubernetesCluster.new.create!
Flow::Login.sign_in
@project, @runner = deploy_project_with_prometheus
end end
after do after :all do
@runner.remove_via_api!
@cluster&.remove! @cluster&.remove!
end end
before do
Flow::Login.sign_in_unless_signed_in
@project.visit!
end
it 'configures custom metrics' do
Page::Project::Menu.perform(&:go_to_operations_metrics)
Page::Project::Operations::Metrics::Show.perform do |metrics|
metrics.add_custom_metric
end
Page::Project::Menu.perform(&:go_to_operations_metrics)
Page::Project::Operations::Metrics::Show.perform do |metrics|
expect(metrics).to have_custom_metric
end
end
it 'allows configuration of alerts' do it 'allows configuration of alerts' do
Flow::Login.sign_in Page::Project::Menu.perform(&:go_to_operations_metrics)
project = create_project
create_kubernetes_cluster(project, @cluster)
push_repository(project)
wait_for_deployment
Page::Project::Operations::Metrics::Show.perform do |metrics| Page::Project::Operations::Metrics::Show.perform do |metrics|
verify_metrics(metrics) verify_metrics(metrics)
...@@ -27,46 +45,77 @@ module QA ...@@ -27,46 +45,77 @@ module QA
end end
end end
private it 'observes cluster health graph' do
Page::Project::Menu.perform(&:go_to_operations_kubernetes)
Page::Project::Operations::Kubernetes::Index.perform do |cluster|
cluster.click_on_cluster(@cluster)
end
Page::Project::Operations::Kubernetes::Show.perform do |cluster|
cluster.open_health
cluster.wait_for_cluster_health
end
end
it 'creates and sets an incident template' do
create_incident_template
Page::Project::Menu.perform(&:go_to_operations_settings)
def create_project Page::Project::Settings::Operations.perform do |settings|
Resource::Project.fabricate_via_api! do |p| settings.expand_incidents do |incident_settings|
p.name = 'alerts' incident_settings.enable_issues_for_incidents
p.description = 'Project with alerting configured' incident_settings.select_issue_template('incident')
incident_settings.save_incident_settings
end
settings.expand_incidents do |incident_settings|
expect(incident_settings).to have_template('incident')
end
end
end end
private
def deploy_project_with_prometheus
project = Resource::Project.fabricate_via_api! do |project|
project.name = 'cluster-with-prometheus'
project.description = 'Cluster with Prometheus'
end end
def create_kubernetes_cluster(project, cluster) runner = Resource::Runner.fabricate_via_api! do |runner|
Resource::KubernetesCluster::ProjectCluster.fabricate_via_browser_ui! do |c| runner.project = project
c.project = project runner.name = project.name
c.cluster = cluster
c.install_helm_tiller = true
c.install_prometheus = true
c.install_runner = true
end end
cluster_props = Resource::KubernetesCluster::ProjectCluster.fabricate! do |cluster|
cluster.project = project
cluster.cluster = @cluster
cluster.install_helm_tiller = true
cluster.install_ingress = true
cluster.install_prometheus = true
end end
def push_repository(project)
Resource::Repository::ProjectPush.fabricate! do |push| Resource::Repository::ProjectPush.fabricate! do |push|
push.project = project push.project = project
push.directory = Pathname push.directory = Pathname
.new(__dir__) .new(__dir__)
.join('../../../../../../fixtures/monitored_auto_devops') .join('../../../../../fixtures/monitored_auto_devops')
push.commit_message = 'Create Auto DevOps compatible gitlab-ci.yml' push.commit_message = 'Create AutoDevOps compatible Project for Monitoring'
end end
Resource::CiVariable.fabricate_via_api! do |resource| Resource::CiVariable.fabricate_via_api! do |ci_variable|
resource.project = project ci_variable.project = project
resource.key = 'AUTO_DEVOPS_DOMAIN' ci_variable.key = 'AUTO_DEVOPS_DOMAIN'
resource.value = 'my-fake-domain.com' ci_variable.value = cluster_props.ingress_ip
resource.masked = false ci_variable.masked = false
end
end end
def wait_for_deployment
Page::Project::Menu.perform(&:click_ci_cd_pipelines) Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success_or_retry) Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success_or_retry)
Page::Project::Menu.perform(&:go_to_operations_metrics)
[project, runner]
end end
def verify_metrics(metrics) def verify_metrics(metrics)
...@@ -101,6 +150,31 @@ module QA ...@@ -101,6 +150,31 @@ module QA
expect(metrics).not_to have_alert('<') expect(metrics).not_to have_alert('<')
end end
def create_incident_template
Page::Project::Menu.perform(&:go_to_operations_metrics)
@chart_link = Page::Project::Operations::Metrics::Show.perform do |metric|
metric.wait_for_metrics
metric.copy_link_to_first_chart
end
incident_template = "Incident Metric: #{@chart_link}"
push_template_to_repository(incident_template)
end
def push_template_to_repository(template)
@project.visit!
Page::Project::Show.perform(&:create_new_file!)
Page::File::Form.perform do |form|
form.add_name('.gitlab/issue_templates/incident.md')
form.add_content(template)
form.add_commit_message('Add Incident template')
form.commit_changes
end
end
end end
end end
end end
# frozen_string_literal: true
module QA
context 'Monitor' do
describe 'Metrics with Prometheus', :orchestrated, :kubernetes, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28436', type: :waiting_on } do
before do
@cluster = Service::KubernetesCluster.new.create!
Flow::Login.sign_in
create_project_to_monitor
wait_for_deployment
end
after do
@cluster&.remove!
end
it 'configures custom metrics in Prometheus running on a Kubernetes cluster' do
Page::Project::Operations::Metrics::Show.perform do |metrics|
metrics.add_custom_metric
end
Page::Project::Menu.perform(&:go_to_operations_metrics)
Page::Project::Operations::Metrics::Show.perform do |metrics|
expect(metrics).to have_custom_metric
end
end
private
def wait_for_deployment
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success_or_retry)
Page::Project::Menu.perform(&:go_to_operations_metrics)
end
def create_project_to_monitor
@project = Resource::Project.fabricate_via_api! do |p|
p.name = 'cluster-with-prometheus'
p.description = 'Cluster with Prometheus'
end
@cluster_props = Resource::KubernetesCluster::ProjectCluster.fabricate_via_browser_ui! do |c|
c.project = @project
c.cluster = @cluster
c.install_helm_tiller = true
c.install_prometheus = true
c.install_ingress = true
end
Resource::CiVariable.fabricate_via_api! do |resource|
resource.project = @project
resource.key = 'AUTO_DEVOPS_DOMAIN'
resource.value = @cluster_props.ingress_ip
resource.masked = false
end
Resource::Repository::ProjectPush.fabricate! do |push|
push.project = @project
push.directory = Pathname
.new(__dir__)
.join('../../../../../../fixtures/monitored_auto_devops')
push.commit_message = 'Create AutoDevOps compatible Project for Monitoring'
end
end
end
end
end
# frozen_string_literal: true
module QA
context 'Monitor' do
describe 'Cluster health graphs', :orchestrated, :kubernetes do
before do
@cluster = Service::KubernetesCluster.new.create!
end
after do
@cluster&.remove!
end
it 'installs Kubernetes and Prometheus' do
Flow::Login.sign_in
create_project
create_kubernetes_cluster
verify_cluster_health_graphs
end
private
def create_project
@project = Resource::Project.fabricate_via_api! do |p|
p.name = 'cluster-health'
p.description = 'Cluster health'
end
end
def create_kubernetes_cluster
Resource::KubernetesCluster::ProjectCluster.fabricate_via_browser_ui! do |c|
c.project = @project
c.cluster = @cluster
c.install_helm_tiller = true
c.install_prometheus = true
end
end
def verify_cluster_health_graphs
Page::Project::Operations::Kubernetes::Show.perform do |cluster|
cluster.refresh
cluster.open_health
cluster.wait_for_cluster_health
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment