Update README.md #330
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Slow tests (Docker + pytest) | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| slow: | |
| name: Slow tests - ${{ matrix.db }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| db: [postgres, mariadb, mysql, oracle, mssql] | |
| env: | |
| RUN_SLOW_TESTS: "1" | |
| steps: | |
| - uses: actions/checkout@v5 | |
| # Compute a monthly suffix so Docker cache refreshes once a month | |
| - name: Compute cache suffix (monthly) | |
| id: date | |
| run: echo "MONTHLY=$(date -u +'%Y-%m')" >> "$GITHUB_ENV" | |
| - name: Set up uv + Python | |
| uses: astral-sh/setup-uv@v7.1.1 | |
| with: | |
| python-version: '3.12.10' | |
| enable-cache: true | |
| # (optional) uncomment if you want to pin the cache to explicit files | |
| # cache-dependency-path: | | |
| # pyproject.toml | |
| # uv.lock | |
| - name: Verify Docker availability | |
| run: | | |
| docker --version | |
| docker info | |
| # ---------- Docker images (pre-pull only what's needed per DB) ---------- | |
| - name: Pre-pull DB image(s) | |
| run: | | |
| set -e | |
| case "${{ matrix.db }}" in | |
| postgres) | |
| IMAGES="postgres:latest gvenzl/oracle-free:latest-faststart mcr.microsoft.com/mssql/server:2022-latest" ;; | |
| mssql) | |
| IMAGES="mcr.microsoft.com/mssql/server:2022-latest gvenzl/oracle-free:latest-faststart" ;; | |
| mysql) | |
| IMAGES="mysql:8.0 gvenzl/oracle-free:latest-faststart" ;; | |
| mariadb) | |
| IMAGES="mariadb:latest gvenzl/oracle-free:latest-faststart" ;; | |
| oracle) | |
| IMAGES="gvenzl/oracle-free:latest-faststart" ;; | |
| esac | |
| for img in $IMAGES; do | |
| echo "Pulling $img" | |
| docker pull "$img" | |
| done | |
| # ---------- APT cache for MS ODBC (needed for mssql and for postgres→mssql cross test) ---------- | |
| - name: Configure APT to use a writeable cache | |
| if: matrix.db == 'mssql' || matrix.db == 'postgres' | |
| run: | | |
| set -e | |
| CACHE_ROOT="${RUNNER_TEMP}/apt-cache" | |
| mkdir -p "$CACHE_ROOT/archives/partial" | |
| { | |
| echo "Dir::Cache \"$CACHE_ROOT\";"; | |
| echo "Dir::Cache::archives \"$CACHE_ROOT/archives\";"; | |
| } | sudo tee /etc/apt/apt.conf.d/99cache >/dev/null | |
| - name: Cache APT archives | |
| if: matrix.db == 'mssql' || matrix.db == 'postgres' | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ runner.temp }}/apt-cache | |
| key: apt-${{ runner.os }}-msodbcsql18 | |
| restore-keys: | | |
| apt-${{ runner.os }}- | |
| - name: Install MS ODBC Driver 18 for SQL Server | |
| if: matrix.db == 'mssql' || matrix.db == 'postgres' | |
| run: | | |
| set -e | |
| UBUNTU_VERSION=$(lsb_release -rs) | |
| curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /usr/share/keyrings/microsoft.gpg >/dev/null | |
| curl -sSL https://packages.microsoft.com/config/ubuntu/${UBUNTU_VERSION}/prod.list | sudo tee /etc/apt/sources.list.d/microsoft-prod.list >/dev/null | |
| sudo apt-get update | |
| sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev | |
| # ---------- Oracle Instant Client cache (needed in all jobs; tests transfer to/from Oracle under other DB markers) ---------- | |
| - name: Restore Oracle Instant Client cache | |
| id: cache-oracle | |
| uses: actions/cache@v4 | |
| with: | |
| path: .cache/oracle | |
| key: oracle-instantclient-${{ runner.os }}-basiclite-23 | |
| restore-keys: | | |
| oracle-instantclient-${{ runner.os }}- | |
| - name: Prepare Oracle Instant Client zip (download if missing) | |
| run: | | |
| set -e | |
| mkdir -p .cache/oracle | |
| if [ -f .cache/oracle/instantclient.zip ]; then | |
| echo "Using cached .cache/oracle/instantclient.zip" | |
| else | |
| echo "Downloading Oracle Instant Client (Basic Lite) permanent link" | |
| ORACLE_IC_PERM_BASICLITE="https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip" | |
| ORACLE_IC_PERM_BASIC="https://download.oracle.com/otn_software/linux/instantclient/instantclient-basic-linuxx64.zip" | |
| if ! curl -fsSL "$ORACLE_IC_PERM_BASICLITE" -o .cache/oracle/instantclient.zip; then | |
| echo "Basic Lite failed; trying Basic (larger)" | |
| curl -fsSL "$ORACLE_IC_PERM_BASIC" -o .cache/oracle/instantclient.zip | |
| fi | |
| fi | |
| - name: Install Oracle Instant Client | |
| run: | | |
| set -e | |
| sudo apt-get update | |
| sudo apt-get install -y unzip curl libnsl2 libaio1t64 || true | |
| sudo mkdir -p /opt/oracle | |
| sudo unzip -qo .cache/oracle/instantclient.zip -d /opt/oracle | |
| icdir=$(find /opt/oracle -maxdepth 1 -type d -name "instantclient_*" | head -n1) | |
| if [ -z "$icdir" ]; then | |
| echo "Could not locate Instant Client directory after unzip" >&2 | |
| exit 1 | |
| fi | |
| echo "Detected Instant Client at: $icdir" | |
| # Make libraries discoverable for native clients | |
| echo "$icdir" | sudo tee /etc/ld.so.conf.d/oracle-instantclient.conf >/dev/null | |
| sudo ldconfig | |
| # Expose for your Python code / ConnectorX and ensure runtime linker can find it | |
| { | |
| echo "SRC_ORACLE_CLIENT_PATH=$icdir" | |
| echo "LD_LIBRARY_PATH=$icdir:\$LD_LIBRARY_PATH" | |
| echo "ORACLE_HOME=$icdir" | |
| } >> "$GITHUB_ENV" | |
| - name: Ensure libaio compat symlink on Ubuntu 24.04+ | |
| run: | | |
| set -e | |
| sudo apt-get update | |
| sudo apt-get install -y libaio1t64 | |
| # Find the actual libaio.so.* path that the package installed | |
| AIO=$(dpkg -L libaio1t64 | grep -E '/libaio\.so(\.1t64|\.1)$' | head -n1 || true) | |
| if [ -z "$AIO" ]; then | |
| echo "Could not locate libaio from libaio1t64 package" >&2 | |
| exit 1 | |
| fi | |
| # Create a compat symlink that Instant Client expects | |
| for dir in /usr/lib/x86_64-linux-gnu /lib/x86_64-linux-gnu; do | |
| if [ -d "$dir" ]; then | |
| sudo ln -sf "$AIO" "$dir/libaio.so.1" | |
| fi | |
| done | |
| sudo ldconfig | |
| echo "libaio present as: $(ldconfig -p | grep -E 'libaio\.so\.1\b' || true)" | |
| - name: Smoke-test Oracle Instant Client (quick diagnostics) | |
| run: | | |
| set -e | |
| icdir="${SRC_ORACLE_CLIENT_PATH}" | |
| echo "Instant Client in: $icdir" | |
| echo "ldd on libclntsh:" | |
| ldd "$icdir"/libclntsh.so* | sed 's/^/ /' | |
| # Simple dlopen to catch missing deps early | |
| python - <<'PY' | |
| import ctypes, os, glob, sys | |
| d = os.environ.get("SRC_ORACLE_CLIENT_PATH","") | |
| so = sorted(glob.glob(os.path.join(d, "libclntsh.so*"))) | |
| if not so: | |
| print("libclntsh not found in", d); sys.exit(1) | |
| try: | |
| ctypes.CDLL(so[0]) | |
| print("Loaded", os.path.basename(so[0]), "OK") | |
| except OSError as e: | |
| print("Failed to load:", e); sys.exit(1) | |
| PY | |
| # ---------- Run tests per-DB ---------- | |
| - name: Run marker-based slow tests for ${{ matrix.db }} | |
| run: >- | |
| uv run --frozen -m pytest | |
| -m "slow and ${{ matrix.db }}" | |
| -vv -s -rA --durations=25 --maxfail=1 | |
| -o log_cli=true -o log_cli_level=INFO |