198 lines
5.6 KiB
Python
198 lines
5.6 KiB
Python
import math
|
|
import requests
|
|
import time
|
|
import pytest
|
|
|
|
from typing import Dict
|
|
|
|
from .conftest import API_PREFIX
|
|
from .utils import get_crawl_status
|
|
|
|
|
|
EXEC_MINS_QUOTA = 1
|
|
EXEC_SECS_QUOTA = EXEC_MINS_QUOTA * 60
|
|
GIFTED_MINS_QUOTA = 3
|
|
GIFTED_SECS_QUOTA = GIFTED_MINS_QUOTA * 60
|
|
EXTRA_MINS_QUOTA = 5
|
|
EXTRA_SECS_QUOTA = EXTRA_MINS_QUOTA * 60
|
|
|
|
config_id = None
|
|
|
|
|
|
def test_set_execution_mins_quota(org_with_quotas, admin_auth_headers):
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/quotas",
|
|
headers=admin_auth_headers,
|
|
json={"maxExecMinutesPerMonth": EXEC_MINS_QUOTA},
|
|
)
|
|
data = r.json()
|
|
assert data.get("updated") == True
|
|
|
|
|
|
def test_crawl_stopped_when_quota_reached(org_with_quotas, admin_auth_headers):
|
|
# Run crawl
|
|
global config_id
|
|
crawl_id, config_id = run_crawl(org_with_quotas, admin_auth_headers)
|
|
time.sleep(1)
|
|
|
|
while get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers) in (
|
|
"starting",
|
|
"waiting_capacity",
|
|
):
|
|
time.sleep(2)
|
|
|
|
while get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers) in (
|
|
"running",
|
|
"generate-wacz",
|
|
"uploading-wacz",
|
|
"pending-wait",
|
|
):
|
|
time.sleep(2)
|
|
|
|
# Ensure that crawl was stopped by quota
|
|
assert (
|
|
get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers)
|
|
== "stopped_time_quota_reached"
|
|
)
|
|
|
|
time.sleep(5)
|
|
|
|
# Ensure crawl execution seconds went over quota
|
|
r = requests.get(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/crawls/{crawl_id}/replay.json",
|
|
headers=admin_auth_headers,
|
|
)
|
|
data = r.json()
|
|
execution_seconds = data["crawlExecSeconds"]
|
|
assert math.floor(execution_seconds / 60) >= EXEC_MINS_QUOTA
|
|
|
|
time.sleep(5)
|
|
|
|
# Ensure we can't start another crawl when over the quota
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/crawlconfigs/{config_id}/run",
|
|
headers=admin_auth_headers,
|
|
)
|
|
assert r.status_code == 403
|
|
assert r.json()["detail"] == "exec_minutes_quota_reached"
|
|
|
|
|
|
def test_set_execution_mins_extra_quotas(org_with_quotas, admin_auth_headers):
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/quotas",
|
|
headers=admin_auth_headers,
|
|
json={
|
|
"maxExecMinutesPerMonth": EXEC_MINS_QUOTA,
|
|
"extraExecMinutes": EXTRA_MINS_QUOTA,
|
|
"giftedExecMinutes": GIFTED_MINS_QUOTA,
|
|
},
|
|
)
|
|
data = r.json()
|
|
assert data.get("updated") == True
|
|
|
|
# Ensure org data looks as we expect
|
|
r = requests.get(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}",
|
|
headers=admin_auth_headers,
|
|
)
|
|
data = r.json()
|
|
assert data["extraExecSecondsAvailable"] == EXTRA_SECS_QUOTA
|
|
assert data["giftedExecSecondsAvailable"] == GIFTED_SECS_QUOTA
|
|
assert data["extraExecSeconds"] == {}
|
|
assert data["giftedExecSeconds"] == {}
|
|
assert get_total_exec_seconds(data["crawlExecSeconds"]) >= EXEC_SECS_QUOTA
|
|
assert len(data["quotaUpdates"])
|
|
for update in data["quotaUpdates"]:
|
|
assert update["modified"]
|
|
assert update["update"]
|
|
|
|
|
|
@pytest.mark.timeout(1200)
|
|
def test_crawl_stopped_when_quota_reached_with_extra(
|
|
org_with_quotas, admin_auth_headers
|
|
):
|
|
# Run crawl
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/crawlconfigs/{config_id}/run",
|
|
headers=admin_auth_headers,
|
|
)
|
|
assert r.status_code == 200
|
|
crawl_id = r.json()["started"]
|
|
|
|
while get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers) in (
|
|
"starting",
|
|
"waiting_capacity",
|
|
):
|
|
time.sleep(2)
|
|
|
|
while get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers) in (
|
|
"running",
|
|
"generate-wacz",
|
|
"uploading-wacz",
|
|
"pending-wait",
|
|
):
|
|
time.sleep(2)
|
|
|
|
# Ensure that crawl was stopped by quota
|
|
assert (
|
|
get_crawl_status(org_with_quotas, crawl_id, admin_auth_headers)
|
|
== "stopped_time_quota_reached"
|
|
)
|
|
|
|
time.sleep(5)
|
|
|
|
# Ensure org data looks as we expect
|
|
r = requests.get(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}",
|
|
headers=admin_auth_headers,
|
|
)
|
|
data = r.json()
|
|
assert data["extraExecSecondsAvailable"] == 0
|
|
assert data["giftedExecSecondsAvailable"] == 0
|
|
assert get_total_exec_seconds(data["extraExecSeconds"]) >= EXTRA_SECS_QUOTA
|
|
assert get_total_exec_seconds(data["giftedExecSeconds"]) == GIFTED_SECS_QUOTA
|
|
assert get_total_exec_seconds(data["crawlExecSeconds"]) >= EXEC_SECS_QUOTA
|
|
|
|
time.sleep(5)
|
|
|
|
# Ensure we can't start another crawl when over the quota
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/crawlconfigs/{config_id}/run",
|
|
headers=admin_auth_headers,
|
|
)
|
|
assert r.status_code == 403
|
|
assert r.json()["detail"] == "exec_minutes_quota_reached"
|
|
|
|
|
|
def run_crawl(org_id, headers):
|
|
crawl_data = {
|
|
"runNow": True,
|
|
"name": "Execution Mins Quota",
|
|
"config": {
|
|
"seeds": [{"url": "https://webrecorder.net/"}],
|
|
"extraHops": 1,
|
|
},
|
|
}
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_id}/crawlconfigs/",
|
|
headers=headers,
|
|
json=crawl_data,
|
|
)
|
|
data = r.json()
|
|
|
|
return data["run_now_job"], data["id"]
|
|
|
|
|
|
def get_total_exec_seconds(execSeconds: Dict[str, int]) -> int:
|
|
return sum(list(execSeconds.values()))
|
|
|
|
|
|
def test_unset_execution_mins_quota(org_with_quotas, admin_auth_headers):
|
|
r = requests.post(
|
|
f"{API_PREFIX}/orgs/{org_with_quotas}/quotas",
|
|
headers=admin_auth_headers,
|
|
json={"maxExecMinutesPerMonth": 0},
|
|
)
|
|
data = r.json()
|
|
assert data.get("updated") == True
|