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.
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.
Get the installer for your host OS from the official site:
virtualbox.org/wiki/Downloads — choose "VirtualBox 7.x platform packages" for your OS.
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.
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)
su - oracle sqlplus / as sysdba ALTER USER SYS IDENTIFIED BY "YourSysPassword123!"; ALTER USER SYSTEM IDENTIFIED BY "YourSystemPassword123!"; exit
sudo systemctl enable --now sshd # Verify it's listening: sudo ss -tlnp | grep 22
With NAT networking (default), set up port forwarding in VirtualBox so your host machine can reach the VM's Oracle listener and SSH daemon.
| 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 |
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.
ssh -p 2222 oracle@localhost # Accept the host key fingerprint # You should land in the Oracle Linux VM shell
# 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
TuneVault uses a dedicated read-only user with SELECT_CATALOG_ROLE. Run this SQL block inside the VM as SYSDBA:
ssh -p 2222 oracle@localhost su - oracle sqlplus / as sysdba
-- 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
# 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;
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.
# 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
# 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
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.
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.
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 checkslocal_validation.py — Python harness (9 checks, exercises all 5 bugs)proxy.env.template — copy to proxy.env and fill in your values# 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
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!"
# 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.