Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:

- name: Run pycodestyle
run: |
pycodestyle api/*.py
pycodestyle --max-line-length=100 api/*.py

- name: Run API containers
run: |
Expand Down
6 changes: 3 additions & 3 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ py-version=3.10

# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
# suggestion-mode is removed in pylint 4.x

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
Expand Down Expand Up @@ -564,5 +564,5 @@ min-public-methods=2

# Exceptions that will emit a warning when being caught. Defaults to
# "BaseException, Exception".
overgeneral-exceptions=BaseException,
Exception
overgeneral-exceptions=builtins.BaseException,
builtins.Exception
8 changes: 4 additions & 4 deletions api/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from fastapi_pagination.ext.motor import paginate
from motor import motor_asyncio
from redis import asyncio as aioredis
from kernelci.api.models import EventHistory, Hierarchy, Node, parse_node_obj

Check failure on line 14 in api/db.py

View workflow job for this annotation

GitHub Actions / Lint

Unable to import 'kernelci.api.models'
from .models import User, UserGroup


Expand Down Expand Up @@ -70,31 +70,31 @@
Get value from redis key-value store
Create a keyname by concatenating namespace and key
"""
keyname = f"{namespace}:{key}"
keyname = ":".join([namespace, key])
return await self._redis.get(keyname)

async def set_kv(self, namespace, key, value):
"""
Set value in redis key-value store
Create a keyname by concatenating namespace and key
"""
keyname = f"{namespace}:{key}"
keyname = ":".join([namespace, key])
return await self._redis.set(keyname, value)

async def del_kv(self, namespace, key):
"""
Delete key from redis key-value store
Create a keyname by concatenating namespace and key
"""
keyname = f"{namespace}:{key}"
keyname = ":".join([namespace, key])
return await self._redis.delete(keyname)

async def exists_kv(self, namespace, key):
"""
Check if key exists in redis key-value store
Create a keyname by concatenating namespace and key
"""
keyname = f"{namespace}:{key}"
keyname = ":".join([namespace, key])
return await self._redis.exists(keyname)

async def create_indexes(self):
Expand Down
14 changes: 10 additions & 4 deletions api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
from pydantic import BaseModel
from jose import jwt
from jose.exceptions import JWTError
from kernelci.api.models import (

Check failure on line 49 in api/main.py

View workflow job for this annotation

GitHub Actions / Lint

Unable to import 'kernelci.api.models'
Node,
Hierarchy,
PublishEvent,
Expand Down Expand Up @@ -305,7 +305,7 @@

if forwarded_host:
scheme = forwarded_proto or request.url.scheme
return f"{scheme}://{forwarded_host}".rstrip("/")
return (scheme + "://" + forwarded_host).rstrip("/")

return str(request.base_url).rstrip("/")

Expand Down Expand Up @@ -745,8 +745,8 @@
return True
runtime = _get_node_runtime(node)
if runtime:
runtime_editor = f'runtime:{runtime}:node-editor'
runtime_admin = f'runtime:{runtime}:node-admin'
runtime_editor = ":".join(['runtime', runtime, 'node-editor'])
runtime_admin = ":".join(['runtime', runtime, 'node-admin'])
if (runtime_editor in user_group_names
or runtime_admin in user_group_names):
return True
Expand Down Expand Up @@ -895,7 +895,13 @@

if from_ts:
if isinstance(from_ts, str):
from_ts = datetime.fromisoformat(from_ts)
try:
from_ts = datetime.fromisoformat(from_ts)
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid 'from' parameter, must be an ISO 8601 datetime"
) from exc
query_params['timestamp'] = {'$gt': from_ts}
if path:
query_params['data.path'] = {'$regex': path}
Expand Down
3 changes: 2 additions & 1 deletion api/pubsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def __init__(self, host=None, db_number=None):
if db_number is None:
db_number = self._settings.redis_db_number
self._redis = aioredis.from_url(
f'redis://{host}/{db_number}', health_check_interval=30
'redis://' + host + '/' + str(db_number),
health_check_interval=30
)
# self._subscriptions is a dict that matches a subscription id
# (key) with a Subscription object ('sub') and a redis
Expand Down
3 changes: 2 additions & 1 deletion api/pubsub_mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def __init__(self, mongo_client=None, host=None, db_number=None,
db_number = self._settings.redis_db_number

self._redis = aioredis.from_url(
f'redis://{host}/{db_number}', health_check_interval=30
'redis://' + host + '/' + str(db_number),
health_check_interval=30
)

# MongoDB setup
Expand Down
15 changes: 6 additions & 9 deletions scripts/usermanager.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3

Check warning on line 1 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Missing module docstring
import argparse
import getpass
import json
Expand Down Expand Up @@ -133,7 +133,7 @@
raise SystemExit(1)
try:
payload = json.loads(body) if body else []
except json.JSONDecodeError as exc:

Check warning on line 136 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
raise SystemExit("Failed to parse users response") from exc
items = _parse_paginated_items(payload)
matches = []
Expand Down Expand Up @@ -174,7 +174,7 @@
raise SystemExit(1)
try:
payload = json.loads(body) if body else {}
except json.JSONDecodeError as exc:

Check warning on line 177 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
raise SystemExit("Failed to parse user-groups response") from exc
items = _parse_paginated_items(payload)
matches = [
Expand Down Expand Up @@ -203,7 +203,7 @@
raise SystemExit(1)
try:
payload = json.loads(body) if body else {}
except json.JSONDecodeError as exc:

Check warning on line 206 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
raise SystemExit("Failed to parse user-group response") from exc
resolved_name = payload.get("name")
if not resolved_name:
Expand All @@ -222,7 +222,7 @@
raise SystemExit(1)
try:
payload = json.loads(body) if body else {}
except json.JSONDecodeError as exc:

Check warning on line 225 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
raise SystemExit("Failed to parse user response") from exc
current_groups = _extract_group_names(payload)
data = {
Expand All @@ -248,7 +248,7 @@
with urllib.request.urlopen(req) as response:
payload = response.read().decode("utf-8")
return response.status, payload
except urllib.error.HTTPError as exc:

Check warning on line 251 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
payload = exc.read().decode("utf-8")
return exc.code, payload

Expand All @@ -274,7 +274,7 @@
)


def main():

Check warning on line 277 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Too many local variables (41/15)

Check warning on line 277 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Missing function or method docstring
command_help = [
("accept-invite", "Accept an invite"),
("assign-group", "Assign group(s) to a user"),
Expand All @@ -294,18 +294,15 @@
("update-user", "Patch user by id/email/username"),
("whoami", "Show current user"),
]
command_list = "\n".join(f" {name:<18} {desc}" for name, desc in command_help)
default_paths = "\n".join(f" - {path}" for path in DEFAULT_CONFIG_PATHS)
command_list = "\n".join(
" {:<18} {}".format(name, desc) for name, desc in command_help)

Check warning on line 298 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Formatting a regular string which could be an f-string
default_paths = "\n".join(
" - {}".format(path) for path in DEFAULT_CONFIG_PATHS)
parser = argparse.ArgumentParser(
description="KernelCI API user management helper",
usage=(
"usermanager.py [-h] [--config CONFIG] [--api-url API_URL] "
"[--token TOKEN] [--instance INSTANCE] [--token-label TOKEN_LABEL]\n"
" <command> [<args>]\n\n"
"Commands:\n"
f"{command_list}"
),
epilog=(
"Commands:\n"
f"{command_list}\n\n"
"Examples:\n"
" ./scripts/usermanager.py invite --username alice --email "
"alice@example.org --return-token\n"
Expand Down Expand Up @@ -575,7 +572,7 @@
if status < 400:
try:
payload = json.loads(body) if body else {}
except json.JSONDecodeError as exc:

Check warning on line 575 in scripts/usermanager.py

View workflow job for this annotation

GitHub Actions / Lint

Redefining name 'exc' from outer scope (line 14)
raise SystemExit("Failed to parse login response") from exc
token = payload.get("access_token")
if not token:
Expand Down
3 changes: 2 additions & 1 deletion tests/e2e_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
from httpx import AsyncClient
from motor.motor_asyncio import AsyncIOMotorClient

from api.main import versioned_app
from kernelci.api.models import Node, Regression

Check failure on line 13 in tests/e2e_tests/conftest.py

View workflow job for this annotation

GitHub Actions / Lint

Unable to import 'kernelci.api.models'

from api.main import versioned_app

BASE_URL = 'http://api:8000/latest/'
DB_URL = 'mongodb://db:27017'
DB_NAME = 'kernelci'
Expand Down
16 changes: 10 additions & 6 deletions tests/e2e_tests/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ async def test_node_pipeline(test_async_client):
"""

# Create Task to listen pubsub event on 'node' channel
task_listen = create_listen_task(test_async_client,
pytest.node_channel_subscription_id) # pylint: disable=no-member
task_listen = create_listen_task(
test_async_client,
pytest.node_channel_subscription_id) # pylint: disable=no-member

# Create a node
node = {
Expand All @@ -48,8 +49,10 @@ async def test_node_pipeline(test_async_client):
"data": {
"kernel_revision": {
"tree": "mainline",
"url": ("https://git.kernel.org/pub/scm/linux/kernel/git/"
"torvalds/linux.git"),
"url": (
"https://git.kernel.org/pub/scm/"
"linux/kernel/git/torvalds/linux.git"
),
"branch": "master",
"commit": "2a987e65025e2b79c6d453b78cb5985ac6e5eb28",
"describe": "v5.16-rc4-31-g2a987e65025e"
Expand All @@ -73,8 +76,9 @@ async def test_node_pipeline(test_async_client):
node = response.json()

# Create Task to listen 'updated' event on 'node' channel
task_listen = create_listen_task(test_async_client,
pytest.node_channel_subscription_id) # pylint: disable=no-member
task_listen = create_listen_task(
test_async_client,
pytest.node_channel_subscription_id) # pylint: disable=no-member

# Update node.state
node.update({"state": "done"})
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e_tests/test_pubsub_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ async def test_pubsub_handler(test_async_client):
Use pubsub listener task to verify published event message.
"""
# Create Task to listen pubsub event on 'test_channel' channel
task_listen = create_listen_task(test_async_client,
pytest.test_channel_subscription_id) # pylint: disable=no-member
task_listen = create_listen_task(
test_async_client,
pytest.test_channel_subscription_id) # pylint: disable=no-member

# Created and publish CloudEvent
attributes = {
Expand Down
3 changes: 2 additions & 1 deletion tests/unit_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
t3bAE-pHSzZaSHp7FMlImqgYvL6f_0xDUD-nQwxEm3k'

API_VERSION = 'latest'
BASE_URL = f'http://testserver/{API_VERSION}/'
BASE_URL = 'http://testserver/' + API_VERSION + '/'


def mock_get_current_user(request: Request):
Expand Down Expand Up @@ -90,6 +90,7 @@ def mock_get_current_admin_user(request: Request):
is_verified=True
)


# Mock dependency callables for getting current user
app.dependency_overrides[get_current_user] = mock_get_current_user
app.dependency_overrides[get_current_superuser] = mock_get_current_admin_user
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/test_events_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""Unit tests for KernelCI API events handler"""

from bson import ObjectId
from kernelci.api.models import EventHistory

Check failure on line 8 in tests/unit_tests/test_events_handler.py

View workflow job for this annotation

GitHub Actions / Lint

Unable to import 'kernelci.api.models'


def test_get_events_filter_by_id(mock_db_find_by_attributes, test_client):
Expand Down Expand Up @@ -34,7 +34,7 @@
oid1, oid2 = ObjectId(), ObjectId()
mock_db_find_by_attributes.return_value = []

resp = test_client.get(f"events?ids={oid1},{oid2}")
resp = test_client.get("events?ids=" + oid1 + "," + oid2)

assert resp.status_code == 200
called_model, called_query = mock_db_find_by_attributes.call_args.args
Expand Down
7 changes: 4 additions & 3 deletions tests/unit_tests/test_node_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@

import json

from tests.unit_tests.conftest import BEARER_TOKEN
from kernelci.api.models import Node, Revision

Check failure on line 15 in tests/unit_tests/test_node_handler.py

View workflow job for this annotation

GitHub Actions / Lint

Unable to import 'kernelci.api.models'

from api.models import PageModel
from tests.unit_tests.conftest import BEARER_TOKEN


def test_create_node_endpoint(mock_db_create, mock_publish_cloudevent,
Expand All @@ -40,7 +41,7 @@
name="checkout",
path=["checkout"],
group="debug",
data= {'kernel_revision': revision_obj},
data={'kernel_revision': revision_obj},
parent=None,
state="closing",
result=None,
Expand Down Expand Up @@ -216,7 +217,7 @@
name="checkout",
path=["checkout"],
group="blah",
data = {'kernel_revision': revision_obj},
data={'kernel_revision': revision_obj},
parent=None,
state="closing",
result=None,
Expand Down
22 changes: 15 additions & 7 deletions tests/unit_tests/test_pubsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,24 @@ async def test_pubsub_publish_couldevent(mock_pubsub_publish):
"""

data = 'validate json'
attributes = { "specversion": "1.0", "id": "6878b661-96dc-4e93-8c92-26eb9ff8db64",
"source": "https://api.kernelci.org/", "type": "api.kernelci.org",
"time": "2022-01-31T21:29:29.675593+00:00"}
attributes = {
"specversion": "1.0",
"id": "6878b661-96dc-4e93-8c92-26eb9ff8db64",
"source": "https://api.kernelci.org/",
"type": "api.kernelci.org",
"time": "2022-01-31T21:29:29.675593+00:00",
}

await mock_pubsub_publish.publish_cloudevent('CHANNEL1', data, attributes)

expected_json = str.encode('{"specversion": "1.0", '\
'"id": "6878b661-96dc-4e93-8c92-26eb9ff8db64", "source": "https://api.kernelci.org/", '\
'"type": "api.kernelci.org", "time": "2022-01-31T21:29:29.675593+00:00", '\
'"data": "validate json"}')
expected_json = str.encode(
'{"specversion": "1.0", '
'"id": "6878b661-96dc-4e93-8c92-26eb9ff8db64", '
'"source": "https://api.kernelci.org/", '
'"type": "api.kernelci.org", '
'"time": "2022-01-31T21:29:29.675593+00:00", '
'"data": "validate json"}'
)

json_arg = mock_pubsub_publish._redis.execute_command.call_args.args[2]

Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/test_user_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ async def test_create_user_endpoint_negative(test_async_client):

@pytest.mark.asyncio
async def test_create_user_with_group(test_async_client, mock_db_find_one,
mock_db_update,mock_db_find_by_id):
mock_db_update, mock_db_find_by_id):
"""
Test Case : Test KernelCI API /user/register endpoint to create a user
with a user group
Expand Down
Loading