1- """Real-service conformance checks for PostgreSQL, MySQL, MariaDB, and Dolt ."""
1+ """Real-service conformance checks plus Dolt fail-closed and candidate probes ."""
22
33import os
44from uuid import uuid4
1010from sqlalchemy .exc import DBAPIError
1111
1212import openstatspec
13- import openstatspec .sql .wide as wide
1413from openstatspec .core import UnsupportedOperationError
14+ from openstatspec .sql .dolt_conformance import DoltConformanceSource
1515from conformance import compare_sav_semantics , write_supported_semantics_fixture
1616
1717
@@ -37,7 +37,7 @@ def source_sav(tmp_path):
3737
3838@pytest .mark .parametrize (
3939 ("environment_name" , "dataset_id" ),
40- [("OPENSTATSPEC_POSTGRES_URL" , "profile_pg" ), ("OPENSTATSPEC_MYSQL_URL" , "profile_mysql" ), ("OPENSTATSPEC_MARIADB_URL" , "profile_mariadb" ), ( "OPENSTATSPEC_DOLT_URL" , "profile_dolt" ) ],
40+ [("OPENSTATSPEC_POSTGRES_URL" , "profile_pg" ), ("OPENSTATSPEC_MYSQL_URL" , "profile_mysql" ), ("OPENSTATSPEC_MARIADB_URL" , "profile_mariadb" )],
4141)
4242def test_live_profile_import_validate_and_export (environment_name , dataset_id , source_sav , tmp_path ):
4343 database_url = os .environ .get (environment_name )
@@ -70,7 +70,7 @@ def test_live_profile_import_validate_and_export(environment_name, dataset_id, s
7070
7171@pytest .mark .parametrize (
7272 ("environment_name" , "dataset_id" ),
73- [("OPENSTATSPEC_POSTGRES_URL" , "semantics_pg" ), ("OPENSTATSPEC_MYSQL_URL" , "semantics_mysql" ), ("OPENSTATSPEC_MARIADB_URL" , "semantics_mariadb" ), ( "OPENSTATSPEC_DOLT_URL" , "semantics_dolt" ) ],
73+ [("OPENSTATSPEC_POSTGRES_URL" , "semantics_pg" ), ("OPENSTATSPEC_MYSQL_URL" , "semantics_mysql" ), ("OPENSTATSPEC_MARIADB_URL" , "semantics_mariadb" )],
7474)
7575@pytest .mark .parametrize ("suffix" , [".sav" , ".zsav" ])
7676def test_live_profile_preserves_supported_sav_semantics (environment_name , dataset_id , suffix , tmp_path ):
@@ -95,168 +95,43 @@ def test_live_profile_preserves_supported_sav_semantics(environment_name, datase
9595 )
9696 assert compare_sav_semantics (source , destination ) == {"equivalent" : True , "differences" : []}
9797
98- def test_live_dolt_conservative_source_width_envelope (tmp_path ) -> None :
98+ def test_live_dolt_is_read_only_and_rejects_writes_without_declarations (
99+ tmp_path ,
100+ ) -> None :
99101 database_url = os .environ .get ("OPENSTATSPEC_DOLT_URL" )
100102 if not database_url :
101103 pytest .skip ("OPENSTATSPEC_DOLT_URL is not configured" )
102- openstatspec .initialize_catalog (database_url = database_url )
103- token = uuid4 ().hex [:8 ]
104- accepted_id = f"dolt_width_accepted_{ token } "
105- rejected_id = f"dolt_width_rejected_{ token } "
106- accepted_source = tmp_path / f"{ accepted_id } .sav"
107- rejected_source = tmp_path / f"{ rejected_id } .sav"
108- accepted_columns = [f"v{ ordinal :03d} " for ordinal in range (1 , 306 )]
109- rejected_columns = [* accepted_columns , "v306" ]
110- pyspssio .write_sav (
111- str (accepted_source ),
112- pd .DataFrame ([[float (ordinal ) for ordinal in range (1 , 306 )]],
113- columns = accepted_columns ),
114- )
115- pyspssio .write_sav (
116- str (rejected_source ),
117- pd .DataFrame ([[float (ordinal ) for ordinal in range (1 , 307 )]],
118- columns = rejected_columns ),
119- )
120-
121- imported = openstatspec .import_sav (
122- accepted_source , database_url = database_url , dataset_id = accepted_id ,
123- )
124- assert imported ["case_count" ] == 1
125- assert openstatspec .validate (
126- database_url = database_url , dataset_id = accepted_id ,
127- )["variable_count" ] == 305
128104
129- with pytest . raises ( UnsupportedOperationError , match = "Target capability exceeded" ):
130- openstatspec . import_sav (
131- rejected_source , database_url = database_url , dataset_id = rejected_id ,
132- )
105+ status = DoltConformanceSource . packaged (). status ()
106+ assert status [ "status" ] == "blocked_no_concrete_declarations"
107+ assert status [ "declaration_count" ] == 0
108+ assert status [ "write_enabled" ] is False
133109
134- engine = create_engine (database_url )
135- with engine .connect () as connection :
136- assert connection .execute (text (
137- "select count(*) from dataset where dataset_name = :name"
138- ), {"name" : rejected_id }).scalar_one () == 0
139- assert connection .execute (text (
140- "select count(*) from dataset_catalog where dataset_id = :name"
141- ), {"name" : rejected_id }).scalar_one () == 0
142- mirror_event = connection .execute (text ("""
143- select f.dataset_id, f.direction, f.severity, f.code
144- from fidelity_event_catalog f
145- join operation_catalog o on o.operation_id = f.operation_id
146- where o.source = :source
147- """ ), {"source" : rejected_source .name }).mappings ().one ()
148- normative_event = connection .execute (text ("""
149- select f.dataset_id, f.direction, f.severity, f.event_code
150- from fidelity_event f
151- where f.source_item = :source
152- """ ), {"source" : rejected_source .name }).mappings ().one ()
153- assert tuple (mirror_event .values ()) == (
154- None , "import" , "error" , "target_capability_exceeded" ,
155- )
156- assert tuple (normative_event .values ()) == (
157- None , "import" , "error" , "target_capability_exceeded" ,
158- )
159- assert f"data_{ rejected_id } " not in inspect_database (engine ).get_table_names ()
110+ before = openstatspec .dolt_state_snapshot (database_url = database_url )
111+ assert before ["read_only" ] is True
112+ assert before ["operational_write_enabled" ] is False
160113
114+ rejection = "no concrete declarations; write rejected before mutation"
115+ with pytest .raises (UnsupportedOperationError , match = rejection ):
116+ openstatspec .initialize_catalog (database_url = database_url )
117+ after_initialize = openstatspec .dolt_state_snapshot (database_url = database_url )
161118
162- def test_live_dolt_post_ddl_fault_has_complete_compensating_cleanup (
163- tmp_path , monkeypatch ,
164- ) -> None :
165- database_url = os .environ .get ("OPENSTATSPEC_DOLT_URL" )
166- if not database_url :
167- pytest .skip ("OPENSTATSPEC_DOLT_URL is not configured" )
168- openstatspec .initialize_catalog (database_url = database_url )
169- dataset_id = f"dolt_cleanup_{ uuid4 ().hex [:8 ]} "
170- source = tmp_path / f"{ dataset_id } .sav"
119+ source = tmp_path / "blocked-write.sav"
171120 pyspssio .write_sav (str (source ), pd .DataFrame ({"answer" : [1.0 ]}))
172- real_store = wide .store_normative_dataset
173-
174- def fail_after_normative_write (* args , ** kwargs ):
175- real_store (* args , ** kwargs )
176- raise RuntimeError ("injected Dolt post-DDL fault" )
177-
178- monkeypatch .setattr (wide , "store_normative_dataset" , fail_after_normative_write )
179-
180- with pytest .raises (RuntimeError , match = "injected Dolt post-DDL fault" ):
121+ with pytest .raises (UnsupportedOperationError , match = rejection ):
181122 openstatspec .import_sav (
182- source , database_url = database_url , dataset_id = dataset_id ,
123+ source , database_url = database_url , dataset_id = "blocked_write" ,
183124 )
125+ after_import = openstatspec .dolt_state_snapshot (database_url = database_url )
184126
185- engine = create_engine (database_url )
186- with engine .connect () as connection :
187- assert connection .execute (text (
188- "select count(*) from dataset where dataset_name = :name"
189- ), {"name" : dataset_id }).scalar_one () == 0
190- assert connection .execute (text (
191- "select count(*) from dataset_catalog where dataset_id = :name"
192- ), {"name" : dataset_id }).scalar_one () == 0
193- assert connection .execute (text (
194- "select status, dataset_id from operation_catalog where source = :source"
195- ), {"source" : source .name }).one () == ("failed" , None )
196- assert connection .execute (text ("""
197- select f.dataset_id, f.direction, f.severity, f.code
198- from fidelity_event_catalog f
199- join operation_catalog o on o.operation_id = f.operation_id
200- where o.source = :source
201- """ ), {"source" : source .name }).one () == (
202- None , "import" , "error" , "import_failed" ,
203- )
204- assert f"data_{ dataset_id } " not in inspect_database (engine ).get_table_names ()
205-
206-
207- def test_live_dolt_adapter_value_boundary_is_atomic () -> None :
208- database_url = os .environ .get ("OPENSTATSPEC_DOLT_URL" )
209- if not database_url :
210- pytest .skip ("OPENSTATSPEC_DOLT_URL is not configured" )
211- openstatspec .initialize_catalog (database_url = database_url )
212- token = uuid4 ().hex [:8 ]
213- accepted_id = f"dolt_value_accepted_{ token } "
214- rejected_id = f"dolt_value_rejected_{ token } "
215- accepted_value = "é" * 32_752
216- rejected_value = accepted_value + "x"
217- assert len (accepted_value .encode ("utf-8" )) == 65_504
218- assert len (rejected_value .encode ("utf-8" )) == 65_505
219- variables = [{
220- "ordinal" : 1 , "source_name" : "value" , "physical_name" : "value" ,
221- "storage_kind" : "string" , "string_width" : 65_504 , "label" : "" ,
222- "format" : "A65504" , "measure" : "nominal" , "alignment" : "left" ,
223- "display_width" : 8 , "value_labels" : "{}" , "missing_ranges" : "[]" ,
224- }]
225-
226- imported = wide .create_wide_dataset (
227- database_url = database_url , dataset_id = accepted_id ,
228- source_name = "accepted.sav" , source_format = "SAV" ,
229- rows = [{"value" : accepted_value }], variables = variables ,
230- )
231- assert imported ["case_count" ] == 1
232-
233- with pytest .raises (UnsupportedOperationError ) as caught :
234- wide .create_wide_dataset (
235- database_url = database_url , dataset_id = rejected_id ,
236- source_name = "rejected.sav" , source_format = "SAV" ,
237- rows = [{"value" : rejected_value }], variables = variables ,
238- )
239- assert caught .value .details ["reason" ] == "text_value_limit"
240-
241- engine = create_engine (database_url )
242- accepted_table = wide .data_table_name (accepted_id )
243- rejected_table = wide .data_table_name (rejected_id )
244- quote = engine .dialect .identifier_preparer .quote
245- with engine .connect () as connection :
246- assert connection .execute (text (
247- f"SELECT OCTET_LENGTH(value) FROM { quote (accepted_table )} "
248- )).scalar_one () == 65_504
249- assert connection .execute (text (
250- "SELECT COUNT(*) FROM dataset_catalog WHERE dataset_id = :dataset_id"
251- ), {"dataset_id" : rejected_id }).scalar_one () == 0
252- assert connection .execute (text (
253- "SELECT COUNT(*) FROM dataset WHERE dataset_name = :dataset_id"
254- ), {"dataset_id" : rejected_id }).scalar_one () == 0
255- assert rejected_table not in inspect_database (engine ).get_table_names ()
256- engine .dispose ()
127+ assert after_initialize ["working_set_binding" ] == before ["working_set_binding" ]
128+ assert after_import ["working_set_binding" ] == before ["working_set_binding" ]
129+ assert after_initialize ["state" ] == before ["state" ]
130+ assert after_import ["state" ] == before ["state" ]
257131
258132
259- def test_live_dolt_published_storage_and_identifier_evidence () -> None :
133+ @pytest .mark .candidate_evidence
134+ def test_live_dolt_candidate_limit_probe_smoke () -> None :
260135 database_url = os .environ .get ("OPENSTATSPEC_DOLT_URL" )
261136 if not database_url :
262137 pytest .skip ("OPENSTATSPEC_DOLT_URL is not configured" )
0 commit comments