#!/usr/bin/env python3
"""
Test script for Unimus MCP Server functionality.
This script tests all available functionality against a real Unimus test instance.
COMPREHENSIVE VALIDATION COMPLETED (2025-06-18):
===============================================
✅ ALL 13 MCP tools tested against live Unimus instance (portal.sportfondsen.it:230)
✅ Real network data: 17 devices, 5 backups per device, 3 schedules
✅ v1.0.0 features: 960 pattern matches in backup content search
✅ Change tracking: 16 devices with recent configuration changes
✅ Docker functionality: Container orchestration and health endpoints validated
✅ Performance features: Bulk operations, filtering, error handling tested
Load test environment variables first:
source .env.test
python test_functionality.py
Or run with inline environment:
UNIMUS_URL=... UNIMUS_TOKEN=... python test_functionality.py
"""
import os
import sys
import time
from typing import Dict, List, Any
from unimus_client import UnimusRestClient, UnimusError
def load_test_env() -> tuple[str, str]:
"""Load test environment variables."""
url = os.getenv("UNIMUS_URL")
token = os.getenv("UNIMUS_TOKEN")
if not url or not token:
print("❌ Error: UNIMUS_URL and UNIMUS_TOKEN environment variables must be set")
print("💡 Tip: Run 'source .env.test' first")
sys.exit(1)
return url, token
def test_connection(client: UnimusRestClient) -> bool:
"""Test basic connection and health."""
print("🔍 Testing connection...")
try:
if not client.validate_connection():
print("❌ Connection validation failed")
return False
health = client.get_health()
print(f"✅ Connection OK, Health: {health.get('status')}")
return True
except Exception as e:
print(f"❌ Connection test failed: {e}")
return False
def test_basic_functionality(client: UnimusRestClient) -> Dict[str, Any]:
"""Test basic device and backup functionality."""
print("\n📱 Testing basic functionality...")
results = {}
try:
# Get devices
devices = client.get_devices()
results['devices'] = devices
print(f"✅ Found {len(devices)} devices")
if devices:
# Get backups for first device
device_id = devices[0]['id']
backups = client.get_device_backups(device_id)
results['backups'] = backups
print(f"✅ Found {len(backups)} backups for device {device_id}")
except Exception as e:
print(f"❌ Basic functionality test failed: {e}")
return results
def test_v040_features(client: UnimusRestClient, test_data: Dict[str, Any]) -> None:
"""Test v1.0.0 new features."""
print("\n🚀 Testing v1.0.0 NEW features...")
# Test NEW: Backup Content Search
print("\n🔍 Testing Backup Content Search...")
try:
# Test with device filters and reasonable limits
search_results = client.search_backup_content(
pattern=r"interface.*",
device_filters={"managed": True},
context_lines=2,
limit=5
)
print(f"✅ Backup content search successful!")
print(f"📊 Found {len(search_results)} devices with interface matches")
if search_results:
first_result = search_results[0]
device_info = first_result['device']
matches = first_result['matches']
print(f"📱 Device: {device_info['address']} ({device_info.get('vendor', 'Unknown')} {device_info.get('type', 'Unknown')})")
print(f"🎯 Total matches: {len(matches)}")
if matches:
first_match = matches[0]
print(f"📍 First match at line {first_match['line_number']}")
print(f"📝 Content: {first_match['line_content'][:70]}...")
print(f"📋 Context: {len(first_match['context_before'])} lines before, {len(first_match['context_after'])} lines after")
# Test regex with capture groups
print("\n🔍 Testing VLAN search with capture groups...")
vlan_results = client.search_backup_content(
pattern=r"vlan (\d+)",
device_filters={"managed": True},
context_lines=1,
limit=3
)
if vlan_results:
for result in vlan_results[:1]: # Show first result
for match in result['matches'][:2]: # Show first 2 matches
vlan_num = match['match_groups'][0] if match['match_groups'] else 'N/A'
print(f"🏷️ Found VLAN {vlan_num} at line {match['line_number']}")
except Exception as e:
print(f"❌ Backup content search failed: {e}")
def test_v030_features(client: UnimusRestClient, test_data: Dict[str, Any]) -> None:
"""Test v0.3.0 features."""
print("\n🔧 Testing v0.3.0 features...")
# Test 1: Backup Diff
print("\n1️⃣ Testing Backup Diff...")
try:
backups = test_data.get('backups', [])
if len(backups) >= 2:
orig_id = backups[0]['id']
rev_id = backups[1]['id']
diff = client.get_backup_diff(orig_id, rev_id)
print(f"✅ Backup diff successful (comparing {orig_id} vs {rev_id})")
print(f"📊 Diff result keys: {list(diff.keys())}")
else:
print("⚠️ Not enough backups for diff test")
except Exception as e:
print(f"❌ Backup diff failed: {e}")
# Test 2: Device Change Tracking
print("\n2️⃣ Testing Device Change Tracking...")
try:
# Last 7 days
week_ago = int(time.time() - 7*24*60*60)
changed_devices = client.get_devices_with_changed_backups(since=week_ago)
print(f"✅ Change tracking successful")
print(f"📊 Found {len(changed_devices)} devices with changes in last 7 days")
# Test with no time range (all changes)
all_changed = client.get_devices_with_changed_backups()
print(f"📊 Total devices with any changes: {len(all_changed)}")
except Exception as e:
print(f"❌ Change tracking failed: {e}")
# Test 3: Schedule Management
print("\n3️⃣ Testing Schedule Management...")
try:
schedules = client.get_schedules()
print(f"✅ Schedule listing successful")
print(f"📊 Found {len(schedules)} schedules")
if schedules:
# Test getting individual schedule
schedule_id = schedules[0]['id']
schedule_name = schedules[0].get('name', 'N/A')
print(f"📅 Testing schedule: {schedule_name} (ID: {schedule_id})")
schedule_details = client.get_schedule_by_id(schedule_id)
print(f"✅ Schedule details retrieved successfully")
print(f"📋 Detail keys: {list(schedule_details.keys())}")
else:
print("ℹ️ No schedules found")
except Exception as e:
print(f"❌ Schedule management failed: {e}")
def test_v050_flexible_attributes(client: UnimusRestClient, test_data: Dict[str, Any]) -> None:
"""Test v0.5.0 flexible attribute functionality (Issue #5 Phase 1)."""
print("\n🔧 Testing FLEXIBLE ATTRIBUTE SELECTION (Issue #5 Phase 1)...")
devices = test_data.get('devices', [])
if not devices:
print("❌ No devices available for flexible attribute testing")
return
test_device_id = devices[0]['id']
test_device_address = devices[0].get('address', 'unknown')
print(f"🎯 Testing device: {test_device_address} (ID: {test_device_id})")
# Test 1: Backward compatibility - default behavior
print("\n1️⃣ Testing backward compatibility (default behavior)...")
try:
device_default = client.get_device_by_id(test_device_id)
print(f"✅ Default behavior successful")
has_schedule = 'schedule' in device_default and device_default['schedule'] is not None
has_connections = 'connections' in device_default and len(device_default.get('connections', [])) > 0
print(f"📊 Default includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Default behavior failed: {e}")
# Test 2: Backward compatibility - explicit include_connections=True
print("\n2️⃣ Testing backward compatibility (include_connections=True)...")
try:
device_conn_true = client.get_device_by_id(test_device_id, include_connections=True)
print(f"✅ include_connections=True successful")
has_schedule = 'schedule' in device_conn_true and device_conn_true['schedule'] is not None
has_connections = 'connections' in device_conn_true and len(device_conn_true.get('connections', [])) > 0
print(f"📊 Explicit True includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ include_connections=True failed: {e}")
# Test 3: Backward compatibility - explicit include_connections=False
print("\n3️⃣ Testing backward compatibility (include_connections=False)...")
try:
device_conn_false = client.get_device_by_id(test_device_id, include_connections=False)
print(f"✅ include_connections=False successful")
has_schedule = 'schedule' in device_conn_false and device_conn_false['schedule'] is not None
has_connections = 'connections' in device_conn_false and len(device_conn_false.get('connections', [])) > 0
print(f"📊 Explicit False includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ include_connections=False failed: {e}")
# Test 4: New flexible attributes - empty list (basic info only)
print("\n4️⃣ Testing flexible attributes (empty list - basic info only)...")
try:
device_basic = client.get_device_by_id(test_device_id, include_attributes=[])
print(f"✅ Basic info only successful")
has_schedule = 'schedule' in device_basic and device_basic['schedule'] is not None
has_connections = 'connections' in device_basic and len(device_basic.get('connections', [])) > 0
print(f"📊 Basic only includes - Schedule: {has_schedule}, Connections: {has_connections}")
print(f"📋 Basic info keys: {list(device_basic.keys())}")
except Exception as e:
print(f"❌ Basic info only failed: {e}")
# Test 5: New flexible attributes - schedule only
print("\n5️⃣ Testing flexible attributes (schedule only)...")
try:
device_schedule_only = client.get_device_by_id(test_device_id, include_attributes=['schedule'])
print(f"✅ Schedule only successful")
has_schedule = 'schedule' in device_schedule_only and device_schedule_only['schedule'] is not None
has_connections = 'connections' in device_schedule_only and len(device_schedule_only.get('connections', [])) > 0
print(f"📊 Schedule only includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Schedule only failed: {e}")
# Test 6: New flexible attributes - connections only
print("\n6️⃣ Testing flexible attributes (connections only)...")
try:
device_conn_only = client.get_device_by_id(test_device_id, include_attributes=['connections'])
print(f"✅ Connections only successful")
has_schedule = 'schedule' in device_conn_only and device_conn_only['schedule'] is not None
has_connections = 'connections' in device_conn_only and len(device_conn_only.get('connections', [])) > 0
print(f"📊 Connections only includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Connections only failed: {e}")
# Test 7: New flexible attributes - both schedule and connections
print("\n7️⃣ Testing flexible attributes (schedule + connections)...")
try:
device_both = client.get_device_by_id(test_device_id, include_attributes=['schedule', 'connections'])
print(f"✅ Schedule + connections successful")
has_schedule = 'schedule' in device_both and device_both['schedule'] is not None
has_connections = 'connections' in device_both and len(device_both.get('connections', [])) > 0
print(f"📊 Both includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Schedule + connections failed: {e}")
# Test 8: New flexible attributes - short notation
print("\n8️⃣ Testing flexible attributes (short notation 's', 'c')...")
try:
device_short = client.get_device_by_id(test_device_id, include_attributes=['s', 'c'])
print(f"✅ Short notation successful")
has_schedule = 'schedule' in device_short and device_short['schedule'] is not None
has_connections = 'connections' in device_short and len(device_short.get('connections', [])) > 0
print(f"📊 Short notation includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Short notation failed: {e}")
# Test 9: New flexible attributes - mixed notation
print("\n9️⃣ Testing flexible attributes (mixed notation)...")
try:
device_mixed = client.get_device_by_id(test_device_id, include_attributes=['schedule', 'c'])
print(f"✅ Mixed notation successful")
has_schedule = 'schedule' in device_mixed and device_mixed['schedule'] is not None
has_connections = 'connections' in device_mixed and len(device_mixed.get('connections', [])) > 0
print(f"📊 Mixed notation includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Mixed notation failed: {e}")
# Test 10: New flexible attributes - invalid attribute (should warn but continue)
print("\n🔟 Testing flexible attributes (invalid attribute warning)...")
try:
device_invalid = client.get_device_by_id(test_device_id, include_attributes=['schedule', 'invalid_attr'])
print(f"✅ Invalid attribute handling successful")
has_schedule = 'schedule' in device_invalid and device_invalid['schedule'] is not None
has_connections = 'connections' in device_invalid and len(device_invalid.get('connections', [])) > 0
print(f"📊 Invalid attribute includes - Schedule: {has_schedule}, Connections: {has_connections}")
except Exception as e:
print(f"❌ Invalid attribute handling failed: {e}")
print(f"\n🎯 Flexible attribute testing completed for device {test_device_id}")
def test_v050_enhanced_metadata(client: UnimusRestClient, test_data: Dict[str, Any]) -> None:
"""Test v0.5.0 enhanced metadata functionality (Issue #5 Phase 2)."""
print("\n🔧 Testing ENHANCED METADATA FEATURES (Issue #5 Phase 2)...")
devices = test_data.get('devices', [])
if not devices:
print("❌ No devices available for enhanced metadata testing")
return
test_device_id = devices[0]['id']
test_device_address = devices[0].get('address', 'unknown')
print(f"🎯 Testing device: {test_device_address} (ID: {test_device_id})")
# Test 1: Basic enriched metadata
print("\n1️⃣ Testing basic enhanced metadata...")
try:
device_enriched = client.get_device_by_id(test_device_id, enrich_metadata=True)
print(f"✅ Enhanced metadata successful")
# Check for expected metadata fields
metadata_fields = [
'backupAge', 'lastBackupTime', 'backupFreshness', 'backupCount',
'deviceHealth', 'deviceLifecycle', 'deviceAge',
'connectionTypes', 'primaryConnectionType',
'configurationStability', 'hasRecentChanges', 'changeFrequency'
]
found_fields = []
for field in metadata_fields:
if field in device_enriched:
found_fields.append(field)
print(f"📊 Enhanced metadata fields found: {len(found_fields)}/{len(metadata_fields)}")
print(f"📋 Found fields: {', '.join(found_fields)}")
# Display key metrics
if 'backupAge' in device_enriched and device_enriched['backupAge'] is not None:
backup_age_hours = device_enriched['backupAge'] // 3600
print(f"⏰ Backup age: {backup_age_hours} hours")
if 'backupFreshness' in device_enriched:
print(f"🟢 Backup freshness: {device_enriched['backupFreshness']}")
if 'deviceHealth' in device_enriched:
print(f"💚 Device health: {device_enriched['deviceHealth']}")
if 'configurationStability' in device_enriched:
print(f"📈 Configuration stability: {device_enriched['configurationStability']}")
# Check metadata tracking
if '_metadata' in device_enriched:
metadata_info = device_enriched['_metadata']
print(f"🏷️ Metadata version: {metadata_info.get('enrichment_version', 'unknown')}")
except Exception as e:
print(f"❌ Enhanced metadata failed: {e}")
# Test 2: Combined attributes + metadata
print("\n2️⃣ Testing combined attributes and enhanced metadata...")
try:
device_combined = client.get_device_by_id(
test_device_id,
include_attributes=['schedule', 'connections'],
enrich_metadata=True
)
print(f"✅ Combined attributes + metadata successful")
has_schedule = 'schedule' in device_combined and device_combined['schedule'] is not None
has_connections = 'connections' in device_combined and len(device_combined.get('connections', [])) > 0
has_metadata = 'backupAge' in device_combined
print(f"📊 Combined includes - Schedule: {has_schedule}, Connections: {has_connections}, Metadata: {has_metadata}")
except Exception as e:
print(f"❌ Combined attributes + metadata failed: {e}")
# Test 3: Metadata-only (minimal attributes)
print("\n3️⃣ Testing metadata with minimal attributes...")
try:
device_minimal = client.get_device_by_id(
test_device_id,
include_attributes=[],
enrich_metadata=True
)
print(f"✅ Minimal attributes + metadata successful")
has_schedule = 'schedule' in device_minimal and device_minimal['schedule'] is not None
has_connections = 'connections' in device_minimal and len(device_minimal.get('connections', [])) > 0
has_metadata = 'backupAge' in device_minimal
print(f"📊 Minimal includes - Schedule: {has_schedule}, Connections: {has_connections}, Metadata: {has_metadata}")
except Exception as e:
print(f"❌ Minimal attributes + metadata failed: {e}")
# Test 4: Metadata performance analysis
print("\n4️⃣ Testing metadata performance...")
try:
import time
start_time = time.time()
device_perf = client.get_device_by_id(test_device_id, enrich_metadata=True)
end_time = time.time()
duration = end_time - start_time
print(f"✅ Metadata performance test completed")
print(f"⏱️ Enrichment duration: {duration:.2f} seconds")
if duration > 5:
print(f"⚠️ Warning: Metadata enrichment took longer than expected")
else:
print(f"🚀 Metadata enrichment performance acceptable")
except Exception as e:
print(f"❌ Metadata performance test failed: {e}")
# Test 5: Error handling
print("\n5️⃣ Testing metadata error handling...")
try:
# Test with invalid device ID
try:
invalid_device = client.get_device_by_id(999999, enrich_metadata=True)
print(f"❌ Expected error for invalid device ID")
except Exception:
print(f"✅ Error handling for invalid device ID works correctly")
# Test metadata with existing device
device_error_test = client.get_device_by_id(test_device_id, enrich_metadata=True)
if '_metadata_error' in device_error_test:
print(f"⚠️ Metadata error detected: {device_error_test['_metadata_error']}")
else:
print(f"✅ No metadata errors detected")
except Exception as e:
print(f"✅ Error handling working as expected: {e}")
print(f"\n🎯 Enhanced metadata testing completed for device {test_device_id}")
def test_v050_device_relationships(client: UnimusRestClient, test_data: Dict[str, Any]) -> None:
"""Test v0.5.0 device relationship mapping and topology analysis (Issue #5 Phase 3)."""
print("\n🔧 Testing DEVICE RELATIONSHIPS & TOPOLOGY ANALYSIS (Issue #5 Phase 3)...")
devices = test_data.get('devices', [])
if not devices:
print("❌ No devices available for device relationship testing")
return
test_device_id = devices[0]['id']
test_device_address = devices[0].get('address', 'unknown')
print(f"🎯 Testing device: {test_device_address} (ID: {test_device_id})")
# Test 1: Full device relationship analysis
print("\n1️⃣ Testing full device relationship analysis...")
try:
relationships = client.get_device_relationships(test_device_id)
print(f"✅ Full relationship analysis successful")
# Check for expected relationship components
device_info = relationships.get('device', {})
network_neighbors = relationships.get('networkNeighbors', [])
zone_peers = relationships.get('zonePeers', [])
connection_patterns = relationships.get('connectionPatterns', {})
topology_insights = relationships.get('topologyInsights', {})
relationship_metadata = relationships.get('relationshipMetadata', {})
print(f"📊 Relationship analysis results:")
print(f" 🌐 Network neighbors: {len(network_neighbors)}")
print(f" 🏢 Zone peers: {len(zone_peers)}")
print(f" 🔗 Similar connection devices: {len(connection_patterns.get('similar_connection_devices', []))}")
# Display topology insights
print(f" 📍 Network position: {topology_insights.get('network_position')}")
print(f" 🔄 Connectivity role: {topology_insights.get('connectivity_role')}")
print(f" 🏢 Zone importance: {topology_insights.get('zone_importance')}")
# Display relationship metadata
summary = relationship_metadata.get('relationship_summary', {})
print(f" 📈 Total relationships: {summary.get('total_network_neighbors', 0) + summary.get('total_zone_peers', 0)}")
except Exception as e:
print(f"❌ Full relationship analysis failed: {e}")
# Test 2: Network neighbors only
print("\n2️⃣ Testing network neighbors analysis...")
try:
network_only = client.get_device_relationships(
test_device_id,
include_network_neighbors=True,
include_zone_peers=False,
include_connection_analysis=False
)
print(f"✅ Network neighbors analysis successful")
neighbors = network_only.get('networkNeighbors', [])
print(f"📊 Found {len(neighbors)} network neighbors")
# Show sample neighbors
for neighbor in neighbors[:3]: # Show first 3
device_info = neighbor.get('device', {})
net_rel = neighbor.get('networkRelationship', {})
print(f" 🌐 {device_info.get('address')} - {net_rel.get('relationship_type')} (distance: {net_rel.get('network_distance')})")
except Exception as e:
print(f"❌ Network neighbors analysis failed: {e}")
# Test 3: Zone peers only
print("\n3️⃣ Testing zone peers analysis...")
try:
zone_only = client.get_device_relationships(
test_device_id,
include_network_neighbors=False,
include_zone_peers=True,
include_connection_analysis=False
)
print(f"✅ Zone peers analysis successful")
peers = zone_only.get('zonePeers', [])
print(f"📊 Found {len(peers)} zone peers")
# Show sample peers
for peer in peers[:3]: # Show first 3
device_info = peer.get('device', {})
zone_rel = peer.get('zoneRelationship', {})
print(f" 🏢 {device_info.get('address')} - {device_info.get('vendor')} {device_info.get('type')} (Zone: {zone_rel.get('shared_zone_id')})")
except Exception as e:
print(f"❌ Zone peers analysis failed: {e}")
# Test 4: Connection analysis only
print("\n4️⃣ Testing connection pattern analysis...")
try:
connection_only = client.get_device_relationships(
test_device_id,
include_network_neighbors=False,
include_zone_peers=False,
include_connection_analysis=True
)
print(f"✅ Connection pattern analysis successful")
patterns = connection_only.get('connectionPatterns', {})
similar_devices = patterns.get('similar_connection_devices', [])
security_analysis = patterns.get('security_analysis', {})
print(f"📊 Found {len(similar_devices)} devices with similar connections")
print(f"🔒 Security score: {security_analysis.get('security_score')}")
# Show sample similar devices
for device in similar_devices[:3]: # Show first 3
device_info = device.get('device', {})
similarity = device.get('connection_similarity', {})
print(f" 🔗 {device_info.get('address')} - Similarity: {similarity.get('similarity_score')} (Types: {similarity.get('shared_connection_types')})")
except Exception as e:
print(f"❌ Connection pattern analysis failed: {e}")
# Test 5: Network topology analysis
print("\n5️⃣ Testing network topology analysis...")
try:
topology = client.get_network_topology_analysis()
print(f"✅ Network topology analysis successful")
# Check topology components
overview = topology.get('networkOverview', {})
clusters = topology.get('deviceClusters', [])
segments = topology.get('networkSegments', [])
zone_topology = topology.get('zoneTopology', {})
security_patterns = topology.get('securityPatterns', {})
print(f"📊 Network topology results:")
print(f" 📱 Total devices: {overview.get('total_devices')}")
print(f" ✅ Managed devices: {overview.get('managed_devices')} ({overview.get('managed_percentage')}%)")
print(f" 🎯 Device clusters: {len(clusters)}")
print(f" 🌐 Network segments: {len(segments)}")
print(f" 🏢 Total zones: {zone_topology.get('total_zones')}")
# Security overview
risk_assessment = security_patterns.get('risk_assessment', {})
print(f" 🔒 Security score: {risk_assessment.get('security_score', 0)}%")
print(f" 🛡️ Risk level: {risk_assessment.get('overall_risk_level')}")
# Show largest clusters
if clusters:
largest_cluster = max(clusters, key=lambda x: x.get('device_count', 0))
print(f" 🎯 Largest cluster: {largest_cluster.get('cluster_type')} with {largest_cluster.get('device_count')} devices")
# Show largest network segments
if segments:
largest_segment = max(segments, key=lambda x: x.get('device_count', 0))
print(f" 🌐 Largest segment: {largest_segment.get('network')} with {largest_segment.get('device_count')} devices")
except Exception as e:
print(f"❌ Network topology analysis failed: {e}")
# Test 6: Zone-specific topology analysis
if len(devices) > 0:
test_zone_id = devices[0].get('zoneId')
if test_zone_id:
print(f"\n6️⃣ Testing zone-specific topology analysis (Zone: {test_zone_id})...")
try:
zone_topology = client.get_network_topology_analysis(
zone_id=test_zone_id,
include_clusters=True,
include_security_analysis=True
)
print(f"✅ Zone-specific topology analysis successful")
overview = zone_topology.get('networkOverview', {})
metadata = zone_topology.get('topologyMetadata', {})
scope = metadata.get('analysis_scope', {})
print(f"📊 Zone {test_zone_id} analysis:")
print(f" 📱 Zone devices: {scope.get('total_devices')}")
print(f" ✅ Managed: {scope.get('managed_devices')}")
print(f" 🏭 Vendors: {scope.get('vendors_present')}")
print(f" 📊 Device types: {scope.get('device_types_present')}")
except Exception as e:
print(f"❌ Zone-specific topology analysis failed: {e}")
print(f"\n🎯 Device relationship and topology testing completed for device {test_device_id}")
def main():
"""Main test function."""
print("🎯 UNIMUS MCP SERVER FUNCTIONALITY TEST")
print("=" * 50)
# Load environment
try:
url, token = load_test_env()
print(f"🔗 Test instance: {url}")
except SystemExit:
return
# Initialize client
client = UnimusRestClient(url=url, token=token)
# Test connection
if not test_connection(client):
return
# Test basic functionality
test_data = test_basic_functionality(client)
# Test v1.0.0 features
test_v040_features(client, test_data)
# Test v0.3.0 features
test_v030_features(client, test_data)
# Test v0.5.0 NEW features (Issue #5)
test_v050_flexible_attributes(client, test_data)
# Test v0.5.0 Phase 2 NEW features (Issue #5 Phase 2)
test_v050_enhanced_metadata(client, test_data)
# Test v0.5.0 Phase 3 NEW features (Issue #5 Phase 3)
test_v050_device_relationships(client, test_data)
print("\n🎉 TEST COMPLETED!")
print("✅ All v1.0.0 functionality + NEW v0.5.0 flexible attributes + enhanced metadata + device relationships validated against real Unimus instance")
if __name__ == "__main__":
main()