Skip to content

Commit 119c7ac

Browse files
committed
Cloud API: Add software tests for cluster deployment conversation
1 parent c76fbe3 commit 119c7ac

File tree

6 files changed

+175
-48
lines changed

6 files changed

+175
-48
lines changed

cratedb_toolkit/util/runtime.py

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def wrapper(*args, **kwargs):
4646
if CONFIG.runtime_errors == "raise":
4747
raise
4848
elif CONFIG.runtime_errors == "exit": # noqa: RET506
49+
logger.error(ex)
4950
sys.exit(runtime_error_exit_code)
5051
else:
5152
raise NotImplementedError(

tests/cluster/__init__.py

Whitespace-only changes.

tests/cluster/test_examples.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright (c) 2023, Crate.io Inc.
2+
# Distributed under the terms of the AGPLv3 license, see LICENSE.
3+
import responses
4+
5+
import cratedb_toolkit
6+
7+
8+
@responses.activate
9+
def test_example_cloud_cluster_exists(mocker, mock_cloud_cluster_exists):
10+
"""
11+
Verify that the program `examples/cloud_cluster.py` works.
12+
In this case, there is a mock which pretends the cluster already exists.
13+
"""
14+
15+
cratedb_toolkit.configure(
16+
settings_accept_cli=True,
17+
settings_accept_env=True,
18+
)
19+
20+
mocker.patch.dict(
21+
"os.environ",
22+
{
23+
"CRATEDB_CLOUD_SUBSCRIPTION_ID": "f33a2f55-17d1-4f21-8130-b6595d7c52db",
24+
"CRATEDB_CLOUD_CLUSTER_NAME": "testcluster",
25+
"CRATEDB_USERNAME": "crate",
26+
},
27+
)
28+
from examples.cloud_cluster import main
29+
30+
main()
31+
32+
33+
@responses.activate
34+
def test_example_cloud_cluster_with_deploy(mocker, mock_cloud_cluster_deploy):
35+
"""
36+
Verify that the program `examples/cloud_cluster.py` works.
37+
In this case, mocking-wise, there is no cluster, but the test exercises a full cluster deployment.
38+
"""
39+
40+
cratedb_toolkit.configure(
41+
settings_accept_cli=True,
42+
settings_accept_env=True,
43+
)
44+
45+
mocker.patch.dict(
46+
"os.environ",
47+
{
48+
"CRATEDB_CLOUD_SUBSCRIPTION_ID": "f33a2f55-17d1-4f21-8130-b6595d7c52db",
49+
"CRATEDB_CLOUD_CLUSTER_NAME": "testcluster",
50+
"CRATEDB_USERNAME": "crate",
51+
},
52+
)
53+
from examples.cloud_cluster import main
54+
55+
main()
56+
57+
58+
@responses.activate
59+
def test_example_cloud_import(mocker, mock_cloud_import):
60+
"""
61+
Verify that the program `examples/cloud_import.py` works.
62+
"""
63+
64+
cratedb_toolkit.configure(
65+
settings_accept_cli=True,
66+
settings_accept_env=True,
67+
)
68+
69+
mocker.patch.dict(
70+
"os.environ",
71+
{
72+
"CRATEDB_CLOUD_CLUSTER_ID": "e1e38d92-a650-48f1-8a70-8133f2d5c400",
73+
},
74+
)
75+
from examples.cloud_import import main
76+
77+
main()

tests/conftest.py

+95-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Copyright (c) 2021-2023, Crate.io Inc.
22
# Distributed under the terms of the AGPLv3 license, see LICENSE.
3+
import json
4+
35
import pytest
46
import responses
57

@@ -86,38 +88,106 @@ def cratedb(cratedb_service):
8688

8789

8890
@pytest.fixture
89-
def cloud_cluster_mock():
91+
def mock_cloud_cluster_exists(cratedb):
92+
"""
93+
Mock a CrateDB Cloud API conversation, pretending a cluster exists.
94+
"""
95+
responses.add_passthru("http+docker://localhost/")
9096
responses.add(
91-
responses.Response(
92-
method="GET",
93-
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/",
94-
json={
95-
"url": "https://testdrive.example.org:4200/",
97+
method="GET",
98+
url="https://console.cratedb.cloud/api/v2/clusters/",
99+
json=[
100+
{
101+
"id": "e1e38d92-a650-48f1-8a70-8133f2d5c400",
102+
"url": cratedb.get_connection_url(),
96103
"project_id": "3b6b7c82-d0ab-458c-ae6f-88f8346765ee",
97104
"name": "testcluster",
98-
},
99-
)
105+
}
106+
],
100107
)
108+
109+
110+
@pytest.fixture
111+
def mock_cloud_cluster_deploy(cratedb):
112+
"""
113+
Mock a CrateDB Cloud API conversation, for exercising a full deployment process.
114+
"""
115+
responses.add_passthru("http+docker://localhost/")
116+
117+
callcount = 0
118+
119+
def cluster_list_callback(request):
120+
nonlocal callcount
121+
callcount += 1
122+
headers = {}
123+
if callcount == 1:
124+
data = []
125+
else:
126+
data = [
127+
{
128+
"id": "e1e38d92-a650-48f1-8a70-8133f2d5c400",
129+
"url": cratedb.get_connection_url(),
130+
"project_id": "3b6b7c82-d0ab-458c-ae6f-88f8346765ee",
131+
"name": "testcluster",
132+
}
133+
]
134+
return 200, headers, json.dumps(data)
135+
136+
responses.add_callback(
137+
method="GET",
138+
url="https://console.cratedb.cloud/api/v2/clusters/",
139+
callback=cluster_list_callback,
140+
)
141+
101142
responses.add(
102-
responses.Response(
103-
method="POST",
104-
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/import-jobs/",
105-
json={"id": "testdrive-job-id", "status": "REGISTERED"},
106-
)
143+
method="GET",
144+
url="https://console.cratedb.cloud/api/v2/projects/",
145+
json=[],
107146
)
147+
108148
responses.add(
109-
responses.Response(
110-
method="GET",
111-
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/import-jobs/",
112-
json=[
113-
{
114-
"id": "testdrive-job-id",
115-
"status": "SUCCEEDED",
116-
"progress": {"message": "Import succeeded"},
117-
"destination": {"table": "basic"},
118-
}
119-
],
120-
)
149+
method="POST",
150+
url="https://console.cratedb.cloud/api/v2/projects/",
151+
json={"id": "3b6b7c82-d0ab-458c-ae6f-88f8346765ee"},
152+
)
153+
154+
responses.add(
155+
method="GET",
156+
url="https://console.cratedb.cloud/api/v2/projects/3b6b7c82-d0ab-458c-ae6f-88f8346765ee/",
157+
json={},
158+
)
159+
160+
161+
@pytest.fixture
162+
def mock_cloud_import():
163+
"""
164+
Mock a CrateDB Cloud API conversation, pretending to run a successful data import.
165+
"""
166+
responses.add(
167+
method="GET",
168+
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/",
169+
json={
170+
"url": "https://testdrive.example.org:4200/",
171+
"project_id": "3b6b7c82-d0ab-458c-ae6f-88f8346765ee",
172+
"name": "testcluster",
173+
},
174+
)
175+
responses.add(
176+
method="POST",
177+
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/import-jobs/",
178+
json={"id": "testdrive-job-id", "status": "REGISTERED"},
179+
)
180+
responses.add(
181+
method="GET",
182+
url="https://console.cratedb.cloud/api/v2/clusters/e1e38d92-a650-48f1-8a70-8133f2d5c400/import-jobs/",
183+
json=[
184+
{
185+
"id": "testdrive-job-id",
186+
"status": "SUCCEEDED",
187+
"progress": {"message": "Import succeeded"},
188+
"destination": {"table": "basic"},
189+
}
190+
],
121191
)
122192

123193

tests/io/test_import.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_import_csv_dask_with_progressbar(cratedb, dummy_csv):
5252

5353
@pytest.mark.skip("Does not work. Q: Why? A: Response mocking? Q: And now? A: Just patch the low-level functions!")
5454
@responses.activate
55-
def test_import_cloud_file(tmp_path, caplog, cloud_cluster_mock):
55+
def test_import_cloud_file(tmp_path, caplog, mock_cloud_import):
5656
"""
5757
CLI test: Invoke `ctk load table ...` for a CrateDB Cloud Import, from a local file.
5858
"""
@@ -86,7 +86,7 @@ def test_import_cloud_file(tmp_path, caplog, cloud_cluster_mock):
8686

8787

8888
@responses.activate
89-
def test_import_cloud_url(caplog, cloud_cluster_mock):
89+
def test_import_cloud_url(caplog, mock_cloud_import):
9090
"""
9191
CLI test: Invoke `ctk load table ...` for a CrateDB Cloud Import, from a URL.
9292
"""

tests/retention/test_examples.py

-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
# Copyright (c) 2023, Crate.io Inc.
22
# Distributed under the terms of the AGPLv3 license, see LICENSE.
3-
import responses
4-
5-
import cratedb_toolkit
63

74

85
def test_example_edit(store):
@@ -21,21 +18,3 @@ def test_example_retire_cutoff(store):
2118
from examples.retention_retire_cutoff import main
2219

2320
main(dburi=store.database.dburi)
24-
25-
26-
@responses.activate
27-
def test_example_cloud_import(mocker, store, cloud_cluster_mock):
28-
"""
29-
Verify that the program `examples/cloud_import.py` works.
30-
"""
31-
32-
cratedb_toolkit.configure(
33-
settings_accept_cli=True,
34-
settings_accept_env=True,
35-
)
36-
37-
cluster_id = "e1e38d92-a650-48f1-8a70-8133f2d5c400"
38-
mocker.patch.dict("os.environ", {"CRATEDB_CLOUD_CLUSTER_ID": cluster_id})
39-
from examples.cloud_import import main
40-
41-
main()

0 commit comments

Comments
 (0)