Skip to content

Commit 7c1c71f

Browse files
authored
API spec 1.1.1 and .NET implementation (#175)
This removes embedded blobs and dbs into the test server at build time and instead downloads them from GitHub
1 parent 0cf3a4b commit 7c1c71f

15 files changed

Lines changed: 137 additions & 79 deletions

File tree

client/smoke_tests/test_new_session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ async def test_logslurp(self, cblpytest: CBLPyTest) -> None:
3131
async def test_duplicate_new_session(self, cblpytest: CBLPyTest) -> None:
3232
with pytest.raises(CblTestServerBadResponseError, match="returned 400"):
3333
await cblpytest.test_servers[0].new_session(
34-
str(cblpytest.request_factory.uuid), None, None
34+
str(cblpytest.request_factory.uuid), "3.2", None, None
3535
)

client/src/cbltest/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
CouchbaseServerInfo,
1111
ParsedConfig,
1212
SyncGatewayInfo,
13+
TestServerInfo,
1314
_parse_config,
1415
)
1516
from .extrapropsparser import _parse_extra_props
@@ -80,6 +81,7 @@ async def create(
8081
for ts in ret_val.test_servers:
8182
await ts.new_session(
8283
str(ret_val.request_factory.uuid),
84+
ret_val.config.dataset_version_at(ts_index),
8385
ret_val.config.logslurp_url,
8486
f"test-server[{ts_index}]",
8587
)
@@ -105,8 +107,11 @@ def __init__(
105107
self.__request_factory = RequestFactory(self.__config)
106108
self.__test_servers: List[TestServer] = []
107109
index = 0
108-
for url in self.__config.test_servers:
109-
self.__test_servers.append(TestServer(self.__request_factory, index, url))
110+
for ts in self.__config.test_servers:
111+
ts_info = TestServerInfo(ts)
112+
self.__test_servers.append(
113+
TestServer(self.__request_factory, index, ts_info.url)
114+
)
110115
index += 1
111116

112117
self.__sync_gateways: List[SyncGateway] = []

client/src/cbltest/api/testserver.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ async def create_and_reset_db(
7979

8080
return ret_val
8181

82-
async def new_session(self, id: str, url: Optional[str], tag: Optional[str]):
82+
async def new_session(
83+
self, id: str, dataset_version: str, url: Optional[str], tag: Optional[str]
84+
):
8385
"""
8486
Instructs this test server to log to the given LogSlurp instance
8587
@@ -88,7 +90,7 @@ async def new_session(self, id: str, url: Optional[str], tag: Optional[str]):
8890
:param tag: The tag to use for this test server
8991
"""
9092
with self.__tracer.start_as_current_span("new_session"):
91-
payload = PostNewSessionRequestBody(id, url, tag)
93+
payload = PostNewSessionRequestBody(id, dataset_version, url, tag)
9294
request = self.__request_factory.create_request(
9395
TestServerRequestType.NEW_SESSION, payload
9496
)

client/src/cbltest/configparser.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@
1212
)
1313

1414

15+
class TestServerInfo:
16+
"""The parsed Test Server information from the config file"""
17+
18+
___url_key: Final[str] = "url"
19+
__dataset_version_key: Final[str] = "dataset_version"
20+
21+
@property
22+
def url(self) -> str:
23+
"""Gets the URL of the test server instance"""
24+
return self.__url
25+
26+
@property
27+
def dataset_version(self) -> str:
28+
"""Gets the dataset version of the test server instance"""
29+
return self.__dataset_version
30+
31+
def __init__(self, data: dict):
32+
self.__url: str = _assert_string_entry(data, self.___url_key)
33+
self.__dataset_version: str = _assert_string_entry(
34+
data, self.__dataset_version_key
35+
)
36+
37+
1538
class SyncGatewayInfo:
1639
"""The parsed Sync Gateway information from the config file"""
1740

@@ -105,9 +128,10 @@ class ParsedConfig:
105128
__greenboard_key: Final[str] = "greenboard"
106129
__api_version_key: Final[str] = "api-version"
107130
__logslurp_key: Final[str] = "logslurp"
131+
__dataset_version_key: Final[str] = "dataset_version"
108132

109133
@property
110-
def test_servers(self) -> List[str]:
134+
def test_servers(self) -> List[dict]:
111135
"""The list of test servers that can be interacted with"""
112136
return self.__test_servers
113137

@@ -160,9 +184,13 @@ def logslurp_url(self) -> Optional[str]:
160184
"""The URL of the optional logslurp server to send and collect logs"""
161185
return self.__logslurp_url
162186

187+
def dataset_version_at(self, i: int) -> str:
188+
"""The dataset version of the test server instance"""
189+
return self.__test_servers[i][self.__dataset_version_key]
190+
163191
def __init__(self, json: dict):
164192
self.__test_servers = _get_typed_nonnull(
165-
json, self.__test_server_key, List[str], []
193+
json, self.__test_server_key, List[Dict], []
166194
)
167195
self.__sync_gateways = _get_typed_nonnull(json, self.__sgw_key, List[Dict], [])
168196
self.__couchbase_servers = _get_typed_nonnull(

client/src/cbltest/requests.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from importlib import import_module
66
from pathlib import Path
77
from shutil import rmtree
8-
from typing import Any, Optional, Type, cast
8+
from typing import Any, List, Optional, Type, cast
99
from urllib.parse import urljoin
1010
from uuid import UUID, uuid4
1111

@@ -238,7 +238,9 @@ def __init__(self, config: ParsedConfig):
238238
self.__uuid = uuid4()
239239
self.__session = ClientSession()
240240
self.__version = available_api_version(config.api_version)
241-
self.__server_urls = config.test_servers
241+
self.__server_urls = cast(
242+
List[str], list(str(ts["url"]) for ts in config.test_servers)
243+
)
242244
cbl_info(
243245
f"RequestFactory created with API version {self.__version} ({self.__uuid})"
244246
)

client/src/cbltest/v1/requests.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,14 +568,20 @@ def tag(self) -> Optional[str]:
568568
"""Returns the tag to use to print in log statements from this particular remote"""
569569
return self.__tag
570570

571-
def __init__(self, id: str, url: Optional[str], tag: Optional[str]):
571+
def __init__(
572+
self, id: str, dataset_version: str, url: Optional[str], tag: Optional[str]
573+
):
572574
super().__init__(1)
573575
self.__url = url
576+
self.__dataset_version = dataset_version
574577
self.__id = id
575578
self.__tag = tag
576579

577580
def to_json(self) -> Any:
578-
json: Dict[str, Any] = {"id": self.__id}
581+
json: Dict[str, Any] = {
582+
"id": self.__id,
583+
"dataset_version": self.__dataset_version,
584+
}
579585
if self.__url is not None and self.__tag is not None:
580586
json["logging"] = {"url": self.__url, "tag": self.__tag}
581587

client/src/cbltest/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Final
22

33
# For hatchling to easily detect the version
4-
__version__ = "1.1.0"
4+
__version__ = "1.1.1"
55

66
# Typed version for outside use
77
VERSION: Final[str] = __version__

environment/aws/start_backend.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,12 @@ def write_config(
180180
test_servers = []
181181
for ts in topology.test_servers:
182182
port = 5555 if ts.platform.startswith("dotnet") else 8080
183-
test_servers.append(f"http://{ts.ip_address}:{port}")
183+
test_servers.append(
184+
{
185+
"url": f"http://{ts.ip_address}:{port}",
186+
"dataset_version": ts.dataset_version,
187+
}
188+
)
184189

185190
config_json["test-servers"] = test_servers
186191

environment/aws/topology_setup/setup_topology.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,20 @@ def ip_address(self) -> str:
372372
def cbl_version(self) -> str:
373373
return self.__cbl_version
374374

375+
@property
376+
def dataset_version(self) -> str:
377+
return self.__dataset_version
378+
375379
@property
376380
def platform(self) -> str:
377381
return self.__platform
378382

379-
def __init__(self, ip_address: str, cbl_version: str, platform: str):
383+
def __init__(
384+
self, ip_address: str, cbl_version: str, dataset_version: str, platform: str
385+
):
380386
self.__ip_address = ip_address
381387
self.__cbl_version = cbl_version
388+
self.__dataset_version = dataset_version
382389
self.__platform = platform
383390

384391

@@ -648,6 +655,7 @@ def resolve_test_servers(self):
648655
TestServerConfig(
649656
bridge.get_ip(test_server_input.location),
650657
test_server_input.cbl_version,
658+
test_server_input.dataset_version,
651659
test_server_input.platform,
652660
)
653661
)
@@ -807,6 +815,7 @@ def dump(self):
807815
click.echo(f"Test Server {i}:")
808816
click.echo(f"\tPlatform: {test_server.platform}")
809817
click.echo(f"\tCBL Version: {test_server.cbl_version}")
818+
click.echo(f"\tDataset Version: {test_server.dataset_version}")
810819
click.echo(f"\tIP Address: {test_server.ip_address}")
811820
i += 1
812821

environment/aws/topology_setup/test_server_platforms/dotnet_register.py

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@
4141

4242
from environment.aws.common.io import unzip_directory, zip_directory
4343
from environment.aws.common.output import header
44-
from environment.aws.topology_setup.test_server import (
45-
TEST_SERVER_DIR,
46-
TestServer,
47-
copy_dataset,
48-
)
44+
from environment.aws.topology_setup.test_server import TEST_SERVER_DIR, TestServer
4945

5046
from .android_bridge import AndroidBridge
5147
from .exe_bridge import ExeBridge
@@ -73,12 +69,6 @@ class DotnetTestServer(TestServer):
7369
def __init__(self, version: str, dataset_version: str):
7470
super().__init__(version, dataset_version)
7571

76-
def _copy_dataset(self) -> None:
77-
copy_dataset(
78-
DOTNET_TEST_SERVER_DIR / "testserver" / "Resources" / "Raw",
79-
self.dataset_version,
80-
)
81-
8272
@property
8373
@abstractmethod
8474
def dotnet_framework(self) -> str:
@@ -115,7 +105,6 @@ def build(self) -> None:
115105
"""
116106
Build the .NET test server.
117107
"""
118-
self._copy_dataset()
119108
version_parts = self.version.split("-")
120109
build = version_parts[1]
121110
cbl_version = f"{version_parts[0]}-b{build.zfill(4)}"
@@ -179,19 +168,10 @@ def rid(self) -> str:
179168
"""
180169
pass
181170

182-
def _copy_dataset(self) -> None:
183-
dest_dir = DOTNET_TEST_SERVER_DIR / "testserver.cli" / "Resources"
184-
dest_dir.mkdir(0o755, exist_ok=True)
185-
copy_dataset(
186-
dest_dir,
187-
self.dataset_version,
188-
)
189-
190171
def build(self) -> None:
191172
"""
192173
Build the .NET CLI test server.
193174
"""
194-
self._copy_dataset()
195175
version_parts = self.version.split("-")
196176
build = version_parts[1]
197177
cbl_version = f"{version_parts[0]}-b{build.zfill(4)}"
@@ -293,7 +273,7 @@ def latestbuilds_path(self) -> str:
293273
str: The path for the latest builds.
294274
"""
295275
version_parts = self.version.split("-")
296-
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_ios_{self.dataset_version}.zip"
276+
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_ios.zip"
297277

298278
def create_bridge(self) -> PlatformBridge:
299279
"""
@@ -400,7 +380,7 @@ def latestbuilds_path(self) -> str:
400380
str: The path for the latest builds.
401381
"""
402382
version_parts = self.version.split("-")
403-
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_android_{self.dataset_version}.apk"
383+
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_android.apk"
404384

405385
def create_bridge(self) -> PlatformBridge:
406386
"""
@@ -414,7 +394,7 @@ def create_bridge(self) -> PlatformBridge:
414394
/ "downloaded"
415395
/ self.platform
416396
/ self.version
417-
/ f"testserver_android_{self.dataset_version}.apk"
397+
/ "testserver_android.apk"
418398
if self._downloaded
419399
else DOTNET_TEST_SERVER_DIR
420400
/ "testserver"
@@ -444,9 +424,7 @@ def compress_package(self) -> str:
444424
/ "net8.0-android"
445425
/ "com.couchbase.dotnet.testserver-Signed.apk"
446426
)
447-
zip_path = (
448-
apk_path.parents[5] / f"testserver_android_{self.dataset_version}.apk"
449-
)
427+
zip_path = apk_path.parents[5] / "testserver_android.apk"
450428
shutil.copy(apk_path, zip_path)
451429
return str(zip_path)
452430

@@ -503,7 +481,7 @@ def latestbuilds_path(self) -> str:
503481
str: The path for the latest builds.
504482
"""
505483
version_parts = self.version.split("-")
506-
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_windows_{self.dataset_version}.zip"
484+
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_windows.zip"
507485

508486
def create_bridge(self) -> PlatformBridge:
509487
"""
@@ -611,7 +589,7 @@ def latestbuilds_path(self) -> str:
611589
str: The path for the latest builds.
612590
"""
613591
version_parts = self.version.split("-")
614-
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_macos_{self.dataset_version}.zip"
592+
return f"couchbase-lite-net/{version_parts[0]}/{version_parts[1]}/testserver_macos.zip"
615593

616594
def create_bridge(self) -> PlatformBridge:
617595
"""

0 commit comments

Comments
 (0)