forked from openml/openml-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_api_calls.py
More file actions
129 lines (104 loc) · 4.6 KB
/
test_api_calls.py
File metadata and controls
129 lines (104 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from __future__ import annotations
import unittest.mock
from pathlib import Path
from typing import NamedTuple, Iterable, Iterator
from unittest import mock
import minio
import pytest
import openml
from openml.config import ConfigurationForExamples
import openml.testing
from openml._api_calls import _download_minio_bucket, API_TOKEN_HELP_LINK
class TestConfig(openml.testing.TestBase):
@pytest.mark.test_server()
def test_too_long_uri(self):
with pytest.raises(openml.exceptions.OpenMLServerError, match="URI too long!"):
openml.datasets.list_datasets(data_id=list(range(10000)))
@pytest.mark.skip(reason="Pending resolution of #1657")
@unittest.mock.patch("time.sleep")
@unittest.mock.patch("requests.Session")
@pytest.mark.test_server()
def test_retry_on_database_error(self, Session_class_mock, _):
response_mock = unittest.mock.Mock()
response_mock.text = (
"<oml:error>\n"
"<oml:code>107</oml:code>"
"<oml:message>Database connection error. "
"Usually due to high server load. "
"Please wait for N seconds and try again.</oml:message>\n"
"</oml:error>"
)
Session_class_mock.return_value.__enter__.return_value.get.return_value = response_mock
with pytest.raises(openml.exceptions.OpenMLServerException, match="/abc returned code 107"):
openml._api_calls._send_request("get", "/abc", {})
assert Session_class_mock.return_value.__enter__.return_value.get.call_count == 20
class FakeObject(NamedTuple):
object_name: str
etag: str
"""We use the etag of a Minio object as the name of a marker if we already downloaded it."""
class FakeMinio:
def __init__(self, objects: Iterable[FakeObject] | None = None):
self._objects = objects or []
def list_objects(self, *args, **kwargs) -> Iterator[FakeObject]:
yield from self._objects
def fget_object(self, object_name: str, file_path: str, *args, **kwargs) -> None:
if object_name in [obj.object_name for obj in self._objects]:
Path(file_path).write_text("foo")
return
raise FileNotFoundError
@mock.patch.object(minio, "Minio")
def test_download_all_files_observes_cache(mock_minio, tmp_path: Path) -> None:
some_prefix, some_filename = "some/prefix", "dataset.arff"
some_object_path = f"{some_prefix}/{some_filename}"
some_url = f"https://not.real.com/bucket/{some_object_path}"
mock_minio.return_value = FakeMinio(
objects=[
FakeObject(object_name=some_object_path, etag=str(hash(some_object_path))),
],
)
_download_minio_bucket(source=some_url, destination=tmp_path)
time_created = (tmp_path / "dataset.arff").stat().st_ctime
_download_minio_bucket(source=some_url, destination=tmp_path)
time_modified = (tmp_path / some_filename).stat().st_mtime
assert time_created == time_modified
@mock.patch.object(minio, "Minio")
def test_download_minio_failure(mock_minio, tmp_path: Path) -> None:
some_prefix, some_filename = "some/prefix", "dataset.arff"
some_object_path = f"{some_prefix}/{some_filename}"
some_url = f"https://not.real.com/bucket/{some_object_path}"
mock_minio.return_value = FakeMinio(
objects=[
FakeObject(object_name=None, etag="tmp"),
],
)
with pytest.raises(ValueError):
_download_minio_bucket(source=some_url, destination=tmp_path)
mock_minio.return_value = FakeMinio(
objects=[
FakeObject(object_name="tmp", etag=None),
],
)
with pytest.raises(ValueError):
_download_minio_bucket(source=some_url, destination=tmp_path)
@pytest.mark.parametrize(
"endpoint, method",
[
# https://github.com/openml/OpenML/blob/develop/openml_OS/views/pages/api_new/v1/xml/pre.php
("flow/exists", "post"), # 102
("dataset", "post"), # 137
("dataset/42", "delete"), # 350
# ("flow/owned", "post"), # 310 - Couldn't find what would trigger this
("flow/42", "delete"), # 320
("run/42", "delete"), # 400
("task/42", "delete"), # 460
],
)
@pytest.mark.test_server()
def test_authentication_endpoints_requiring_api_key_show_relevant_help_link(
endpoint: str,
method: str,
) -> None:
# We need to temporarily disable the API key to test the error message
with openml.config.overwrite_config_context({"apikey": None}):
with pytest.raises(openml.exceptions.OpenMLAuthenticationError, match=API_TOKEN_HELP_LINK):
openml._api_calls._perform_api_call(call=endpoint, request_method=method, data=None)