Skip to main content
Glama
test_crash_fix_validation.py10.6 kB
#!/usr/bin/env python3 """ Test script to validate FreeCAD crash fixes This script properly tests the fixed FreeCAD bridge and connection manager to ensure that creating documents and shapes no longer crashes. """ import os import sys import json import logging from pathlib import Path # Add src to Python path sys.path.insert(0, str(Path(__file__).parent / "src")) # Set up logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) logger = logging.getLogger("crash_fix_validation") def load_config(): """Load configuration from config.json""" config_path = Path(__file__).parent / "config.json" try: with open(config_path, 'r') as f: config = json.load(f) return config except Exception as e: logger.error(f"Failed to load config: {e}") return None def test_bridge_import(): """Test if we can import the bridge""" try: from mcp_freecad.server.freecad_bridge import FreeCADBridge logger.info("✅ Successfully imported FreeCADBridge") return True, FreeCADBridge except ImportError as e: logger.error(f"❌ Failed to import FreeCADBridge: {e}") return False, None def test_config_loading(): """Test configuration loading""" try: from mcp_freecad.server.components.config import load_config config = load_config("config.json") freecad_path = config.get("freecad", {}).get("path", "freecad") logger.info(f"✅ Config loaded successfully, FreeCAD path: {freecad_path}") return True, freecad_path except Exception as e: logger.error(f"❌ Config loading failed: {e}") # Fallback to direct config loading config = load_config() if config: freecad_path = config.get("freecad", {}).get("path", "freecad") logger.info(f"✅ Fallback config loaded, FreeCAD path: {freecad_path}") return True, freecad_path return False, None def test_bridge_creation(FreeCADBridge, freecad_path): """Test bridge creation with correct path""" try: bridge = FreeCADBridge(freecad_path) logger.info("✅ Successfully created FreeCADBridge instance") return True, bridge except Exception as e: logger.error(f"❌ Failed to create FreeCADBridge: {e}") return False, None def test_freecad_availability(bridge): """Test if FreeCAD is available through the bridge""" try: available = bridge.is_available() if available: logger.info("✅ FreeCAD is available through bridge") else: logger.warning("⚠️ FreeCAD is not available (may not be installed or configured)") return available except Exception as e: logger.error(f"❌ Error checking FreeCAD availability: {e}") return False def test_version_check(bridge): """Test version checking (this was previously crashing)""" try: version_info = bridge.get_version() if version_info.get("success"): version = version_info.get("version", "Unknown") logger.info(f"✅ Version check successful: {version}") return True else: error = version_info.get("error", "Unknown error") logger.warning(f"⚠️ Version check failed: {error}") return False except Exception as e: logger.error(f"❌ Version check crashed: {e}") return False def test_document_creation(bridge): """Test document creation (this was previously crashing)""" try: doc_name = bridge.create_document("CrashTestDoc") logger.info(f"✅ Document creation successful: {doc_name}") return True, doc_name except Exception as e: logger.error(f"❌ Document creation crashed: {e}") return False, None def test_shape_creation(bridge, doc_name): """Test shape creation (this was previously crashing)""" try: box_name = bridge.create_box(10.0, 20.0, 30.0, doc_name) logger.info(f"✅ Box creation successful: {box_name}") return True, box_name except Exception as e: logger.error(f"❌ Box creation crashed: {e}") return False, None def test_connection_manager(): """Test the connection manager with crash fixes""" try: from mcp_freecad.client.freecad_connection_manager import FreeCADConnection # Load config for connection config = load_config() if not config: logger.error("❌ Cannot test connection manager without config") return False freecad_path = config.get("freecad", {}).get("path", "freecad") # Test connection with bridge method fc = FreeCADConnection(freecad_path=freecad_path, auto_connect=False) # Try bridge connection specifically success = fc.connect(prefer_method="bridge") if success: logger.info("✅ Connection manager bridge connection successful") # Test operations through connection manager doc_name = fc.create_document("ConnectionTestDoc") if doc_name: logger.info(f"✅ Document creation through connection manager: {doc_name}") box_name = fc.create_box(5.0, 10.0, 15.0, doc_name) if box_name: logger.info(f"✅ Box creation through connection manager: {box_name}") else: logger.warning("⚠️ Box creation returned None") else: logger.warning("⚠️ Document creation returned None") else: logger.warning("⚠️ Bridge connection failed, trying other methods...") success = fc.connect() if success: connection_type = fc.get_connection_type() logger.info(f"✅ Connected using {connection_type} method") else: logger.error("❌ All connection methods failed") return False fc.close() return True except Exception as e: logger.error(f"❌ Connection manager test failed: {e}") return False def main(): """Main test function""" logger.info("=" * 60) logger.info("FreeCAD Crash Fix Validation Tests") logger.info("=" * 60) results = [] # Test 1: Import test logger.info("\n" + "=" * 40) logger.info("TEST 1: Module Import Test") logger.info("=" * 40) import_success, FreeCADBridge = test_bridge_import() results.append(("Module Import", import_success)) if not import_success: logger.error("❌ Cannot continue without successful import") return 1 # Test 2: Config loading logger.info("\n" + "=" * 40) logger.info("TEST 2: Configuration Loading") logger.info("=" * 40) config_success, freecad_path = test_config_loading() results.append(("Configuration Loading", config_success)) if not config_success: logger.error("❌ Cannot continue without config") return 1 # Test 3: Bridge creation logger.info("\n" + "=" * 40) logger.info("TEST 3: Bridge Creation") logger.info("=" * 40) bridge_success, bridge = test_bridge_creation(FreeCADBridge, freecad_path) results.append(("Bridge Creation", bridge_success)) if not bridge_success: logger.error("❌ Cannot continue without bridge") return 1 # Test 4: FreeCAD availability logger.info("\n" + "=" * 40) logger.info("TEST 4: FreeCAD Availability") logger.info("=" * 40) availability = test_freecad_availability(bridge) results.append(("FreeCAD Availability", availability)) if not availability: logger.warning("⚠️ FreeCAD not available - skipping crash tests") logger.info("\n" + "=" * 60) logger.info("BASIC SETUP TESTS SUMMARY") logger.info("=" * 60) for test_name, success in results: status = "✅ PASS" if success else "❌ FAIL" logger.info(f"{test_name}: {status}") logger.info("\n✅ Basic setup works - crash fixes are in place but FreeCAD needs proper installation") return 0 # Test 5: Version check (crash test) logger.info("\n" + "=" * 40) logger.info("TEST 5: Version Check (Crash Test)") logger.info("=" * 40) version_success = test_version_check(bridge) results.append(("Version Check", version_success)) # Test 6: Document creation (crash test) logger.info("\n" + "=" * 40) logger.info("TEST 6: Document Creation (Crash Test)") logger.info("=" * 40) doc_success, doc_name = test_document_creation(bridge) results.append(("Document Creation", doc_success)) # Test 7: Shape creation (crash test) if doc_success and doc_name: logger.info("\n" + "=" * 40) logger.info("TEST 7: Shape Creation (Crash Test)") logger.info("=" * 40) shape_success, box_name = test_shape_creation(bridge, doc_name) results.append(("Shape Creation", shape_success)) else: results.append(("Shape Creation", False)) # Test 8: Connection manager logger.info("\n" + "=" * 40) logger.info("TEST 8: Connection Manager") logger.info("=" * 40) connection_success = test_connection_manager() results.append(("Connection Manager", connection_success)) # Summary logger.info("\n" + "=" * 60) logger.info("CRASH FIX VALIDATION SUMMARY") logger.info("=" * 60) passed = 0 total = len(results) for test_name, success in results: status = "✅ PASS" if success else "❌ FAIL" logger.info(f"{test_name}: {status}") if success: passed += 1 logger.info(f"\nOverall: {passed}/{total} tests passed") if passed >= 6: # Allow some flexibility for different environments logger.info("🎉 Crash fixes are working! The app should no longer crash when creating documents and shapes.") return 0 elif passed >= 4: logger.info("✅ Basic fixes are working, but some advanced features may need attention.") return 0 else: logger.error("❌ Some critical tests failed. Check the logs above for details.") return 1 if __name__ == "__main__": exit_code = main() sys.exit(exit_code)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jango-blockchained/mcp-freecad'

If you have feedback or need assistance with the MCP directory API, please join our Discord server