Compare commits

...

24 Commits

Author SHA1 Message Date
spiritlhl
487dd7c1d2 fix: 测试修复无权限下硬盘测试引擎选择的问题 2025-07-01 09:37:56 +00:00
spiritlhl
2dbf97de8c fix: 测试修复无权限下硬盘测试引擎选择的问题 2025-07-01 09:35:56 +00:00
github-actions[bot]
97e7cae2c2 chore: update ECS_VERSION to 0.1.47 in goecs.sh 2025-07-01 08:44:22 +00:00
spiritlhl
d61a1879f5 fix: 修复macos上无权限时的测试路径选择 2025-07-01 08:33:30 +00:00
github-actions[bot]
29dd4ac57e chore: update ECS_VERSION to 0.1.46 in goecs.sh 2025-07-01 03:30:58 +00:00
spiritlhl
dc3eff1fe3 fix: 更新版本 2025-07-01 11:20:24 +08:00
spiritlhl
0a0f2199bc fix: 修复内存和硬盘测试的权限校验问题 2025-07-01 03:19:07 +00:00
github-actions[bot]
91004d87f5 chore: update ECS_VERSION to 0.1.45 in goecs.sh 2025-06-30 14:30:04 +00:00
spiritlhl
8f41c37203 fix: 修复windows下的Admin权限检测 2025-06-30 14:18:42 +00:00
github-actions[bot]
12b1ae0702 chore: update ECS_VERSION to 0.1.44 in goecs.sh 2025-06-30 13:43:29 +00:00
spiritlhl
653cd75a97 fix: 修复内存测试在无root环境下测试的权限问题,添加无权限的内存测试方法mbw 2025-06-30 13:32:20 +00:00
github-actions[bot]
ea36e88c9f chore: update ECS_VERSION to 0.1.43 in goecs.sh 2025-06-29 08:49:03 +00:00
spiritlhl
c81ebb3c7a fix: 异步函数传值需要指针传递,值传递可能会出现同步问题 2025-06-29 08:45:15 +00:00
github-actions[bot]
7896b3ead5 chore: update ECS_VERSION to 0.1.42 in goecs.sh 2025-06-29 08:33:10 +00:00
spiritlhl
eb98a7b857 fix: 更加严格的启动条件,同时避免死锁等待 2025-06-29 08:29:24 +00:00
github-actions[bot]
d4d86229de chore: update ECS_VERSION to 0.1.41 in goecs.sh 2025-06-29 07:59:30 +00:00
spiritlhl
651a183382 fix: 修复版本号 2025-06-29 15:55:56 +08:00
spiritlhl
afc313a2a8 fix: 同步流媒体检测的判断逻辑 2025-06-29 15:44:16 +08:00
github-actions[bot]
39ac8d198d chore: update ECS_VERSION to 0.1.40 in goecs.sh 2025-06-29 07:36:33 +00:00
spiritlhl
a70dc2bab1 fix: 更新版本号至 v0.1.40 2025-06-29 07:26:48 +00:00
spiritlhl
5041a16a9a fix: 修复同步机制问题,保护最终输出不出现数据竞争 2025-06-29 07:22:27 +00:00
github-actions[bot]
21deb3587e chore: update ECS_VERSION to 0.1.39 in goecs.sh 2025-06-29 07:07:10 +00:00
spiritlhl
3bac30edc2 fix: 修复协程部分等待位置错误的问题 2025-06-29 07:02:10 +00:00
github-actions[bot]
9ef2ec4a9e chore: update ECS_VERSION to 0.1.38 in goecs.sh 2025-06-29 06:39:24 +00:00
6 changed files with 82 additions and 76 deletions

View File

@@ -33,7 +33,7 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS
| arm | arm | Windows | Windows | | arm | arm | Windows | Windows |
| arm64 | arm64 | FreeBSD | FreeBSD | | arm64 | arm64 | FreeBSD | FreeBSD |
| 386 | 386 | OpenBSD | | | 386 | 386 | OpenBSD | |
| mips | | MacOS | | | mips | | MacOS | MacOS |
| mipsle | | | | | mipsle | | | |
| s390x | s390x | | | | s390x | s390x | | |
| riscv64 | | | | | riscv64 | | | |
@@ -44,7 +44,6 @@ Shell 版本:[https://github.com/spiritLHLS/ecs](https://github.com/spiritLHLS
### **待支持的系统** ### **待支持的系统**
| 系统 | 说明 | | 系统 | 说明 |
|-----|---------------------------| |-----|---------------------------|
| MacOS | 存在硬件测试 BUG 未修复,存在环境依赖未修复 |
| Android(arm64) | 存在权限问题未修复非安卓系统的ARM架构无问题 | | Android(arm64) | 存在权限问题未修复非安卓系统的ARM架构无问题 |
--- ---

View File

@@ -31,7 +31,7 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https:
| arm | arm | Windows | Windows | | arm | arm | Windows | Windows |
| arm64 | arm64 | FreeBSD | FreeBSD | | arm64 | arm64 | FreeBSD | FreeBSD |
| 386 | 386 | OpenBSD | | | 386 | 386 | OpenBSD | |
| mips | | MacOS | | | mips | | MacOS | MacOS |
| mipsle | | | | | mipsle | | | |
| s390x | s390x | | | | s390x | s390x | | |
| riscv64 | | | | | riscv64 | | | |
@@ -41,7 +41,6 @@ Shell version: [https://github.com/spiritLHLS/ecs/blob/main/README_EN.md](https:
### **Systems Pending Support** ### **Systems Pending Support**
| OS | Notes | | OS | Notes |
|--------|-------------------------------------------------------------------------------------------------| |--------|-------------------------------------------------------------------------------------------------|
| MacOS | Hardware testing bugs and environment dependencies unresolved |
| Android(arm64) | Permission issues that are not fixed, no problems with ARM architecture for non-Android systems | | Android(arm64) | Permission issues that are not fixed, no problems with ARM architecture for non-Android systems |
--- ---

11
go.mod
View File

@@ -12,9 +12,9 @@ require (
github.com/oneclickvirt/basics v0.0.13-20250629023612 github.com/oneclickvirt/basics v0.0.13-20250629023612
github.com/oneclickvirt/cputest v0.0.10-20250404151448 github.com/oneclickvirt/cputest v0.0.10-20250404151448
github.com/oneclickvirt/defaultset v0.0.2-20240624082446 github.com/oneclickvirt/defaultset v0.0.2-20240624082446
github.com/oneclickvirt/disktest v0.0.8-20250425015826 github.com/oneclickvirt/disktest v0.0.8-20250701092629
github.com/oneclickvirt/gostun v0.0.3-20250329105202 github.com/oneclickvirt/gostun v0.0.3-20250329105202
github.com/oneclickvirt/memorytest v0.0.5-20250406063420 github.com/oneclickvirt/memorytest v0.0.6-20250630141424.0.20250701022859-5967f9d8d3eb
github.com/oneclickvirt/nt3 v0.0.5-20250416131047 github.com/oneclickvirt/nt3 v0.0.5-20250416131047
github.com/oneclickvirt/pingtest v0.0.7-20250413051539 github.com/oneclickvirt/pingtest v0.0.7-20250413051539
github.com/oneclickvirt/portchecker v0.0.3-20250329125750 github.com/oneclickvirt/portchecker v0.0.3-20250329125750
@@ -61,8 +61,9 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nxtrace/NTrace-core v1.4.0 // indirect github.com/nxtrace/NTrace-core v1.4.0 // indirect
github.com/oneclickvirt/dd v0.0.1-20250406062523 // indirect github.com/oneclickvirt/dd v0.0.2-20250701085922 // indirect
github.com/oneclickvirt/fio v0.0.1-20250406060851 // indirect github.com/oneclickvirt/fio v0.0.2-20250701085933 // indirect
github.com/oneclickvirt/mbw v0.0.1-20250630140849 // indirect
github.com/onsi/ginkgo/v2 v2.22.1 // indirect github.com/onsi/ginkgo/v2 v2.22.1 // indirect
github.com/oschwald/maxminddb-golang v1.13.1 // indirect github.com/oschwald/maxminddb-golang v1.13.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect
@@ -106,7 +107,7 @@ require (
golang.org/x/mod v0.22.0 // indirect golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.39.0 // indirect golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.13.0 // indirect golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.31.0 // indirect golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect golang.org/x/text v0.24.0 // indirect
golang.org/x/tools v0.29.0 // indirect golang.org/x/tools v0.29.0 // indirect

22
go.sum
View File

@@ -107,18 +107,20 @@ github.com/oneclickvirt/basics v0.0.13-20250629023612 h1:cQg+cGBt2NMRrjhJPH+Cbev
github.com/oneclickvirt/basics v0.0.13-20250629023612/go.mod h1:yN1IEOXN6v/GJqJSA70Pooo6nXBI/6rq72vTY72wJMQ= github.com/oneclickvirt/basics v0.0.13-20250629023612/go.mod h1:yN1IEOXN6v/GJqJSA70Pooo6nXBI/6rq72vTY72wJMQ=
github.com/oneclickvirt/cputest v0.0.10-20250404151448 h1:ovGtCwFXG0qmpyNDRqcNDIiAmhrtemCjIUXTJ1fPH0o= github.com/oneclickvirt/cputest v0.0.10-20250404151448 h1:ovGtCwFXG0qmpyNDRqcNDIiAmhrtemCjIUXTJ1fPH0o=
github.com/oneclickvirt/cputest v0.0.10-20250404151448/go.mod h1:MmaHN9+XMntI3rLycwj8Ne31fG18IfNoa8N2utDK1CY= github.com/oneclickvirt/cputest v0.0.10-20250404151448/go.mod h1:MmaHN9+XMntI3rLycwj8Ne31fG18IfNoa8N2utDK1CY=
github.com/oneclickvirt/dd v0.0.1-20250406062523 h1:jegTww4fuoFEqwFozvGJEqUNI/5ew3QJ0XcKZZ/zuTs= github.com/oneclickvirt/dd v0.0.2-20250701085922 h1:WiWZwcnCPhRc8hLZdvkjD2kOEpnqn1S31z1j0x3V4l0=
github.com/oneclickvirt/dd v0.0.1-20250406062523/go.mod h1:tImu9sPTkLWo2tf1dEN1xQzrylWKauj9hbU8PHfyAeU= github.com/oneclickvirt/dd v0.0.2-20250701085922/go.mod h1:tImu9sPTkLWo2tf1dEN1xQzrylWKauj9hbU8PHfyAeU=
github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc= github.com/oneclickvirt/defaultset v0.0.2-20240624082446 h1:5Pg3mK/u/vQvSz7anu0nxzrNdELi/AcDAU1mMsmPzyc=
github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E= github.com/oneclickvirt/defaultset v0.0.2-20240624082446/go.mod h1:e9Jt4tf2sbemCtc84/XgKcHy9EZ2jkc5x2sW1NiJS+E=
github.com/oneclickvirt/disktest v0.0.8-20250425015826 h1:bwVg0zysB3uCwQV+KIIQpuq2IJXWdIcdjD2+FiKPo5w= github.com/oneclickvirt/disktest v0.0.8-20250701092629 h1:B/gA6SOr4qL5pQmVpHl9m5bn3paDcL7wJ1SZ7aY66M8=
github.com/oneclickvirt/disktest v0.0.8-20250425015826/go.mod h1:sqVu6HwbnLmbnRj4389Xn08c301IhLnWCcbaEk2WzEc= github.com/oneclickvirt/disktest v0.0.8-20250701092629/go.mod h1:6YCvGr+Z0tvcP4Ue8bezZqm/GqS/dSyEnSUhvS3Q03o=
github.com/oneclickvirt/fio v0.0.1-20250406060851 h1:b7xHKpPmU4q0NmvigRCEr3tQuAV/83ZIAGtHycLegw8= github.com/oneclickvirt/fio v0.0.2-20250701085933 h1:4P7QcOTxbqyx5DhHdFvyeRSsdNajSo9l/H2XK0vICIc=
github.com/oneclickvirt/fio v0.0.1-20250406060851/go.mod h1:NIq+XYTey68KNERGIy/oRDlzpwLzBVoHOCiqX8didsE= github.com/oneclickvirt/fio v0.0.2-20250701085933/go.mod h1:NIq+XYTey68KNERGIy/oRDlzpwLzBVoHOCiqX8didsE=
github.com/oneclickvirt/gostun v0.0.3-20250329105202 h1:aJ6E91Lp94lq8iWRcCaxpXTjqOOaWvufr5oras6cFtM= github.com/oneclickvirt/gostun v0.0.3-20250329105202 h1:aJ6E91Lp94lq8iWRcCaxpXTjqOOaWvufr5oras6cFtM=
github.com/oneclickvirt/gostun v0.0.3-20250329105202/go.mod h1:f7DPEXAxbmwXSW33dbxtb0/KzqvOBWhTs2Or5xBerQA= github.com/oneclickvirt/gostun v0.0.3-20250329105202/go.mod h1:f7DPEXAxbmwXSW33dbxtb0/KzqvOBWhTs2Or5xBerQA=
github.com/oneclickvirt/memorytest v0.0.5-20250406063420 h1:eHqpqFIx8Ss062uyNf7Ruv7FC4AdZbElR7u9vX2Oj3g= github.com/oneclickvirt/mbw v0.0.1-20250630140849 h1:p6RMhOPBnQKAm9+VEQ2axAFsidrdSdrhXMyheIyv2a8=
github.com/oneclickvirt/memorytest v0.0.5-20250406063420/go.mod h1:HTd0sSxRjT4BcV8kcCh4fF2Nia0xgZNaVjhefsnypic= github.com/oneclickvirt/mbw v0.0.1-20250630140849/go.mod h1:0Vq6NRpyLmGUdfHfL3uDcFsuZhi7KlG+OCs5ky2757Y=
github.com/oneclickvirt/memorytest v0.0.6-20250630141424.0.20250701022859-5967f9d8d3eb h1:EKYQWLw4um/C2xm6z8aDl+owWtvaIp0z7nlyMj62kkk=
github.com/oneclickvirt/memorytest v0.0.6-20250630141424.0.20250701022859-5967f9d8d3eb/go.mod h1:7xMacjQobvFAtODht2hxTsB9hM2IFS7vZk3gxx+bsjo=
github.com/oneclickvirt/nt3 v0.0.5-20250416131047 h1:KL0xowq19cW+FMBGMJxdqpRNoeyR+eEmb+jYSubmlTk= github.com/oneclickvirt/nt3 v0.0.5-20250416131047 h1:KL0xowq19cW+FMBGMJxdqpRNoeyR+eEmb+jYSubmlTk=
github.com/oneclickvirt/nt3 v0.0.5-20250416131047/go.mod h1:CVsDJEaIdyyZHn3WKbhU8Wn6GOfmBNvJlC/dDLRqcSQ= github.com/oneclickvirt/nt3 v0.0.5-20250416131047/go.mod h1:CVsDJEaIdyyZHn3WKbhU8Wn6GOfmBNvJlC/dDLRqcSQ=
github.com/oneclickvirt/pingtest v0.0.7-20250413051539 h1:mYOsEmMtwKr40hwM2NimVLpnbR2cjwuOh1c/9fQr2Dw= github.com/oneclickvirt/pingtest v0.0.7-20250413051539 h1:mYOsEmMtwKr40hwM2NimVLpnbR2cjwuOh1c/9fQr2Dw=
@@ -278,8 +280,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

109
goecs.go
View File

@@ -39,7 +39,7 @@ import (
) )
var ( var (
ecsVersion = "v0.1.38" ecsVersion = "v0.1.48"
menuMode bool menuMode bool
onlyChinaTest bool onlyChinaTest bool
input, choice string input, choice string
@@ -387,8 +387,7 @@ func handleLanguageSpecificSettings() {
} }
} }
func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *string, tempOutput string, uploadDone chan bool) { func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *string, tempOutput string, uploadDone chan bool, outputMutex *sync.Mutex) {
*startTime = time.Now()
select { select {
case <-sig: case <-sig:
if !finish { if !finish {
@@ -397,21 +396,23 @@ func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *str
minutes := int(duration.Minutes()) minutes := int(duration.Minutes())
seconds := int(duration.Seconds()) % 60 seconds := int(duration.Seconds()) % 60
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006") currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
var mu sync.Mutex outputMutex.Lock()
mu.Lock()
*output = utils.PrintAndCapture(func() { *output = utils.PrintAndCapture(func() {
utils.PrintCenteredTitle("", width) utils.PrintCenteredTitle("", width)
fmt.Printf("Cost Time : %d min %d sec\n", minutes, seconds) fmt.Printf("Cost Time : %d min %d sec\n", minutes, seconds)
fmt.Printf("Current Time : %s\n", currentTime) fmt.Printf("Current Time : %s\n", currentTime)
utils.PrintCenteredTitle("", width) utils.PrintCenteredTitle("", width)
}, tempOutput, *output) }, tempOutput, *output)
mu.Unlock() outputMutex.Unlock()
resultChan := make(chan struct { resultChan := make(chan struct {
httpURL string httpURL string
httpsURL string httpsURL string
}, 1) }, 1)
go func() { go func() {
httpURL, httpsURL := utils.ProcessAndUpload(*output, filePath, enabelUpload) outputMutex.Lock()
finalOutput := *output
outputMutex.Unlock()
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, filePath, enabelUpload)
resultChan <- struct { resultChan <- struct {
httpURL string httpURL string
httpsURL string httpsURL string
@@ -434,7 +435,11 @@ func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *str
} }
os.Exit(0) os.Exit(0)
case <-time.After(30 * time.Second): case <-time.After(30 * time.Second):
if language == "en" {
fmt.Println("Upload timeout, program exit")
} else {
fmt.Println("上传超时,程序退出") fmt.Println("上传超时,程序退出")
}
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
fmt.Println("Press Enter to exit...") fmt.Println("Press Enter to exit...")
fmt.Scanln() fmt.Scanln()
@@ -446,11 +451,11 @@ func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *str
} }
} }
func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output, tempOutput string, startTime time.Time) string { func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
output = runBasicTests(preCheck, basicInfo, securityInfo, output, tempOutput) output = runBasicTests(preCheck, basicInfo, securityInfo, output, tempOutput, outputMutex)
output = runCPUTest(output, tempOutput) output = runCPUTest(output, tempOutput, outputMutex)
output = runMemoryTest(output, tempOutput) output = runMemoryTest(output, tempOutput, outputMutex)
output = runDiskTest(output, tempOutput) output = runDiskTest(output, tempOutput, outputMutex)
if (onlyChinaTest || pingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { if (onlyChinaTest || pingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
wg3.Add(1) wg3.Add(1)
go func() { go func() {
@@ -458,14 +463,14 @@ func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGrou
*ptInfo = pt.PingTest() *ptInfo = pt.PingTest()
}() }()
} }
if emailTestStatus { if emailTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
wg2.Add(1) wg2.Add(1)
go func() { go func() {
defer wg2.Done() defer wg2.Done()
*emailInfo = email.EmailCheck() *emailInfo = email.EmailCheck()
}() }()
} }
if utTestStatus && !onlyChinaTest { if utTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !onlyChinaTest {
wg1.Add(1) wg1.Add(1)
go func() { go func() {
defer wg1.Done() defer wg1.Done()
@@ -473,24 +478,24 @@ func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGrou
}() }()
} }
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
output = runStreamingTests(wg1, *mediaInfo, output, tempOutput) output = runStreamingTests(wg1, mediaInfo, output, tempOutput, outputMutex)
output = runSecurityTests(*securityInfo, output, tempOutput) output = runSecurityTests(*securityInfo, output, tempOutput, outputMutex)
output = runEmailTests(wg2, *emailInfo, output, tempOutput) output = runEmailTests(wg2, emailInfo, output, tempOutput, outputMutex)
} }
if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
output = runNetworkTests(wg3, *ptInfo, output, tempOutput) output = runNetworkTests(wg3, ptInfo, output, tempOutput, outputMutex)
} }
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
output = runSpeedTests(output, tempOutput) output = runSpeedTests(output, tempOutput, outputMutex)
} }
return appendTimeInfo(output, tempOutput, startTime) return appendTimeInfo(output, tempOutput, startTime, outputMutex)
} }
func runEnglishTests(preCheck utils.NetCheckResult, wg1, wg2 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo *string, output, tempOutput string, startTime time.Time) string { func runEnglishTests(preCheck utils.NetCheckResult, wg1, wg2 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo *string, output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
output = runBasicTests(preCheck, basicInfo, securityInfo, output, tempOutput) output = runBasicTests(preCheck, basicInfo, securityInfo, output, tempOutput, outputMutex)
output = runCPUTest(output, tempOutput) output = runCPUTest(output, tempOutput, outputMutex)
output = runMemoryTest(output, tempOutput) output = runMemoryTest(output, tempOutput, outputMutex)
output = runDiskTest(output, tempOutput) output = runDiskTest(output, tempOutput, outputMutex)
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" { if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
if utTestStatus { if utTestStatus {
wg1.Add(1) wg1.Add(1)
@@ -506,15 +511,15 @@ func runEnglishTests(preCheck utils.NetCheckResult, wg1, wg2 *sync.WaitGroup, ba
*emailInfo = email.EmailCheck() *emailInfo = email.EmailCheck()
}() }()
} }
output = runStreamingTests(wg1, *mediaInfo, output, tempOutput) output = runStreamingTests(wg1, mediaInfo, output, tempOutput, outputMutex) // 传递指针
output = runSecurityTests(*securityInfo, output, tempOutput) output = runSecurityTests(*securityInfo, output, tempOutput, outputMutex)
output = runEmailTests(wg2, *emailInfo, output, tempOutput) output = runEmailTests(wg2, emailInfo, output, tempOutput, outputMutex)
output = runEnglishSpeedTests(output, tempOutput) output = runEnglishSpeedTests(output, tempOutput, outputMutex)
} }
return appendTimeInfo(output, tempOutput, startTime) return appendTimeInfo(output, tempOutput, startTime, outputMutex)
} }
func runBasicTests(preCheck utils.NetCheckResult, basicInfo, securityInfo *string, output, tempOutput string) string { func runBasicTests(preCheck utils.NetCheckResult, basicInfo, securityInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
utils.PrintHead(language, width, ecsVersion) utils.PrintHead(language, width, ecsVersion)
if basicStatus || securityTestStatus { if basicStatus || securityTestStatus {
@@ -550,7 +555,7 @@ func runBasicTests(preCheck utils.NetCheckResult, basicInfo, securityInfo *strin
}, tempOutput, output) }, tempOutput, output)
} }
func runCPUTest(output, tempOutput string) string { func runCPUTest(output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if cpuTestStatus { if cpuTestStatus {
if language == "zh" { if language == "zh" {
@@ -563,7 +568,7 @@ func runCPUTest(output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func runMemoryTest(output, tempOutput string) string { func runMemoryTest(output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if memoryTestStatus { if memoryTestStatus {
if language == "zh" { if language == "zh" {
@@ -576,7 +581,7 @@ func runMemoryTest(output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func runDiskTest(output, tempOutput string) string { func runDiskTest(output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if diskTestStatus && autoChangeDiskTestMethod { if diskTestStatus && autoChangeDiskTestMethod {
if language == "zh" { if language == "zh" {
@@ -601,7 +606,7 @@ func runDiskTest(output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func runStreamingTests(wg1 *sync.WaitGroup, mediaInfo string, output, tempOutput string) string { func runStreamingTests(wg1 *sync.WaitGroup, mediaInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if language == "zh" { if language == "zh" {
if commTestStatus && !onlyChinaTest { if commTestStatus && !onlyChinaTest {
@@ -610,18 +615,18 @@ func runStreamingTests(wg1 *sync.WaitGroup, mediaInfo string, output, tempOutput
} }
} }
if utTestStatus && (language == "zh" && !onlyChinaTest || language == "en") { if utTestStatus && (language == "zh" && !onlyChinaTest || language == "en") {
wg1.Wait()
if language == "zh" { if language == "zh" {
utils.PrintCenteredTitle("跨国流媒体解锁", width) utils.PrintCenteredTitle("跨国流媒体解锁", width)
} else { } else {
utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", width) utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", width)
} }
wg1.Wait() fmt.Printf("%s", *mediaInfo)
fmt.Printf("%s", mediaInfo)
} }
}, tempOutput, output) }, tempOutput, output)
} }
func runSecurityTests(securityInfo string, output, tempOutput string) string { func runSecurityTests(securityInfo, output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if securityTestStatus { if securityTestStatus {
if language == "zh" { if language == "zh" {
@@ -634,21 +639,21 @@ func runSecurityTests(securityInfo string, output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func runEmailTests(wg2 *sync.WaitGroup, emailInfo string, output, tempOutput string) string { func runEmailTests(wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if emailTestStatus { if emailTestStatus {
wg2.Wait()
if language == "zh" { if language == "zh" {
utils.PrintCenteredTitle("邮件端口检测", width) utils.PrintCenteredTitle("邮件端口检测", width)
} else { } else {
utils.PrintCenteredTitle("Email-Port-Check", width) utils.PrintCenteredTitle("Email-Port-Check", width)
} }
wg2.Wait() fmt.Println(*emailInfo)
fmt.Println(emailInfo)
} }
}, tempOutput, output) }, tempOutput, output)
} }
func runNetworkTests(wg3 *sync.WaitGroup, ptInfo string, output, tempOutput string) string { func runNetworkTests(wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
output = utils.PrintAndCapture(func() { output = utils.PrintAndCapture(func() {
if backtraceStatus && !onlyChinaTest { if backtraceStatus && !onlyChinaTest {
utils.PrintCenteredTitle("三网回程线路检测", width) utils.PrintCenteredTitle("三网回程线路检测", width)
@@ -667,14 +672,14 @@ func runNetworkTests(wg3 *sync.WaitGroup, ptInfo string, output, tempOutput stri
}, tempOutput, output) }, tempOutput, output)
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if onlyChinaTest || pingTestStatus { if onlyChinaTest || pingTestStatus {
utils.PrintCenteredTitle("三网ICMP的PING值检测", width)
wg3.Wait() wg3.Wait()
fmt.Println(ptInfo) utils.PrintCenteredTitle("三网ICMP的PING值检测", width)
fmt.Println(*ptInfo)
} }
}, tempOutput, output) }, tempOutput, output)
} }
func runSpeedTests(output, tempOutput string) string { func runSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if speedTestStatus { if speedTestStatus {
utils.PrintCenteredTitle("就近节点测速", width) utils.PrintCenteredTitle("就近节点测速", width)
@@ -694,7 +699,7 @@ func runSpeedTests(output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func runEnglishSpeedTests(output, tempOutput string) string { func runEnglishSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
return utils.PrintAndCapture(func() { return utils.PrintAndCapture(func() {
if speedTestStatus { if speedTestStatus {
utils.PrintCenteredTitle("Speed-Test", width) utils.PrintCenteredTitle("Speed-Test", width)
@@ -705,7 +710,7 @@ func runEnglishSpeedTests(output, tempOutput string) string {
}, tempOutput, output) }, tempOutput, output)
} }
func appendTimeInfo(output, tempOutput string, startTime time.Time) string { func appendTimeInfo(output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
endTime := time.Now() endTime := time.Now()
duration := endTime.Sub(startTime) duration := endTime.Sub(startTime)
minutes := int(duration.Minutes()) minutes := int(duration.Minutes())
@@ -750,21 +755,21 @@ func main() {
} }
handleLanguageSpecificSettings() handleLanguageSpecificSettings()
var ( var (
startTime time.Time
wg1, wg2, wg3 sync.WaitGroup wg1, wg2, wg3 sync.WaitGroup
basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string
output, tempOutput string output, tempOutput string
outputMutex sync.Mutex
) )
startTime := time.Now()
uploadDone := make(chan bool, 1) uploadDone := make(chan bool, 1)
sig := make(chan os.Signal, 1) sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone) go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone, &outputMutex)
startTime = time.Now()
switch language { switch language {
case "zh": case "zh":
output = runChineseTests(preCheck, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, output, tempOutput, startTime) output = runChineseTests(preCheck, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, output, tempOutput, startTime, &outputMutex)
case "en": case "en":
output = runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, output, tempOutput, startTime) output = runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, output, tempOutput, startTime, &outputMutex)
default: default:
fmt.Println("Unsupported language") fmt.Println("Unsupported language")
} }

View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# From https://github.com/oneclickvirt/ecs # From https://github.com/oneclickvirt/ecs
# 2025.06.05 # 2025.06.29
# curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh # curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh
# 或 # 或
@@ -143,7 +143,7 @@ goecs_check() {
os=$(uname -s 2>/dev/null || echo "Unknown") os=$(uname -s 2>/dev/null || echo "Unknown")
arch=$(uname -m 2>/dev/null || echo "Unknown") arch=$(uname -m 2>/dev/null || echo "Unknown")
check_china check_china
ECS_VERSION="0.1.37" ECS_VERSION="0.1.47"
for api in \ for api in \
"https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \ "https://api.github.com/repos/oneclickvirt/ecs/releases/latest" \
"https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \ "https://githubapi.spiritlhl.workers.dev/repos/oneclickvirt/ecs/releases/latest" \
@@ -155,8 +155,8 @@ goecs_check() {
sleep 1 sleep 1
done done
if [ -z "$ECS_VERSION" ]; then if [ -z "$ECS_VERSION" ]; then
_yellow "Unable to get version info, using default version 0.1.37" _yellow "Unable to get version info, using default version 0.1.47"
ECS_VERSION="0.1.37" ECS_VERSION="0.1.47"
fi fi
version_output="" version_output=""
for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do for cmd_path in "goecs" "./goecs" "/usr/bin/goecs" "/usr/local/bin/goecs"; do