diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f03d2c9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Module", + "type": "python", + "request": "launch", + "program": "./test/test_driver.py", + + //"args": ["TestArrays"], + + "justMyCode": false, + }, + { + // Disable JustMyCode on Pytest -- https://stackoverflow.com/a/57831657 + "name": "Debug Unit Test", + "type": "python", + "request": "test", + "justMyCode": false, + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1777f62 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "python.envFile": "${workspaceFolder}/test/environment.txt", + "python.testing.unittestArgs": ["-v", "-s", "./test", "-p", "test_*.py"], + "python.testing.pytestEnabled": false, + "python.testing.unittestEnabled": true +} diff --git a/Rebuild-Databases.ps1 b/Rebuild-Databases.ps1 new file mode 100644 index 0000000..1a4eba3 --- /dev/null +++ b/Rebuild-Databases.ps1 @@ -0,0 +1,46 @@ +[CmdletBinding()] +Param( + [ValidateSet('All', 'fb30', 'fb40', 'fb50')] + [System.String[]] + $Engines = 'All', + + [Switch] + $Force +) + +$rootFolder = Join-Path $env:TEMP 'firebird-driver-tests' + +if ($Force) { + Remove-Item -Path $rootFolder -Force -Recurse -ErrorAction SilentlyContinue + mkdir $rootFolder | Out-Null +} + +$binariesExist = Test-Path "$rootFolder/fb30/fbclient.dll" +if ($Force -or (-not $binariesExist)) { + Write-Verbose 'Downloading Firebird binaries...' + + Remove-Item -Path $rootFolder -Force -Recurse -ErrorAction SilentlyContinue + mkdir $rootFolder | Out-Null + + git clone --quiet --depth 1 --single-branch https://github.com/fdcastel/firebird-binaries $rootFolder +} + +$DbPrefix='firebird-driver' +$fbkFile = Join-Path $PSScriptRoot './test/fbtest30-src.fbk' + +# Build databases +if ($Engines -eq 'All') { + $Engines = 'fb30', 'fb40', 'fb50' +} +$Engines | ForEach-Object { + $engine = $_ + + $engineFolder = Join-Path $rootFolder $engine + $gbak = Join-Path $engineFolder 'gbak.exe' + + $database = Join-Path $rootFolder "$DbPrefix.$engine.fdb" + Remove-Item $database -Force -ErrorAction SilentlyContinue + + Write-Verbose "Creating '$database'..." + & $gbak -c $fbkFile $database +} diff --git a/Set-TestEnvironment.ps1 b/Set-TestEnvironment.ps1 new file mode 100644 index 0000000..6c4af0e --- /dev/null +++ b/Set-TestEnvironment.ps1 @@ -0,0 +1,31 @@ +[CmdletBinding()] +Param( + [Parameter(ParameterSetName = 'Default')] + [Alias("Local")] + [Switch] + $Default, + + [Parameter(ParameterSetName = 'Embedded')] + [Alias("Engine")] + [ValidateSet('fb30', 'fb40', 'fb50')] + [System.String[]] + $Embedded = 'fb50' +) + +$environmentFile = './test/environment.txt' +if ($Default) { + # Use default environment (locally installed Firebird). Clear all environment variables. + $env:FBTEST_CLIENT_LIBRARY= + $env:FBTEST_DATABASE= + + Remove-Item $environmentFile -ErrorAction SilentlyContinue +} else { + # Use embedded environment (Firebird embedded and database in TEMP subfolder) + $env:FBTEST_CLIENT_LIBRARY="$($env:TEMP)/firebird-driver-tests/$($Embedded)/fbclient.dll" + $env:FBTEST_DATABASE="$($env:TEMP)/firebird-driver-tests/FIREBIRD-DRIVER.$($Embedded.ToUpper()).FDB" + + @" + FBTEST_CLIENT_LIBRARY=%TEMP%/firebird-driver-tests/$($Embedded)/fbclient.dll + FBTEST_DATABASE=%TEMP%/firebird-driver-tests/FIREBIRD-DRIVER.$($Embedded.ToUpper()).FDB +"@ | Out-File $environmentFile -Encoding ascii +} diff --git a/test/fbtest30.fdb b/test/fbtest30.fdb deleted file mode 100644 index 891db4c..0000000 Binary files a/test/fbtest30.fdb and /dev/null differ diff --git a/test/fbtest40.fdb b/test/fbtest40.fdb deleted file mode 100644 index ce2c2a7..0000000 Binary files a/test/fbtest40.fdb and /dev/null differ diff --git a/test/test_driver.py b/test/test_driver.py index f7015d7..d31c839 100644 --- a/test/test_driver.py +++ b/test/test_driver.py @@ -42,15 +42,24 @@ FB30 = '3.0' FB40 = '4.0' +FB50 = '5.0' + +# Default client library +FBTEST_CLIENT_LIBRARY = os.environ.get('FBTEST_CLIENT_LIBRARY', None) +FBTEST_CLIENT_LIBRARY = os.path.expandvars(FBTEST_CLIENT_LIBRARY) if FBTEST_CLIENT_LIBRARY is not None else None # Default server host -#FBTEST_HOST = '' -FBTEST_HOST = 'localhost' +FBTEST_HOST = None +if FBTEST_CLIENT_LIBRARY is None: + FBTEST_HOST = os.environ.get('FBTEST_HOST', 'localhost') + # Default user -FBTEST_USER = 'SYSDBA' +FBTEST_USER = os.environ.get('ISC_USER', 'SYSDBA') + # Default user password -FBTEST_PASSWORD = 'masterkey' +FBTEST_PASSWORD = os.environ.get('ISC_PASSWORD', 'masterkey') +driver_config.fb_client_library.value = FBTEST_CLIENT_LIBRARY cfg = driver_config.register_server('FBTEST_HOST') cfg.host.value = FBTEST_HOST cfg.user.value = FBTEST_USER @@ -117,13 +126,20 @@ def setUp(self) -> None: with connect_server(FBTEST_HOST, user=FBTEST_USER, password=FBTEST_PASSWORD) as svc: self.version = svc.info.version if self.version.startswith(FB30): - self.FBTEST_DB = 'fbtest30.fdb' self.version = FB30 elif self.version.startswith(FB40): - self.FBTEST_DB = 'fbtest40.fdb' self.version = FB40 + elif self.version.startswith(FB50): + self.version = FB50 else: raise Exception("Unsupported Firebird version (%s)" % self.version) + + self.FBTEST_DB = os.environ.get('FBTEST_DATABASE', None) + if self.FBTEST_DB is None: + engine = "FB" + self.version.replace(".", "") + self.FBTEST_DB = f"%TEMP%/firebird-driver-tests/FIREBIRD-DRIVER.{engine}.FDB" + self.FBTEST_DB = os.path.expandvars(self.FBTEST_DB) + # self.cwd = os.getcwd() self.dbpath = self.cwd if os.path.split(self.cwd)[1] == 'test' \ @@ -442,7 +458,10 @@ def test_db_info(self): self.assertEqual(con.info.page_size, 8192) self.assertGreater(con.info.id, 0) self.assertEqual(con.info.sql_dialect, 3) - self.assertEqual(con.info.name.upper(), self.dbfile.upper()) + self.assertEqual( + os.path.realpath(con.info.name), + os.path.realpath(self.dbfile) + ) self.assertIsInstance(con.info.site, str) self.assertIsInstance(con.info.implementation, driver.types.Implementation) self.assertIsInstance(con.info.provider, driver.types.DbProvider) @@ -508,7 +527,10 @@ def test_db_info(self): self.assertIsInstance(con.info.get_info(DbInfoCode.BASE_LEVEL), int) res = con.info.get_info(DbInfoCode.DB_ID) self.assertIsInstance(res, list) - self.assertEqual(res[0].upper(), self.dbfile.upper()) + self.assertEqual( + os.path.realpath(res[0]), + os.path.realpath(self.dbfile) + ) res = con.info.get_info(DbInfoCode.IMPLEMENTATION) self.assertIsInstance(res, tuple) self.assertEqual(len(res), 4) @@ -1559,10 +1581,8 @@ def test_query(self): x = svc.info.home_directory # On Windows it returns 'security.db', a bug? #self.assertIn('security.db', svc.info.security_database) - if self.version == FB40: - self.assertIn('security4.fdb'.upper(), svc.info.security_database.upper()) - else: - self.assertIn('security3.fdb', svc.info.security_database) + security_database = f"security{self.version[0]}.fdb" + self.assertIn(security_database.casefold(), svc.info.security_database.casefold()) x = svc.info.lock_directory x = svc.info.capabilities self.assertIn(ServerCapability.REMOTE_HOP, x) @@ -1574,8 +1594,8 @@ def test_query(self): con2._logging_id_ = self.__class__.__name__ self.assertGreaterEqual(len(svc.info.attached_databases), 2, "Should work for Superserver, may fail with value 0 for Classic") - self.assertIn(self.dbfile.upper(), - [s.upper() for s in svc.info.attached_databases]) + self.assertIn(os.path.realpath(self.dbfile), + [os.path.realpath(s) for s in svc.info.attached_databases]) self.assertGreaterEqual(svc.info.connection_count, 2) # BAD request code with self.assertRaises(Error) as cm: