Skip to content

Commit b3f201d

Browse files
authored
feat: Integration test (#3125)
1 parent 645c5c8 commit b3f201d

File tree

6 files changed

+524
-1
lines changed

6 files changed

+524
-1
lines changed

.github/workflows/test.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,27 @@ jobs:
5353
cache: "maven"
5454
- name: Build with Maven
5555
run: mvn -V -ntp clean install -P full
56+
57+
telnet_stop_leak_it:
58+
runs-on: ubuntu-latest
59+
timeout-minutes: 30
60+
steps:
61+
- uses: actions/checkout@v3
62+
- name: Setup java
63+
uses: actions/setup-java@v3
64+
with:
65+
java-version: 17
66+
distribution: "zulu"
67+
cache: "maven"
68+
- name: Install expect/telnet
69+
run: sudo apt-get update && sudo apt-get install -y expect telnet
70+
- name: Build packaging
71+
run: mvn -V -ntp clean install -P full -DskipTests
72+
- name: Run telnet stop leak test
73+
run: python3 integration-test/telnet-stop-leak/run_telnet_stop_leak_test.py --iterations 10 --warmup 2 --threshold 5 --work-dir integration-test/telnet-stop-leak/work
74+
- name: Upload artifacts on failure
75+
if: failure()
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: telnet-stop-leak-logs
79+
path: integration-test/telnet-stop-leak/work

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,7 @@ pom.xml.versionsBackup
2727
**/cmake-build-debug/**
2828

2929
# VSCode
30-
.vscode/
30+
.vscode/
31+
32+
# integration-test (python/expect)
33+
integration-test/telnet-stop-leak/work*/
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# telnet-stop-leak 集成测试
2+
3+
目的:对同一目标 JVM 反复执行 `attach -> telnet 执行多命令 -> stop -> jmap`,检查 `com.taobao.arthas.agent.ArthasClassloader` 实例数是否随轮次增长。
4+
5+
## 依赖
6+
7+
- JDK(需要 `java``jmap`
8+
- `expect``telnet`
9+
- Maven(用于构建 `packaging/target/arthas-bin`
10+
11+
## 本地运行
12+
13+
1. 构建打包产物:
14+
15+
```bash
16+
mvn -V -ntp -pl packaging -am package -DskipTests
17+
```
18+
19+
2. 运行测试(默认会创建临时目录保存日志;建议指定 `--work-dir` 便于排查):
20+
21+
`threshold` 可以考虑设置更高,JVM不能保证 ArthasClassLoader 必定会被回收。
22+
23+
```bash
24+
python3 integration-test/telnet-stop-leak/run_telnet_stop_leak_test.py \
25+
--iterations 10 \
26+
--warmup 2 \
27+
--threshold 3 \
28+
--work-dir integration-test/telnet-stop-leak/work
29+
```
30+
31+
输出目录里会生成:
32+
33+
- `results.csv`:每轮统计的 `ArthasClassloader` 实例数
34+
- `logs/`:目标 JVM、attach、telnet transcript、jmap 错误输出
35+
36+
## 调整覆盖面
37+
38+
- 命令集合:`integration-test/telnet-stop-leak/commands.txt`
39+
- telnet 执行逻辑:`integration-test/telnet-stop-leak/arthas_telnet.exp`
40+
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env expect -f
2+
3+
# 用法:
4+
# arthas_telnet.exp <host> <port> <commands_file> <timeout_seconds> <transcript_file>
5+
#
6+
# 说明:
7+
# - 通过 telnet 连接 Arthas,按行执行 commands_file 里的命令,最后执行 stop 并等待连接关闭。
8+
# - 为避免 CI 卡死,每条命令都设置超时;超时会尝试发送 Ctrl+C 进行中断并继续。
9+
10+
proc usage {} {
11+
puts stderr "usage: arthas_telnet.exp <host> <port> <commands_file> <timeout_seconds> <transcript_file>"
12+
exit 1
13+
}
14+
15+
if {[llength $argv] < 5} {
16+
usage
17+
}
18+
19+
set host [lindex $argv 0]
20+
set port [lindex $argv 1]
21+
set commands_file [lindex $argv 2]
22+
set timeout_seconds [lindex $argv 3]
23+
set transcript_file [lindex $argv 4]
24+
25+
log_file -noappend $transcript_file
26+
set timeout $timeout_seconds
27+
28+
spawn telnet $host $port
29+
30+
# Arthas 默认 prompt 为 "$ "(可能带 ANSI 颜色),匹配子串即可。
31+
set prompt_re {\$ }
32+
33+
expect {
34+
-re $prompt_re {}
35+
timeout {
36+
puts stderr "ERROR: 等待 Arthas prompt 超时"
37+
exit 2
38+
}
39+
eof {
40+
puts stderr "ERROR: 未出现 prompt 连接已关闭"
41+
exit 3
42+
}
43+
}
44+
45+
set fp [open $commands_file r]
46+
while {[gets $fp line] >= 0} {
47+
set line [string trim $line]
48+
if {$line eq ""} { continue }
49+
if {[string match "#*" $line]} { continue }
50+
51+
send -- "$line\r"
52+
53+
expect {
54+
-re $prompt_re {}
55+
-re {Session has been terminated} {
56+
close $fp
57+
exit 0
58+
}
59+
timeout {
60+
# 命令可能是持续输出/等待触发,尝试 Ctrl+C 打断后继续。
61+
send -- "\003"
62+
expect {
63+
-re $prompt_re {}
64+
timeout {
65+
puts stderr "ERROR: 命令超时且 Ctrl+C 未恢复到 prompt: $line"
66+
close $fp
67+
exit 4
68+
}
69+
eof {
70+
puts stderr "ERROR: Ctrl+C 后连接关闭: $line"
71+
close $fp
72+
exit 5
73+
}
74+
}
75+
}
76+
eof {
77+
puts stderr "ERROR: 命令执行后连接关闭: $line"
78+
close $fp
79+
exit 6
80+
}
81+
}
82+
}
83+
close $fp
84+
85+
send -- "stop\r"
86+
expect {
87+
-re {Session has been terminated} {}
88+
eof {}
89+
timeout {
90+
puts stderr "ERROR: stop 超时"
91+
exit 7
92+
}
93+
}
94+
95+
exit 0
96+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# 这些命令用于覆盖常见路径(查询类命令 + 触发增强命令),最后由 expect 脚本统一执行 stop。
2+
help
3+
version
4+
session
5+
dashboard -n 1
6+
thread -n 3
7+
sc -d demo.MathGame
8+
sm demo.MathGame
9+
jad demo.MathGame
10+
watch demo.MathGame primeFactors "{params,returnObj,throwExp}" -n 1 -x 1
11+
# trace 命令:追踪方法调用路径及耗时
12+
trace demo.MathGame run -n 1
13+
trace demo.MathGame primeFactors '#cost>0' -n 1
14+
# ognl 命令:执行 OGNL 表达式
15+
ognl '@java.lang.System@getProperty("java.version")'
16+
ognl '@java.lang.Runtime@getRuntime().availableProcessors()'
17+
ognl -x 2 '@java.lang.System@getProperties()'
18+
# vmtool 命令:JVM 工具
19+
vmtool --action getInstances --className demo.MathGame --limit 5
20+
vmtool --action getInstances --className demo.MathGame --express 'instances.length'
21+
vmtool --action forceGc
22+
reset
23+

0 commit comments

Comments
 (0)