Skip to content

Fix #3 - Route Testing #13

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

Open
wants to merge 63 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
4f6750f
Add base to test for routes
GabrielTiveron Aug 27, 2021
18a326d
try to set test database
aquiles23 Sep 3, 2021
58d0245
make test database work in test enviroment
aquiles23 Sep 4, 2021
883b620
Add sqlalchemy to poetry lock file
GabrielTiveron Sep 7, 2021
2885b1e
Add sqlalchemy to poetry lock file
GabrielTiveron Sep 7, 2021
8e9b4fc
make a folder for route tests
aquiles23 Sep 7, 2021
0094c2d
make autentications on tests
aquiles23 Sep 7, 2021
95f2cc0
use fixtures to separate get and post tests
aquiles23 Sep 8, 2021
77256b0
test create user with auth required
aquiles23 Sep 8, 2021
e596266
create test user get me
aquiles23 Sep 8, 2021
7973cbd
apply black formatter
aquiles23 Sep 8, 2021
37499e4
test user put
aquiles23 Sep 8, 2021
cbcbb3f
add one more assert
aquiles23 Sep 8, 2021
4932311
test 'user put me' route
aquiles23 Sep 8, 2021
65446d8
remove unused import
aquiles23 Sep 9, 2021
e106cae
remove unused var
aquiles23 Sep 9, 2021
f2d5ae1
test accuraccy post and test accuracy get
aquiles23 Sep 9, 2021
11d6e3b
test accuracy get id
aquiles23 Sep 9, 2021
5692d58
test accuracy put
aquiles23 Sep 9, 2021
e03bea0
use teardown to test delete endpoint
aquiles23 Sep 9, 2021
315dc96
Change flake8 settings
m-theus Sep 9, 2021
bd0d356
Fix code style
m-theus Sep 9, 2021
ceaff1e
Add tpu post test
GabrielTiveron Sep 9, 2021
81637a3
Add tpu tests
GabrielTiveron Sep 9, 2021
00ae670
Add task route tests
GabrielTiveron Sep 9, 2021
da59ee6
Add submission route test
GabrielTiveron Sep 13, 2021
94eddc0
test cpu post and delete
aquiles23 Sep 19, 2021
bc2c2d9
change list to set in test_accuracy_type
aquiles23 Sep 19, 2021
9835d9f
change list to set in test user route
aquiles23 Sep 19, 2021
7bb3981
test put, get and get_id in cpu route tests
aquiles23 Sep 19, 2021
0d4e9dc
format cpu route tests with black
aquiles23 Sep 19, 2021
1259e17
dataset route tests, with put test not working.
aquiles23 Sep 19, 2021
88bfae7
test test_token route
aquiles23 Sep 19, 2021
8e8d2a0
add comment on why not test reset password
aquiles23 Sep 19, 2021
1e0fed8
remove my email from CODE_OF_CONDUCT
aquiles23 Sep 20, 2021
ea0cf00
remove useless file
aquiles23 Sep 20, 2021
fc2b1c3
make creation of dataset and task global.
aquiles23 Sep 20, 2021
04eaf80
fix error
aquiles23 Sep 23, 2021
6656204
Merge branch '14-code-style' of github.com:FGA-GCES/api into route_test
GabrielTiveron Oct 7, 2021
c75badf
Add style sheet to route tests files
GabrielTiveron Oct 7, 2021
2e1ae4a
Applying clean code to test routes
GabrielTiveron Oct 7, 2021
296571f
Add status constants to test files
GabrielTiveron Oct 7, 2021
d40146a
test paper post endpoint
aquiles23 Oct 17, 2021
242c146
test paper get endpoint
aquiles23 Oct 17, 2021
bbf4c84
test paper put endpoint
aquiles23 Oct 17, 2021
2fc8e2f
test papers delete endpoint
aquiles23 Oct 17, 2021
b57cdc4
fixing test and supressing unwanted logs
GabrielTiveron Oct 21, 2021
e3f635e
Add test environment for initial seeding data.
GabrielTiveron Oct 31, 2021
5f2601c
make submission flow works
aquiles23 Oct 31, 2021
6350624
test model put route
aquiles23 Nov 1, 2021
41e33c3
test model delete route and some fix codestyle
aquiles23 Nov 1, 2021
2d9982a
test model get task dataset route
aquiles23 Nov 1, 2021
4d97f0f
test get model csv route
aquiles23 Nov 1, 2021
fc308bd
test all gpu routes
aquiles23 Nov 1, 2021
9dc2df4
add one more assert to test model csv route
aquiles23 Nov 1, 2021
7516750
install pytest-order
aquiles23 Nov 1, 2021
93203cd
test sota route
aquiles23 Nov 1, 2021
afb1ad6
test paper with code get route
aquiles23 Nov 1, 2021
1e8aa1a
test paper with code get model route
aquiles23 Nov 1, 2021
77abdd2
Fixing sota test and model test warning
GabrielTiveron Nov 2, 2021
a6edf8e
Adding failure case tests to datasets route
GabrielTiveron Nov 2, 2021
d8ca7f7
Adding failure test case for task route and fix datasets const
GabrielTiveron Nov 2, 2021
c9960a0
Adding accuracy failure test cases
GabrielTiveron Nov 2, 2021
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 .flake8
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[flake8]
max-line-length = 88
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache
exclude = .git,__pycache__,__init__.py,.mypy_cache,.pytest_cache,alembic/versions
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [email protected]. All
reported by contacting the project team at [email protected]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include .env

.PHONY: up-test

test:
(sudo docker-compose -f test.docker-compose.yml up -d && \
sudo docker-compose -f test.docker-compose.yml exec backend-tests pytest);\
sudo docker-compose -f test.docker-compose.yml down
1 change: 0 additions & 1 deletion app/crud/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
from sqlalchemy.orm import Session
import logging

from app.database.base import Base

Expand Down
3 changes: 1 addition & 2 deletions app/crud/paper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@


class CRUDPaper(CRUDBase[Paper, PaperCreate, PaperUpdate]):
pass

pass


paper = CRUDPaper(Paper)
10 changes: 8 additions & 2 deletions app/crud/paper_with_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ def get_multi_model_metrics_by_identifier(
'model_identifier': row.model_identifier,
'model_name': row.model_name,
'model_hardware_burden': row.model_hardware_burden,
'model_operation_per_network_pass': row.model_gflops if row.model_gflops else row.model_multiply_adds,
'model_operation_per_network_pass': (
row.model_gflops
if row.model_gflops else row.model_multiply_adds
),

'paper_identifier': row.paper_identifier,
})
Expand Down Expand Up @@ -83,7 +86,10 @@ def get_model_metrics_by_identifier(
'model_identifier': response[0].model_identifier,
'model_name': response[0].model_name,
'model_hardware_burden': response[0].model_hardware_burden,
'model_operation_per_network_pass': response[0].model_gflops if response[0].model_gflops else response[0].model_multiply_adds,
'model_operation_per_network_pass': (
response[0].model_gflops
if response[0].model_gflops else response[0].model_multiply_adds
),
'paper_identifier': response[0].paper_identifier,
}

Expand Down
10 changes: 8 additions & 2 deletions app/crud/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,10 @@ def get_models(
'gflops': row.model_gflops,
'number_of_parameters': row.model_number_of_parameters,
'multiply_adds': row.model_multiply_adds,
'operation_per_network_pass': row.model_gflops if row.model_gflops else row.model_multiply_adds,
'operation_per_network_pass': (
row.model_gflops
if row.model_gflops else row.model_multiply_adds
),
'hardware_burden': row.model_hardware_burden,
'paper_title': row.paper_title,
'paper_code_link': row.paper_code_link,
Expand Down Expand Up @@ -443,7 +446,10 @@ def get_models_csv(
row.accuracy_type: row.accuracy_value,
'model_gflops': row.model_gflops,
'model_multiply_adds': row.model_multiply_adds,
'model_operation_per_network_pass': row.model_gflops if row.model_gflops else row.model_multiply_adds,
'model_operation_per_network_pass': (
row.model_gflops
if row.model_gflops else row.model_multiply_adds
),
'model_extra_training_time': row.model_extra_training_time,
'model_number_of_cpus': row.model_number_of_cpus,
'model_cpu': row.model_cpu,
Expand Down
2 changes: 1 addition & 1 deletion app/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
Base = declarative_base()
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
2 changes: 1 addition & 1 deletion main.py → app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@

app.include_router(api_router, prefix=settings.API_V1_STR)

app.mount("/image", StaticFiles(directory="image"), name="image")
app.mount("/image", StaticFiles(directory="app/image"), name="image")
2 changes: 1 addition & 1 deletion app/models/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ class Cpu(Base):
tdp = Column(Float(precision=3))
gflops = Column(Float(precision=3))
die_size = Column(Integer)
year = Column(Integer)
year = Column(Integer)
2 changes: 1 addition & 1 deletion app/models/gpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ class Gpu(Base):
tdp = Column(Float(precision=3))
gflops = Column(Float(precision=3))
die_size = Column(Integer)
year = Column(Integer)
year = Column(Integer)
13 changes: 7 additions & 6 deletions app/models/task_dataset.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from sqlalchemy import event
import logging
from sqlalchemy.sql.expression import bindparam, select, text
from app.models import Dataset, Task
from sqlalchemy.sql.functions import func

from sqlalchemy.sql.expression import text
from app.database.base import Base
from sqlalchemy import Column, Integer, ForeignKey, String
from sqlalchemy.orm import relationship
Expand All @@ -25,8 +23,11 @@ class TaskDataset(Base):

def my_before_insert_listener(mapper, connection, target):
target.identifier = connection.execute(
text("select concat(task.identifier,'-on-', dataset.identifier) from task, dataset where task.id = %d and dataset.id = %d" %
(target.task_id, target.dataset_id))
text(
"select concat(task.identifier,'-on-', dataset.identifier) from task, "
"dataset where task.id = %d and dataset.id = %d" %
(target.task_id, target.dataset_id)
)
).scalar()


Expand Down
4 changes: 3 additions & 1 deletion app/routes/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ def get_models_csv(
media_type="text/csv"
)

response.headers["Content-Disposition"] = f"attachment; filename={task_id}-{dataset_id}.csv"
response.headers[
"Content-Disposition"
] = f"attachment; filename={task_id}-{dataset_id}.csv"

return response

Expand Down
2 changes: 1 addition & 1 deletion app/schemas/msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


class Msg(BaseModel):
msg: str
msg: str
2 changes: 0 additions & 2 deletions app/schemas/task.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from app import models
from pydantic.main import BaseModel
from typing import List, Optional

from .dataset import Dataset
from .model import Model

# Shared properties
Expand Down
1 change: 1 addition & 0 deletions app/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '0.1.0'
60 changes: 60 additions & 0 deletions app/test/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest
import asyncio
from httpx import AsyncClient
from sqlalchemy_utils import create_database, database_exists
from os import system, name
from time import sleep

from app.database.base import Base
from app.settings import settings
from app.database.init_db import init_db
from app.main import app
from app.deps import get_db
from app.test.utils.overrides import override_get_db
from app.test.utils.test_db import (
engine,
SQLALCHEMY_TEST_DATABASE_URI,
)
from .utils.test_db import TestSessionLocal

app.dependency_overrides[get_db] = override_get_db

if not database_exists(SQLALCHEMY_TEST_DATABASE_URI):
create_database(SQLALCHEMY_TEST_DATABASE_URI)

Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
init_db(TestSessionLocal())

with open('app/test/utils/initial_seed.sql') as sql_file:
for statement in sql_file.read().split(';'):
if len(statement.strip()) > 0:
engine.execute(statement + ';')

if name == 'nt':
_ = system('cls')

else:
_ = system('clear')

@pytest.fixture(scope="session")
def event_loop():
return asyncio.get_event_loop()


@pytest.fixture(scope="session")
def base_url() -> str:
return "http://localhost:8000/api/v1"


@pytest.fixture(scope="session")
async def headers(base_url) -> dict:
body = {
"username": settings.FIRST_SUPERUSER,
"password": settings.FIRST_SUPERUSER_PASSWORD,
}
async with AsyncClient(app=app, base_url=base_url) as ac:
response = await ac.post("/login/access-token", data=body)
json = response.json()
assert json == {"token_type": "bearer", **json}
return {"Authorization": f"{json['token_type']} {json['access_token']}"}
Empty file.
142 changes: 142 additions & 0 deletions app/test/route_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import pytest
from httpx import AsyncClient, Response

from app.main import app
from app.test.utils.constants import (
DATASETS_KEYS,
DATASETS_BODY,
TASK_KEYS,
TASK,
PAPER_BODY,
PAPER_KEYS,
SUBMISSION_ALT_BODY,
MODEL_KEYS,
SUCCESS,
CPU_BODY,
CPU_KEYS,
TPU_BODY,
GPU_BODY,
GPU_KEYS,
)


@pytest.fixture(scope="session")
async def cpu_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/cpus", json=CPU_BODY)
yield response


@pytest.fixture(scope="session")
async def tpu_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/tpus", json=TPU_BODY)
yield response
# json = response.json()
# tpu_id = json["id"]
# async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
# response = await ac.delete(f"/tpus/{tpu_id}")
# assert response.status_code == SUCCESS
# assert response.json().keys() == json.keys()


@pytest.fixture(scope="session")
async def gpu_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/gpus", json=GPU_BODY)
yield response
# gpu_id = response.json()["id"]
# async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
# response = await ac.delete(f"/gpus/{gpu_id}")
# assert response.status_code == SUCCESS
# assert GPU_KEYS == set(response.json().keys())


@pytest.fixture(scope="session")
async def datasets_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/datasets", json=DATASETS_BODY)
yield response
datasets_id = response.json()["id"]
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.delete(f"/datasets/{datasets_id}")
assert response.status_code == SUCCESS
assert DATASETS_KEYS == set(response.json().keys())


@pytest.fixture(scope="session")
async def task_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/tasks", json=TASK)
a = response.json()
assert response.status_code == SUCCESS
assert response.json().keys() == a.keys()
yield response
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.delete(f"/tasks/{a['id']}")
assert response.status_code == SUCCESS
assert response.json().keys() == TASK_KEYS.keys()


@pytest.fixture(scope="session")
async def submission_approved_created(
base_url: str,
headers: dict,
tpu_created: Response,
cpu_created: Response,
gpu_created: Response,
):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response_create = await ac.post("/submissions", json=SUBMISSION_ALT_BODY)
response_update_status = await ac.put(
f'/submissions/{response_create.json()["id"]}/status',
json={"status": "approved"},
)
assert response_create.status_code == SUCCESS
assert response_update_status.status_code == SUCCESS
return response_update_status.json()


@pytest.fixture(scope="session")
async def get_test_model(
headers: dict,
base_url: str,
submission_approved_created: Response,
cpu_created: Response,
tpu_created: Response,
gpu_created: Response,
):
async with AsyncClient(app=app, base_url=base_url) as ac:
response = await ac.get("/models/?skip=0&limit=1", headers=headers)
assert response.status_code == SUCCESS
assert set(response.json()[0].keys()) == MODEL_KEYS
yield response.json()[0]
model_id = response.json()[0]["id"]
cpu_id = cpu_created.json()["id"]
tpu_id = tpu_created.json()["id"]
gpu_id = gpu_created.json()["id"]
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response_models = await ac.delete(f"/models/{model_id}")
response_cpu = await ac.delete(f"/cpus/{cpu_id}")
response_tpu = await ac.delete(f"/tpus/{tpu_id}")
response_gpu = await ac.delete(f"/gpus/{gpu_id}")
assert response_cpu.status_code == SUCCESS
assert CPU_KEYS == set(response_cpu.json().keys())
assert response_models.status_code == SUCCESS
assert MODEL_KEYS == set(response_models.json().keys())
assert response_tpu.status_code == SUCCESS
assert response_tpu.json().keys() == tpu_created.json().keys()
assert response_gpu.status_code == SUCCESS
assert GPU_KEYS == set(response_gpu.json().keys())


@pytest.fixture(scope="session")
async def paper_created(base_url: str, headers: dict):
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.post("/papers", json=PAPER_BODY)
yield response
paper_id = response.json()["id"]
async with AsyncClient(app=app, base_url=base_url, headers=headers) as ac:
response = await ac.delete(f"/papers/{paper_id}")
assert response.status_code == SUCCESS
assert PAPER_KEYS == set(response.json().keys())
Loading