Agents SSH Targets EBS Validation Proxy Self-Test Agent Upgrades
⚙ Admin — Test Harness

# VirtualBox Oracle XE Test Harness

Step-by-step guide to set up a local Oracle XE 21c VM and validate the TuneVault proxy. Exercises all 5 known proxy bugs in a reproducible local environment. No licensed Oracle EBS media required.

### Progress Checklist

○ 1. VirtualBox + Oracle XE installed
○ 2. Network ports forwarded
○ 3. SSH confirmed working
○ 4. TUNEVAULT_RO user created
○ 5. Proxy installed + configured
○ 6. Validator bundle downloaded + run
1
VirtualBox + Oracle XE Setup
Download, install, boot — ~30 min
▶
ℹ

Oracle XE 21c is free for development/testing. It supports all the V$ and DBA_ views TuneVault reads. Real Oracle EBS requires licensed media — on XE the EBS-specific probes will return `ebs_detected: false`, which is the correct negative-path test.

Step 1.1 — Download VirtualBox 7.x

Get the installer for your host OS from the official site:

virtualbox.org/wiki/Downloads — choose "VirtualBox 7.x platform packages" for your OS.

Step 1.2 — Get Oracle XE 21c VirtualBox appliance

Oracle provides a free pre-built OVA (requires Oracle account, free registration):

oracle.com/database/technologies/xe-downloads.html

Download Oracle Database 21c Express Edition for Linux x86-64 (RPM installer). You'll install it inside an Oracle Linux 8 / AlmaLinux 8 VM, or use an existing Oracle XE appliance if you have one.

Alternatively, search VirtualBox Appliance Gallery for a pre-built Oracle XE 21c OVA to import directly.

Step 1.3 — Import + boot the VM

Import the OVA in VirtualBox: File → Import Appliance → select the .ova file.

Start the VM. Default credentials are typically `oracle/oracle` or shown in the appliance README.

Inside the VM, verify Oracle is running:

    systemctl status oracle-xe-21c
    # Should show: active (running)

Step 1.4 — Change SYS/SYSTEM passwords

    su - oracle
    sqlplus / as sysdba
    ALTER USER SYS   IDENTIFIED BY "YourSysPassword123!";
    ALTER USER SYSTEM IDENTIFIED BY "YourSystemPassword123!";
    exit

Step 1.5 — Enable SSH

    sudo systemctl enable --now sshd
    # Verify it's listening:
    sudo ss -tlnp | grep 22

2
VirtualBox Network + Port Forwarding
Map host ports to guest ports
▶

With NAT networking (default), set up port forwarding in VirtualBox so your host machine can reach the VM's Oracle listener and SSH daemon.

VirtualBox GUI method

1. Select the VM → Settings → Network → Adapter 1
2. Confirm: Attached to = NAT
3. Click Port Forwarding
4. Add three rules:

Name | Protocol | Host IP | Host Port | Guest IP | Guest Port
--- | --- | --- | --- | --- | ---
SSH | TCP | 127.0.0.1 | 2222 |  | 22
Oracle | TCP | 127.0.0.1 | 1521 |  | 1521
EM Express | TCP | 127.0.0.1 | 8080 |  | 8080

Or via VBoxManage CLI

    VBoxManage modifyvm "OracleXE" --natpf1 "ssh,tcp,,2222,,22"
    VBoxManage modifyvm "OracleXE" --natpf1 "oracle,tcp,,1521,,1521"
    VBoxManage modifyvm "OracleXE" --natpf1 "em-express,tcp,,8080,,8080"

Replace `OracleXE` with the name of your VM.

Verify SSH from your host

    ssh -p 2222 oracle@localhost
    # Accept the host key fingerprint
    # You should land in the Oracle Linux VM shell

Verify Oracle listener from your host

    # Quick TCP test (macOS / Linux)
    timeout 3 bash -c "echo > /dev/tcp/localhost/1521" && echo "✓ Port 1521 reachable" || echo "✗ Not reachable"

    # Or with sqlplus if you have Oracle client installed:
    sqlplus TUNEVAULT_RO/password@localhost:1521/XE

3
Oracle User Setup (TUNEVAULT_RO)
Create read-only monitoring user with required grants
▶

TuneVault uses a dedicated read-only user with `SELECT_CATALOG_ROLE`. Run this SQL block inside the VM as SYSDBA:

SSH into the VM + connect as SYSDBA

    ssh -p 2222 oracle@localhost
    su - oracle
    sqlplus / as sysdba

Create user + grant roles (paste this in SQLPlus)

    -- Create the monitoring user
    CREATE USER TUNEVAULT_RO IDENTIFIED BY "TVReadOnly2024!";

    -- Basic connection + catalog read
    GRANT CREATE SESSION TO TUNEVAULT_RO;
    GRANT SELECT_CATALOG_ROLE TO TUNEVAULT_RO;

    -- V$ dynamic performance views (needed for all core checks)
    GRANT SELECT ANY DICTIONARY TO TUNEVAULT_RO;

    -- Additional grants for specific checks
    GRANT SELECT ON v_$session        TO TUNEVAULT_RO;
    GRANT SELECT ON v_$sql            TO TUNEVAULT_RO;
    GRANT SELECT ON v_$sqlarea        TO TUNEVAULT_RO;
    GRANT SELECT ON v_$sysstat        TO TUNEVAULT_RO;
    GRANT SELECT ON v_$parameter      TO TUNEVAULT_RO;
    GRANT SELECT ON v_$tablespace     TO TUNEVAULT_RO;
    GRANT SELECT ON v_$datafile       TO TUNEVAULT_RO;
    GRANT SELECT ON v_$sga            TO TUNEVAULT_RO;
    GRANT SELECT ON v_$sgastat        TO TUNEVAULT_RO;
    GRANT SELECT ON v_$pgastat        TO TUNEVAULT_RO;
    GRANT SELECT ON v_$rman_backup_job_details TO TUNEVAULT_RO;
    GRANT SELECT ON dba_segments      TO TUNEVAULT_RO;
    GRANT SELECT ON dba_tablespaces   TO TUNEVAULT_RO;
    GRANT SELECT ON dba_free_space    TO TUNEVAULT_RO;
    GRANT SELECT ON dba_objects       TO TUNEVAULT_RO;
    GRANT SELECT ON dba_users         TO TUNEVAULT_RO;
    GRANT SELECT ON dba_sys_privs     TO TUNEVAULT_RO;

    -- Confirm grants
    SELECT granted_role FROM dba_role_privs WHERE grantee = 'TUNEVAULT_RO';
    exit

Test the user from your host

    # With sqlplus (if Oracle client installed on host):
    sqlplus TUNEVAULT_RO/"TVReadOnly2024!"@localhost:1521/XE

    # Verify V$ access:
    SELECT banner FROM v$version WHERE ROWNUM = 1;

4
Proxy Install + Self-Test
Copy proxy to VM, configure proxy.env, run --validate-only
▶
⚡

For local testing, the proxy can run on your host machine (not inside the VM) since you've port-forwarded Oracle :1521 to localhost:1521. The `--validate-only` flag tests connectivity without starting an HTTP server.

Option A — Run proxy on host (simplest for testing)

    # Download oracle-proxy.py from TuneVault dashboard or use the validator bundle below

    # Create proxy.env (copy from proxy.env.template, edit values)
    cat > proxy.env << 'EOF'
    ORACLE_HOST=localhost
    ORACLE_PORT=1521
    ORACLE_SERVICE=XE
    ORACLE_USER=TUNEVAULT_RO
    ORACLE_PASSWORD=TVReadOnly2024!
    TUNEVAULT_API_KEY=local-test-key
    EOF

    # Self-test without starting the HTTP server:
    python3 oracle-proxy.py --validate-only
    # Exit 0 = all pass, 1 = failures

Option B — Run proxy inside the VM

    # Copy proxy to VM:
    scp -P 2222 oracle-proxy.py oracle@localhost:~/

    # SSH in + set up:
    ssh -p 2222 oracle@localhost

    # Inside VM:
    pip3 install cx_Oracle

    cat > proxy.env << 'EOF'
    ORACLE_HOST=localhost
    ORACLE_PORT=1521
    ORACLE_SERVICE=XE
    ORACLE_USER=TUNEVAULT_RO
    ORACLE_PASSWORD=TVReadOnly2024!
    TUNEVAULT_API_KEY=local-test-key
    EOF

    # Self-test:
    python3 oracle-proxy.py --validate-only

Start the proxy normally (after --validate-only passes)

    export TUNEVAULT_API_KEY=local-test-key
    python3 oracle-proxy.py
    # Listening on 127.0.0.1:3100

    # From your host, hit the health endpoint:
    curl http://localhost:3100/health
    # {"status":"ok","version":"..."}

For the proxy to be reachable from TuneVault, you'll need an HTTPS tunnel or reverse proxy to expose the local port over HTTPS. For local-only testing, the validator bundle below handles this directly.

5
Expected Results on Oracle XE 21c (no EBS)
What passes, what fails, and why each result is correct
▶

On a vanilla Oracle XE 21c instance (no Oracle EBS installed), here's what the validator should return:

Check | Expected | Reason
--- | --- | ---
cx_Oracle import | ✓ PASS | Library installed via `pip3 install cx_Oracle`
TCP connectivity | ✓ PASS | Port 1521 forwarded from host to guest
Oracle connection | ✓ PASS | TUNEVAULT_RO user exists with correct password
SELECT_CATALOG_ROLE | ✓ PASS | DBA_ views accessible — role granted in setup SQL
Payload structure (Bug 1) | ✓ PASS | collect_metrics() returns all required keys
EBS probe variants (Bug 2) | ✓ PASS | APPS.* tables don't exist on XE — all probes fail gracefully, `ebs_detected=false`
Health check coverage (Bug 3) | ✓ PASS | All 5 core V$ queries accessible on XE 21c
Edition detection (Bug 4) | ✓ PASS | XE banner detected as "Express Edition"
CM multi-row handling (Bug 5) | ✓ PASS | FND_CONCURRENT_QUEUES doesn't exist on XE — proxy returns gracefully
EBS detection (in proxy) | ! EXPECTED | APPS.FND_APPLICATION not present → `ebs_detected=false`. Correct for XE.
FND_CONCURRENT_QUEUES query | ! EXPECTED | Table doesn't exist on non-EBS → ORA-00942. Proxy must NOT crash.

⚠

If the proxy crashes when EBS probes fail (ORA-00942 / table not found), that is Bug #1 reproduced. The fix is shipped in the current proxy version — all APPS.* queries are wrapped in try/except with graceful fallback to `ebs_detected=false`.

6
Download Validator Bundle
run-local-validation.sh + local_validation.py + oracle-proxy.py
▶

The bundle contains everything needed to run the full validation locally:

- `oracle-proxy.py` — the TuneVault proxy (with `--validate-only` flag)
- `run-local-validation.sh` — shell wrapper with pre-flight checks
- `local_validation.py` — Python harness (9 checks, exercises all 5 bugs)
- `proxy.env.template` — copy to `proxy.env` and fill in your values

Download + extract

    # Download the bundle (requires admin session cookie):
    curl -O -b "$(cat ~/.tv_cookie)" https://tunevault.app/api/test-harness/validator-bundle
    # File: tunevault-validator.tar

    # Extract:
    tar xf tunevault-validator.tar

    # Edit config:
    cp proxy.env.template proxy.env
    nano proxy.env   # set ORACLE_HOST, PORT, SERVICE, USER, PASSWORD

Or click to download directly
Download Validator Bundle (.tar)
Run the validation

    chmod +x run-local-validation.sh
    ./run-local-validation.sh

    # Or directly with Python:
    python3 local_validation.py

    # With explicit args (overrides proxy.env):
    python3 local_validation.py \
      --host localhost --port 1521 --service XE \
      --user TUNEVAULT_RO --password "TVReadOnly2024!"

Use oracle-proxy.py --validate-only directly

    # Self-test mode — reads proxy.env, no HTTP server started
    python3 oracle-proxy.py --validate-only

    # Exit code 0 = all pass
    # Exit code 1 = one or more failures
    # Report: validation-report.json written to same directory

Note: The validator writes `validation-report.json` to its working directory. Share this file with TuneVault support if you're reporting a proxy bug — it contains all check results with Oracle version, edition, and EBS detection state.