Skip to content

Commit 5572439

Browse files
committed
Set version 4.0.1
1 parent 42e3d84 commit 5572439

File tree

3 files changed

+98
-17
lines changed

3 files changed

+98
-17
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,14 @@ USAGE:
275275
Get the status of async-profiler on a running Java application
276276

277277
OPTIONS:
278+
-args -a, Miscellaneous arguments to pass to the command (if supported) in the
279+
container, be aware to end it with a space if it is a simple option. For
280+
commands that create arbitrary files (jcmd, asprof), the environment
281+
variables @FSPATH, @ARGS, @APP_NAME, @FILE_NAME, and @STATIC_FILE_NAME are
282+
available in --args to reference the working directory path, arguments,
283+
application name, and generated file name respectively.
284+
-container-dir -cd, the directory path in the container that the heap dump/JFR/... file will be
285+
saved to
278286
-dry-run -n, just output to command line what would be executed
279287
-keep -k, keep the heap dump in the container; by default the heap dump/JFR/... will
280288
be deleted from the container's filesystem after being downloaded
@@ -284,14 +292,6 @@ OPTIONS:
284292
container, implies '--keep'
285293
-verbose -v, enable verbose output for the plugin
286294
-app-instance-index -i [index], select to which instance of the app to connect
287-
-args -a, Miscellaneous arguments to pass to the command (if supported) in the
288-
container, be aware to end it with a space if it is a simple option. For
289-
commands that create arbitrary files (jcmd, asprof), the environment
290-
variables @FSPATH, @ARGS, @APP_NAME, @FILE_NAME, and @STATIC_FILE_NAME are
291-
available in --args to reference the working directory path, arguments,
292-
application name, and generated file name respectively.
293-
-container-dir -cd, the directory path in the container that the heap dump/JFR/... file will be
294-
saved to
295295

296296
</pre>
297297

@@ -429,7 +429,9 @@ create GitHub issues for security-related doubts or problems.
429429

430430
## Changelog
431431

432-
### Snapshot
432+
### 4.0.1
433+
434+
- Fix thread-dump command
433435

434436
### 4.0.0
435437

cf_cli_java_plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ func (c *JavaPlugin) GetMetadata() plugin.PluginMetadata {
958958
Version: plugin.VersionType{
959959
Major: 4,
960960
Minor: 0,
961-
Build: 0,
961+
Build: 1,
962962
},
963963
MinCliVersion: plugin.VersionType{
964964
Major: 4,

test/framework/dsl.py

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import glob
77
import re
8+
import time
89
from typing import TYPE_CHECKING, Dict, List, Optional
910

1011
from .core import CFJavaTestRunner, CommandResult, TestContext
@@ -13,6 +14,29 @@
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+
1640
class 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

Comments
 (0)