From ef1109316866df469192da7e5612581f6a3687c3 Mon Sep 17 00:00:00 2001
From: Paul Gerber
Date: Mon, 5 Oct 2026 09:05:30 +0200
Subject: [PATCH] sdk: Add `REQUIRE_COUCHDB_INTEGRATION_TESTS` to fail CouchDB
tests
---
.github/workflows/pr.yml | 4 ++++
sdk/test/_helper/setup_testdb.py | 6 ++++--
sdk/test/_helper/test_helpers.py | 8 +++++++-
sdk/test/backend/test_couchdb.py | 18 ++++++++++++++++--
4 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index bd0d5d772..f6000e8fa 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -112,6 +112,10 @@ jobs:
run: |
python test/_helper/setup_testdb.py -u "admin" -p "$COUCHDB_ADMIN_PASSWORD"
- name: Test with coverage + unittest
+ env:
+ # A CouchDB service container is always started for this job (see `services:` above), so a
+ # missing or misconfigured CouchDB should fail the build, not silently skip the CouchDB tests.
+ REQUIRE_COUCHDB_INTEGRATION_TESTS: "1"
run: |
python -m coverage run --source=basyx -m unittest
- name: Report test coverage
diff --git a/sdk/test/_helper/setup_testdb.py b/sdk/test/_helper/setup_testdb.py
index e5f15d0ae..c093b726f 100755
--- a/sdk/test/_helper/setup_testdb.py
+++ b/sdk/test/_helper/setup_testdb.py
@@ -13,8 +13,10 @@
setup_testdb.py -u admin -p admin_password
-If no CouchDB server at the configured URL, the script will exit with exit code 1. To avoid the error exit code (for use
-in CI), provide the ``--failsafe`` option.
+If no CouchDB server is reachable at the configured URL, or the test database already exists, the script exits with
+exit code 1 by default. CI relies on this to fail fast if the CouchDB service container isn't healthy, rather than
+silently continuing into a test run that would just skip the CouchDB-backed tests. For idempotent/local re-runs
+where an already-existing database is expected and fine, pass ``--failsafe`` to exit with code 0 instead.
"""
import argparse
diff --git a/sdk/test/_helper/test_helpers.py b/sdk/test/_helper/test_helpers.py
index 3633519a1..4dbe47664 100644
--- a/sdk/test/_helper/test_helpers.py
+++ b/sdk/test/_helper/test_helpers.py
@@ -7,6 +7,7 @@
import base64
import configparser
+import os
import os.path
import urllib.error
import urllib.request
@@ -20,7 +21,12 @@
)
-# Check if CouchDB database is available. Otherwise, skip tests.
+# Set this environment variable, to fail (instead of skip) the CouchDB tests when no CouchDB is reachable
+REQUIRE_COUCHDB_INTEGRATION_TESTS = os.environ.get("REQUIRE_COUCHDB_INTEGRATION_TESTS", "false").lower() in {
+ "1", "true", "yes",
+}
+
+# Check if CouchDB database is available. Otherwise, skip tests (unless REQUIRE_COUCHDB_INTEGRATION_TESTS is set).
try:
request = urllib.request.Request(
"{}/{}".format(
diff --git a/sdk/test/backend/test_couchdb.py b/sdk/test/backend/test_couchdb.py
index 829ccb889..350ccbc78 100644
--- a/sdk/test/backend/test_couchdb.py
+++ b/sdk/test/backend/test_couchdb.py
@@ -10,7 +10,12 @@
from basyx.aas.backend import couchdb
from basyx.aas.examples.data.example_aas import *
-from test._helper.test_helpers import COUCHDB_ERROR, COUCHDB_OKAY, TEST_CONFIG
+from test._helper.test_helpers import (
+ COUCHDB_ERROR,
+ COUCHDB_OKAY,
+ REQUIRE_COUCHDB_INTEGRATION_TESTS,
+ TEST_CONFIG,
+)
source_core: str = (
"couchdb://"
@@ -22,12 +27,21 @@
@unittest.skipUnless(
- COUCHDB_OKAY,
+ COUCHDB_OKAY or REQUIRE_COUCHDB_INTEGRATION_TESTS,
"No CouchDB is reachable at {}/{}: {}".format(
TEST_CONFIG["couchdb"]["url"], TEST_CONFIG["couchdb"]["database"], COUCHDB_ERROR
),
)
class CouchDBBackendTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls) -> None:
+ if not COUCHDB_OKAY:
+ raise RuntimeError(
+ f"REQUIRE_COUCHDB_INTEGRATION_TESTS is set, but no CouchDB is reachable at "
+ f"{TEST_CONFIG['couchdb']['url']}/{TEST_CONFIG['couchdb']['database']}: {COUCHDB_ERROR}"
+ )
+
def setUp(self) -> None:
self.couch_identifiable_store = couchdb.CouchDBIdentifiableStore(
TEST_CONFIG["couchdb"]["url"], TEST_CONFIG["couchdb"]["database"]