@@ -155,6 +155,123 @@ def test_instance_always_allowed_in_thread_safe_mode(self, monkeypatch):
155155 assert callable (Instance )
156156
157157
158+ class TestInstanceBackend :
159+ """Test Instance backend parameter."""
160+
161+ def test_instance_backend_sets_config (self , monkeypatch ):
162+ """Instance(backend=...) sets config.database.backend."""
163+ monkeypatch .setenv ("DJ_THREAD_SAFE" , "false" )
164+ from datajoint .instance import Instance
165+ from unittest .mock import patch
166+
167+ with patch ("datajoint.instance.Connection" ):
168+ inst = Instance (
169+ host = "localhost" , user = "root" , password = "secret" ,
170+ backend = "postgresql" ,
171+ )
172+ assert inst .config .database .backend == "postgresql"
173+
174+ def test_instance_backend_default_from_config (self , monkeypatch ):
175+ """Instance without backend uses config default."""
176+ monkeypatch .setenv ("DJ_THREAD_SAFE" , "false" )
177+ from datajoint .instance import Instance
178+ from unittest .mock import patch
179+
180+ with patch ("datajoint.instance.Connection" ):
181+ inst = Instance (
182+ host = "localhost" , user = "root" , password = "secret" ,
183+ )
184+ assert inst .config .database .backend == "mysql"
185+
186+ def test_instance_backend_affects_port_default (self , monkeypatch ):
187+ """Instance(backend='postgresql') uses port 5432 by default."""
188+ monkeypatch .setenv ("DJ_THREAD_SAFE" , "false" )
189+ from datajoint .instance import Instance
190+ from unittest .mock import patch , call
191+
192+ with patch ("datajoint.instance.Connection" ) as MockConn :
193+ Instance (
194+ host = "localhost" , user = "root" , password = "secret" ,
195+ backend = "postgresql" ,
196+ )
197+ # Connection should be called with port 5432 (PostgreSQL default)
198+ args , kwargs = MockConn .call_args
199+ assert args [3 ] == 5432 # port is the 4th positional arg
200+
201+
202+ class TestCrossConnectionValidation :
203+ """Test that cross-connection operations are rejected."""
204+
205+ def test_join_different_connections_raises (self ):
206+ """Join of expressions from different connections raises DataJointError."""
207+ from datajoint .expression import QueryExpression
208+ from datajoint .errors import DataJointError
209+ from unittest .mock import MagicMock
210+
211+ expr1 = QueryExpression ()
212+ expr1 ._connection = MagicMock ()
213+ expr1 ._heading = MagicMock ()
214+ expr1 ._heading .names = []
215+
216+ expr2 = QueryExpression ()
217+ expr2 ._connection = MagicMock () # different connection object
218+ expr2 ._heading = MagicMock ()
219+ expr2 ._heading .names = []
220+
221+ with pytest .raises (DataJointError , match = "different connections" ):
222+ expr1 * expr2
223+
224+ def test_join_same_connection_allowed (self ):
225+ """Join of expressions from the same connection does not raise."""
226+ from datajoint .condition import assert_join_compatibility
227+ from datajoint .expression import QueryExpression
228+ from unittest .mock import MagicMock
229+
230+ shared_conn = MagicMock ()
231+
232+ expr1 = QueryExpression ()
233+ expr1 ._connection = shared_conn
234+ expr1 ._heading = MagicMock ()
235+ expr1 ._heading .names = []
236+ expr1 ._heading .lineage_available = False
237+
238+ expr2 = QueryExpression ()
239+ expr2 ._connection = shared_conn
240+ expr2 ._heading = MagicMock ()
241+ expr2 ._heading .names = []
242+ expr2 ._heading .lineage_available = False
243+
244+ # Should not raise
245+ assert_join_compatibility (expr1 , expr2 )
246+
247+ def test_restriction_different_connections_raises (self ):
248+ """Restriction by expression from different connection raises DataJointError."""
249+ from datajoint .expression import QueryExpression
250+ from datajoint .errors import DataJointError
251+ from unittest .mock import MagicMock
252+
253+ expr1 = QueryExpression ()
254+ expr1 ._connection = MagicMock ()
255+ expr1 ._heading = MagicMock ()
256+ expr1 ._heading .names = ["a" ]
257+ expr1 ._heading .__getitem__ = MagicMock ()
258+ expr1 ._heading .new_attributes = set ()
259+ expr1 ._support = ["`db`.`t1`" ]
260+ expr1 ._restriction = []
261+ expr1 ._restriction_attributes = set ()
262+ expr1 ._joins = []
263+ expr1 ._top = None
264+ expr1 ._original_heading = expr1 ._heading
265+
266+ expr2 = QueryExpression ()
267+ expr2 ._connection = MagicMock () # different connection
268+ expr2 ._heading = MagicMock ()
269+ expr2 ._heading .names = ["a" ]
270+
271+ with pytest .raises (DataJointError , match = "different connections" ):
272+ expr1 & expr2
273+
274+
158275class TestThreadSafetyError :
159276 """Test ThreadSafetyError exception."""
160277
0 commit comments