Commit c1ea9151 authored by Dan Davison's avatar Dan Davison

Merge branch 'incidents-e2e-test' into 'master'

Incidents e2e test

See merge request gitlab-org/gitlab!28436
parents a2d3d7b3 7ab55880
...@@ -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' }
...@@ -263,6 +263,8 @@ module QA ...@@ -263,6 +263,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