6464 - name : embedded-seekdb
6565 artifact-suffix : embedded-seekdb-base
6666 db-type : embedded-seekdb
67+ poetry-extra-args : -E pyseekdb
6768 port : " "
6869 user : " "
6970 image : " "
@@ -72,12 +73,14 @@ jobs:
7273 upgrade-latest-stack : false
7374 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpointer_embedded_seekdb.py tests/integration_tests/test_checkpoint_conformance.py
7475 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_embedded_seekdb.py tests/integration_tests/test_vectorstores.py
76+ store-target : tests/integration_tests/test_store.py
7577 chat-history-target : tests/integration_tests/test_chat_message_histories.py
7678 hybrid-target : tests/integration_tests/test_hybrid_search.py
7779 ai-functions-target : " "
7880 - name : oceanbase
7981 artifact-suffix : oceanbase-base
8082 db-type : oceanbase
83+ poetry-extra-args : " "
8184 port : 2881
8285 user : root@test
8386 image : oceanbase/oceanbase-ce:4.3.5-lts
@@ -86,12 +89,14 @@ jobs:
8689 upgrade-latest-stack : false
8790 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpoint_conformance.py
8891 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_vectorstores.py
92+ store-target : tests/integration_tests/test_store.py
8993 chat-history-target : tests/integration_tests/test_chat_message_histories.py
9094 hybrid-target : tests/integration_tests/test_hybrid_search.py
9195 ai-functions-target : " "
9296 - name : seekdb
9397 artifact-suffix : seekdb-base
9498 db-type : seekdb
99+ poetry-extra-args : " "
95100 port : 2882
96101 user : root
97102 image : oceanbase/seekdb
@@ -100,12 +105,14 @@ jobs:
100105 upgrade-latest-stack : false
101106 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpoint_conformance.py
102107 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_vectorstores.py
108+ store-target : tests/integration_tests/test_store.py
103109 chat-history-target : tests/integration_tests/test_chat_message_histories.py
104110 hybrid-target : tests/integration_tests/test_hybrid_search.py
105111 ai-functions-target : tests/integration_tests/test_ai_functions.py
106112 - name : mysql
107113 artifact-suffix : mysql-base
108114 db-type : mysql
115+ poetry-extra-args : " "
109116 port : 3306
110117 user : root
111118 image : mysql:8.4
@@ -114,12 +121,14 @@ jobs:
114121 upgrade-latest-stack : false
115122 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpointer_mysql.py tests/integration_tests/test_checkpoint_conformance.py
116123 vectorstore-target : " "
124+ store-target : tests/integration_tests/test_store.py
117125 chat-history-target : " "
118126 hybrid-target : " "
119127 ai-functions-target : " "
120128 - name : embedded-seekdb, latest-checkpoint-stack
121129 artifact-suffix : embedded-seekdb-latest
122130 db-type : embedded-seekdb
131+ poetry-extra-args : -E pyseekdb
123132 port : " "
124133 user : " "
125134 image : " "
@@ -128,12 +137,14 @@ jobs:
128137 upgrade-latest-stack : true
129138 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpointer_embedded_seekdb.py tests/integration_tests/test_checkpoint_conformance.py
130139 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_embedded_seekdb.py tests/integration_tests/test_vectorstores.py
140+ store-target : tests/integration_tests/test_store.py
131141 chat-history-target : tests/integration_tests/test_chat_message_histories.py
132142 hybrid-target : tests/integration_tests/test_hybrid_search.py
133143 ai-functions-target : " "
134144 - name : oceanbase, latest-checkpoint-stack
135145 artifact-suffix : oceanbase-latest
136146 db-type : oceanbase
147+ poetry-extra-args : " "
137148 port : 2881
138149 user : root@test
139150 image : oceanbase/oceanbase-ce:4.3.5-lts
@@ -142,12 +153,14 @@ jobs:
142153 upgrade-latest-stack : true
143154 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpoint_conformance.py
144155 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_vectorstores.py
156+ store-target : tests/integration_tests/test_store.py
145157 chat-history-target : tests/integration_tests/test_chat_message_histories.py
146158 hybrid-target : tests/integration_tests/test_hybrid_search.py
147159 ai-functions-target : " "
148160 - name : seekdb, latest-checkpoint-stack
149161 artifact-suffix : seekdb-latest
150162 db-type : seekdb
163+ poetry-extra-args : " "
151164 port : 2882
152165 user : root
153166 image : oceanbase/seekdb
@@ -156,12 +169,14 @@ jobs:
156169 upgrade-latest-stack : true
157170 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpoint_conformance.py
158171 vectorstore-target : tests/integration_tests/test_vectorstore_standard.py tests/integration_tests/test_vectorstores.py
172+ store-target : tests/integration_tests/test_store.py
159173 chat-history-target : tests/integration_tests/test_chat_message_histories.py
160174 hybrid-target : tests/integration_tests/test_hybrid_search.py
161175 ai-functions-target : " "
162176 - name : mysql, latest-checkpoint-stack
163177 artifact-suffix : mysql-latest
164178 db-type : mysql
179+ poetry-extra-args : " "
165180 port : 3306
166181 user : root
167182 image : mysql:8.4
@@ -170,6 +185,7 @@ jobs:
170185 upgrade-latest-stack : true
171186 checkpoint-target : tests/integration_tests/test_checkpointer.py tests/integration_tests/test_checkpointer_mysql.py tests/integration_tests/test_checkpoint_conformance.py
172187 vectorstore-target : " "
188+ store-target : tests/integration_tests/test_store.py
173189 chat-history-target : " "
174190 hybrid-target : " "
175191 ai-functions-target : " "
@@ -198,7 +214,7 @@ jobs:
198214
199215 - name : Install dependencies
200216 run : |
201- poetry install --with test,test_integration --no-interaction
217+ poetry install --with test,test_integration --no-interaction ${{ matrix.poetry-extra-args }}
202218
203219 - name : Upgrade to latest supported LangChain and LangGraph stack
204220 if : matrix.upgrade-latest-stack
@@ -349,6 +365,7 @@ jobs:
349365 tests/unit_tests/test_checkpointer_async_api.py \
350366 tests/unit_tests/test_checkpointer_mysql_compat.py \
351367 tests/unit_tests/test_legacy_checkpoint_saver.py \
368+ tests/unit_tests/test_store.py \
352369 tests/unit_tests/test_vectorstore_standard.py \
353370 -v --tb=short --junitxml="$report_path"
354371
@@ -401,6 +418,23 @@ jobs:
401418 echo "Running vectorstore integration tests with ${{ matrix.db-type }}..."
402419 poetry run pytest ${{ matrix.vectorstore-target }} -v --tb=short --junitxml="$report_path"
403420
421+ - name : Run store integration tests
422+ id : store-tests
423+ if : matrix.store-target != ''
424+ continue-on-error : true
425+ env :
426+ OB_HOST : 127.0.0.1
427+ OB_PORT : ${{ matrix.port }}
428+ OB_USER : ${{ matrix.user }}
429+ OB_PASSWORD : ${{ matrix.db-type == 'mysql' && 'rootpass' || '' }}
430+ OB_DB : test
431+ OB_CI_DB_TYPE : ${{ matrix.db-type }}
432+ run : |
433+ set -euo pipefail
434+ report_path="${RUNNER_TEMP}/store-integration-${{ matrix.artifact-suffix }}.xml"
435+ echo "Running store integration tests with ${{ matrix.db-type }}..."
436+ poetry run pytest ${{ matrix.store-target }} -v --tb=short --junitxml="$report_path"
437+
404438 - name : Run chat message history integration tests
405439 id : chat-history-tests
406440 if : matrix.chat-history-target != ''
@@ -446,6 +480,11 @@ jobs:
446480 OB_PASSWORD : ${{ matrix.db-type == 'mysql' && 'rootpass' || '' }}
447481 OB_DB : test
448482 OB_CI_DB_TYPE : ${{ matrix.db-type }}
483+ OB_AI_TEST_URL : ${{ secrets.OB_AI_TEST_URL }}
484+ OB_AI_TEST_ACCESS_KEY : ${{ secrets.OB_AI_TEST_ACCESS_KEY }}
485+ OB_AI_TEST_EMBED_MODEL : ${{ secrets.OB_AI_TEST_EMBED_MODEL }}
486+ OB_AI_TEST_COMPLETE_MODEL : ${{ secrets.OB_AI_TEST_COMPLETE_MODEL }}
487+ OB_AI_TEST_PROVIDER : ${{ secrets.OB_AI_TEST_PROVIDER }}
449488 run : |
450489 set -euo pipefail
451490 report_path="${RUNNER_TEMP}/ai-functions-integration-${{ matrix.artifact-suffix }}.xml"
@@ -472,24 +511,68 @@ jobs:
472511
473512 - name : Fail job if any suite failed
474513 if : always()
514+ env :
515+ ARTIFACT_SUFFIX : ${{ matrix.artifact-suffix }}
516+ VECTORSTORE_TARGET : ${{ matrix.vectorstore-target }}
517+ STORE_TARGET : ${{ matrix.store-target }}
518+ CHAT_HISTORY_TARGET : ${{ matrix.chat-history-target }}
519+ HYBRID_TARGET : ${{ matrix.hybrid-target }}
520+ AI_FUNCTIONS_TARGET : ${{ matrix.ai-functions-target }}
521+ COMPREHENSIVE_OUTCOME : ${{ steps.comprehensive-tests.outcome }}
475522 run : |
476523 set -euo pipefail
477- failed=0
478- for outcome in \
479- "${{ steps.unit-tests.outcome }}" \
480- "${{ steps.comprehensive-tests.outcome }}" \
481- "${{ steps.checkpoint-tests.outcome }}" \
482- "${{ steps.vectorstore-tests.outcome }}" \
483- "${{ steps.chat-history-tests.outcome }}" \
484- "${{ steps.hybrid-tests.outcome }}" \
485- "${{ steps.ai-functions-tests.outcome }}"; do
486- if [ "$outcome" = "failure" ] || [ "$outcome" = "cancelled" ]; then
487- failed=1
488- fi
489- done
490- if [ "$failed" -ne 0 ]; then
491- exit 1
492- fi
524+ python3 - <<'PY'
525+ import os
526+ import sys
527+ import xml.etree.ElementTree as ET
528+ from pathlib import Path
529+
530+ artifact_suffix = os.environ["ARTIFACT_SUFFIX"]
531+ report_root = Path(os.environ["RUNNER_TEMP"])
532+ expected_reports = [
533+ report_root / f"unit-tests-{artifact_suffix}.xml",
534+ report_root / f"checkpoint-integration-{artifact_suffix}.xml",
535+ ]
536+
537+ optional_reports = [
538+ ("VECTORSTORE_TARGET", f"vectorstore-integration-{artifact_suffix}.xml"),
539+ ("STORE_TARGET", f"store-integration-{artifact_suffix}.xml"),
540+ ("CHAT_HISTORY_TARGET", f"chat-history-integration-{artifact_suffix}.xml"),
541+ ("HYBRID_TARGET", f"hybrid-search-integration-{artifact_suffix}.xml"),
542+ ("AI_FUNCTIONS_TARGET", f"ai-functions-integration-{artifact_suffix}.xml"),
543+ ]
544+ for env_name, filename in optional_reports:
545+ if os.environ[env_name]:
546+ expected_reports.append(report_root / filename)
547+
548+ missing = [str(path) for path in expected_reports if not path.exists()]
549+ if missing:
550+ print("Missing expected JUnit reports:")
551+ for path in missing:
552+ print(f" - {path}")
553+ sys.exit(1)
554+
555+ failures = 0
556+ errors = 0
557+ for path in expected_reports:
558+ root = ET.parse(path).getroot()
559+ suites = [root] if root.tag == "testsuite" else root.findall("testsuite")
560+ failures += sum(int(suite.attrib.get("failures", 0)) for suite in suites)
561+ errors += sum(int(suite.attrib.get("errors", 0)) for suite in suites)
562+
563+ if failures or errors:
564+ print(
565+ f"JUnit suites reported failures={failures} errors={errors}"
566+ )
567+ sys.exit(1)
568+
569+ if os.environ["COMPREHENSIVE_OUTCOME"] in {"failure", "cancelled"}:
570+ print(
571+ "Comprehensive test step failed with outcome="
572+ f"{os.environ['COMPREHENSIVE_OUTCOME']}"
573+ )
574+ sys.exit(1)
575+ PY
493576
494577 - name : Cleanup
495578 if : always()
@@ -527,7 +610,7 @@ jobs:
527610
528611 - name : Install dependencies
529612 run : |
530- poetry install --with test --no-interaction --no-root
613+ poetry install --with test --no-interaction --no-root -E pyseekdb
531614
532615 - name : Test embedding functionality
533616 run : |
0 commit comments