Skip to content

Commit b0696aa

Browse files
authored
🧪 Skip tests with jsonld url resolution failures (#3798)
* ✨ Create `skip_on_jsonld_url_error` decorator Signed-off-by: ff137 <ff137@proton.me> * 🧪 Add `skip_on_jsonld_url_error` decorator to tests Signed-off-by: ff137 <ff137@proton.me> * 🎨 Switch uuid to uuid_utils Signed-off-by: ff137 <ff137@proton.me> #OCD * 🧪 Mark more tests Signed-off-by: ff137 <ff137@proton.me> * 🎨 Signed-off-by: ff137 <ff137@proton.me> --------- Signed-off-by: ff137 <ff137@proton.me>
1 parent e25a002 commit b0696aa

6 files changed

Lines changed: 93 additions & 6 deletions

File tree

acapy_agent/messaging/jsonld/tests/test_credential.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import json
44
from unittest import IsolatedAsyncioTestCase
55

6-
from ....utils.testing import create_test_profile
6+
from ....utils.testing import create_test_profile, skip_on_jsonld_url_error
77
from ....wallet.base import BaseWallet
88
from ....wallet.key_type import ED25519
99
from .. import credential as test_module
@@ -52,6 +52,7 @@ async def asyncSetUp(self):
5252
self.wallet = session.inject(BaseWallet)
5353
await self.wallet.create_signing_key(ED25519, TEST_SEED)
5454

55+
@skip_on_jsonld_url_error
5556
async def test_verify_credential(self):
5657
async with self.profile.session() as session:
5758
for input_ in TEST_VERIFY_OBJS:
@@ -73,6 +74,7 @@ async def test_sign_credential(self):
7374
assert "proof" in result.keys()
7475
assert "jws" in result.get("proof", {}).keys()
7576

77+
@skip_on_jsonld_url_error
7678
async def test_sign_dropped_attribute_exception(self):
7779
async with self.profile.session() as session:
7880
for input_ in TEST_SIGN_ERROR_OBJS:
@@ -97,6 +99,7 @@ async def test_signature_option_type(self):
9799
TEST_VERKEY,
98100
)
99101

102+
@skip_on_jsonld_url_error
100103
async def test_invalid_jws_header(self):
101104
with self.assertRaises(BadJWSHeaderError):
102105
async with self.profile.session() as session:

acapy_agent/messaging/jsonld/tests/test_routes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ....resolver.base import DIDMethodNotSupported, DIDNotFound, ResolverError
1313
from ....resolver.did_resolver import DIDResolver
1414
from ....tests import mock
15-
from ....utils.testing import create_test_profile
15+
from ....utils.testing import create_test_profile, skip_on_jsonld_url_error
1616
from ....wallet.base import BaseWallet
1717
from ....wallet.did_method import SOV, DIDMethods
1818
from ....wallet.error import WalletError
@@ -308,6 +308,7 @@ async def asyncTearDown(self):
308308
# Ensure the event loop is closed
309309
await self.profile.close()
310310

311+
@skip_on_jsonld_url_error
311312
async def test_verify_credential(self):
312313
POSTED_REQUEST = { # posted json
313314
"verkey": (
@@ -439,6 +440,7 @@ async def test_verify_credential(self):
439440
with self.assertRaises(test_module.web.HTTPForbidden):
440441
await test_module.verify(self.request)
441442

443+
@skip_on_jsonld_url_error
442444
async def test_sign_credential(self):
443445
POSTED_REQUEST = { # posted json
444446
"verkey": self.did_info.verkey,

acapy_agent/messaging/v2_agent_message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""DIDComm V2 Agent message base class and schema."""
22

3-
from uuid import uuid4
3+
from uuid_utils import uuid4
44

55
from .base_message import BaseMessage, DIDCommVersion
66

acapy_agent/protocols/present_proof/dif/tests/test_pres_exch_handler.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .....resolver.did_resolver import DIDResolver
1212
from .....storage.vc_holder.vc_record import VCRecord
1313
from .....tests import mock
14-
from .....utils.testing import create_test_profile
14+
from .....utils.testing import create_test_profile, skip_on_jsonld_url_error
1515
from .....vc.ld_proofs import BbsBlsSignature2020
1616
from .....vc.ld_proofs.constants import SECURITY_CONTEXT_BBS_URL
1717
from .....vc.ld_proofs.document_loader import DocumentLoader
@@ -82,6 +82,7 @@ async def setup_tuple(self, profile):
8282
creds, pds = get_test_data()
8383
return creds, pds
8484

85+
@skip_on_jsonld_url_error
8586
async def test_load_cred_json_a(self):
8687
cred_list, pd_list = await self.setup_tuple(self.profile)
8788
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
@@ -103,6 +104,7 @@ async def test_load_cred_json_a(self):
103104
assert len(tmp_vp.get("verifiableCredential")) == tmp_pd[1]
104105

105106
@pytest.mark.ursa_bbs_signatures
107+
@skip_on_jsonld_url_error
106108
async def test_load_cred_json_b(self):
107109
cred_list, pd_list = await self.setup_tuple(self.profile)
108110
dif_pres_exch_handler = DIFPresExchHandler(
@@ -346,6 +348,7 @@ async def test_make_requirement_with_none_params(self):
346348
)
347349

348350
@pytest.mark.ursa_bbs_signatures
351+
@skip_on_jsonld_url_error
349352
async def test_subject_is_issuer_check(self):
350353
cred_list, _ = await self.setup_tuple(self.profile)
351354
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
@@ -712,6 +715,7 @@ async def test_reveal_doc_wildcard(self):
712715
assert tmp_reveal_doc
713716

714717
@pytest.mark.ursa_bbs_signatures
718+
@skip_on_jsonld_url_error
715719
async def test_filter_number_type_check(self):
716720
await self.setup_tuple(self.profile)
717721
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
@@ -1246,6 +1250,7 @@ async def test_edd_jsonld_creds(self):
12461250
assert len(tmp_vp.get("verifiableCredential")) == 3
12471251

12481252
@pytest.mark.ursa_bbs_signatures
1253+
@skip_on_jsonld_url_error
12491254
async def test_filter_string(self):
12501255
cred_list, _ = await self.setup_tuple(self.profile)
12511256
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
@@ -1864,6 +1869,7 @@ async def test_sign_pres_bbsbls(self):
18641869
)
18651870
assert len(tmp_vp.get("verifiableCredential")) == 6
18661871

1872+
@skip_on_jsonld_url_error
18671873
def test_create_vc_record_with_graph_struct(self):
18681874
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
18691875
test_credential_dict_a = {
@@ -2639,6 +2645,7 @@ def test_validate_patch_catch_errors(self):
26392645
)
26402646

26412647
@pytest.mark.ursa_bbs_signatures
2648+
@skip_on_jsonld_url_error
26422649
async def test_derive_cred_missing_credsubjectid(self):
26432650
dif_pres_exch_handler = DIFPresExchHandler(self.profile)
26442651
test_pd = """

acapy_agent/protocols/present_proof/v2_0/formats/dif/tests/test_handler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .......storage.vc_holder.base import VCHolder
1111
from .......storage.vc_holder.vc_record import VCRecord
1212
from .......tests import mock
13-
from .......utils.testing import create_test_profile
13+
from .......utils.testing import create_test_profile, skip_on_jsonld_url_error
1414
from .......vc.ld_proofs import DocumentLoader
1515
from .......vc.vc_di.manager import VcDiManager
1616
from .......vc.vc_ld.manager import VcLdpManager
@@ -2025,6 +2025,7 @@ async def test_verify_received_pres_no_match_a(self):
20252025
await self.handler.receive_pres(message=dif_pres, pres_ex_record=record)
20262026
mock_log_err.assert_called_once()
20272027

2028+
@skip_on_jsonld_url_error
20282029
async def test_verify_received_pres_no_match_b(self):
20292030
dif_proof_req = deepcopy(DIF_PRES_REQUEST_B)
20302031
dif_proof_req["presentation_definition"]["input_descriptors"][0]["constraints"][
@@ -2128,6 +2129,7 @@ async def test_verify_received_pres_limit_disclosure_fail_a(self):
21282129
await self.handler.receive_pres(message=dif_pres, pres_ex_record=record)
21292130
mock_log_err.assert_called_once()
21302131

2132+
@skip_on_jsonld_url_error
21312133
async def test_verify_received_pres_limit_disclosure_fail_b(self):
21322134
dif_proof = deepcopy(DIF_PRES)
21332135
dif_proof["verifiableCredential"][0]["credentialSubject"]["test"] = "Test"

acapy_agent/utils/testing.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
"""Utilities for testing."""
22

3+
import functools
4+
import inspect
35
from typing import Optional
4-
from uuid import uuid4
6+
7+
import pytest
8+
from pyld.jsonld import JsonLdError
9+
from uuid_utils import uuid4
510

611
from ..askar.profile import AskarProfile
712
from ..askar.profile_anon import AskarAnonCredsProfile
@@ -46,3 +51,71 @@ async def create_test_profile(
4651
opened=opened,
4752
context=context,
4853
)
54+
55+
56+
def skip_on_jsonld_url_error(test_func):
57+
"""Decorator to skip tests when they fail due to JSON-LD URL resolution issues.
58+
59+
This catches specific errors related to w3.org/w3id.org URL dereferencing failures
60+
that occur when external JSON-LD context URLs are not accessible. This prevents
61+
test failures due to temporary network issues or external service downtime.
62+
63+
Args:
64+
test_func: The test function to decorate
65+
66+
Returns:
67+
Wrapped test function that skips on JSON-LD URL resolution errors
68+
"""
69+
70+
def _handle_jsonld_error(e):
71+
"""Check if exception is a JSON-LD URL resolution error and skip if so."""
72+
73+
if isinstance(e, JsonLdError):
74+
error_str = str(e)
75+
# Check for specific JSON-LD URL resolution error patterns
76+
if any(
77+
pattern in error_str
78+
for pattern in [
79+
"Dereferencing a URL did not result in a valid JSON-LD object",
80+
"Could not retrieve a JSON-LD document from the URL",
81+
"loading remote context failed",
82+
"Could not process context before compaction",
83+
"Could not expand input before compaction",
84+
"Could not convert input to RDF dataset before normalization",
85+
"Could not expand input before serialization to RDF",
86+
]
87+
) and any(
88+
url in error_str
89+
for url in [
90+
"w3id.org/citizenship",
91+
"w3id.org/security",
92+
"w3.org/2018/credentials",
93+
"w3.org/ns/",
94+
]
95+
):
96+
pytest.skip(
97+
f"Skipping test due to JSON-LD URL resolution error: {error_str}"
98+
)
99+
100+
# Re-raise if it's not a URL resolution error we want to skip
101+
raise
102+
103+
@functools.wraps(test_func)
104+
async def async_wrapper(*args, **kwargs):
105+
try:
106+
return await test_func(*args, **kwargs)
107+
except Exception as e:
108+
_handle_jsonld_error(e)
109+
110+
@functools.wraps(test_func)
111+
def sync_wrapper(*args, **kwargs):
112+
try:
113+
return test_func(*args, **kwargs)
114+
except Exception as e:
115+
_handle_jsonld_error(e)
116+
117+
# Return appropriate wrapper based on whether the function is async
118+
if inspect.iscoroutinefunction(test_func):
119+
return async_wrapper
120+
else:
121+
return sync_wrapper

0 commit comments

Comments
 (0)