fix:拆分单文件重构组织形式,便于后续维护

This commit is contained in:
spiritlhl
2025-11-02 16:37:07 +00:00
parent 6b42f626b0
commit 40f63e6cb1
7 changed files with 1275 additions and 1148 deletions

5
.gitignore vendored
View File

@@ -1,2 +1,5 @@
vendor/
.idea/
.idea/
ecs
goecs.txt
*.log

View File

@@ -205,6 +205,8 @@ Usage: goecs [options]
-email
Enable/Disable email port test (default true)
-h Show help information
-help
Show help information
-l string
Set language (supported: en, zh) (default "zh")
-log
@@ -212,28 +214,34 @@ Usage: goecs [options]
-memory
Enable/Disable memory test (default true)
-memorym string
Set memory test method (supported: sysbench, dd, winsat) (default "sysbench")
Set memory test method (supported: stream, sysbench, dd, winsat, auto) (default "stream")
-menu
Enable/Disable menu mode, disable example: -menu=false (default true)
-nt3
Enable/Disable NT3 test (in 'en' language or on windows it always false) (default true)
-nt3loc string
Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu) (default "GZ")
Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all) (default "GZ")
-nt3t string
Set NT3 test type (supported: both, ipv4, ipv6) (default "ipv4")
-ping
Enable/Disable ping test
-security
Enable/Disable security test (default true)
-speed
Enable/Disable speed test (default true)
-ping
Enable/Disable ping test (default false)
-spnum int
Set the number of servers per operator for speed test (default 2)
-tgdc
Enable/Disable Telegram DC test
-upload
Enable/Disable upload the result (default true)
-ut
Enable/Disable unlock media test (default true)
-v Display version information
-version
Display version information
-web
Enable/Disable popular websites test
```
</details>

View File

@@ -204,6 +204,8 @@ Usage: goecs [options]
-email
Enable/Disable email port test (default true)
-h Show help information
-help
Show help information
-l string
Set language (supported: en, zh) (default "zh")
-log
@@ -211,28 +213,34 @@ Usage: goecs [options]
-memory
Enable/Disable memory test (default true)
-memorym string
Set memory test method (supported: sysbench, dd, winsat) (default "sysbench")
Set memory test method (supported: stream, sysbench, dd, winsat, auto) (default "stream")
-menu
Enable/Disable menu mode, disable example: -menu=false (default true)
-nt3
Enable/Disable NT3 test (in 'en' language or on windows it always false) (default true)
-nt3loc string
Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu) (default "GZ")
Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all) (default "GZ")
-nt3t string
Set NT3 test type (supported: both, ipv4, ipv6) (default "ipv4")
-ping
Enable/Disable ping test
-security
Enable/Disable security test (default true)
-speed
Enable/Disable speed test (default true)
-ping
Enable/Disable ping test (default false)
-spnum int
Set the number of servers per operator for speed test (default 2)
-tgdc
Enable/Disable Telegram DC test
-upload
Enable/Disable upload the result (default true)
-ut
Enable/Disable unlock media test (default true)
-v Display version information
-version
Display version information
-web
Enable/Disable popular websites test
```
</details>

1163
goecs.go

File diff suppressed because it is too large Load Diff

365
internal/menu/menu.go Normal file
View File

@@ -0,0 +1,365 @@
package menu
import (
"context"
"fmt"
"os"
"os/signal"
"regexp"
"strings"
"sync"
"syscall"
"github.com/oneclickvirt/ecs/internal/params"
"github.com/oneclickvirt/ecs/utils"
)
// GetMenuChoice prompts user for menu choice
func GetMenuChoice(language string) string {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(sigChan)
inputChan := make(chan string, 1)
go func() {
select {
case <-sigChan:
fmt.Println("\n程序在选择过程中被用户中断")
os.Exit(0)
case <-ctx.Done():
return
}
}()
for {
go func() {
var input string
fmt.Print("请输入选项 / Please enter your choice: ")
fmt.Scanln(&input)
input = strings.TrimSpace(input)
input = strings.TrimRight(input, "\n")
select {
case inputChan <- input:
case <-ctx.Done():
return
}
}()
select {
case input := <-inputChan:
re := regexp.MustCompile(`^\d+$`)
if re.MatchString(input) {
inChoice := input
switch inChoice {
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10":
return inChoice
default:
if language == "zh" {
fmt.Println("无效的选项")
} else {
fmt.Println("Invalid choice")
}
}
} else {
if language == "zh" {
fmt.Println("输入错误,请输入一个纯数字")
} else {
fmt.Println("Invalid input, please enter a number")
}
}
case <-ctx.Done():
return ""
}
}
}
// PrintMenuOptions displays menu options
func PrintMenuOptions(preCheck utils.NetCheckResult, config *params.Config) {
var stats *utils.StatsResponse
var statsErr error
var githubInfo *utils.GitHubRelease
var githubErr error
if preCheck.Connected {
var pwg sync.WaitGroup
pwg.Add(2)
go func() {
defer pwg.Done()
stats, statsErr = utils.GetGoescStats()
}()
go func() {
defer pwg.Done()
githubInfo, githubErr = utils.GetLatestEcsRelease()
}()
pwg.Wait()
} else {
statsErr = fmt.Errorf("network not connected")
githubErr = fmt.Errorf("network not connected")
}
var statsInfo string
var cmp int
if preCheck.Connected {
if statsErr != nil {
statsInfo = "NULL"
} else {
switch config.Language {
case "zh":
statsInfo = fmt.Sprintf("总使用量: %s | 今日使用: %s",
utils.FormatGoecsNumber(stats.Total),
utils.FormatGoecsNumber(stats.Daily))
case "en":
statsInfo = fmt.Sprintf("Total Usage: %s | Daily Usage: %s",
utils.FormatGoecsNumber(stats.Total),
utils.FormatGoecsNumber(stats.Daily))
}
}
if githubErr == nil {
cmp = utils.CompareVersions(config.EcsVersion, githubInfo.TagName)
} else {
cmp = 0
}
}
switch config.Language {
case "zh":
fmt.Printf("VPS融合怪版本: %s\n", config.EcsVersion)
if preCheck.Connected {
switch cmp {
case -1:
fmt.Printf("检测到新版本 %s 如有必要请更新!\n", githubInfo.TagName)
}
fmt.Printf("使用统计: %s\n", statsInfo)
}
fmt.Println("1. 融合怪完全体(能测全测)")
fmt.Println("2. 极简版(系统信息+CPU+内存+磁盘+测速节点5个)")
fmt.Println("3. 精简版(系统信息+CPU+内存+磁盘+常用流媒体+路由+测速节点5个)")
fmt.Println("4. 精简网络版(系统信息+CPU+内存+磁盘+回程+路由+测速节点5个)")
fmt.Println("5. 精简解锁版(系统信息+CPU+内存+磁盘IO+御三家+常用流媒体+测速节点5个)")
fmt.Println("6. 网络单项(IP质量检测+上游及三网回程+广州三网回程详细路由+全国延迟+TGDC+网站延迟+测速节点11个)")
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
fmt.Println("8. 硬件单项(系统信息+CPU+dd磁盘测试+fio磁盘测试)")
fmt.Println("9. IP质量检测(15个数据库的IP质量检测+邮件端口检测)")
fmt.Println("10. 三网回程线路检测+三网回程详细路由(北京上海广州成都)+全国延迟+TGDC+网站延迟")
fmt.Println("0. 退出程序")
case "en":
fmt.Printf("VPS Fusion Monster Test Version: %s\n", config.EcsVersion)
if preCheck.Connected {
switch cmp {
case -1:
fmt.Printf("New version detected %s update if necessary!\n", githubInfo.TagName)
}
fmt.Printf("%s\n", statsInfo)
}
fmt.Println("1. VPS Fusion Monster Test (Full Test)")
fmt.Println("2. Minimal Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
fmt.Println("3. Standard Test Suite (System Info + CPU + Memory + Disk + Basic Unlock Tests + 5 Speed Test Nodes)")
fmt.Println("4. Network-Focused Test Suite (System Info + CPU + Memory + Disk + 5 Speed Test Nodes)")
fmt.Println("5. Unlock-Focused Test Suite (System Info + CPU + Memory + Disk IO + Basic Unlock Tests + Common Streaming Services + 5 Speed Test Nodes)")
fmt.Println("6. Network-Only Test (IP Quality Test + TGDC + Websites + 11 Speed Test Nodes)")
fmt.Println("7. Unlock-Only Test (Basic Unlock Tests + Common Streaming Services Unlock)")
fmt.Println("8. Hardware-Only Test (System Info + CPU + Memory + dd Disk Test + fio Disk Test)")
fmt.Println("9. IP Quality Test (IP Test with 15 Databases + Email Port Test)")
fmt.Println("0. Exit Program")
}
}
// HandleMenuMode handles menu selection
func HandleMenuMode(preCheck utils.NetCheckResult, config *params.Config) {
savedParams := config.SaveUserSetParams()
config.BasicStatus = false
config.CpuTestStatus = false
config.MemoryTestStatus = false
config.DiskTestStatus = false
config.CommTestStatus = false
config.UtTestStatus = false
config.SecurityTestStatus = false
config.EmailTestStatus = false
config.BacktraceStatus = false
config.Nt3Status = false
config.SpeedTestStatus = false
config.TgdcTestStatus = false
config.WebTestStatus = false
config.AutoChangeDiskMethod = true
PrintMenuOptions(preCheck, config)
Loop:
for {
config.Choice = GetMenuChoice(config.Language)
switch config.Choice {
case "0":
os.Exit(0)
case "1":
SetFullTestStatus(preCheck, config)
config.OnlyChinaTest = utils.CheckChina(config.EnableLogger)
break Loop
case "2":
SetMinimalTestStatus(preCheck, config)
break Loop
case "3":
SetStandardTestStatus(preCheck, config)
break Loop
case "4":
SetNetworkFocusedTestStatus(preCheck, config)
break Loop
case "5":
SetUnlockFocusedTestStatus(preCheck, config)
break Loop
case "6":
if !preCheck.Connected {
fmt.Println("Can not test without network connection!")
return
}
SetNetworkOnlyTestStatus(config)
break Loop
case "7":
if !preCheck.Connected {
fmt.Println("Can not test without network connection!")
return
}
SetUnlockOnlyTestStatus(config)
break Loop
case "8":
SetHardwareOnlyTestStatus(preCheck, config)
break Loop
case "9":
if !preCheck.Connected {
fmt.Println("Can not test without network connection!")
return
}
SetIPQualityTestStatus(config)
break Loop
case "10":
if !preCheck.Connected {
fmt.Println("Can not test without network connection!")
return
}
config.Nt3Location = "ALL"
SetRouteTestStatus(config)
break Loop
default:
PrintInvalidChoice(config.Language)
}
}
config.RestoreUserSetParams(savedParams)
}
// SetFullTestStatus enables all tests
func SetFullTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
if preCheck.Connected {
config.CommTestStatus = true
config.UtTestStatus = true
config.SecurityTestStatus = true
config.EmailTestStatus = true
config.BacktraceStatus = true
config.Nt3Status = true
config.SpeedTestStatus = true
config.TgdcTestStatus = true
config.WebTestStatus = true
}
}
// SetMinimalTestStatus sets minimal test configuration
func SetMinimalTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
if preCheck.Connected {
config.SpeedTestStatus = true
}
}
// SetStandardTestStatus sets standard test configuration
func SetStandardTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
if preCheck.Connected {
config.UtTestStatus = true
config.Nt3Status = true
config.SpeedTestStatus = true
}
}
// SetNetworkFocusedTestStatus sets network-focused test configuration
func SetNetworkFocusedTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
if preCheck.Connected {
config.BacktraceStatus = true
config.Nt3Status = true
config.SpeedTestStatus = true
}
}
// SetUnlockFocusedTestStatus sets unlock-focused test configuration
func SetUnlockFocusedTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
if preCheck.Connected {
config.CommTestStatus = true
config.UtTestStatus = true
config.SpeedTestStatus = true
}
}
// SetNetworkOnlyTestStatus sets network-only test configuration
func SetNetworkOnlyTestStatus(config *params.Config) {
config.OnlyIpInfoCheck = true
config.SecurityTestStatus = true
config.SpeedTestStatus = true
config.BacktraceStatus = true
config.Nt3Status = true
config.PingTestStatus = true
config.TgdcTestStatus = true
config.WebTestStatus = true
}
// SetUnlockOnlyTestStatus sets unlock-only test configuration
func SetUnlockOnlyTestStatus(config *params.Config) {
config.OnlyIpInfoCheck = true
config.CommTestStatus = true
config.UtTestStatus = true
}
// SetHardwareOnlyTestStatus sets hardware-only test configuration
func SetHardwareOnlyTestStatus(preCheck utils.NetCheckResult, config *params.Config) {
_ = preCheck
config.BasicStatus = true
config.CpuTestStatus = true
config.MemoryTestStatus = true
config.DiskTestStatus = true
config.SecurityTestStatus = false
config.AutoChangeDiskMethod = false
}
// SetIPQualityTestStatus sets IP quality test configuration
func SetIPQualityTestStatus(config *params.Config) {
config.OnlyIpInfoCheck = true
config.SecurityTestStatus = true
config.EmailTestStatus = true
}
// SetRouteTestStatus sets route test configuration
func SetRouteTestStatus(config *params.Config) {
config.OnlyIpInfoCheck = true
config.BacktraceStatus = true
config.Nt3Status = true
config.PingTestStatus = true
config.TgdcTestStatus = true
config.WebTestStatus = true
}
// PrintInvalidChoice prints invalid choice message
func PrintInvalidChoice(language string) {
if language == "zh" {
fmt.Println("无效的选项")
} else {
fmt.Println("Invalid choice")
}
}

369
internal/params/params.go Normal file
View File

@@ -0,0 +1,369 @@
package params
import (
"flag"
"fmt"
)
// Config holds all configuration parameters
type Config struct {
EcsVersion string
MenuMode bool
OnlyChinaTest bool
Input string
Choice string
ShowVersion bool
EnableLogger bool
Language string
CpuTestMethod string
CpuTestThreadMode string
MemoryTestMethod string
DiskTestMethod string
DiskTestPath string
DiskMultiCheck bool
Nt3CheckType string
Nt3Location string
SpNum int
Width int
BasicStatus bool
CpuTestStatus bool
MemoryTestStatus bool
DiskTestStatus bool
CommTestStatus bool
UtTestStatus bool
SecurityTestStatus bool
EmailTestStatus bool
BacktraceStatus bool
Nt3Status bool
SpeedTestStatus bool
PingTestStatus bool
TgdcTestStatus bool
WebTestStatus bool
AutoChangeDiskMethod bool
FilePath string
EnableUpload bool
OnlyIpInfoCheck bool
Help bool
Finish bool
UserSetFlags map[string]bool
GoecsFlag *flag.FlagSet
}
// NewConfig creates a new Config with default values
func NewConfig(version string) *Config {
return &Config{
EcsVersion: version,
MenuMode: true,
Language: "zh",
CpuTestMethod: "sysbench",
CpuTestThreadMode: "multi",
MemoryTestMethod: "stream",
DiskTestMethod: "fio",
SpNum: 2,
Width: 82,
BasicStatus: true,
CpuTestStatus: true,
MemoryTestStatus: true,
DiskTestStatus: true,
CommTestStatus: true,
UtTestStatus: true,
SecurityTestStatus: true,
EmailTestStatus: true,
BacktraceStatus: true,
Nt3Status: true,
SpeedTestStatus: true,
Nt3Location: "GZ",
Nt3CheckType: "ipv4",
AutoChangeDiskMethod: true,
FilePath: "goecs.txt",
EnableUpload: true,
UserSetFlags: make(map[string]bool),
GoecsFlag: flag.NewFlagSet("goecs", flag.ContinueOnError),
}
}
// ParseFlags parses command line flags
func (c *Config) ParseFlags(args []string) {
c.GoecsFlag.BoolVar(&c.Help, "h", false, "Show help information")
c.GoecsFlag.BoolVar(&c.Help, "help", false, "Show help information")
c.GoecsFlag.BoolVar(&c.ShowVersion, "v", false, "Display version information")
c.GoecsFlag.BoolVar(&c.ShowVersion, "version", false, "Display version information")
c.GoecsFlag.BoolVar(&c.MenuMode, "menu", true, "Enable/Disable menu mode, disable example: -menu=false")
c.GoecsFlag.StringVar(&c.Language, "l", "zh", "Set language (supported: en, zh)")
c.GoecsFlag.BoolVar(&c.BasicStatus, "basic", true, "Enable/Disable basic test")
c.GoecsFlag.BoolVar(&c.CpuTestStatus, "cpu", true, "Enable/Disable CPU test")
c.GoecsFlag.BoolVar(&c.MemoryTestStatus, "memory", true, "Enable/Disable memory test")
c.GoecsFlag.BoolVar(&c.DiskTestStatus, "disk", true, "Enable/Disable disk test")
c.GoecsFlag.BoolVar(&c.CommTestStatus, "comm", true, "Enable/Disable common media test")
c.GoecsFlag.BoolVar(&c.UtTestStatus, "ut", true, "Enable/Disable unlock media test")
c.GoecsFlag.BoolVar(&c.SecurityTestStatus, "security", true, "Enable/Disable security test")
c.GoecsFlag.BoolVar(&c.EmailTestStatus, "email", true, "Enable/Disable email port test")
c.GoecsFlag.BoolVar(&c.BacktraceStatus, "backtrace", true, "Enable/Disable backtrace test (in 'en' language or on windows it always false)")
c.GoecsFlag.BoolVar(&c.Nt3Status, "nt3", true, "Enable/Disable NT3 test (in 'en' language or on windows it always false)")
c.GoecsFlag.BoolVar(&c.SpeedTestStatus, "speed", true, "Enable/Disable speed test")
c.GoecsFlag.BoolVar(&c.PingTestStatus, "ping", false, "Enable/Disable ping test")
c.GoecsFlag.BoolVar(&c.TgdcTestStatus, "tgdc", false, "Enable/Disable Telegram DC test")
c.GoecsFlag.BoolVar(&c.WebTestStatus, "web", false, "Enable/Disable popular websites test")
c.GoecsFlag.StringVar(&c.CpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)")
c.GoecsFlag.StringVar(&c.CpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)")
c.GoecsFlag.StringVar(&c.MemoryTestMethod, "memorym", "stream", "Set memory test method (supported: stream, sysbench, dd, winsat, auto)")
c.GoecsFlag.StringVar(&c.DiskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)")
c.GoecsFlag.StringVar(&c.DiskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root")
c.GoecsFlag.BoolVar(&c.DiskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false")
c.GoecsFlag.StringVar(&c.Nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD, ALL for Guangzhou, Shanghai, Beijing, Chengdu and all)")
c.GoecsFlag.StringVar(&c.Nt3CheckType, "nt3t", "ipv4", "Set NT3 test type (supported: both, ipv4, ipv6)")
c.GoecsFlag.IntVar(&c.SpNum, "spnum", 2, "Set the number of servers per operator for speed test")
c.GoecsFlag.BoolVar(&c.EnableLogger, "log", false, "Enable/Disable logging in the current path")
c.GoecsFlag.BoolVar(&c.EnableUpload, "upload", true, "Enable/Disable upload the result")
c.GoecsFlag.Parse(args)
c.GoecsFlag.Visit(func(f *flag.Flag) {
c.UserSetFlags[f.Name] = true
})
}
// HandleHelpAndVersion handles help and version flags
func (c *Config) HandleHelpAndVersion(programName string) bool {
if c.Help {
fmt.Printf("Usage: %s [options]\n", programName)
c.GoecsFlag.PrintDefaults()
return true
}
if c.ShowVersion {
fmt.Println(c.EcsVersion)
return true
}
return false
}
// SaveUserSetParams saves user-set parameters
func (c *Config) SaveUserSetParams() map[string]interface{} {
saved := make(map[string]interface{})
if c.UserSetFlags["basic"] {
saved["basic"] = c.BasicStatus
}
if c.UserSetFlags["cpu"] {
saved["cpu"] = c.CpuTestStatus
}
if c.UserSetFlags["memory"] {
saved["memory"] = c.MemoryTestStatus
}
if c.UserSetFlags["disk"] {
saved["disk"] = c.DiskTestStatus
}
if c.UserSetFlags["comm"] {
saved["comm"] = c.CommTestStatus
}
if c.UserSetFlags["ut"] {
saved["ut"] = c.UtTestStatus
}
if c.UserSetFlags["security"] {
saved["security"] = c.SecurityTestStatus
}
if c.UserSetFlags["email"] {
saved["email"] = c.EmailTestStatus
}
if c.UserSetFlags["backtrace"] {
saved["backtrace"] = c.BacktraceStatus
}
if c.UserSetFlags["nt3"] {
saved["nt3"] = c.Nt3Status
}
if c.UserSetFlags["speed"] {
saved["speed"] = c.SpeedTestStatus
}
if c.UserSetFlags["ping"] {
saved["ping"] = c.PingTestStatus
}
if c.UserSetFlags["tgdc"] {
saved["tgdc"] = c.TgdcTestStatus
}
if c.UserSetFlags["web"] {
saved["web"] = c.WebTestStatus
}
if c.UserSetFlags["cpum"] {
saved["cpum"] = c.CpuTestMethod
}
if c.UserSetFlags["cput"] {
saved["cput"] = c.CpuTestThreadMode
}
if c.UserSetFlags["memorym"] {
saved["memorym"] = c.MemoryTestMethod
}
if c.UserSetFlags["diskm"] {
saved["diskm"] = c.DiskTestMethod
}
if c.UserSetFlags["diskp"] {
saved["diskp"] = c.DiskTestPath
}
if c.UserSetFlags["diskmc"] {
saved["diskmc"] = c.DiskMultiCheck
}
if c.UserSetFlags["nt3loc"] {
saved["nt3loc"] = c.Nt3Location
}
if c.UserSetFlags["nt3t"] {
saved["nt3t"] = c.Nt3CheckType
}
if c.UserSetFlags["spnum"] {
saved["spnum"] = c.SpNum
}
return saved
}
// RestoreUserSetParams restores user-set parameters
func (c *Config) RestoreUserSetParams(saved map[string]interface{}) {
if val, ok := saved["basic"]; ok {
c.BasicStatus = val.(bool)
}
if val, ok := saved["cpu"]; ok {
c.CpuTestStatus = val.(bool)
}
if val, ok := saved["memory"]; ok {
c.MemoryTestStatus = val.(bool)
}
if val, ok := saved["disk"]; ok {
c.DiskTestStatus = val.(bool)
}
if val, ok := saved["comm"]; ok {
c.CommTestStatus = val.(bool)
}
if val, ok := saved["ut"]; ok {
c.UtTestStatus = val.(bool)
}
if val, ok := saved["security"]; ok {
c.SecurityTestStatus = val.(bool)
}
if val, ok := saved["email"]; ok {
c.EmailTestStatus = val.(bool)
}
if val, ok := saved["backtrace"]; ok {
c.BacktraceStatus = val.(bool)
}
if val, ok := saved["nt3"]; ok {
c.Nt3Status = val.(bool)
}
if val, ok := saved["speed"]; ok {
c.SpeedTestStatus = val.(bool)
}
if val, ok := saved["ping"]; ok {
c.PingTestStatus = val.(bool)
}
if val, ok := saved["tgdc"]; ok {
c.TgdcTestStatus = val.(bool)
}
if val, ok := saved["web"]; ok {
c.WebTestStatus = val.(bool)
}
if val, ok := saved["cpum"]; ok {
c.CpuTestMethod = val.(string)
}
if val, ok := saved["cput"]; ok {
c.CpuTestThreadMode = val.(string)
}
if val, ok := saved["memorym"]; ok {
c.MemoryTestMethod = val.(string)
}
if val, ok := saved["diskm"]; ok {
c.DiskTestMethod = val.(string)
}
if val, ok := saved["diskp"]; ok {
c.DiskTestPath = val.(string)
}
if val, ok := saved["diskmc"]; ok {
c.DiskMultiCheck = val.(bool)
}
if val, ok := saved["nt3loc"]; ok {
if c.Choice != "10" {
c.Nt3Location = val.(string)
}
}
if val, ok := saved["nt3t"]; ok {
c.Nt3CheckType = val.(string)
}
if val, ok := saved["spnum"]; ok {
c.SpNum = val.(int)
}
c.ValidateParams()
}
// ValidateParams validates parameter values
func (c *Config) ValidateParams() {
validCpuMethods := map[string]bool{"sysbench": true, "geekbench": true, "winsat": true}
if !validCpuMethods[c.CpuTestMethod] {
if c.Language == "zh" {
fmt.Printf("警告: CPU测试方法 '%s' 无效,使用默认值 'sysbench'\n", c.CpuTestMethod)
} else {
fmt.Printf("Warning: Invalid CPU test method '%s', using default 'sysbench'\n", c.CpuTestMethod)
}
c.CpuTestMethod = "sysbench"
}
validThreadModes := map[string]bool{"single": true, "multi": true}
if !validThreadModes[c.CpuTestThreadMode] {
if c.Language == "zh" {
fmt.Printf("警告: CPU线程模式 '%s' 无效,使用默认值 'multi'\n", c.CpuTestThreadMode)
} else {
fmt.Printf("Warning: Invalid CPU thread mode '%s', using default 'multi'\n", c.CpuTestThreadMode)
}
c.CpuTestThreadMode = "multi"
}
validMemoryMethods := map[string]bool{"stream": true, "sysbench": true, "dd": true, "winsat": true, "auto": true}
if !validMemoryMethods[c.MemoryTestMethod] {
if c.Language == "zh" {
fmt.Printf("警告: 内存测试方法 '%s' 无效,使用默认值 'stream'\n", c.MemoryTestMethod)
} else {
fmt.Printf("Warning: Invalid memory test method '%s', using default 'stream'\n", c.MemoryTestMethod)
}
c.MemoryTestMethod = "stream"
}
validDiskMethods := map[string]bool{"fio": true, "dd": true, "winsat": true}
if !validDiskMethods[c.DiskTestMethod] {
if c.Language == "zh" {
fmt.Printf("警告: 磁盘测试方法 '%s' 无效,使用默认值 'fio'\n", c.DiskTestMethod)
} else {
fmt.Printf("Warning: Invalid disk test method '%s', using default 'fio'\n", c.DiskTestMethod)
}
c.DiskTestMethod = "fio"
}
validNt3Locations := map[string]bool{"GZ": true, "SH": true, "BJ": true, "CD": true, "ALL": true}
if !validNt3Locations[c.Nt3Location] {
if c.Language == "zh" {
fmt.Printf("警告: NT3测试位置 '%s' 无效,使用默认值 'GZ'\n", c.Nt3Location)
} else {
fmt.Printf("Warning: Invalid NT3 location '%s', using default 'GZ'\n", c.Nt3Location)
}
c.Nt3Location = "GZ"
}
validNt3Types := map[string]bool{"both": true, "ipv4": true, "ipv6": true}
if !validNt3Types[c.Nt3CheckType] {
if c.Language == "zh" {
fmt.Printf("警告: NT3测试类型 '%s' 无效,使用默认值 'ipv4'\n", c.Nt3CheckType)
} else {
fmt.Printf("Warning: Invalid NT3 check type '%s', using default 'ipv4'\n", c.Nt3CheckType)
}
c.Nt3CheckType = "ipv4"
}
if c.SpNum < 0 {
if c.Language == "zh" {
fmt.Printf("警告: 测速节点数量 '%d' 无效,使用默认值 2\n", c.SpNum)
} else {
fmt.Printf("Warning: Invalid speed test node count '%d', using default 2\n", c.SpNum)
}
c.SpNum = 2
}
validLanguages := map[string]bool{"zh": true, "en": true}
if !validLanguages[c.Language] {
fmt.Printf("Warning: Invalid language '%s', using default 'zh'\n", c.Language)
c.Language = "zh"
}
}

489
internal/runner/runner.go Normal file
View File

@@ -0,0 +1,489 @@
package runner
import (
"bufio"
"fmt"
"os"
"runtime"
"strings"
"sync"
"time"
"github.com/oneclickvirt/CommonMediaTests/commediatests"
"github.com/oneclickvirt/ecs/cputest"
"github.com/oneclickvirt/ecs/disktest"
"github.com/oneclickvirt/ecs/internal/params"
"github.com/oneclickvirt/ecs/memorytest"
"github.com/oneclickvirt/ecs/nexttrace"
"github.com/oneclickvirt/ecs/speedtest"
"github.com/oneclickvirt/ecs/unlocktest"
"github.com/oneclickvirt/ecs/upstreams"
"github.com/oneclickvirt/ecs/utils"
"github.com/oneclickvirt/pingtest/pt"
"github.com/oneclickvirt/portchecker/email"
)
// RunChineseTests runs all tests in Chinese mode
func RunChineseTests(preCheck utils.NetCheckResult, config *params.Config, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
*output = RunBasicTests(preCheck, config, basicInfo, securityInfo, *output, tempOutput, outputMutex)
*output = RunCPUTest(config, *output, tempOutput, outputMutex)
*output = RunMemoryTest(config, *output, tempOutput, outputMutex)
*output = RunDiskTest(config, *output, tempOutput, outputMutex)
if config.OnlyIpInfoCheck && !config.BasicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
*output = RunIpInfoCheck(config, *output, tempOutput, outputMutex)
}
if config.UtTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !config.OnlyChinaTest {
wg1.Add(1)
go func() {
defer wg1.Done()
*mediaInfo = unlocktest.MediaTest(config.Language)
}()
}
if config.EmailTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
wg2.Add(1)
go func() {
defer wg2.Done()
*emailInfo = email.EmailCheck()
}()
}
if (config.OnlyChinaTest || config.PingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
wg3.Add(1)
go func() {
defer wg3.Done()
*ptInfo = pt.PingTest()
}()
}
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
*output = RunStreamingTests(config, wg1, mediaInfo, *output, tempOutput, outputMutex)
*output = RunSecurityTests(config, *securityInfo, *output, tempOutput, outputMutex)
*output = RunEmailTests(config, wg2, emailInfo, *output, tempOutput, outputMutex)
}
if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
*output = RunNetworkTests(config, wg3, ptInfo, *output, tempOutput, outputMutex)
}
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
*output = RunSpeedTests(config, *output, tempOutput, outputMutex)
}
*output = AppendTimeInfo(config, *output, tempOutput, startTime, outputMutex)
}
// RunEnglishTests runs all tests in English mode
func RunEnglishTests(preCheck utils.NetCheckResult, config *params.Config, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
*output = RunBasicTests(preCheck, config, basicInfo, securityInfo, *output, tempOutput, outputMutex)
*output = RunCPUTest(config, *output, tempOutput, outputMutex)
*output = RunMemoryTest(config, *output, tempOutput, outputMutex)
*output = RunDiskTest(config, *output, tempOutput, outputMutex)
if config.OnlyIpInfoCheck && !config.BasicStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
*output = RunIpInfoCheck(config, *output, tempOutput, outputMutex)
}
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
if config.UtTestStatus {
wg1.Add(1)
go func() {
defer wg1.Done()
*mediaInfo = unlocktest.MediaTest(config.Language)
}()
}
if config.EmailTestStatus {
wg2.Add(1)
go func() {
defer wg2.Done()
*emailInfo = email.EmailCheck()
}()
}
*output = RunStreamingTests(config, wg1, mediaInfo, *output, tempOutput, outputMutex)
*output = RunSecurityTests(config, *securityInfo, *output, tempOutput, outputMutex)
*output = RunEmailTests(config, wg2, emailInfo, *output, tempOutput, outputMutex)
*output = RunEnglishNetworkTests(config, wg3, ptInfo, *output, tempOutput, outputMutex)
*output = RunEnglishSpeedTests(config, *output, tempOutput, outputMutex)
}
*output = AppendTimeInfo(config, *output, tempOutput, startTime, outputMutex)
}
// RunIpInfoCheck performs IP info check
func RunIpInfoCheck(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
var ipinfo string
upstreams.IPV4, upstreams.IPV6, ipinfo = utils.OnlyBasicsIpInfo(config.Language)
if ipinfo != "" {
if config.Language == "zh" {
utils.PrintCenteredTitle("IP信息", config.Width)
} else {
utils.PrintCenteredTitle("IP-Information", config.Width)
}
fmt.Printf("%s", ipinfo)
}
}, tempOutput, output)
}
// RunBasicTests runs basic system tests
func RunBasicTests(preCheck utils.NetCheckResult, config *params.Config, basicInfo, securityInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
utils.PrintHead(config.Language, config.Width, config.EcsVersion)
if config.BasicStatus || config.SecurityTestStatus {
if config.BasicStatus {
if config.Language == "zh" {
utils.PrintCenteredTitle("系统基础信息", config.Width)
} else {
utils.PrintCenteredTitle("System-Basic-Information", config.Width)
}
}
if preCheck.Connected && preCheck.StackType == "DualStack" {
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, config.Nt3CheckType, config.SecurityTestStatus)
} else if preCheck.Connected && preCheck.StackType == "IPv4" {
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "ipv4", config.SecurityTestStatus)
} else if preCheck.Connected && preCheck.StackType == "IPv6" {
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "ipv6", config.SecurityTestStatus)
} else {
upstreams.IPV4, upstreams.IPV6, *basicInfo, *securityInfo, config.Nt3CheckType = utils.BasicsAndSecurityCheck(config.Language, "", false)
config.SecurityTestStatus = false
}
if config.BasicStatus {
fmt.Printf("%s", *basicInfo)
} else if (config.Input == "6" || config.Input == "9") && config.SecurityTestStatus {
scanner := bufio.NewScanner(strings.NewReader(*basicInfo))
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, "IPV") {
fmt.Println(line)
}
}
}
}
}, tempOutput, output)
}
// RunCPUTest runs CPU test
func RunCPUTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.CpuTestStatus {
realTestMethod, res := cputest.CpuTest(config.Language, config.CpuTestMethod, config.CpuTestThreadMode)
if config.Language == "zh" {
utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", realTestMethod), config.Width)
} else {
utils.PrintCenteredTitle(fmt.Sprintf("CPU-Test--%s-Method", realTestMethod), config.Width)
}
fmt.Print(res)
}
}, tempOutput, output)
}
// RunMemoryTest runs memory test
func RunMemoryTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.MemoryTestStatus {
realTestMethod, res := memorytest.MemoryTest(config.Language, config.MemoryTestMethod)
if config.Language == "zh" {
utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", realTestMethod), config.Width)
} else {
utils.PrintCenteredTitle(fmt.Sprintf("Memory-Test--%s-Method", realTestMethod), config.Width)
}
fmt.Print(res)
}
}, tempOutput, output)
}
// RunDiskTest runs disk test
func RunDiskTest(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.DiskTestStatus && config.AutoChangeDiskMethod {
realTestMethod, res := disktest.DiskTest(config.Language, config.DiskTestMethod, config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
if config.Language == "zh" {
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", realTestMethod), config.Width)
} else {
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", realTestMethod), config.Width)
}
fmt.Print(res)
} else if config.DiskTestStatus && !config.AutoChangeDiskMethod {
if config.Language == "zh" {
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "dd"), config.Width)
_, res := disktest.DiskTest(config.Language, "dd", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
fmt.Print(res)
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "fio"), config.Width)
_, res = disktest.DiskTest(config.Language, "fio", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
fmt.Print(res)
} else {
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "dd"), config.Width)
_, res := disktest.DiskTest(config.Language, "dd", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
fmt.Print(res)
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "fio"), config.Width)
_, res = disktest.DiskTest(config.Language, "fio", config.DiskTestPath, config.DiskMultiCheck, config.AutoChangeDiskMethod)
fmt.Print(res)
}
}
}, tempOutput, output)
}
// RunStreamingTests runs streaming media tests
func RunStreamingTests(config *params.Config, wg1 *sync.WaitGroup, mediaInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.Language == "zh" {
if config.CommTestStatus && !config.OnlyChinaTest {
utils.PrintCenteredTitle("御三家流媒体解锁", config.Width)
fmt.Printf("%s", commediatests.MediaTests(config.Language))
}
}
if config.UtTestStatus && (config.Language == "zh" && !config.OnlyChinaTest || config.Language == "en") {
wg1.Wait()
if config.Language == "zh" {
utils.PrintCenteredTitle("跨国流媒体解锁", config.Width)
} else {
utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", config.Width)
}
fmt.Printf("%s", *mediaInfo)
}
}, tempOutput, output)
}
// RunSecurityTests runs security tests
func RunSecurityTests(config *params.Config, securityInfo, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.SecurityTestStatus {
if config.Language == "zh" {
utils.PrintCenteredTitle("IP质量检测", config.Width)
} else {
utils.PrintCenteredTitle("IP-Quality-Check", config.Width)
}
fmt.Printf("%s", securityInfo)
}
}, tempOutput, output)
}
// RunEmailTests runs email port tests
func RunEmailTests(config *params.Config, wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.EmailTestStatus {
wg2.Wait()
if config.Language == "zh" {
utils.PrintCenteredTitle("邮件端口检测", config.Width)
} else {
utils.PrintCenteredTitle("Email-Port-Check", config.Width)
}
fmt.Println(*emailInfo)
}
}, tempOutput, output)
}
// RunNetworkTests runs network tests (Chinese mode)
func RunNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.BacktraceStatus && !config.OnlyChinaTest {
utils.PrintCenteredTitle("上游及回程线路检测", config.Width)
upstreams.UpstreamsCheck()
}
if config.Nt3Status && !config.OnlyChinaTest {
utils.PrintCenteredTitle("三网回程路由检测", config.Width)
nexttrace.NextTrace3Check(config.Language, config.Nt3Location, config.Nt3CheckType)
}
if config.OnlyChinaTest && *ptInfo != "" {
wg3.Wait()
utils.PrintCenteredTitle("PING值检测", config.Width)
fmt.Println(*ptInfo)
}
if config.PingTestStatus && *ptInfo != "" {
wg3.Wait()
utils.PrintCenteredTitle("PING值检测", config.Width)
fmt.Println(*ptInfo)
if config.TgdcTestStatus {
fmt.Println(pt.TelegramDCTest())
}
if config.WebTestStatus {
fmt.Println(pt.WebsiteTest())
}
}
if !config.OnlyChinaTest && !config.PingTestStatus && (config.TgdcTestStatus || config.WebTestStatus) {
utils.PrintCenteredTitle("PING值检测", config.Width)
if config.TgdcTestStatus {
fmt.Println(pt.TelegramDCTest())
}
if config.WebTestStatus {
fmt.Println(pt.WebsiteTest())
}
}
}, tempOutput, output)
}
// RunSpeedTests runs speed tests (Chinese mode)
func RunSpeedTests(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.SpeedTestStatus {
utils.PrintCenteredTitle("就近节点测速", config.Width)
speedtest.ShowHead(config.Language)
if config.Choice == "1" || !config.MenuMode {
speedtest.NearbySP()
speedtest.CustomSP("net", "global", 2, config.Language)
speedtest.CustomSP("net", "cu", config.SpNum, config.Language)
speedtest.CustomSP("net", "ct", config.SpNum, config.Language)
speedtest.CustomSP("net", "cmcc", config.SpNum, config.Language)
} else if config.Choice == "2" || config.Choice == "3" || config.Choice == "4" || config.Choice == "5" {
speedtest.CustomSP("net", "global", 4, config.Language)
} else if config.Choice == "6" {
speedtest.CustomSP("net", "global", 11, config.Language)
}
}
}, tempOutput, output)
}
// RunEnglishNetworkTests runs network tests (English mode)
func RunEnglishNetworkTests(config *params.Config, wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.TgdcTestStatus || config.WebTestStatus {
utils.PrintCenteredTitle("PING-Test", config.Width)
if config.TgdcTestStatus {
fmt.Println(pt.TelegramDCTest())
}
if config.WebTestStatus {
fmt.Println(pt.WebsiteTest())
}
}
}, tempOutput, output)
}
// RunEnglishSpeedTests runs speed tests (English mode)
func RunEnglishSpeedTests(config *params.Config, output, tempOutput string, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
return utils.PrintAndCapture(func() {
if config.SpeedTestStatus {
utils.PrintCenteredTitle("Speed-Test", config.Width)
speedtest.ShowHead(config.Language)
speedtest.NearbySP()
speedtest.CustomSP("net", "global", -1, config.Language)
}
}, tempOutput, output)
}
// AppendTimeInfo appends timing information
func AppendTimeInfo(config *params.Config, output, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) string {
outputMutex.Lock()
defer outputMutex.Unlock()
endTime := time.Now()
duration := endTime.Sub(startTime)
minutes := int(duration.Minutes())
seconds := int(duration.Seconds()) % 60
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
return utils.PrintAndCapture(func() {
utils.PrintCenteredTitle("", config.Width)
if config.Language == "zh" {
fmt.Printf("花费 : %d 分 %d 秒\n", minutes, seconds)
fmt.Printf("时间 : %s\n", currentTime)
} else {
fmt.Printf("Cost Time : %d min %d sec\n", minutes, seconds)
fmt.Printf("Current Time : %s\n", currentTime)
}
utils.PrintCenteredTitle("", config.Width)
}, tempOutput, output)
}
// HandleSignalInterrupt handles interrupt signals
func HandleSignalInterrupt(sig chan os.Signal, config *params.Config, startTime *time.Time, output *string, tempOutput string, uploadDone chan bool, outputMutex *sync.Mutex) {
select {
case <-sig:
if !config.Finish {
endTime := time.Now()
duration := endTime.Sub(*startTime)
minutes := int(duration.Minutes())
seconds := int(duration.Seconds()) % 60
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
outputMutex.Lock()
timeInfo := utils.PrintAndCapture(func() {
utils.PrintCenteredTitle("", config.Width)
if config.Language == "zh" {
fmt.Printf("花费 : %d 分 %d 秒\n", minutes, seconds)
fmt.Printf("时间 : %s\n", currentTime)
} else {
fmt.Printf("Cost Time : %d min %d sec\n", minutes, seconds)
fmt.Printf("Current Time : %s\n", currentTime)
}
utils.PrintCenteredTitle("", config.Width)
}, "", "")
*output += timeInfo
finalOutput := *output
outputMutex.Unlock()
resultChan := make(chan struct {
httpURL string
httpsURL string
}, 1)
if config.EnableUpload {
go func() {
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, config.FilePath, config.EnableUpload)
resultChan <- struct {
httpURL string
httpsURL string
}{httpURL, httpsURL}
uploadDone <- true
}()
select {
case result := <-resultChan:
if result.httpURL != "" || result.httpsURL != "" {
if config.Language == "en" {
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
} else {
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", result.httpURL, result.httpsURL)
}
}
time.Sleep(100 * time.Millisecond)
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
fmt.Println("Press Enter to exit...")
fmt.Scanln()
}
os.Exit(0)
case <-time.After(30 * time.Second):
if config.Language == "en" {
fmt.Println("Upload timeout, program exit")
} else {
fmt.Println("上传超时,程序退出")
}
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
fmt.Println("Press Enter to exit...")
fmt.Scanln()
}
os.Exit(1)
}
} else {
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
fmt.Println("Press Enter to exit...")
fmt.Scanln()
}
os.Exit(0)
}
}
os.Exit(0)
}
}
// HandleUploadResults handles uploading results
func HandleUploadResults(config *params.Config, output string) {
httpURL, httpsURL := utils.ProcessAndUpload(output, config.FilePath, config.EnableUpload)
if httpURL != "" || httpsURL != "" {
if config.Language == "en" {
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
fmt.Println("Each Test Benchmark: https://bash.spiritlhl.net/ecsguide")
} else {
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
fmt.Println("每项测试基准见: https://bash.spiritlhl.net/ecsguide")
}
}
}