55
66import glob
77import re
8+ import time
89from typing import TYPE_CHECKING , Dict , List , Optional
910
1011from .core import CFJavaTestRunner , CommandResult , TestContext
1314 from .file_validators import FileType
1415
1516
17+ def is_ssh_auth_error (output : str ) -> tuple [bool , Optional [str ]]:
18+ """
19+ Check if the given output contains SSH authentication errors.
20+
21+ Returns:
22+ tuple: (is_auth_error: bool, detected_error: Optional[str])
23+ """
24+ ssh_auth_errors = [
25+ "Error getting one time auth code: Error getting SSH code: Error requesting one time code from server:" ,
26+ "Error getting one time auth code" ,
27+ "Error getting SSH code" ,
28+ "Authentication failed" ,
29+ "SSH authentication failed" ,
30+ "Error opening SSH connection: ssh: handshake failed" ,
31+ ]
32+
33+ for error_pattern in ssh_auth_errors :
34+ if error_pattern in output :
35+ return True , error_pattern
36+
37+ return False , None
38+
39+
1640class FluentAssertion :
1741 """Fluent assertion interface for test results."""
1842
@@ -28,15 +52,70 @@ def __init__(self, result: CommandResult, context: TestContext, runner: CFJavaTe
2852 def should_succeed (self ) -> "FluentAssertion" :
2953 """Assert that the command succeeded."""
3054 if self .result .failed :
31- # Check for SSH auth errors that should skip the test instead of failing
32- ssh_auth_error = (
33- "Error getting one time auth code: Error getting SSH code: Error requesting one time code from server:"
34- )
35-
36- if ssh_auth_error in self .result .stderr or ssh_auth_error in self .result .stdout :
55+ # Check for SSH auth errors that should trigger re-login and restart
56+ output_to_check = self .result .stderr + " " + self .result .stdout
57+ ssh_error_detected , detected_error = is_ssh_auth_error (output_to_check )
58+ print ("🔍 Checking for SSH auth errors in command output..." )
59+ print ("output_to_check:" , output_to_check )
60+ print ("ssh_error_detected:" , ssh_error_detected )
61+ if ssh_error_detected :
3762 import pytest
3863
39- pytest .skip (f"Test skipped due to SSH auth error (CF platform issue): { ssh_auth_error } " )
64+ print (f"🔄 SSH AUTH ERROR DETECTED: { detected_error } " )
65+ print ("🔄 SSH AUTH ERROR DETECTED: Attempting re-login and app restart" )
66+
67+ # Try to recover by re-logging in and restarting the app
68+ try :
69+ # Force re-login by clearing login state
70+ from .core import CFManager
71+
72+ CFManager .reset_global_login_state ()
73+
74+ time .sleep (5 )
75+
76+ # Re-login
77+ cf_manager = CFManager (self .runner .config )
78+ login_success = cf_manager .login ()
79+
80+ if login_success :
81+ print ("✅ SSH AUTH RECOVERY: Successfully re-logged in" )
82+
83+ # Restart the app
84+ if hasattr (self .context , "app_name" ) and self .context .app_name :
85+ restart_success = cf_manager .restart_single_app (self .context .app_name )
86+ if restart_success :
87+ print (f"✅ SSH AUTH RECOVERY: Successfully restarted { self .context .app_name } " )
88+
89+ # Re-run the original command
90+ print (f"🔄 SSH AUTH RECOVERY: Retrying original command: { self .result .command } " )
91+ retry_result = self .runner .run_command (
92+ self .result .command , app_name = self .context .app_name
93+ )
94+
95+ # Replace the result with the retry result
96+ self .result = retry_result
97+
98+ # Check if retry succeeded
99+ if not retry_result .failed :
100+ print ("✅ SSH AUTH RECOVERY: Command succeeded after recovery" )
101+ return self
102+ else :
103+ print (
104+ "❌ SSH AUTH RECOVERY: Command still failed after recovery: "
105+ f"{ retry_result .stderr } "
106+ )
107+ else :
108+ print (f"❌ SSH AUTH RECOVERY: Failed to restart { self .context .app_name } " )
109+ else :
110+ print ("❌ SSH AUTH RECOVERY: No app name available for restart" )
111+ else :
112+ print ("❌ SSH AUTH RECOVERY: Failed to re-login" )
113+
114+ except Exception as e :
115+ print (f"❌ SSH AUTH RECOVERY: Exception during recovery: { e } " )
116+
117+ # If we get here, recovery failed or retry failed, so skip the test
118+ pytest .skip (f"Test skipped due to SSH auth error (CF platform issue): { detected_error } " )
40119
41120 raise AssertionError (
42121 f"Expected command to succeed, but it failed with code { self .result .returncode } :\n "
0 commit comments