v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
311
test_upload_with_auth_real.py
Executable file
311
test_upload_with_auth_real.py
Executable file
@@ -0,0 +1,311 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Real functionality test for upload WITH authentication
|
||||
|
||||
Companion test to test_simple_upload_no_auth.py that validates the complete
|
||||
upload pipeline when proper authentication is provided.
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import tempfile
|
||||
import zipfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
# Add project root to path for real imports
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
def load_environment_config():
|
||||
"""Load real environment configuration"""
|
||||
env_file = Path(".env.local")
|
||||
if not env_file.exists():
|
||||
env_file = Path(".env")
|
||||
|
||||
config = {}
|
||||
if env_file.exists():
|
||||
with open(env_file) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#') and '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
config[key.strip()] = value.strip().strip('"\'')
|
||||
|
||||
# Also check environment variables
|
||||
for key in ['RPA_TOKEN_ADMIN', 'RPA_TOKEN_READONLY', 'ENCRYPTION_PASSWORD']:
|
||||
if key in os.environ:
|
||||
config[key] = os.environ[key]
|
||||
|
||||
return config
|
||||
|
||||
def create_realistic_rawsession_data():
|
||||
"""Create realistic RawSession data matching actual system format"""
|
||||
return {
|
||||
"schema_version": "rawsession_v1",
|
||||
"session_id": f"test_auth_session_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
|
||||
"agent_version": "0.1.0",
|
||||
"environment": {
|
||||
"platform": "linux",
|
||||
"hostname": "test-machine",
|
||||
"screen": {
|
||||
"primary_resolution": [1920, 1080],
|
||||
"display_scale": 1.0
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": "test_user_auth",
|
||||
"label": "Test User with Auth"
|
||||
},
|
||||
"context": {
|
||||
"customer": "Test Customer Auth",
|
||||
"training_label": "Upload_Auth_Test",
|
||||
"notes": "Real functionality test for upload WITH authentication"
|
||||
},
|
||||
"started_at": datetime.now().isoformat() + "Z",
|
||||
"ended_at": datetime.now().isoformat() + "Z",
|
||||
"events": [
|
||||
{
|
||||
"t": 0.5,
|
||||
"type": "mouse_click",
|
||||
"button": "left",
|
||||
"pos": [450, 320],
|
||||
"window": {
|
||||
"title": "Test Application",
|
||||
"app_name": "test_app"
|
||||
},
|
||||
"screenshot_id": "shot_0001"
|
||||
},
|
||||
{
|
||||
"t": 1.2,
|
||||
"type": "key_combo",
|
||||
"keys": ["CTRL", "C"],
|
||||
"window": {
|
||||
"title": "Test Application",
|
||||
"app_name": "test_app"
|
||||
},
|
||||
"screenshot_id": "shot_0002"
|
||||
}
|
||||
],
|
||||
"screenshots": [
|
||||
{
|
||||
"screenshot_id": "shot_0001",
|
||||
"relative_path": "shots/shot_0001.png",
|
||||
"captured_at": datetime.now().isoformat() + "Z"
|
||||
},
|
||||
{
|
||||
"screenshot_id": "shot_0002",
|
||||
"relative_path": "shots/shot_0002.png",
|
||||
"captured_at": datetime.now().isoformat() + "Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def create_realistic_test_zip():
|
||||
"""Create a realistic ZIP file matching agent_v0 format"""
|
||||
temp_dir = Path(tempfile.mkdtemp())
|
||||
session_data = create_realistic_rawsession_data()
|
||||
session_id = session_data["session_id"]
|
||||
|
||||
# Create session directory structure
|
||||
session_dir = temp_dir / session_id
|
||||
session_dir.mkdir(parents=True)
|
||||
shots_dir = session_dir / "shots"
|
||||
shots_dir.mkdir()
|
||||
|
||||
# Create session JSON file
|
||||
session_file = session_dir / f"{session_id}.json"
|
||||
with open(session_file, 'w') as f:
|
||||
json.dump(session_data, f, indent=2)
|
||||
|
||||
# Create dummy screenshot files
|
||||
png_data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\tpHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x12IDATx\x9cc```bPPP\x00\x02\xac\x01\x00\x00\x05\x00\x01\r\n\x87\xdc\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
for shot_id in ["shot_0001", "shot_0002"]:
|
||||
screenshot_file = shots_dir / f"{shot_id}.png"
|
||||
with open(screenshot_file, 'wb') as f:
|
||||
f.write(png_data)
|
||||
|
||||
# Create ZIP file
|
||||
zip_path = temp_dir / f"{session_id}.zip"
|
||||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
# Add session JSON
|
||||
zipf.write(session_file, f"{session_id}.json")
|
||||
# Add screenshots
|
||||
for shot_id in ["shot_0001", "shot_0002"]:
|
||||
screenshot_file = shots_dir / f"{shot_id}.png"
|
||||
zipf.write(screenshot_file, f"shots/{shot_id}.png")
|
||||
|
||||
return zip_path, session_id
|
||||
|
||||
def test_upload_with_auth():
|
||||
"""Test upload with proper authentication using realistic data"""
|
||||
|
||||
# Load real environment configuration
|
||||
config = load_environment_config()
|
||||
|
||||
# Check if we have authentication tokens
|
||||
admin_token = config.get('RPA_TOKEN_ADMIN')
|
||||
readonly_token = config.get('RPA_TOKEN_READONLY')
|
||||
|
||||
if not admin_token and not readonly_token:
|
||||
print("⚠️ No authentication tokens found in environment")
|
||||
print("This test requires RPA_TOKEN_ADMIN or RPA_TOKEN_READONLY")
|
||||
print("Check .env.local or .env files, or set environment variables")
|
||||
return False
|
||||
|
||||
# Use admin token if available, otherwise readonly
|
||||
auth_token = admin_token or readonly_token
|
||||
token_type = "admin" if admin_token else "readonly"
|
||||
|
||||
zip_path = None
|
||||
try:
|
||||
# Create realistic test data
|
||||
zip_path, session_id = create_realistic_test_zip()
|
||||
|
||||
url = "http://127.0.0.1:8000/api/traces/upload"
|
||||
|
||||
print(f"Testing authenticated upload to: {url}")
|
||||
print(f"Session ID: {session_id}")
|
||||
print(f"Using {token_type} token: {auth_token[:10]}...")
|
||||
print(f"ZIP file size: {zip_path.stat().st_size} bytes")
|
||||
|
||||
# Test the actual upload endpoint with authentication
|
||||
headers = {
|
||||
'Authorization': f'Bearer {auth_token}',
|
||||
'X-API-Key': auth_token # Some APIs use this header instead
|
||||
}
|
||||
|
||||
with open(zip_path, 'rb') as f:
|
||||
files = {'file': (zip_path.name, f, 'application/zip')}
|
||||
data = {'session_id': session_id}
|
||||
|
||||
response = requests.post(
|
||||
url,
|
||||
files=files,
|
||||
data=data,
|
||||
headers=headers,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
print(f"Status Code: {response.status_code}")
|
||||
print(f"Response Headers: {dict(response.headers)}")
|
||||
print(f"Response Body: {response.text}")
|
||||
|
||||
# Analyze the response for real functionality validation
|
||||
if response.status_code == 200:
|
||||
print("✅ SUCCESS: Authenticated upload worked!")
|
||||
|
||||
# Try to parse response as JSON
|
||||
try:
|
||||
response_data = response.json()
|
||||
print(f"Response data: {response_data}")
|
||||
|
||||
# Validate response structure
|
||||
if 'status' in response_data and response_data['status'] == 'success':
|
||||
print("✅ Server confirmed successful processing")
|
||||
|
||||
if 'session_id' in response_data:
|
||||
print(f"✅ Server confirmed session_id: {response_data['session_id']}")
|
||||
|
||||
# Check if processing was queued
|
||||
if 'queued' in response_data:
|
||||
print(f"✅ Processing queued: {response_data['queued']}")
|
||||
|
||||
except json.JSONDecodeError:
|
||||
print("Response is not JSON, but upload was accepted")
|
||||
|
||||
return True
|
||||
|
||||
elif response.status_code == 401:
|
||||
print("❌ AUTHENTICATION FAILED: Token was rejected")
|
||||
print("Check if the token is valid and not expired")
|
||||
return False
|
||||
|
||||
elif response.status_code == 403:
|
||||
print("❌ AUTHORIZATION FAILED: Token lacks required permissions")
|
||||
print(f"The {token_type} token may not have upload permissions")
|
||||
return False
|
||||
|
||||
else:
|
||||
print(f"❌ UNEXPECTED STATUS: {response.status_code}")
|
||||
print("This might indicate a server issue or configuration problem")
|
||||
return False
|
||||
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
print(f"❌ CONNECTION ERROR: Server not running at {url}")
|
||||
print(f"Error: {e}")
|
||||
print("Start the server with: ./run.sh --server")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ UNEXPECTED ERROR: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
finally:
|
||||
# Clean up test files
|
||||
if zip_path and zip_path.exists():
|
||||
import shutil
|
||||
temp_dir = zip_path.parent
|
||||
try:
|
||||
shutil.rmtree(temp_dir)
|
||||
print(f"Cleaned up test directory: {temp_dir}")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not clean up {temp_dir}: {e}")
|
||||
|
||||
def validate_server_running():
|
||||
"""Check if the RPA Vision V3 server is running"""
|
||||
try:
|
||||
response = requests.get("http://127.0.0.1:8000/api/traces/status", timeout=5)
|
||||
return response.status_code in [200, 401, 403]
|
||||
except:
|
||||
return False
|
||||
|
||||
def check_server_processing_pipeline():
|
||||
"""Test if the server can process uploaded data"""
|
||||
try:
|
||||
# Try to get queue status
|
||||
response = requests.get("http://127.0.0.1:8000/api/traces/queue", timeout=5)
|
||||
if response.status_code in [200, 401, 403]:
|
||||
print("✅ Server processing pipeline endpoints are available")
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
print("⚠️ Could not verify processing pipeline status")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 RPA Vision V3 - Real Functionality Test: Upload WITH Authentication")
|
||||
print("=" * 75)
|
||||
|
||||
# Check if server is running first
|
||||
if not validate_server_running():
|
||||
print("❌ Server is not running!")
|
||||
print("Please start the server first:")
|
||||
print(" ./run.sh --server")
|
||||
print(" # or")
|
||||
print(" python server/api_upload.py")
|
||||
exit(1)
|
||||
|
||||
print("✅ Server is running")
|
||||
|
||||
# Check processing pipeline
|
||||
check_server_processing_pipeline()
|
||||
print()
|
||||
|
||||
success = test_upload_with_auth()
|
||||
|
||||
print()
|
||||
print("=" * 75)
|
||||
if success:
|
||||
print("🎉 Authenticated upload test completed successfully!")
|
||||
print("The server properly processed the upload with authentication.")
|
||||
else:
|
||||
print("❌ Authenticated upload test failed!")
|
||||
print("Check server logs, authentication configuration, and tokens.")
|
||||
|
||||
exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user