5
5
import struct
6
6
from typing import Awaitable
7
7
from typing import Callable
8
+ from typing import Iterable
8
9
from typing import Literal
9
10
from typing import Mapping
10
11
from typing import Sequence
@@ -261,7 +262,10 @@ async def violation_atomic_write_check_failure_with_out_of_bounds_index(
261
262
).SerializeToString (),
262
263
)
263
264
264
- async def violation_atomic_write_check_failure_without_failed_checks (
265
+ # The denokv self-hosted implementation does not return indexes of failed
266
+ # checks.
267
+ # https://github.com/denoland/denokv/issues/110
268
+ async def quirk_atomic_write_check_failure_without_failed_checks (
265
269
request : web .Request ,
266
270
) -> web .Response :
267
271
write = AtomicWrite ()
@@ -363,7 +367,7 @@ def add_datapath_post(app: web.Application, path: str, handler: Handler) -> None
363
367
)
364
368
app .router .add_post (
365
369
"/check_failure_without_failed_checks/atomic_write" ,
366
- violation_atomic_write_check_failure_without_failed_checks ,
370
+ quirk_atomic_write_check_failure_without_failed_checks ,
367
371
)
368
372
app .router .add_post ("/unusable/atomic_write" , unusable_atomic_write )
369
373
app .router .add_post (
@@ -781,10 +785,12 @@ async def test_atomic_write__raises_when_given_endpoint_without_strong_consisten
781
785
),
782
786
(
783
787
"/check_failure_without_failed_checks" ,
784
- lambda endpoint : ProtocolViolation (
785
- "Server responded to Data Path Atomic Write with CHECK_FAILURE "
786
- "containing no failed checks" ,
787
- data = AtomicWriteOutput (status = AtomicWriteStatus .AW_CHECK_FAILURE ),
788
+ lambda endpoint : CheckFailure (
789
+ "Not all checks required by the Atomic Write passed" ,
790
+ all_checks = [
791
+ Check (key = pack_key (("x" ,)), versionstamp = bytes (VersionStamp (0 )))
792
+ ],
793
+ failed_check_indexes = [],
788
794
endpoint = endpoint ,
789
795
),
790
796
),
@@ -1385,6 +1391,26 @@ def test_CheckFailure(example_endpoint: EndpointInfo) -> None:
1385
1391
assert msg in str (e )
1386
1392
1387
1393
1394
+ @pytest .mark .parametrize ("failed_check_indexes" , [None , ()])
1395
+ def test_CheckFailure__failed_check_indexes_is_None_when_no_indexes (
1396
+ failed_check_indexes : Iterable [int ] | None , example_endpoint : EndpointInfo
1397
+ ) -> None :
1398
+ checks = [
1399
+ Check (key = bytes (KvKey (f"a{ i } " )), versionstamp = bytes (VersionStamp (i )))
1400
+ for i in range (4 )
1401
+ ]
1402
+ # Failed_check_indexes can be empty (the self-hosted sqlite implementation
1403
+ # does not return the indexes of failed checks).
1404
+ e = CheckFailure (
1405
+ "Foo" ,
1406
+ all_checks = iter (checks ),
1407
+ failed_check_indexes = failed_check_indexes ,
1408
+ endpoint = example_endpoint ,
1409
+ )
1410
+ assert e .all_checks == tuple (checks )
1411
+ assert e .failed_check_indexes is None
1412
+
1413
+
1388
1414
def test_CheckFailure__validates_constructor_args (
1389
1415
example_endpoint : EndpointInfo ,
1390
1416
) -> None :
@@ -1395,11 +1421,6 @@ def test_CheckFailure__validates_constructor_args(
1395
1421
"Foo" , all_checks = [], failed_check_indexes = [], endpoint = example_endpoint
1396
1422
)
1397
1423
1398
- with pytest .raises (ValueError , match = r"failed_check_indexes is empty" ):
1399
- CheckFailure (
1400
- "Foo" , all_checks = checks , failed_check_indexes = [], endpoint = example_endpoint
1401
- )
1402
-
1403
1424
with pytest .raises (
1404
1425
IndexError , match = r"failed_check_indexes contains out-of-bounds index"
1405
1426
):
0 commit comments