Skip to content

Commit

Permalink
Merge branch 'main' into version-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
fretchen committed Jul 6, 2024
2 parents ec0ea2b + ba78dc1 commit 652539c
Show file tree
Hide file tree
Showing 13 changed files with 611 additions and 477 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/django.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
poetry install
- name: Run Tests
run: |
poetry run python runtests.py
poetry run runtests
lint:
env:
Expand Down Expand Up @@ -77,10 +77,12 @@ jobs:
export PYTHONPATH=$PYTHONPATH:$PWD
poetry run pylint --load-plugins pylint_django --django-settings-module=tests.test_settings src
poetry run pylint --load-plugins pylint_django --django-settings-module=tests.test_settings tests
poetry run pylint runtests.py
- name: Run black
run: |
poetry run black --check .
- name: Run mypy
run: |
poetry run mypy src
poetry run mypy tests
poetry run mypy tests
poetry run mypy runtests.py
749 changes: 364 additions & 385 deletions poetry.lock

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "django-qlued"
version = "0.2.0"
version = "0.3.0"
description = "Django packages that enables validated cloud access to quantum hardware."
authors = ["fretchen <fred.jendrzejewski@gmail.com>"]
license = "Apache-2.0"
Expand All @@ -17,7 +17,7 @@ django-ninja = "^1.1.0"
python-decouple = "^3.8"
pytz = "^2024.1"
whitenoise = "^6.6.0"
sqooler = "^0.7.0"
sqooler = "^0.9.0"


[tool.poetry.group.dev.dependencies]
Expand All @@ -28,6 +28,8 @@ django-stubs = {extras = ["compatible-mypy"], version = "^4.2.7"}
django-csp = "^3.7"
black = "^24.1.1"
icecream = "^2.1.3"
click = "^8.1.7"
isort = "^5.13.2"

[tool.poetry.group.docs]
optional = true
Expand All @@ -41,3 +43,6 @@ mkdocstrings-python = "^1.8.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
runtests = "runtests:run_test"
39 changes: 23 additions & 16 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/usr/bin/env python
""""
The tests for the module. This is the main test runner for the project. It can be executed as
`poetry run python runtests.py`
`poetry run runtests`
It takes the argument of the tests that should be run. Take as an example that you would
like to run the the test_api_v2 only then you should execute
Expand All @@ -11,24 +10,32 @@
"""

import os
import sys
import argparse

import click
import django
from django.conf import settings
from django.test.utils import get_runner
from icecream import ic

os.environ["DJANGO_SETTINGS_MODULE"] = "tests.test_settings"
django.setup()

parser = argparse.ArgumentParser(description="Run Django tests.")
parser.add_argument("tests", nargs="*", default=["tests"], help="The tests to be run.")
args = parser.parse_args()

ic(args.tests)
TestRunner = get_runner(settings)
test_runner = TestRunner()
failures = test_runner.run_tests(args.tests)
sys.exit(bool(failures))
@click.command()
@click.option(
"--names",
help="The names of the tests that you would like to run.",
default="tests",
)
def run_test(names: str):
"""
Run the test suite for the project. It takes the argument of the tests that should be run.
Take as an example that you would like to run the the test_api_v2 only then you should execute
`poetry run runtests --names tests.test_api_v2`
"""
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.test_settings"
django.setup()
click.secho(f"Running tests for {names}", fg="green")
t_runner_obj = get_runner(settings)
test_runner = t_runner_obj()
failures = test_runner.run_tests([names])
click.secho(f"Tests failed: {failures}", fg="red" if failures else "green")
112 changes: 112 additions & 0 deletions tests/test_api_local.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"""
In this module we test the API locally without the need of an external mongodb database.
"""

import json
import shutil

from decouple import config
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse_lazy
from icecream import ic
from sqooler.utils import get_dummy_config

from qlued.models import StorageProviderDb
from qlued.storage_providers import get_storage_provider_from_entry

from .utils import get_dummy_config

User = get_user_model()


class BackendConfigTest(TestCase):
"""
The class that contains all the tests for this backends app.
"""

def setUp(self):
self.username = config("USERNAME_TEST")
self.password = config("PASSWORD_TEST")
user = User.objects.create(username=self.username)
user.set_password(self.password)
user.save()

# put together the login information
base_path = "storage"

login_dict = {
"base_path": base_path,
}

# create the storage entry in the models
local_entry = StorageProviderDb.objects.create(
storage_type="local",
name="localtest",
owner=user,
description="Local storage provider for tests",
login=login_dict,
is_active=True,
)
local_entry.full_clean()
local_entry.save()

def tearDown(self):
shutil.rmtree("storage")

def test_get_backend_config(self):
"""
Test that we can nicely and add remove the backend config.
"""
backend_name, backend_info = get_dummy_config(sign=False)

local_entry = StorageProviderDb.objects.get(name="localtest")

local_storage = get_storage_provider_from_entry(local_entry)
local_storage.upload_config(backend_info, backend_name)

# test if the backend is now supposed to be operational.
new_config_dict = local_storage.get_config(backend_name)

assert "operational" not in new_config_dict

# now look for the status
backend_status = local_storage.get_backend_status(backend_name)

assert backend_status.operational is False

# now test that the backend status is obtained through the API
url = reverse_lazy(
"api-2.0.0:get_backend_status",
kwargs={"backend_name": f"localtest_{backend_name}_simulator"},
)
req = self.client.get(url)
data = json.loads(req.content)
self.assertEqual(req.status_code, 200)

ic(data)
# get the operational status and see if it is present
self.assertIn("operational", data)

# make sure that it has the right status
self.assertEqual(data["operational"], False)

# now set the config last queue check to obtain a positive config status
local_storage.timestamp_queue(backend_name)

backend_status = local_storage.get_backend_status(backend_name)
assert backend_status.operational is True

req = self.client.get(url)
data = json.loads(req.content)
self.assertEqual(req.status_code, 200)

ic(data)
# get the operational status and see if it is present
self.assertIn("operational", data)

# make sure that it has the right status
self.assertEqual(data["operational"], True)

# and remove the config
local_storage._delete_config(backend_name) # pylint: disable=protected-access
42 changes: 21 additions & 21 deletions tests/test_api_v2.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
"""
The models that define our tests for the api in version 1.
The models that define our tests for the api in version 2.
"""

import json
from datetime import datetime
import uuid
import shutil
import uuid
from datetime import datetime

import pytz


from decouple import config
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse_lazy
from django.contrib.auth import get_user_model

from sqooler.storage_providers.mongodb import MongodbProviderExtended as MongodbProvider
from sqooler.schemes import MongodbLoginInformation
from qlued.models import Token, StorageProviderDb
from sqooler.storage_providers.mongodb import MongodbProviderExtended as MongodbProvider

from qlued.models import StorageProviderDb, Token
from qlued.storage_providers import get_storage_provider_from_entry

from .utils import get_dummy_config

User = get_user_model()

Expand Down Expand Up @@ -120,8 +119,9 @@ def test_get_backend_status(self):
# get the version
self.assertEqual(data["backend_version"], "0.1")

# get the operational status
self.assertEqual(data["operational"], True)
# get the operational status and see if it is present

self.assertIn("operational", data)

# get the pending jobs
self.assertEqual(data["pending_jobs"], 0)
Expand Down Expand Up @@ -394,12 +394,12 @@ def setUp(self):
local_entry.save()

# create a dummy config for the required fermions
fermions_config = {
"display_name": "fermions",
}

_, config_dict = get_dummy_config(sign=False)
config_dict.display_name = "fermions"
local_storage = get_storage_provider_from_entry(local_entry)
local_storage.upload(fermions_config, "backends/configs", "fermions")

# upload the config
local_storage.upload_config(config_dict, "fermions")

# add the second storage provider
base_path = "storage-2"
Expand All @@ -419,12 +419,12 @@ def setUp(self):
local_entry.save()

# create a dummy config for the required single qudit
single_qudit_config = {
"display_name": "singlequdit",
}

_, config_dict = get_dummy_config(sign=False)
config_dict.display_name = "singlequdit"
local_storage = get_storage_provider_from_entry(local_entry)
local_storage.upload(single_qudit_config, "backends/configs", "singlequdit")

# upload the config
local_storage.upload_config(config_dict, "singlequdit")

def tearDown(self):
shutil.rmtree("storage-1")
Expand Down
17 changes: 8 additions & 9 deletions tests/test_dropbox_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
"""

import uuid
from pydantic import ValidationError
from decouple import config

from django.test import TestCase
from decouple import config
from django.contrib.auth import get_user_model

from sqooler.storage_providers.dropbox import DropboxProviderExtended as DropboxProvider
from django.test import TestCase
from pydantic import ValidationError
from sqooler.schemes import DropboxLoginInformation
from sqooler.storage_providers.dropbox import DropboxProviderExtended as DropboxProvider

from qlued.models import StorageProviderDb

Expand Down Expand Up @@ -96,15 +95,15 @@ def test_upload_etc(self):
# make sure that this did not add the _id field to the dict
self.assertFalse("_id" in test_content)

test_result = storage_provider.get_file_content(storage_path, job_id)
test_result = storage_provider.get(storage_path, job_id)

self.assertDictEqual(test_content, test_result)

# move it and get it back
second_path = "test_folder_2"
storage_provider.move_file(storage_path, second_path, job_id)
test_result = storage_provider.get_file_content(second_path, job_id)
storage_provider.move(storage_path, second_path, job_id)
test_result = storage_provider.get(second_path, job_id)
self.assertDictEqual(test_content, test_result)

# clean up our mess
storage_provider.delete_file(second_path, job_id)
storage_provider.delete(second_path, job_id)
Loading

0 comments on commit 652539c

Please sign in to comment.