|
| 1 | +# Firebird ODBC Driver — Test Suite |
| 2 | + |
| 3 | +Google Test-based test suite for the Firebird ODBC driver. Tests the driver through the **standard ODBC API** via the Driver Manager, connecting to a real Firebird database. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +1. **Firebird Server** — a running Firebird 3.0+ instance with a test database |
| 8 | +2. **Firebird ODBC Driver** — pre-built and registered as an ODBC data source (or referenced via a `Driver=` connection string) |
| 9 | +3. **CMake** ≥ 3.14 |
| 10 | +4. **C++17 compiler** (MSVC 2022, GCC 9+, Clang 10+) |
| 11 | +5. **Google Test** — installed and discoverable via `find_package(GTest CONFIG REQUIRED)` |
| 12 | + |
| 13 | +### Windows-specific |
| 14 | + |
| 15 | +- The driver DLL (built from `Builds/MsVc2022.win/OdbcFb.sln`) must be registered via `odbcconf` or the ODBC Data Source Administrator. |
| 16 | +- Google Test can be installed via [vcpkg](https://vcpkg.io/): `vcpkg install gtest:x64-windows`, then pass `-DCMAKE_TOOLCHAIN_FILE=.../vcpkg/scripts/buildsystems/vcpkg.cmake` to CMake. Or build from source and pass `-DCMAKE_PREFIX_PATH=<gtest-install-dir>`. |
| 17 | + |
| 18 | +### Linux-specific |
| 19 | + |
| 20 | +- `unixODBC` development headers (`unixodbc-dev` / `unixODBC-devel`) |
| 21 | +- The driver `.so` must be registered in `/etc/odbcinst.ini` |
| 22 | +- Google Test can be installed via your package manager: `apt install libgtest-dev` / `dnf install gtest-devel` |
| 23 | + |
| 24 | +## Building the tests |
| 25 | + |
| 26 | +The test suite is a standalone CMake project. Google Test and ODBC are found via `find_package()`. |
| 27 | + |
| 28 | +```bash |
| 29 | +# From the repository root: |
| 30 | +cmake -B build-tests -S tests |
| 31 | +cmake --build build-tests --config Release |
| 32 | +``` |
| 33 | + |
| 34 | +## Running the tests |
| 35 | + |
| 36 | +Set the `FIREBIRD_ODBC_CONNECTION` environment variable with a valid ODBC connection string, then run with CTest: |
| 37 | + |
| 38 | +### Windows (PowerShell) |
| 39 | + |
| 40 | +```powershell |
| 41 | +$env:FIREBIRD_ODBC_CONNECTION = "Driver={Firebird ODBC Driver};Dbname=localhost:C:\path\to\test.fdb;Uid=SYSDBA;Pwd=masterkey;" |
| 42 | +ctest --test-dir build-tests --output-on-failure -C Release |
| 43 | +``` |
| 44 | + |
| 45 | +### Windows (cmd.exe) |
| 46 | + |
| 47 | +```cmd |
| 48 | +set FIREBIRD_ODBC_CONNECTION=Driver={Firebird ODBC Driver};Dbname=localhost:C:\path\to\test.fdb;Uid=SYSDBA;Pwd=masterkey; |
| 49 | +ctest --test-dir build-tests --output-on-failure -C Release |
| 50 | +``` |
| 51 | + |
| 52 | +### Linux |
| 53 | + |
| 54 | +```bash |
| 55 | +export FIREBIRD_ODBC_CONNECTION="Driver=Firebird;Dbname=localhost:/path/to/test.fdb;Uid=SYSDBA;Pwd=masterkey;" |
| 56 | +ctest --test-dir build-tests --output-on-failure |
| 57 | +``` |
| 58 | + |
| 59 | +### Running the test executable directly |
| 60 | + |
| 61 | +```bash |
| 62 | +./build-tests/firebird_odbc_tests --gtest_output=xml:test-results.xml |
| 63 | +``` |
| 64 | + |
| 65 | +## Test categories |
| 66 | + |
| 67 | +Tests are organized into three categories based on their expected behavior against the **current upstream driver** (vanilla master): |
| 68 | + |
| 69 | +### Category A — Pass (~166 tests) |
| 70 | + |
| 71 | +Standard ODBC functionality that the current driver supports. These tests are expected to **pass** on vanilla master. |
| 72 | + |
| 73 | +| File | Tests | Description | |
| 74 | +|------|-------|-------------| |
| 75 | +| `test_data_types.cpp` | ~18 | SMALLINT, INTEGER, BIGINT, FLOAT, DOUBLE, NUMERIC, VARCHAR, DATE, TIME, TIMESTAMP | |
| 76 | +| `test_result_conversions.cpp` | ~35 | SQLGetData type conversions | |
| 77 | +| `test_param_conversions.cpp` | ~18 | SQLBindParameter type conversions | |
| 78 | +| `test_prepare.cpp` | ~10 | SQLPrepare / SQLExecute lifecycle | |
| 79 | +| `test_cursors.cpp` | ~7 | Cursor behavior, commit/rollback, close/re-execute | |
| 80 | +| `test_cursor_commit.cpp` | ~6 | Cursor behavior across transactions | |
| 81 | +| `test_cursor_name.cpp` | ~9 | SQLSetCursorName / SQLGetCursorName | |
| 82 | +| `test_data_at_execution.cpp` | ~6 | SQL_DATA_AT_EXEC / SQLPutData | |
| 83 | +| `test_array_binding.cpp` | ~17 | Column-wise + row-wise parameter arrays | |
| 84 | +| `test_bindcol.cpp` | ~5 | Dynamic unbind/rebind mid-fetch | |
| 85 | +| `test_descrec.cpp` | ~10 | SQLGetDescRec for all column types | |
| 86 | +| `test_blob.cpp` | ~3 | Small/large/null BLOB read/write | |
| 87 | +| `test_multi_statement.cpp` | ~4 | Multiple statement handles on one connection | |
| 88 | +| `test_stmthandles.cpp` | ~4 | 100+ simultaneous statement handles | |
| 89 | +| `test_wchar.cpp` | ~8 | SQL_C_WCHAR bind/fetch, truncation | |
| 90 | +| `test_escape_sequences.cpp` | ~6 | Escape sequence passthrough | |
| 91 | + |
| 92 | +### Category B — Mixed pass/skip (~109 tests) |
| 93 | + |
| 94 | +Files containing a mix of passing tests and tests that require driver improvements. Individual tests that depend on future fixes are marked with `GTEST_SKIP()`. |
| 95 | + |
| 96 | +| File | Total | Pass | Skip | Reason for skip | |
| 97 | +|------|-------|------|------|-----------------| |
| 98 | +| `test_descriptor.cpp` | ~13 | ~6 | ~7 | Phase 7 (OC-1): SQLCopyDesc crash, SetDescCount allocation | |
| 99 | +| `test_connect_options.cpp` | ~36 | ~6 | ~30 | Phase 7/11: CONNECTION_TIMEOUT, ASYNC_ENABLE, QUERY_TIMEOUT, RESET_CONNECTION | |
| 100 | +| `test_errors.cpp` | ~18 | ~11 | ~7 | Phase 7 (OC-2/OC-5): DiagRowCount, TruncationIndicator | |
| 101 | +| `test_catalogfunctions.cpp` | ~29 | ~26 | ~3 | Phase 11: TypeInfo ordering, GUID searchability, BINARY dedup | |
| 102 | +| `test_server_version.cpp` | ~6 | ~4 | ~2 | Phase 4: FB4+ type count in SQLGetTypeInfo | |
| 103 | +| `test_scrollable_cursor.cpp` | ~9 | ~5 | ~4 | Phase 4: Scrollable cursor edge cases | |
| 104 | + |
| 105 | +### Category C — All skipped (~167 tests) |
| 106 | + |
| 107 | +These files test features that don't exist on vanilla master. Every test is marked with `GTEST_SKIP()`. |
| 108 | + |
| 109 | +| File | Tests | Reason | |
| 110 | +|------|-------|--------| |
| 111 | +| `test_null_handles.cpp` | ~65 | Phase 0: NULL handle crash prevention | |
| 112 | +| `test_savepoint.cpp` | ~4 | Phase 4: Savepoint isolation | |
| 113 | +| `test_conn_settings.cpp` | ~3 | Phase 4: ConnSettings DSN attribute | |
| 114 | +| `test_odbc38_compliance.cpp` | ~12 | Phase 8: ODBC 3.8 features | |
| 115 | +| `test_guid_and_binary.cpp` | ~14 | Phase 8: SQL_GUID and FB4+ types | |
| 116 | +| `test_odbc_string.cpp` | ~26 | Phase 12: OdbcString class (guarded with `__has_include`) | |
| 117 | +| `test_phase7_crusher_fixes.cpp` | ~22 | Phase 7: ODBC Crusher bug fixes | |
| 118 | +| `test_phase11_typeinfo_timeout_pool.cpp` | ~21 | Phase 11: TypeInfo, timeout, connection pool | |
| 119 | + |
| 120 | +### Excluded |
| 121 | + |
| 122 | +| File | Reason | |
| 123 | +|------|--------| |
| 124 | +| `bench_fetch.cpp` | Benchmark, not a test — deferred to performance work | |
| 125 | + |
| 126 | +## Expected output |
| 127 | + |
| 128 | +When running against vanilla master, you should see output like: |
| 129 | + |
| 130 | +``` |
| 131 | +[==========] N tests from M test suites ran. |
| 132 | +[ PASSED ] ~<pass_count> tests. |
| 133 | +[ SKIPPED ] ~<skip_count> tests. |
| 134 | +[ FAILED ] 0 tests. |
| 135 | +``` |
| 136 | + |
| 137 | +**Zero failures** are expected. Tests that would fail on vanilla master are pre-emptively SKIP'd. As driver improvements are merged in future PRs, the corresponding `GTEST_SKIP()` markers will be removed, turning those tests into actual pass/fail tests. |
| 138 | + |
| 139 | +## Connection string format |
| 140 | + |
| 141 | +The `FIREBIRD_ODBC_CONNECTION` environment variable should contain a standard ODBC connection string. Common parameters: |
| 142 | + |
| 143 | +| Parameter | Example | Description | |
| 144 | +|-----------|---------|-------------| |
| 145 | +| `Driver` | `{Firebird ODBC Driver}` | Registered driver name | |
| 146 | +| `Dbname` | `localhost:C:\data\test.fdb` | Server:path to database | |
| 147 | +| `Uid` | `SYSDBA` | Username | |
| 148 | +| `Pwd` | `masterkey` | Password | |
| 149 | +| `Role` | `RDB$ADMIN` | Role (optional) | |
| 150 | +| `CharacterSet` | `UTF8` | Character set (optional) | |
| 151 | + |
| 152 | +## Architecture |
| 153 | + |
| 154 | +- Tests link against the **ODBC Driver Manager** (`odbc32`/`odbccp32` on Windows, `libodbc` on Linux) via `find_package(ODBC REQUIRED)` |
| 155 | +- They do **not** link against the driver DLL directly (except `test_null_handles.cpp` which uses `LoadLibrary`) |
| 156 | +- The driver must be registered as an ODBC driver for the connection string to work |
| 157 | +- Google Test is found via `find_package(GTest CONFIG REQUIRED)` — must be pre-installed |
0 commit comments