Skip to content

Commit

Permalink
Introduce UI tests focusing on scans
Browse files Browse the repository at this point in the history
Introduce UI tests that take advantage of cached scans result and
download scans that already exist. They are very similar to existing end
to end tests.

The intent is that new scan tests are going to run only in PR check, to
speed things up. Old end to end tests are going to be run in nightly
pipeline, where execution speed is less of a concern. Since new scan
tests are very much included in old end to end tests, only one of them
should be executed in any given run.
  • Loading branch information
mirekdlugosz committed Jun 28, 2024
1 parent 1791886 commit 75ab416
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 33 deletions.
39 changes: 7 additions & 32 deletions camayoc/tests/qpc/ui/test_endtoend.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@
"""

import random
import shutil
import tarfile
import tempfile
from pathlib import Path

import pytest

from camayoc.config import settings
from camayoc.qpc_models import Scan
from camayoc.tests.qpc.utils import calculate_sha256sums
from camayoc.tests.qpc.utils import get_expected_sha256sums
from camayoc.tests.qpc.utils import assert_ansible_logs
from camayoc.tests.qpc.utils import assert_sha256sums
from camayoc.types.ui import AddCredentialDTO
from camayoc.types.ui import AddSourceDTO
from camayoc.ui import Client
Expand Down Expand Up @@ -63,8 +60,9 @@ def source_names():
yield pytest.param(source_definition.name, id=fixture_id)


@pytest.mark.nightly_only
@pytest.mark.parametrize("source_name", source_names())
def test_end_to_end(cleaning_data_provider, ui_client: Client, source_name):
def test_end_to_end(tmp_path, cleaning_data_provider, ui_client: Client, source_name):
"""End-to-end test using web user interface.
:id: f187fbd0-021c-4563-9691-61e54eb272bf
Expand Down Expand Up @@ -98,33 +96,10 @@ def test_end_to_end(cleaning_data_provider, ui_client: Client, source_name):

is_network_scan = source_dto.select_source_type.source_type == SourceTypes.NETWORK_RANGE
downloaded_report = ui_client.downloaded_files[-1]
report_directory = Path(tempfile.mkdtemp(prefix="camayoc"))
report_file = report_directory / downloaded_report.suggested_filename
shutil.copy(downloaded_report.path(), report_file)
tarfile.open(report_file).extractall(report_directory)
actual_shasums = calculate_sha256sums(report_directory)
expected_shasums = get_expected_sha256sums(report_directory)

for filename, expected_shasum in expected_shasums.items():
actual_shasum = actual_shasums.get(filename)
assert actual_shasum == expected_shasum

has_ansible_logs = False
for file in report_directory.rglob("*"):
if not file.is_file():
continue

# Ansible STDERR may or may not be empty, no point in asserting size
if "ansible-stderr" in file.name:
has_ansible_logs = True
continue

if "ansible-stdout" in file.name:
has_ansible_logs = True

assert file.stat().st_size > 0

assert is_network_scan == has_ansible_logs
tarfile.open(downloaded_report.path()).extractall(tmp_path)
assert_sha256sums(tmp_path)
assert_ansible_logs(tmp_path, is_network_scan)


@pytest.mark.skip("Skipped due to intermittent failure - DISCOVERY-426")
Expand Down
66 changes: 66 additions & 0 deletions camayoc/tests/qpc/ui/test_scans.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Web user interface scan tests.
:caseautomation: automated
:casecomponent: ui
:caseimportance: medium
:caselevel: integration
:testtype: functional
"""

import tarfile

import pytest

from camayoc.config import settings
from camayoc.tests.qpc.utils import assert_ansible_logs
from camayoc.tests.qpc.utils import assert_sha256sums
from camayoc.ui import Client
from camayoc.ui import data_factories
from camayoc.ui.enums import MainMenuPages


def has_network_source(scan_name):
network_sources = set([source.name for source in settings.sources if source.type == "network"])
for scan_definition in settings.scans:
if scan_definition.name != scan_name:
continue
scan_sources = set(scan_definition.sources)
return bool(network_sources.intersection(scan_sources))


def scan_names():
for scan_definition in settings.scans:
yield pytest.param(scan_definition.name)


@pytest.mark.pr_only
@pytest.mark.parametrize("scan_name", scan_names())
def test_download_scan(tmp_path, scans, ui_client: Client, scan_name):
"""Download finished scan and verify basic content properties.
:id: 66abf967-24f1-43cb-9375-c1a5e519a0e6
:description: This is the last part of end-to-end user journey through web
user interface. It is split out from end_to_end test to allow usage of
cached scans results.
:steps:
1) Log into the UI.
2) Download finished scan report.
3) Verify downloaded file looks like a valid scan.
4) Log out.
:expectedresults: Report is downloaded. User is logged out.
"""
finished_scan = scans.with_name(scan_name)
(
ui_client.begin()
.login(data_factories.LoginFormDTOFactory())
.navigate_to(MainMenuPages.SCANS)
.download_scan(finished_scan.definition.name)
.logout()
)

is_network_scan = has_network_source(scan_name)
downloaded_report = ui_client.downloaded_files[-1]

tarfile.open(downloaded_report.path()).extractall(tmp_path)
assert_sha256sums(tmp_path)
assert_ansible_logs(tmp_path, is_network_scan)
30 changes: 30 additions & 0 deletions camayoc/tests/qpc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,36 @@ def get_expected_sha256sums(directory):
return parsed_shasums


def assert_sha256sums(directory: Path):
"""Verify SHA256 sums of files match. Tests helper."""
actual_shasums = calculate_sha256sums(directory)
expected_shasums = get_expected_sha256sums(directory)

for filename, expected_shasum in expected_shasums.items():
actual_shasum = actual_shasums.get(filename)
assert actual_shasum == expected_shasum


def assert_ansible_logs(directory: Path, is_network_scan: bool):
"""Verify that ansible log files exist (or not). Tests helper."""
has_ansible_logs = False
for file in directory.rglob("*"):
if not file.is_file():
continue

# Ansible STDERR may or may not be empty, no point in asserting size
if "ansible-stderr" in file.name:
has_ansible_logs = True
continue

if "ansible-stdout" in file.name:
has_ansible_logs = True

assert file.stat().st_size > 0

assert is_network_scan == has_ansible_logs


def get_object_id(obj):
"""Get id of object whose name is known."""
if obj._id:
Expand Down
4 changes: 3 additions & 1 deletion camayoc/ui/models/components/items_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class ItemsList(UIPage):

def _get_item_from_current_list(self, name: str):
default_timeout = 5000 # 5s
item_elem = self._driver.locator("css=strong").filter(has_text=name)
item_elem = self._driver.locator("css=strong").filter(
has=self._driver.get_by_text(name, exact=True)
)
item_elem_locator = "xpath=./ancestor::tr[contains(@class, 'quipucords-table__tr')]"
item_elem = item_elem.locator(item_elem_locator)
item_elem.hover(timeout=default_timeout, trial=True)
Expand Down

0 comments on commit 75ab416

Please sign in to comment.