Skip to content

Commit

Permalink
Merge pull request #891 from mdujava/stable-2.14
Browse files Browse the repository at this point in the history
[stable-2.14] few backports for 2.14.3
  • Loading branch information
mdujava authored Nov 22, 2024
2 parents 4ee9342 + 591e484 commit 3980976
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 59 deletions.
95 changes: 68 additions & 27 deletions testsuite/tests/apicast/auth/test_basic_auth_app_id.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,106 @@
"""
Service requires credentials (app_id, app_key) to be passed using the Basic Auth
Rewrite ./spec/functional_specs/auth/basic_auth_app_id_spec.rb
"""

import pytest

from threescale_api.resources import Service
from packaging.version import Version # noqa # pylint: disable=unused-import

from testsuite import TESTED_VERSION # noqa # pylint: disable=unused-import
from testsuite.capabilities import Capability
from testsuite.gateways.apicast.selfmanaged import SelfManagedApicast
from testsuite.gateways.apicast.system import SystemApicast
from testsuite.httpx import HttpxClient
from testsuite.utils import basic_auth_string


@pytest.fixture(scope="module")
def service_settings(service_settings):
"Set auth mode to app_id/app_key"
"""Set auth mode to app_id/app_key."""
service_settings.update({"backend_version": Service.AUTH_APP_ID_KEY})
return service_settings


@pytest.fixture(scope="module")
def service_proxy_settings(service_proxy_settings):
"Set credentials location to 'authorization' (Basic HTTP auth)"
"""Set credentials location to 'authorization' (Basic HTTP auth)."""
service_proxy_settings.update({"credentials_location": "authorization"})
return service_proxy_settings


@pytest.mark.smoke
def test_basic_auth_app_id_key(application, api_client):
"""Test client access with Basic HTTP Auth using app id and app key
Configure Api/Service to use App ID / App Key Authentication
and Basic HTTP Auth to pass the credentials.
@pytest.fixture(scope="module")
def http_client(application):
"""Provide an HttpxClient instance using HTTP 1.1."""
client = HttpxClient(False, application)
client.auth = None # No default authentication
yield client
client.close()

Then request made with appropriate Basic auth made has to pass as expected"""

@pytest.fixture(scope="module")
def valid_auth_headers(application):
"""Generate valid Basic Auth headers."""
creds = application.authobj().credentials
expected_authorization = basic_auth_string(creds["app_id"], creds["app_key"])

response = api_client().get("/get")
authorization = basic_auth_string(creds["app_id"], creds["app_key"])
return {"Authorization": authorization}

assert response.status_code == 200
assert response.request.headers["Authorization"] == expected_authorization

@pytest.fixture(scope="module")
def malformed_request(http_client):
"""Create a function to make requests with malformed auth headers."""

def test_basic_auth_app_id_403_with_query(application, api_client):
"Forbid access if credentials passed wrong way"
client = api_client()
def prepare_request():
headers = {"Authorization": "Basic test123?"} # Malformed authorization header
return http_client.get("/get", headers=headers)

client.auth = application.authobj(location="query")
return prepare_request

response = client.get("/get")

assert response.status_code == 403
@pytest.fixture(
scope="module",
params=[
SystemApicast,
pytest.param(SelfManagedApicast, marks=pytest.mark.required_capabilities(Capability.CUSTOM_ENVIRONMENT)),
],
)
def gateway_kind(request):
"""Gateway class to use for tests"""
return request.param


def test_basic_auth_app_id_403_without_auth(api_client):
"Forbid access if no credentials"
@pytest.mark.smoke
def test_basic_auth_success(http_client, valid_auth_headers):
"""Test valid Basic HTTP Auth using app_id and app_key."""
response = http_client.get("/get", headers=valid_auth_headers)
assert response.status_code == 200, "Valid request failed unexpectedly."
assert response.request.headers["Authorization"] == valid_auth_headers["Authorization"]


@pytest.mark.parametrize(
"auth_method, expected_status",
[
("query", 403), # Credentials passed as query parameters
(None, 403), # No credentials
],
)
def test_basic_auth_failure(api_client, application, auth_method, expected_status):
"""Test forbidden access when credentials are passed incorrectly or missing."""
client = api_client()
client.auth = application.authobj(location=auth_method) if auth_method else None
response = client.get("/get")
assert response.status_code == expected_status

client.auth = None

response = client.get("/get")
@pytest.mark.skipif("TESTED_VERSION < Version('2.14')")
@pytest.mark.issue("https://issues.redhat.com/browse/THREESCALE-11435")
# pylint: disable=unused-argument
def test_basic_auth_malformed_secret(http_client, valid_auth_headers, malformed_request, gateway_kind):
"""Test malformed Basic Auth headers."""
# Valid request
response = http_client.get("/get", headers=valid_auth_headers)
assert response.status_code == 200, "Valid request failed unexpectedly."

assert response.status_code == 403
# Malformed request
malformed_status_code = malformed_request().status_code
assert malformed_status_code == 403, "Malformed request did not return 403 as expected."
10 changes: 8 additions & 2 deletions testsuite/tests/prometheus/system/test_internal_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
]


REQUEST_NUM = 42


@pytest.fixture(scope="session")
def backend_listener_url(testconfig):
"""
Expand Down Expand Up @@ -76,7 +79,8 @@ def test_utilization(url, prometheus, application, backend_listener_url, auth_he

service_id = application.service.entity_id
app_plan_id = application.entity["plan_id"]
requests.get(url.format(backend_listener_url, service_id, app_plan_id), verify=False, headers=auth_headers)
for _ in range(REQUEST_NUM):
requests.get(url.format(backend_listener_url, service_id, app_plan_id), verify=False, headers=auth_headers)

# prometheus is downloading metrics periodicity, we need to wait for next fetch
prometheus.wait_on_next_scrape("backend-worker")
Expand All @@ -91,7 +95,9 @@ def test_utilization(url, prometheus, application, backend_listener_url, auth_he
lambda x: x["metric"]["controller"].startswith("admin/api"),
)

assert counts_after == counts_before
for key, count in counts_after.items():
if int(count) >= int(counts_before[key]) + REQUEST_NUM:
assert counts_after == counts_before, f"looks like {key} is increased by internal calls"


def extract_call_metrics(prometheus, query, container, predicate=None):
Expand Down
4 changes: 3 additions & 1 deletion testsuite/tests/toolbox/test_activedoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from testsuite.utils import blame, blame_desc, randomize
from testsuite import rawobj

SWAGGER_LINK = "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/json/petstore.json"
SWAGGER_LINK = (
"https://raw.githubusercontent.com/OAI/learn.openapis.org/refs/heads/main/examples/v2.0/json/petstore.json"
)


@pytest.fixture(scope="module")
Expand Down
63 changes: 34 additions & 29 deletions testsuite/tests/ui/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,46 +465,51 @@ def get_resultsdir_path(node):
return path


# pylint: disable=too-many-locals
def fullpage_screenshot(driver, file_path):
"""
A full-page screenshot function. It scroll the website and screenshots it.
A full-page screenshot function. It scrolls the website and screenshots it.
- Creates multiple files
- Screenshots are made only vertically (on Y axis)
"""
# Removal of the height: 100% style, that disables scroll.
driver.execute_script("document.body.style.height = 'unset'")
driver.execute_script("document.body.parentNode.style.height = 'unset'")
try:
# Removal of the height: 100% style, that disables scroll.
driver.execute_script("document.body.style.height = 'unset'")
driver.execute_script("document.body.parentNode.style.height = 'unset'")

total_height = driver.execute_script("return document.body.parentNode.scrollHeight")
viewport_height = driver.execute_script("return window.innerHeight")
total_height = driver.execute_script("return document.body.parentNode.scrollHeight")
viewport_height = driver.execute_script("return window.innerHeight")

screenshot_bytes = driver.get_screenshot_as_png()
screenshot = Image.open(io.BytesIO(screenshot_bytes))
width, height = screenshot.size
del screenshot

scaling_constant = float(height) / float(viewport_height)
stitched_image = Image.new("RGB", (width, int(total_height * scaling_constant)))
part = 0

for scroll in range(0, total_height, viewport_height):
driver.execute_script("window.scrollTo({0}, {1})".format(0, scroll))
screenshot_bytes = driver.get_screenshot_as_png()
screenshot = Image.open(io.BytesIO(screenshot_bytes))

if scroll + viewport_height > total_height:
offset = (0, int(math.ceil((total_height - viewport_height) * scaling_constant)))
else:
offset = (0, int(math.ceil(scroll * scaling_constant)))

stitched_image.paste(screenshot, offset)
width, height = screenshot.size
del screenshot
part += 1

date = datetime.today().strftime("%Y-%m-%d-%H:%M:%S")
fullpath = f"{file_path}/{date}.png"
stitched_image.save(fullpath)
return fullpath
scaling_constant = float(height) / float(viewport_height)
stitched_image = Image.new("RGB", (width, int(total_height * scaling_constant)))
part = 0

for scroll in range(0, total_height, viewport_height):
driver.execute_script("window.scrollTo({0}, {1})".format(0, scroll))
screenshot_bytes = driver.get_screenshot_as_png()
screenshot = Image.open(io.BytesIO(screenshot_bytes))

if scroll + viewport_height > total_height:
offset = (0, int(math.ceil((total_height - viewport_height) * scaling_constant)))
else:
offset = (0, int(math.ceil(scroll * scaling_constant)))

stitched_image.paste(screenshot, offset)
del screenshot
part += 1

date = datetime.today().strftime("%Y-%m-%d-%H:%M:%S")
fullpath = f"{file_path}/{date}.png"
stitched_image.save(fullpath)
return fullpath
# pylint: disable=broad-exception-caught
except Exception as e:
return f"Error: Failed to take full-page screenshot. Details: {str(e)}"


@pytest.fixture(scope="module")
Expand Down

0 comments on commit 3980976

Please sign in to comment.