Rename tests to python_tests

This commit is contained in:
c-bata
2021-07-21 10:24:44 +09:00
parent 32c3a97650
commit daaf106dcb
5 changed files with 0 additions and 0 deletions
View File
+189
View File
@@ -0,0 +1,189 @@
import json
from unittest import TestCase
import optuna
from optuna_dashboard.app import create_app
from .wsgi_client import send_request
def objective(trial: optuna.trial.Trial) -> float:
x = trial.suggest_float("x", -1, 1)
return x
class APITestCase(TestCase):
def test_get_study_summaries(self) -> None:
storage = optuna.storages.InMemoryStorage()
storage.create_new_study("foo1")
storage.create_new_study("foo2")
app = create_app(storage)
status, _, body = send_request(
app,
"/api/studies/",
"GET",
content_type="application/json",
)
self.assertEqual(status, 200)
study_summaries = json.loads(body)["study_summaries"]
self.assertEqual(len(study_summaries), 2)
def test_get_study_details_without_after_param(self) -> None:
study = optuna.create_study()
study_id = study._study_id
study.optimize(objective, n_trials=2)
app = create_app(study._storage)
status, _, body = send_request(
app,
f"/api/studies/{study_id}",
"GET",
content_type="application/json",
)
self.assertEqual(status, 200)
all_trials = json.loads(body)["trials"]
self.assertEqual(len(all_trials), 2)
def test_get_study_details_with_after_param_partial(self) -> None:
study = optuna.create_study()
study_id = study._study_id
study.optimize(objective, n_trials=2)
app = create_app(study._storage)
status, _, body = send_request(
app,
f"/api/studies/{study_id}",
"GET",
queries={"after": "1"},
content_type="application/json",
)
self.assertEqual(status, 200)
all_trials = json.loads(body)["trials"]
self.assertEqual(len(all_trials), 1)
def test_get_study_details_with_after_param_full(self) -> None:
study = optuna.create_study()
study_id = study._study_id
study.optimize(objective, n_trials=2)
app = create_app(study._storage)
status, _, body = send_request(
app,
f"/api/studies/{study_id}",
"GET",
queries={"after": "2"},
content_type="application/json",
)
self.assertEqual(status, 200)
all_trials = json.loads(body)["trials"]
self.assertEqual(len(all_trials), 0)
def test_get_study_details_with_after_param_illegal(self) -> None:
study = optuna.create_study()
study_id = study._study_id
study.optimize(objective, n_trials=2)
app = create_app(study._storage)
status, _, body = send_request(
app,
f"/api/studies/{study_id}",
"GET",
queries={"after": "-1"},
content_type="application/json",
)
self.assertEqual(status, 400)
def test_create_study(self) -> None:
for name, directions, expected_status in [
("single-objective success", ["minimize"], 201),
("multi-objective success", ["minimize", "maximize"], 201),
("invalid direction name", ["invalid-direction", "maximize"], 400),
]:
with self.subTest(name):
storage = optuna.storages.InMemoryStorage()
self.assertEqual(len(storage.get_all_study_summaries()), 0)
app = create_app(storage)
request_body = {
"study_name": "foo",
"directions": directions,
}
status, _, _ = send_request(
app,
"/api/studies",
"POST",
content_type="application/json",
body=json.dumps(request_body),
)
self.assertEqual(status, expected_status)
if expected_status == 201:
self.assertEqual(len(storage.get_all_study_summaries()), 1)
else:
self.assertEqual(len(storage.get_all_study_summaries()), 0)
def test_create_study_duplicated(self) -> None:
storage = optuna.storages.InMemoryStorage()
storage.create_new_study("foo")
self.assertEqual(len(storage.get_all_study_summaries()), 1)
app = create_app(storage)
request_body = {
"study_name": "foo",
"direction": "minimize",
}
status, _, _ = send_request(
app,
"/api/studies",
"POST",
content_type="application/json",
body=json.dumps(request_body),
)
self.assertEqual(status, 400)
self.assertEqual(len(storage.get_all_study_summaries()), 1)
def test_delete_study(self) -> None:
storage = optuna.storages.InMemoryStorage()
storage.create_new_study("foo1")
storage.create_new_study("foo2")
self.assertEqual(len(storage.get_all_study_summaries()), 2)
app = create_app(storage)
status, _, _ = send_request(
app,
"/api/studies/1",
"DELETE",
content_type="application/json",
)
self.assertEqual(status, 204)
self.assertEqual(len(storage.get_all_study_summaries()), 1)
def test_delete_study_not_found(self) -> None:
storage = optuna.storages.InMemoryStorage()
app = create_app(storage)
status, _, _ = send_request(
app,
"/api/studies/1",
"DELETE",
content_type="application/json",
)
self.assertEqual(status, 404)
class BottleRequestHookTestCase(TestCase):
def test_ignore_trailing_slashes(self) -> None:
storage = optuna.storages.InMemoryStorage()
app = create_app(storage)
endpoints = ["/api/studies", "/api/studies/"]
for endpoint in endpoints:
with self.subTest(msg=endpoint):
status, _, body = send_request(
app,
endpoint,
"GET",
content_type="application/json",
)
self.assertEqual(status, 200)
+115
View File
@@ -0,0 +1,115 @@
from unittest import TestCase
import warnings
import optuna
from optuna import create_trial
from optuna.distributions import UniformDistribution
from optuna.exceptions import ExperimentalWarning
from optuna.trial import TrialState
from optuna_dashboard.search_space import _SearchSpace
class SearchSpaceTestCase(TestCase):
def setUp(self) -> None:
optuna.logging.set_verbosity(optuna.logging.ERROR)
warnings.simplefilter("ignore", category=ExperimentalWarning)
def test_same_distributions(self) -> None:
distributions = [
{
"x0": UniformDistribution(low=0, high=10),
"x1": UniformDistribution(low=0, high=10),
},
{
"x0": UniformDistribution(low=0, high=10),
"x1": UniformDistribution(low=0, high=10),
},
]
params = [
{
"x0": 0.5,
"x1": 0.5,
},
{
"x0": 0.5,
"x1": 0.5,
},
]
trials = [
create_trial(state=TrialState.COMPLETE, value=0, distributions=d, params=p)
for d, p in zip(distributions, params)
]
search_space = _SearchSpace()
search_space.update(trials)
self.assertEqual(len(search_space.intersection), 2)
self.assertEqual(len(search_space.union), 2)
def test_different_distributions(self) -> None:
distributions = [
{
"x0": UniformDistribution(low=0, high=10),
"x1": UniformDistribution(low=0, high=10),
},
{
"x0": UniformDistribution(low=0, high=5),
"x1": UniformDistribution(low=0, high=10),
},
]
params = [
{
"x0": 0.5,
"x1": 0.5,
},
{
"x0": 0.5,
"x1": 0.5,
},
]
trials = [
create_trial(state=TrialState.COMPLETE, value=0, distributions=d, params=p)
for d, p in zip(distributions, params)
]
search_space = _SearchSpace()
search_space.update(trials)
self.assertEqual(len(search_space.intersection), 1)
self.assertEqual(len(search_space.union), 3)
def test_dynamic_search_space(self) -> None:
distributions = [
{
"x0": UniformDistribution(low=0, high=10),
"x1": UniformDistribution(low=0, high=10),
},
{
"x0": UniformDistribution(low=0, high=5),
},
{
"x0": UniformDistribution(low=0, high=10),
"x1": UniformDistribution(low=0, high=10),
},
]
params = [
{
"x0": 0.5,
"x1": 0.5,
},
{
"x0": 0.5,
},
{
"x0": 0.5,
"x1": 0.5,
},
]
trials = [
create_trial(state=TrialState.COMPLETE, value=0, distributions=d, params=p)
for d, p in zip(distributions, params)
]
search_space = _SearchSpace()
search_space.update(trials)
self.assertEqual(len(search_space.intersection), 0)
self.assertEqual(len(search_space.union), 3)
+28
View File
@@ -0,0 +1,28 @@
from unittest import TestCase
from optuna_dashboard.serializer import serialize_attrs
class SerializeAttrsTestCase(TestCase):
def test_serialize_bytes(self) -> None:
serialized = serialize_attrs({"bytes": b"This is a bytes object."})
self.assertEqual(serialized[0]["value"], "<binary object>")
def test_serialize_string(self) -> None:
for length in [1000, 1024, 1100]:
with self.subTest(f"length: {length}"):
value = "a" * length
serialized = serialize_attrs(
{
"key": value,
}
)
self.assertLessEqual(len(serialized[0]["value"]), 1024)
def test_serialize_dict(self) -> None:
serialized = serialize_attrs(
{
"key": {"foo": "bar"},
}
)
self.assertLessEqual(len(serialized), 1)
+77
View File
@@ -0,0 +1,77 @@
import io
from typing import Any
from typing import Callable
from typing import Dict
from typing import Iterable
from typing import List
from typing import Optional
from typing import Tuple
from typing import Union
WSGIEnv = Dict[str, Any] # Cannot use TypedDict because of 'HTTP_' variables
StartResponse = Callable[[str, List[Tuple[str, str]]], None]
WSGIApp = Callable[[WSGIEnv, StartResponse], Iterable[bytes]]
def create_wsgi_env(
path: str,
method: str,
content_type: str,
body: bytes,
queries: Dict[str, str],
headers: Dict[str, str],
) -> WSGIEnv:
# 'key1=value1&key2=value2'
query_string = "&".join([f"{k}={v}" for k, v in queries.items()])
# See https://www.python.org/dev/peps/pep-3333/#environ-variables
env = {
"PATH_INFO": path,
"REQUEST_METHOD": method.upper(),
"SCRIPT_NAME": "",
"QUERY_STRING": query_string,
"CONTENT_TYPE": content_type,
"CONTENT_LENGTH": len(body),
"SERVER_PROTOCOL": "http",
"SERVER_NAME": "localhost",
"wsgi.input": io.BytesIO(body),
"wsgi.version": (1, 0),
"wsgi.errors": io.StringIO(""),
"wsgi.multithread": True,
"wsgi.multitprocess": True,
"wsgi.run_once": False,
}
for k, v in headers.items():
env[f"HTTP_{k.upper()}"] = v
return env
def send_request(
app: WSGIApp,
path: str,
method: str,
body: Union[str, bytes] = b"",
queries: Optional[Dict[str, str]] = None,
headers: Optional[Dict[str, str]] = None,
content_type: str = "text/plain; charset=utf-8",
) -> Tuple[int, List[Tuple[str, str]], bytes]:
status: str = ""
response_headers: List[Tuple[str, str]] = []
def start_response(status_: str, headers_: List[Tuple[str, str]]) -> None:
nonlocal status, response_headers
status = status_
response_headers = headers_
bytes_body = body if isinstance(body, bytes) else body.encode("utf-8")
headers = headers or {}
queries = queries or {}
env = create_wsgi_env(path, method, content_type, bytes_body, queries, headers)
body = b""
iterable_body = app(env, start_response)
for b in iterable_body:
body += b
status_code = int(status.split()[0])
return status_code, response_headers, body