@@ -748,3 +748,123 @@ def test_similar_prefix_names_allowed(self):
748748 finally :
749749 dj .config .stores .clear ()
750750 dj .config .stores .update (original_stores )
751+
752+
753+ class TestBackendConfiguration :
754+ """Test database backend configuration and port auto-detection."""
755+
756+ def test_backend_default (self ):
757+ """Test default backend is mysql."""
758+ from datajoint .settings import DatabaseSettings
759+
760+ settings = DatabaseSettings ()
761+ assert settings .backend == "mysql"
762+ assert settings .port == 3306
763+
764+ def test_backend_postgresql (self , monkeypatch ):
765+ """Test PostgreSQL backend with auto port."""
766+ from datajoint .settings import DatabaseSettings
767+
768+ monkeypatch .setenv ("DJ_BACKEND" , "postgresql" )
769+ settings = DatabaseSettings ()
770+ assert settings .backend == "postgresql"
771+ assert settings .port == 5432
772+
773+ def test_backend_explicit_port_overrides (self , monkeypatch ):
774+ """Test explicit port overrides auto-detection."""
775+ from datajoint .settings import DatabaseSettings
776+
777+ monkeypatch .setenv ("DJ_BACKEND" , "postgresql" )
778+ monkeypatch .setenv ("DJ_PORT" , "9999" )
779+ settings = DatabaseSettings ()
780+ assert settings .backend == "postgresql"
781+ assert settings .port == 9999
782+
783+ def test_backend_env_var (self , monkeypatch ):
784+ """Test DJ_BACKEND environment variable."""
785+ from datajoint .settings import DatabaseSettings
786+
787+ monkeypatch .setenv ("DJ_BACKEND" , "postgresql" )
788+ settings = DatabaseSettings ()
789+ assert settings .backend == "postgresql"
790+ assert settings .port == 5432
791+
792+ def test_port_env_var_overrides_backend_default (self , monkeypatch ):
793+ """Test DJ_PORT overrides backend auto-detection."""
794+ from datajoint .settings import DatabaseSettings
795+
796+ monkeypatch .setenv ("DJ_BACKEND" , "postgresql" )
797+ monkeypatch .setenv ("DJ_PORT" , "8888" )
798+ settings = DatabaseSettings ()
799+ assert settings .backend == "postgresql"
800+ assert settings .port == 8888
801+
802+ def test_invalid_backend (self , monkeypatch ):
803+ """Test invalid backend raises validation error."""
804+ from datajoint .settings import DatabaseSettings
805+
806+ monkeypatch .setenv ("DJ_BACKEND" , "sqlite" )
807+ with pytest .raises (ValidationError , match = "Input should be 'mysql' or 'postgresql'" ):
808+ DatabaseSettings ()
809+
810+ def test_config_file_backend (self , tmp_path , monkeypatch ):
811+ """Test loading backend from config file."""
812+ import json
813+
814+ from datajoint .settings import Config
815+
816+ # Include port in config since auto-detection only happens during initialization
817+ config_file = tmp_path / "test_config.json"
818+ config_file .write_text (json .dumps ({"database" : {"backend" : "postgresql" , "host" : "db.example.com" , "port" : 5432 }}))
819+
820+ # Clear env vars so file values take effect
821+ monkeypatch .delenv ("DJ_BACKEND" , raising = False )
822+ monkeypatch .delenv ("DJ_HOST" , raising = False )
823+ monkeypatch .delenv ("DJ_PORT" , raising = False )
824+
825+ cfg = Config ()
826+ cfg .load (config_file )
827+ assert cfg .database .backend == "postgresql"
828+ assert cfg .database .port == 5432
829+ assert cfg .database .host == "db.example.com"
830+
831+ def test_global_config_backend (self ):
832+ """Test global config has backend configuration."""
833+ # Global config should have backend field with default mysql
834+ assert hasattr (dj .config .database , "backend" )
835+ # Backend should be one of the valid values
836+ assert dj .config .database .backend in ["mysql" , "postgresql" ]
837+ # Port should be set (either 3306 or 5432 or custom)
838+ assert isinstance (dj .config .database .port , int )
839+ assert 1 <= dj .config .database .port <= 65535
840+
841+ def test_port_auto_detection_on_initialization (self ):
842+ """Test port auto-detects only during initialization, not on live updates."""
843+ from datajoint .settings import DatabaseSettings
844+
845+ # Start with MySQL (default)
846+ settings = DatabaseSettings ()
847+ assert settings .port == 3306
848+
849+ # Change backend on live config - port won't auto-update
850+ settings .backend = "postgresql"
851+ # Port remains at previous value (this is expected behavior)
852+ # Users should set port explicitly when changing backend on live config
853+ assert settings .port == 3306 # Didn't auto-update
854+
855+ def test_mysql_backend_with_explicit_port (self , monkeypatch ):
856+ """Test MySQL backend with explicit non-default port."""
857+ from datajoint .settings import DatabaseSettings
858+
859+ monkeypatch .setenv ("DJ_BACKEND" , "mysql" )
860+ monkeypatch .setenv ("DJ_PORT" , "3307" )
861+ settings = DatabaseSettings ()
862+ assert settings .backend == "mysql"
863+ assert settings .port == 3307
864+
865+ def test_backend_field_in_env_var_mapping (self ):
866+ """Test that backend is mapped to DJ_BACKEND in ENV_VAR_MAPPING."""
867+ from datajoint .settings import ENV_VAR_MAPPING
868+
869+ assert "database.backend" in ENV_VAR_MAPPING
870+ assert ENV_VAR_MAPPING ["database.backend" ] == "DJ_BACKEND"
0 commit comments