diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7aa121c81..1bc06f50d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -248,8 +248,90 @@ jobs: if-no-files-found: error include-hidden-files: true + test-oracle: + runs-on: ubuntu-latest + env: + TORTOISE_TEST_MODULES: tests.testmodels + TORTOISE_ORACLE_DB: FREEPDB1 + TORTOISE_ORACLE_USER: SYSTEM + TORTOISE_ORACLE_PASS: oracle + TORTOISE_ORACLE_DRIVER: OracleODBC + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + steps: + - uses: actions/checkout@v6 + - name: Install system dependencies + run: | + sudo apt-get update -qq + sudo apt-get install -y unixodbc unixodbc-dev libaio1t64 + - uses: gvenzl/setup-oracle-free@v1 + with: + app-user: appuser + app-user-password: 123456 + oracle-password: ${{ env.TORTOISE_ORACLE_PASS }} + - uses: iamazeem/setup-oracle-instant-client-action@v2 + - name: Locate Oracle ODBC driver + run: | + DRIVER_PATH=$(find $HOME -name "libsqora.so*" | head -n 1) + + echo "Found driver at: $DRIVER_PATH" + + if [ -z "$DRIVER_PATH" ]; then + echo "ERROR: libsqora.so not found" + exit 1 + fi + + echo "DRIVER_PATH=$DRIVER_PATH" >> $GITHUB_ENV + - name: Configure ODBC + run: | + echo "[OracleODBC]" | sudo tee /etc/odbcinst.ini + echo "Driver=$DRIVER_PATH" | sudo tee -a /etc/odbcinst.ini + + echo "[OracleDB]" | sudo tee /etc/odbc.ini + echo "Driver=OracleODBC" | sudo tee -a /etc/odbc.ini + echo "ServerName=127.0.0.1:1521/FREEPDB1" | sudo tee -a /etc/odbc.ini + echo "User=${TORTOISE_ORACLE_USER}" | sudo tee -a /etc/odbc.ini + echo "Password=${TORTOISE_ORACLE_PASS}" | sudo tee -a /etc/odbc.ini + - name: Wait for Oracle + run: | + for i in {1..15}; do + echo "Checking Oracle service..." + if echo "SELECT 1 FROM dual;" | sqlplus ${TORTOISE_ORACLE_USER}/${TORTOISE_ORACLE_PASS}@127.0.0.1:1521/${TORTOISE_ORACLE_DB} &>/dev/null; then + echo "Oracle ready!" + break + fi + sleep 5 + done + - name: Delete the role with the DB name + run: | + echo -e "WHENEVER SQLERROR EXIT SQL.SQLCODE\nBEGIN EXECUTE IMMEDIATE 'DROP ROLE ${TORTOISE_ORACLE_DB}'; END;\n/" | sqlplus ${TORTOISE_ORACLE_USER}/${TORTOISE_ORACLE_PASS}@127.0.0.1:1521/${TORTOISE_ORACLE_DB} + - uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - uses: astral-sh/setup-uv@v7 + - uses: actions/cache@v5 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/uv.lock') }} + restore-keys: | + ${{ runner.os }}-pip- + - name: Install dependencies + run: make deps + - name: Test Oracle + run: make test_oracle + env: + PYTHONDEVMODE: 1 + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-oracle-${{ matrix.python-version }} + path: .coverage + if-no-files-found: error + include-hidden-files: true + coverage: - needs: [test-sqlite, test-postgres, test-mysql, test-mssql] + needs: [test-sqlite, test-postgres, test-mysql, test-mssql, test-oracle] runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v6 diff --git a/Makefile b/Makefile index 02a99b786..cd9b9577f 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ test_mssql: $(py_warn) TORTOISE_TEST_DB="mssql://sa:$(TORTOISE_MSSQL_PASS)@127.0.0.1:1433/test_\{\}?driver=$(TORTOISE_MSSQL_DRIVER)&TrustServerCertificate=YES" uv run --frozen pytest $(pytest_opts) --cov-report= test_oracle: - $(py_warn) TORTOISE_TEST_DB="oracle://SYSTEM:$(TORTOISE_ORACLE_PASS)@127.0.0.1:1521/test_\{\}?driver=$(TORTOISE_ORACLE_DRIVER)" uv run --frozen pytest $(pytest_opts) --cov-report= + $(py_warn) TORTOISE_TEST_DB="oracle://$(TORTOISE_ORACLE_USER):$(TORTOISE_ORACLE_PASS)@127.0.0.1:1521/$(TORTOISE_ORACLE_DB)?driver=$(TORTOISE_ORACLE_DRIVER)" uv run --frozen pytest $(pytest_opts) --cov-report= _testall: test_sqlite test_postgres_asyncpg test_postgres_psycopg test_mysql_myisam test_mysql test_mysql_asyncmy test_mssql