Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: E2E for prometheus #1325

Merged
merged 37 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9e6b770
E2E with prometheus
Matvey-Kuk Jul 3, 2024
653a8f3
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 3, 2024
69465b7
Cleanu
Matvey-Kuk Jul 3, 2024
2124006
Trying to kick the test to run
Matvey-Kuk Jul 3, 2024
b7b4f2a
Trying to kick tests...
Matvey-Kuk Jul 3, 2024
af0403c
Trying...
Matvey-Kuk Jul 3, 2024
8f8566d
Fix
Matvey-Kuk Jul 3, 2024
0c7d94c
More wait
Matvey-Kuk Jul 4, 2024
701158e
Merge branch 'main' into Matvey-Kuk/fix-1306
talboren Jul 7, 2024
68c348f
Merge branch 'main' into Matvey-Kuk/fix-1306
shahargl Jul 8, 2024
98a84f9
It can't be it...
Matvey-Kuk Jul 8, 2024
ae754f4
Waiting for the prometheus
Matvey-Kuk Jul 8, 2024
885a1ec
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 8, 2024
f56a63e
Wrong URL for prometheus...
Matvey-Kuk Jul 8, 2024
d350b93
Merge remote-tracking branch 'refs/remotes/origin/Matvey-Kuk/fix-1306…
Matvey-Kuk Jul 8, 2024
de6bca1
Localhost:9090?
Matvey-Kuk Jul 8, 2024
b9327ce
Try 5 times?
Matvey-Kuk Jul 9, 2024
e41d38d
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 9, 2024
c56df15
It can't be it
Matvey-Kuk Jul 9, 2024
0c4aba5
Upload some artifacts
Matvey-Kuk Jul 9, 2024
420ee63
prometheus-server-for-test-target
Matvey-Kuk Jul 9, 2024
f9800d5
Works?
Matvey-Kuk Jul 10, 2024
d94fdce
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 10, 2024
6cb6049
Fix test
Matvey-Kuk Jul 10, 2024
f3995f9
Meow please
Matvey-Kuk Jul 10, 2024
22c3b01
Frontend...
Matvey-Kuk Jul 10, 2024
33dd02c
Wrong context
Matvey-Kuk Jul 10, 2024
ba14588
Meow
Matvey-Kuk Jul 10, 2024
1941cb4
Un-meow
Matvey-Kuk Jul 10, 2024
826adc3
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 10, 2024
17e7db5
Un-sync process_event
Matvey-Kuk Jul 10, 2024
5ab2d88
Merge remote-tracking branch 'refs/remotes/origin/Matvey-Kuk/fix-1306…
Matvey-Kuk Jul 10, 2024
45b97be
isinstance(event, list):
Matvey-Kuk Jul 10, 2024
5494315
Drop test scope to make it reliable
Matvey-Kuk Jul 10, 2024
5b80253
??
Matvey-Kuk Jul 10, 2024
1014afb
Let's click, why not
Matvey-Kuk Jul 10, 2024
39d9733
Merge branch 'main' into Matvey-Kuk/fix-1306
Matvey-Kuk Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/test-pr-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
pull_request:
paths:
- 'keep/**'
- 'keep-ui/**'
- 'tests/**'

env:
PYTHON_VERSION: 3.11
Expand Down Expand Up @@ -142,8 +144,8 @@ jobs:
with:
name: test-artifacts
path: |
page_source_test1.html
page_source_test2.html
playwright_dump_*.html
playwright_dump_*.png
backend_logs-${{ matrix.db_type }}.txt
frontend_logs-${{ matrix.db_type }}.txt
continue-on-error: true
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,6 @@ docs/node_modules/


scripts/automatic_extraction_rules.py
page_source_test*.html

playwright_dump_*.html
playwright_dump_*.png
1 change: 1 addition & 0 deletions keep-ui/app/alerts/alert-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export default function AlertMenu({
icon={EllipsisHorizontalIcon}
className="hover:bg-gray-100"
color="gray"
title="Alert actions"
/>
</Menu.Button>
{isMenuOpen && (
Expand Down
8 changes: 6 additions & 2 deletions keep/providers/prometheus_provider/prometheus_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,15 @@ def get_status(event: dict) -> AlertStatus:

@staticmethod
def _format_alert(
event: dict, provider_instance: Optional["PrometheusProvider"] = None
event: dict | list[AlertDto], provider_instance: Optional["PrometheusProvider"] = None
) -> list[AlertDto]:
# TODO: need to support more than 1 alert per event
alert_dtos = []
alerts = event.get("alerts", [event])
if isinstance(event, list):
return event
else:
alerts = event.get("alerts", [event])

for alert in alerts:
alert_id = alert.get("id", alert.get("labels", {}).get("alertname"))
description = alert.get("annotations", {}).pop(
Expand Down
10 changes: 9 additions & 1 deletion tests/e2e_tests/docker-compose-e2e-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
file: docker-compose.common.yml
service: keep-frontend-common
build:
context: ./keep-ui
context: ./keep-ui/
dockerfile: ../docker/Dockerfile.ui
environment:
- AUTH_TYPE=NO_AUTH
Expand Down Expand Up @@ -50,5 +50,13 @@ services:
file: docker-compose.common.yml
service: keep-websocket-server-common

prometheus-server-for-test-target:
image: prom/prometheus
volumes:
- ./tests/e2e_tests/test_pushing_prometheus_config.yaml:/etc/prometheus/prometheus.yml
- ./tests/e2e_tests/test_pushing_prometheus_rules.yaml:/etc/prometheus/test_pushing_prometheus_rules.yaml
ports:
- "9090:9090"

volumes:
mysql-data:
13 changes: 11 additions & 2 deletions tests/e2e_tests/docker-compose-e2e-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ services:
extends:
file: docker-compose.common.yml
service: keep-frontend-common
image:
us-central1-docker.pkg.dev/keephq/keep/keep-ui
build:
Matvey-Kuk marked this conversation as resolved.
Show resolved Hide resolved
context: ./keep-ui/
dockerfile: ../docker/Dockerfile.ui
environment:
- AUTH_TYPE=NO_AUTH
- API_URL=http://keep-backend:8080
Expand Down Expand Up @@ -46,5 +47,13 @@ services:
file: docker-compose.common.yml
service: keep-websocket-server-common

prometheus-server-for-test-target:
image: prom/prometheus
volumes:
- ./tests/e2e_tests/test_pushing_prometheus_config.yaml:/etc/prometheus/prometheus.yml
- ./tests/e2e_tests/test_pushing_prometheus_rules.yaml:/etc/prometheus/test_pushing_prometheus_rules.yaml
ports:
- "9090:9090"

volumes:
postgres-data:
28 changes: 17 additions & 11 deletions tests/e2e_tests/test_end_to_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# - Spin up the environment using docker-compose.
# - Run "playwright codegen localhost:3000"
# - Copy the generated code to a new test function.
import re
import re, os, sys
import string

# Running the tests in GitHub Actions:
Expand Down Expand Up @@ -64,11 +64,14 @@ def test_insert_new_alert(browser):
browser.reload()
browser.get_by_text("1", exact=True).click()
except Exception:
# Capture a screenshot on failure
# browser.screenshot(path="screenshot-test1.png")

# Save the page source on failure
with open("page_source_test1.html", "w") as f:
# Current file + test name for unique html and png dump.
current_test_name = \
"playwright_dump_" + \
os.path.basename(__file__)[:-3] + \
"_" + sys._getframe().f_code.co_name

browser.screenshot(path=current_test_name + ".png")
with open(current_test_name + ".html", "w") as f:
f.write(browser.content())
raise

Expand Down Expand Up @@ -105,10 +108,13 @@ def test_providers_page_is_accessible(browser):
# make sure the provider is connected
browser.get_by_text(f"resend id: {random_provider_name}").click()
except Exception:
# Capture a screenshot on failure
# browser.screenshot(path="screenshot-test2.png")

# Save the page source on failure
with open("page_source_test2.html", "w") as f:
# Current file + test name for unique html and png dump.
current_test_name = \
"playwright_dump_" + \
os.path.basename(__file__)[:-3] + \
"_" + sys._getframe().f_code.co_name

browser.screenshot(path=current_test_name + ".png")
with open(current_test_name + ".html", "w") as f:
f.write(browser.content())
raise
83 changes: 83 additions & 0 deletions tests/e2e_tests/test_pushing_prometheus_alerts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import re, os, sys, time
import requests

from datetime import datetime
from playwright.sync_api import expect

# Dear developer, thank you for checking E2E tests!
# For instructions, please check test_end_to_end.py.

os.environ["PLAYWRIGHT_HEADLESS"] = "false"

def test_pulling_prometheus_alerts_to_provider(browser):
try:
provider_name = "playwright_test_" + datetime.now().strftime("%Y%m%d%H%M%S")

# Wait for prometheus to wake up and evaluate alert rule as "firing"
alerts = None
while alerts is None or \
len(alerts["data"]["alerts"]) == 0 or \
alerts["data"]["alerts"][0]['state'] != "firing":
print("Waiting for prometheus to fire an alert...")
time.sleep(1)
alerts = requests.get("http://localhost:9090/api/v1/alerts").json()
print(alerts)

# Create prometheus provider
browser.goto("http://localhost:3000/providers")
browser.get_by_placeholder("Filter providers...").click()
browser.get_by_placeholder("Filter providers...").fill("prometheus")
browser.get_by_placeholder("Filter providers...").press("Enter")
browser.get_by_text("Available Providers").hover()
browser.locator("div").filter(has_text=re.compile(r"^prometheus dataalertConnect$")).nth(1).hover()

browser.get_by_role("button", name="Connect").click()
browser.get_by_placeholder("Enter provider name").click()
browser.get_by_placeholder("Enter provider name").fill(provider_name)
browser.get_by_placeholder("Enter url").click()

if os.getenv("GITHUB_ACTIONS") == "true":
browser.get_by_placeholder("Enter url").fill("http://prometheus-server-for-test-target:9090/")
else:
browser.get_by_placeholder("Enter url").fill("http://localhost:9090/")

browser.mouse.wheel(1000, 10000) # Scroll down.
browser.get_by_role("button", name="Connect").click()


# Validate provider is created
expect(browser.locator("div").filter(has_text=re.compile(re.escape(provider_name))).first).to_be_visible()

browser.reload()

# Check if alerts were pulled
for i in range(0, 5):
browser.get_by_role("link", name="Feed").click()
browser.wait_for_timeout(5000) # Wait for alerts to be loaded

browser.reload()

# Make sure we pulled multiple instances of the alert
browser.get_by_text("AlwaysFiringAlert").click()

# Delete provider
browser.get_by_role("link", name="Providers").click()
browser.locator("div").filter(has_text=re.compile(re.escape(provider_name))).first.hover()
browser.locator(".tile-basis").first.click()
browser.once("dialog", lambda dialog: dialog.accept())
browser.get_by_role("button", name="Delete").click()

# Assert provider was deleted
expect(browser.locator("div").filter(has_text=re.compile(re.escape(provider_name))).first).not_to_be_visible()
except Exception:
# Current file + test name for unique html and png dump.
current_test_name = \
"playwright_dump_" + \
os.path.basename(__file__)[:-3] + \
"_" + sys._getframe().f_code.co_name

browser.screenshot(path=current_test_name + ".png")
with open(current_test_name + ".html", "w") as f:
f.write(browser.content())

raise
12 changes: 12 additions & 0 deletions tests/e2e_tests/test_pushing_prometheus_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# my global config
global:
scrape_interval: 1s
evaluation_interval: 1s

rule_files:
- "test_pushing_prometheus_rules.yaml"

scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
10 changes: 10 additions & 0 deletions tests/e2e_tests/test_pushing_prometheus_rules.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
groups:
- name: example
rules:
- alert: AlwaysFiringAlert
expr: rate(prometheus_http_requests_total{}[1m]) > 0
for: 1s
labels:
severity: page
annotations:
summary: Unless mathematics has changed, this alert should always fire.
Loading