""" Test suite for cross-platform compatibility validation. Related to Issue #145: Phase 4 - Production Readiness and Release (Week 6) Tests Windows, macOS, and Linux compatibility including filesystem features, symlinks, path handling, and platform-specific integrations. """ import pytest import platform import tempfile import shutil import os from pathlib import Path from unittest.mock import Mock, patch, MagicMock from markitect.production.cross_platform_validator import ( CrossPlatformValidator, PlatformFeature, CompatibilityResult, WindowsCompatibilityChecker, MacOSCompatibilityChecker, LinuxCompatibilityChecker ) class TestCrossPlatformValidator: """Test cross-platform compatibility validation capabilities.""" @pytest.fixture def temp_workspace(self): """Create temporary workspace for testing.""" temp_dir = tempfile.mkdtemp() yield Path(temp_dir) shutil.rmtree(temp_dir, ignore_errors=True) @pytest.fixture def validator(self, temp_workspace): """Create CrossPlatformValidator instance.""" return CrossPlatformValidator( workspace_path=temp_workspace, target_platforms=["windows", "macos", "linux"] ) def test_windows_ntfs_filesystem_compatibility(self, validator): """Test NTFS filesystem compatibility testing.""" with patch('platform.system', return_value='Windows'): with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs: mock_fs.return_value = 'NTFS' result = validator.check_filesystem_compatibility() assert result.platform == "windows" assert result.filesystem_type == "NTFS" assert result.supported_features is not None assert PlatformFeature.SYMLINKS in result.supported_features assert PlatformFeature.HARDLINKS in result.supported_features def test_windows_symlink_alternatives(self, validator, temp_workspace): """Test Windows symlink alternatives (junction points, hardlinks).""" windows_checker = WindowsCompatibilityChecker(temp_workspace) # Test junction point creation target_dir = temp_workspace / "target_directory" target_dir.mkdir() junction_dir = temp_workspace / "junction_link" result = windows_checker.create_directory_link( target=target_dir, link=junction_dir, link_type="junction" ) assert result.success is True assert result.link_type == "junction" assert result.requires_admin is False # Test hardlink creation target_file = temp_workspace / "target_file.txt" target_file.write_text("test content") hardlink_file = temp_workspace / "hardlink.txt" result = windows_checker.create_file_link( target=target_file, link=hardlink_file, link_type="hardlink" ) assert result.success is True assert result.link_type == "hardlink" assert hardlink_file.read_text() == "test content" def test_windows_path_length_limitation_handling(self, validator): """Test handling of Windows 260 character path limit.""" windows_checker = WindowsCompatibilityChecker() # Test path that exceeds traditional limit long_path = "C:\\" + "\\".join(["very_long_directory_name"] * 15) + "\\file.txt" result = windows_checker.validate_path_length(long_path) assert result.path_length > 260 assert result.exceeds_traditional_limit is True assert result.long_path_support_available is not None assert result.suggested_alternatives is not None def test_windows_permission_model_compatibility(self, validator): """Test Windows permission model compatibility.""" windows_checker = WindowsCompatibilityChecker() test_permissions = { "owner": "rwx", "group": "r-x", "other": "r--" } result = windows_checker.map_unix_permissions_to_windows(test_permissions) assert result.success is True assert result.windows_acl is not None assert result.permission_mapping is not None assert "Full Control" in str(result.windows_acl) def test_powershell_integration_testing(self, validator): """Test PowerShell integration testing.""" windows_checker = WindowsCompatibilityChecker() # Test PowerShell command execution with patch('subprocess.run') as mock_run: mock_run.return_value.returncode = 0 mock_run.return_value.stdout = "PowerShell 5.1.19041.1682" result = windows_checker.test_powershell_integration() assert result.success is True assert result.powershell_version is not None assert result.execution_policy_compatible is not None def test_macos_hfs_apfs_filesystem_compatibility(self, validator): """Test HFS+/APFS filesystem compatibility.""" macos_checker = MacOSCompatibilityChecker() with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs: # Test APFS mock_fs.return_value = 'APFS' result = macos_checker.check_filesystem_features() assert result.filesystem_type == "APFS" assert result.supports_snapshots is True assert result.supports_clones is True assert result.case_sensitive is not None # Test HFS+ mock_fs.return_value = 'HFS+' result = macos_checker.check_filesystem_features() assert result.filesystem_type == "HFS+" assert result.supports_resource_forks is True def test_macos_symlink_behavior_validation(self, validator, temp_workspace): """Test macOS symlink behavior validation.""" macos_checker = MacOSCompatibilityChecker(temp_workspace) # Create target file target_file = temp_workspace / "target.txt" target_file.write_text("test content") # Test symlink creation and behavior symlink_file = temp_workspace / "symlink.txt" result = macos_checker.create_and_validate_symlink( target=target_file, link=symlink_file ) assert result.success is True assert result.symlink_created is True assert result.target_accessible is True assert result.permissions_preserved is not None def test_macos_extended_attribute_handling(self, validator, temp_workspace): """Test extended attribute handling on macOS.""" macos_checker = MacOSCompatibilityChecker(temp_workspace) test_file = temp_workspace / "test_file.txt" test_file.write_text("test content") # Test setting and getting extended attributes result = macos_checker.test_extended_attributes( file_path=test_file, attributes={ "com.markitect.asset_id": "asset_123", "com.markitect.content_type": "text/plain" } ) assert result.success is True assert result.attributes_set is True assert result.attributes_retrievable is True def test_macos_security_features_compatibility(self, validator): """Test macOS security features compatibility (Gatekeeper, SIP).""" macos_checker = MacOSCompatibilityChecker() result = macos_checker.check_security_compatibility() assert result.gatekeeper_status is not None assert result.sip_status is not None assert result.code_signing_requirements is not None assert result.sandbox_compatibility is not None def test_homebrew_installation_compatibility(self, validator): """Test Homebrew installation compatibility.""" macos_checker = MacOSCompatibilityChecker() with patch('shutil.which') as mock_which: mock_which.return_value = "/opt/homebrew/bin/brew" result = macos_checker.check_homebrew_compatibility() assert result.homebrew_available is True assert result.homebrew_path is not None assert result.installation_method is not None def test_linux_multiple_filesystem_support(self, validator): """Test multiple filesystem support (ext4, btrfs, xfs).""" linux_checker = LinuxCompatibilityChecker() filesystems = ["ext4", "btrfs", "xfs", "zfs"] for fs_type in filesystems: with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs: mock_fs.return_value = fs_type result = linux_checker.check_filesystem_support(fs_type) assert result.filesystem_type == fs_type assert hasattr(result, 'supports_snapshots') assert hasattr(result, 'supports_clones') def test_linux_distribution_specific_testing(self, validator): """Test distribution-specific testing (Ubuntu, CentOS, Alpine).""" linux_checker = LinuxCompatibilityChecker() distributions = [ {"name": "Ubuntu", "version": "20.04", "package_manager": "apt"}, {"name": "CentOS", "version": "8", "package_manager": "yum"}, {"name": "Alpine", "version": "3.14", "package_manager": "apk"} ] for distro in distributions: with patch('platform.freedesktop_os_release') as mock_os_release: mock_os_release.return_value = { 'NAME': distro["name"], 'VERSION': distro["version"] } result = linux_checker.check_distribution_compatibility(distro) assert result.distribution_name == distro["name"] assert result.version_supported is not None assert result.package_manager == distro["package_manager"] def test_container_environment_compatibility(self, validator): """Test container environment compatibility (Docker, Podman).""" linux_checker = LinuxCompatibilityChecker() container_runtimes = ["docker", "podman"] for runtime in container_runtimes: with patch('shutil.which') as mock_which: mock_which.return_value = f"/usr/bin/{runtime}" result = linux_checker.check_container_compatibility(runtime) assert result.runtime_available is True assert result.runtime_name == runtime assert result.features_supported is not None def test_package_manager_integration_testing(self, validator): """Test package manager integration testing.""" linux_checker = LinuxCompatibilityChecker() package_managers = [ {"name": "apt", "install_cmd": "apt install", "search_cmd": "apt search"}, {"name": "yum", "install_cmd": "yum install", "search_cmd": "yum search"}, {"name": "pacman", "install_cmd": "pacman -S", "search_cmd": "pacman -Ss"} ] for pm in package_managers: with patch('shutil.which') as mock_which: mock_which.return_value = f"/usr/bin/{pm['name']}" result = linux_checker.test_package_manager_integration(pm["name"]) assert result.package_manager == pm["name"] assert result.available is True assert result.install_command is not None def test_systemd_service_integration(self, validator): """Test systemd service integration.""" linux_checker = LinuxCompatibilityChecker() with patch('pathlib.Path.exists') as mock_exists: mock_exists.return_value = True result = linux_checker.check_systemd_integration() assert result.systemd_available is True assert result.service_creation_supported is not None assert result.user_services_supported is not None def test_comprehensive_platform_detection(self, validator): """Test comprehensive platform detection and feature mapping.""" # Test current platform detection result = validator.detect_current_platform() assert result.platform_name is not None assert result.platform_version is not None assert result.architecture is not None assert result.supported_features is not None # Verify platform-specific features are correctly identified current_platform = platform.system().lower() expected_features = validator.get_expected_features_for_platform(current_platform) assert set(result.supported_features).issuperset(set(expected_features)) def test_cross_platform_path_handling(self, validator, temp_workspace): """Test cross-platform path handling and normalization.""" test_paths = [ "/unix/style/path/file.txt", "C:\\Windows\\Style\\Path\\file.txt", "relative/path/file.txt", "../parent/directory/file.txt", "~/home/directory/file.txt" ] for test_path in test_paths: result = validator.normalize_path_for_platform( path=test_path, target_platform="current" ) assert result.normalized_path is not None assert result.is_valid is not None assert result.platform_specific_issues is not None def test_symlink_compatibility_matrix(self, validator, temp_workspace): """Test symlink compatibility across all platforms.""" target_file = temp_workspace / "target.txt" target_file.write_text("test content") platforms = ["windows", "macos", "linux"] link_types = ["symlink", "hardlink", "junction"] compatibility_matrix = validator.test_symlink_compatibility_matrix( target_file=target_file, platforms=platforms, link_types=link_types ) assert len(compatibility_matrix) == len(platforms) for platform_result in compatibility_matrix: assert platform_result.platform in platforms assert platform_result.supported_link_types is not None assert platform_result.limitations is not None def test_unicode_filename_support(self, validator, temp_workspace): """Test Unicode filename support across platforms.""" unicode_filenames = [ "测试文件.txt", # Chinese "αρχείο_δοκιμής.txt", # Greek "файл_теста.txt", # Cyrillic "📄_emoji_file.txt", # Emoji "café_résumé.txt" # Accented characters ] for filename in unicode_filenames: result = validator.test_unicode_filename_support( filename=filename, test_directory=temp_workspace ) assert result.filename == filename assert result.creation_supported is not None assert result.read_supported is not None assert result.platform_issues is not None def test_file_permission_model_mapping(self, validator): """Test file permission model mapping between platforms.""" unix_permissions = "755" # rwxr-xr-x # Test mapping to Windows ACL windows_result = validator.map_permissions_to_platform( permissions=unix_permissions, source_platform="unix", target_platform="windows" ) assert windows_result.success is True assert windows_result.target_permissions is not None # Test mapping to macOS macos_result = validator.map_permissions_to_platform( permissions=unix_permissions, source_platform="unix", target_platform="macos" ) assert macos_result.success is True assert macos_result.target_permissions is not None def test_platform_specific_error_handling(self, validator): """Test platform-specific error handling and recovery.""" error_scenarios = [ { "platform": "windows", "error": "Access is denied", "expected_recovery": "elevate_privileges" }, { "platform": "macos", "error": "Operation not permitted", "expected_recovery": "grant_permissions" }, { "platform": "linux", "error": "Permission denied", "expected_recovery": "check_selinux" } ] for scenario in error_scenarios: result = validator.handle_platform_specific_error( platform=scenario["platform"], error_message=scenario["error"] ) assert result.platform == scenario["platform"] assert result.error_recognized is True assert result.recovery_strategy is not None