# Termux Manual Testing Guide

**Purpose**: Validate GigLez Phase 1 & 2 in real Termux environment
**Branch**: `p1-p2-validation`
**Prerequisites**: Android device with Termux installed

---

## Pre-Flight Checklist

- [ ] Termux installed from F-Droid (not Play Store)
- [ ] Device has at least 2GB free storage
- [ ] Stable internet connection for package installation
- [ ] USB OTG cable (if testing with T-Embed)

---

## Step 1: Environment Setup (30 minutes)

### 1.1 Update Termux Packages
```bash
pkg update && pkg upgrade -y
```

### 1.2 Install Required Packages
```bash
# PostgreSQL
pkg install postgresql -y

# Python and development tools
pkg install python python-pip git -y

# Build dependencies
pkg install build-essential libffi openssl -y
```

**Expected**: All packages install without errors

### 1.3 Clone Repository
```bash
cd ~
git clone https://github.com/yourusername/giglez.git
cd giglez
git checkout p1-p2-validation
```

**Expected**: Repository cloned, on validation branch

### 1.4 Install Python Dependencies
```bash
pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-asyncio python-multipart
```

**Expected**: All dependencies install successfully
**Common Issue**: If psycopg2 fails, try `pkg install postgresql-dev` first

---

## Step 2: Database Setup (10 minutes)

### 2.1 Initialize PostgreSQL
```bash
initdb ~/postgres
pg_ctl -D ~/postgres -l ~/postgres/logfile start
```

**Expected**: PostgreSQL starts, log file created
**Verify**: `pg_ctl -D ~/postgres status` shows "server is running"

### 2.2 Create Database
```bash
cd ~/giglez
./scripts/setup_database.sh
```

**Expected Output**:
```
✅ User giglez_user created
✅ Database giglez created
✅ PostGIS extension enabled
```

**Troubleshoot**: If permission denied, run:
```bash
chmod +x scripts/setup_database.sh
```

### 2.3 Create Schema
```bash
psql -U giglez_user -d giglez -h localhost -f scripts/create_schema.sql
```

**Expected**: 15 tables created, no errors
**Verify**:
```bash
psql -U giglez_user -d giglez -h localhost -c "\dt"
```
Should list: users, sessions, devices, captures, signatures, etc.

### 2.4 Test PostGIS
```bash
psql -U giglez_user -d giglez -h localhost -c "SELECT PostGIS_Version();"
```

**Expected**: PostGIS version string (3.x)

---

## Step 3: Configuration Test (5 minutes)

### 3.1 Copy Environment File
```bash
cp .env.development .env
```

### 3.2 Edit Configuration
```bash
nano .env
```

**Adjust paths**:
```bash
GIGLEZ_STORAGE_PATH=/data/data/com.termux/files/home/giglez/storage
GIGLEZ_QUEUE_PATH=/data/data/com.termux/files/home/giglez/queue
```

**Save**: Ctrl+O, Enter, Ctrl+X

### 3.3 Test Configuration
```bash
python config/settings.py
```

**Expected Output**:
```
========================================================
GigLez Configuration
========================================================
Mode: development
Database: postgresql://giglez_user:****@localhost:5432/giglez
API: 127.0.0.1:8000
Storage: filesystem
Hardware: Disabled
Authentication: Optional
...
✅ Configuration validated successfully
```

**Troubleshoot**: If validation fails, check .env file syntax

---

## Step 4: Unit Tests (10 minutes)

### 4.1 Run GPS Validator Tests
```bash
pytest tests/unit/test_gps_validator.py -v
```

**Expected**: All tests pass (green)
**Count**: ~20 tests

### 4.2 Run Storage Tests (when implemented)
```bash
pytest tests/unit/test_storage.py -v
```

### 4.3 Run All Unit Tests
```bash
pytest tests/unit/ -v
```

**Success Criteria**: All unit tests pass

---

## Step 5: API Server Test (10 minutes)

### 5.1 Start API Server
```bash
python src/api/main.py
```

**Expected Output**:
```
============================================================
GigLez API Starting
============================================================
Mode: development
...
✅ Database connection established
✅ PostGIS extension available
✅ Storage backend initialized: LocalStorage
============================================================
🚀 GigLez API ready on 127.0.0.1:8000
📡 Mode: development
============================================================
```

**Troubleshoot**: If port 8000 busy, change in .env

### 5.2 Test Health Endpoint
Open new Termux session (swipe from left, "New session"):
```bash
curl http://127.0.0.1:8000/health
```

**Expected**:
```json
{
  "status": "healthy",
  "database": "connected",
  "mode": "development",
  "hardware_enabled": false
}
```

### 5.3 Test API Info
```bash
curl http://127.0.0.1:8000/
```

**Expected**: JSON with API name, version, status

### 5.4 Test OpenAPI Docs
```bash
curl http://127.0.0.1:8000/docs
```

**Expected**: HTML response (OpenAPI documentation)

**Browser Test**: If you have Termux:API installed:
```bash
termux-open-url http://127.0.0.1:8000/docs
```

---

## Step 6: Upload Test (15 minutes)

### 6.1 Create Test .sub File
```bash
cd ~/giglez
cat > test_capture.sub << 'EOF'
Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok270Async
Protocol: Princeton
Bit: 24
Key: 00 00 00 00 00 95 D5 D4
TE: 400
EOF
```

### 6.2 Create Test Manifest
```bash
cat > test_manifest.json << 'EOF'
{
    "session_uuid": "termux-test-001",
    "captures": [
        {
            "filename": "test_capture.sub",
            "latitude": 40.7128,
            "longitude": -74.0060,
            "accuracy": 5.0,
            "altitude": 10.5,
            "timestamp": "2026-01-12T10:00:00Z"
        }
    ]
}
EOF
```

### 6.3 Upload Test File
```bash
curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest=$(cat test_manifest.json)" \
  -F "files=@test_capture.sub"
```

**Expected Response**:
```json
{
  "session_uuid": "termux-test-001",
  "uploaded": 1,
  "duplicates": 0,
  "errors": 0,
  "results": [
    {
      "filename": "test_capture.sub",
      "status": "uploaded",
      "file_hash": "abc123...",
      "frequency": 433920000,
      "protocol": "Princeton"
    }
  ]
}
```

**Success Criteria**:
- `uploaded: 1`
- `errors: 0`
- `file_hash` present
- `status: "uploaded"`

### 6.4 Verify in Database
```bash
psql -U giglez_user -d giglez -h localhost << 'SQL'
SELECT file_hash, frequency, protocol, latitude, longitude
FROM captures
LIMIT 5;
SQL
```

**Expected**: Your capture listed with correct data

### 6.5 Verify in Storage
```bash
ls -lh ~/giglez/storage/
```

**Expected**: Directory structure with .sub file:
```
storage/
└── ab/
    └── c1/
        └── abc123...def.sub
```

### 6.6 Test Duplicate Upload
```bash
# Upload same file again
curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest=$(cat test_manifest.json)" \
  -F "files=@test_capture.sub"
```

**Expected Response**:
```json
{
  "uploaded": 0,
  "duplicates": 1,
  ...
}
```

**Success Criteria**: Duplicate detected, not re-uploaded

---

## Step 7: Query Test (5 minutes)

### 7.1 Get Capture by Hash
Get file_hash from previous upload response, then:
```bash
curl http://127.0.0.1:8000/api/v1/captures/{FILE_HASH}
```

Replace `{FILE_HASH}` with actual hash.

**Expected**: JSON with capture details

### 7.2 Test Invalid Hash
```bash
curl http://127.0.0.1:8000/api/v1/captures/invalid_hash_12345
```

**Expected**: 404 error with message "Capture not found"

---

## Step 8: Multiple File Upload (10 minutes)

### 8.1 Create Multiple Test Files
```bash
# Create 3 different captures
for i in {1..3}; do
  cat > test_capture_${i}.sub << EOF
Filetype: Flipper SubGhz Key File
Version: 1
Frequency: $((433920000 + i * 1000))
Preset: FuriHalSubGhzPresetOok270Async
Protocol: Princeton
Bit: 24
Key: 00 00 00 00 00 95 D5 $(printf '%02X' $i)
TE: 400
EOF
done
```

### 8.2 Create Multi-File Manifest
```bash
cat > multi_manifest.json << 'EOF'
{
    "session_uuid": "termux-multi-test-001",
    "captures": [
        {
            "filename": "test_capture_1.sub",
            "latitude": 40.7128,
            "longitude": -74.0060,
            "accuracy": 5.0,
            "timestamp": "2026-01-12T10:00:00Z"
        },
        {
            "filename": "test_capture_2.sub",
            "latitude": 40.7129,
            "longitude": -74.0061,
            "accuracy": 6.0,
            "timestamp": "2026-01-12T10:00:10Z"
        },
        {
            "filename": "test_capture_3.sub",
            "latitude": 40.7130,
            "longitude": -74.0062,
            "accuracy": 4.0,
            "timestamp": "2026-01-12T10:00:20Z"
        }
    ]
}
EOF
```

### 8.3 Upload Multiple Files
```bash
curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest=$(cat multi_manifest.json)" \
  -F "files=@test_capture_1.sub" \
  -F "files=@test_capture_2.sub" \
  -F "files=@test_capture_3.sub"
```

**Expected**: `uploaded: 3`, all 3 files processed successfully

### 8.4 Verify Count
```bash
psql -U giglez_user -d giglez -h localhost -c \
  "SELECT COUNT(*) FROM captures;"
```

**Expected**: At least 4 captures (1 from previous + 3 new)

---

## Step 9: Error Handling Tests (5 minutes)

### 9.1 Test Invalid GPS
```bash
cat > bad_gps_manifest.json << 'EOF'
{
    "session_uuid": "test-errors",
    "captures": [
        {
            "filename": "test_capture.sub",
            "latitude": 91.0,
            "longitude": 0.0,
            "accuracy": 5.0,
            "timestamp": "2026-01-12T10:00:00Z"
        }
    ]
}
EOF

curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest=$(cat bad_gps_manifest.json)" \
  -F "files=@test_capture.sub"
```

**Expected**: Error in response, file rejected

### 9.2 Test Missing Manifest Entry
```bash
cat > incomplete_manifest.json << 'EOF'
{
    "session_uuid": "test-incomplete",
    "captures": []
}
EOF

curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest=$(cat incomplete_manifest.json)" \
  -F "files=@test_capture.sub"
```

**Expected**: Error for missing manifest entry

### 9.3 Test Invalid JSON
```bash
curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
  -F "manifest={invalid json}" \
  -F "files=@test_capture.sub"
```

**Expected**: 400 Bad Request with JSON error message

---

## Step 10: Performance Test (5 minutes)

### 10.1 Upload 10 Files Rapidly
```bash
# Create 10 test files
for i in {1..10}; do
  cp test_capture.sub bulk_test_${i}.sub
done

# Note: This will create duplicates, testing deduplication
time for i in {1..10}; do
  curl -X POST http://127.0.0.1:8000/api/v1/captures/upload \
    -F "manifest=$(cat test_manifest.json)" \
    -F "files=@bulk_test_${i}.sub" &
done
wait
```

**Monitor**: Check API logs for performance
**Expected**: All requests complete, duplicates detected

---

## Success Criteria Checklist

### Database (Phase 1)
- [ ] PostgreSQL installs and starts
- [ ] Database schema creates without errors
- [ ] PostGIS extension available
- [ ] Can insert and query captures
- [ ] Triggers execute (session stats update)

### API (Phase 2)
- [ ] API server starts without errors
- [ ] Health endpoint responds correctly
- [ ] OpenAPI docs accessible
- [ ] Configuration loads correctly
- [ ] Storage backend initializes

### Upload Workflow
- [ ] Single file upload succeeds
- [ ] Multiple file upload succeeds
- [ ] Duplicate detection works
- [ ] GPS validation works (rejects invalid)
- [ ] Files stored in correct directory structure
- [ ] Database records created correctly
- [ ] Session management works

### Error Handling
- [ ] Invalid GPS rejected
- [ ] Invalid JSON handled
- [ ] Missing manifest entries handled
- [ ] Malformed .sub files handled (if tested)

---

## Troubleshooting

### PostgreSQL Won't Start
```bash
# Check if already running
ps aux | grep postgres

# Kill existing processes
pkill postgres

# Remove old PID file
rm ~/postgres/postmaster.pid

# Restart
pg_ctl -D ~/postgres -l ~/postgres/logfile start
```

### API Port Already in Use
```bash
# Find process using port 8000
netstat -tuln | grep 8000

# Kill process (if needed)
pkill -f "python src/api/main.py"
```

### Permission Errors
```bash
# Fix script permissions
chmod +x scripts/*.sh

# Fix storage directory
mkdir -p ~/giglez/storage
chmod 755 ~/giglez/storage
```

### Import Errors
```bash
# Reinstall dependencies
pip install --upgrade --force-reinstall -r requirements.txt
```

---

## Cleanup (Optional)

### Stop Services
```bash
# Stop API server (Ctrl+C in server terminal)

# Stop PostgreSQL
pg_ctl -D ~/postgres stop
```

### Remove Test Data
```bash
# Clean database
psql -U giglez_user -d giglez -h localhost -c "TRUNCATE captures CASCADE;"

# Clean storage
rm -rf ~/giglez/storage/*

# Remove test files
rm ~/giglez/test_*.sub
rm ~/giglez/*.json
```

---

## Test Results Template

### Environment Info
- **Device**: [Device model]
- **Android Version**: [Version]
- **Termux Version**: [Version]
- **PostgreSQL Version**: [Run `psql --version`]
- **Python Version**: [Run `python --version`]

### Test Results
- **Database Setup**: ✅ / ❌
- **API Startup**: ✅ / ❌
- **Single Upload**: ✅ / ❌
- **Multiple Upload**: ✅ / ❌
- **Duplicate Detection**: ✅ / ❌
- **GPS Validation**: ✅ / ❌
- **Error Handling**: ✅ / ❌

### Issues Found
[List any bugs or issues discovered]

### Performance Notes
- Upload time (single file): [X seconds]
- Upload time (3 files): [X seconds]
- API response time: [X ms average]

---

**Testing Complete!**
Document results in TESTING_RESULTS.md
