mirror of
https://github.com/oneclickvirt/ecs.git
synced 2025-09-27 03:36:12 +08:00
829 lines
28 KiB
Go
829 lines
28 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/oneclickvirt/CommonMediaTests/commediatests"
|
|
unlocktestmodel "github.com/oneclickvirt/UnlockTests/model"
|
|
"github.com/oneclickvirt/UnlockTests/uts"
|
|
backtrace "github.com/oneclickvirt/backtrace/bk"
|
|
backtracemodel "github.com/oneclickvirt/backtrace/model"
|
|
basicmodel "github.com/oneclickvirt/basics/model"
|
|
cputestmodel "github.com/oneclickvirt/cputest/model"
|
|
disktestmodel "github.com/oneclickvirt/disktest/disk"
|
|
"github.com/oneclickvirt/ecs/cputest"
|
|
"github.com/oneclickvirt/ecs/disktest"
|
|
"github.com/oneclickvirt/ecs/memorytest"
|
|
"github.com/oneclickvirt/ecs/speedtest"
|
|
"github.com/oneclickvirt/ecs/unlocktest"
|
|
"github.com/oneclickvirt/ecs/utils"
|
|
gostunmodel "github.com/oneclickvirt/gostun/model"
|
|
memorytestmodel "github.com/oneclickvirt/memorytest/memory"
|
|
nt3model "github.com/oneclickvirt/nt3/model"
|
|
"github.com/oneclickvirt/nt3/nt"
|
|
ptmodel "github.com/oneclickvirt/pingtest/model"
|
|
"github.com/oneclickvirt/pingtest/pt"
|
|
"github.com/oneclickvirt/portchecker/email"
|
|
speedtestmodel "github.com/oneclickvirt/speedtest/model"
|
|
)
|
|
|
|
var (
|
|
ecsVersion = "v0.1.71"
|
|
menuMode bool
|
|
onlyChinaTest bool
|
|
input, choice string
|
|
showVersion bool
|
|
enableLogger bool
|
|
language string
|
|
cpuTestMethod, cpuTestThreadMode string
|
|
memoryTestMethod string
|
|
diskTestMethod, diskTestPath string
|
|
diskMultiCheck bool
|
|
nt3CheckType, nt3Location string
|
|
spNum int
|
|
width = 82
|
|
basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus bool
|
|
commTestStatus, utTestStatus, securityTestStatus, emailTestStatus bool
|
|
backtraceStatus, nt3Status, speedTestStatus, pingTestStatus bool
|
|
autoChangeDiskTestMethod = true
|
|
filePath = "goecs.txt"
|
|
enabelUpload = true
|
|
help bool
|
|
goecsFlag = flag.NewFlagSet("goecs", flag.ContinueOnError)
|
|
finish bool
|
|
)
|
|
|
|
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 "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 ""
|
|
}
|
|
}
|
|
}
|
|
|
|
func parseFlags() {
|
|
goecsFlag.BoolVar(&help, "h", false, "Show help information")
|
|
goecsFlag.BoolVar(&showVersion, "v", false, "Display version information")
|
|
goecsFlag.BoolVar(&menuMode, "menu", true, "Enable/Disable menu mode, disable example: -menu=false") // true 默认启用菜单栏模式
|
|
goecsFlag.StringVar(&language, "l", "zh", "Set language (supported: en, zh)")
|
|
goecsFlag.BoolVar(&basicStatus, "basic", true, "Enable/Disable basic test")
|
|
goecsFlag.BoolVar(&cpuTestStatus, "cpu", true, "Enable/Disable CPU test")
|
|
goecsFlag.BoolVar(&memoryTestStatus, "memory", true, "Enable/Disable memory test")
|
|
goecsFlag.BoolVar(&diskTestStatus, "disk", true, "Enable/Disable disk test")
|
|
goecsFlag.BoolVar(&commTestStatus, "comm", true, "Enable/Disable common media test")
|
|
goecsFlag.BoolVar(&utTestStatus, "ut", true, "Enable/Disable unlock media test")
|
|
goecsFlag.BoolVar(&securityTestStatus, "security", true, "Enable/Disable security test")
|
|
goecsFlag.BoolVar(&emailTestStatus, "email", true, "Enable/Disable email port test")
|
|
goecsFlag.BoolVar(&backtraceStatus, "backtrace", true, "Enable/Disable backtrace test (in 'en' language or on windows it always false)")
|
|
goecsFlag.BoolVar(&nt3Status, "nt3", true, "Enable/Disable NT3 test (in 'en' language or on windows it always false)")
|
|
goecsFlag.BoolVar(&speedTestStatus, "speed", true, "Enable/Disable speed test")
|
|
goecsFlag.StringVar(&cpuTestMethod, "cpum", "sysbench", "Set CPU test method (supported: sysbench, geekbench, winsat)")
|
|
goecsFlag.StringVar(&cpuTestThreadMode, "cput", "multi", "Set CPU test thread mode (supported: single, multi)")
|
|
goecsFlag.StringVar(&memoryTestMethod, "memorym", "sysbench", "Set memory test method (supported: sysbench, dd, winsat)")
|
|
goecsFlag.StringVar(&diskTestMethod, "diskm", "fio", "Set disk test method (supported: fio, dd, winsat)")
|
|
goecsFlag.StringVar(&diskTestPath, "diskp", "", "Set disk test path, e.g., -diskp /root")
|
|
goecsFlag.BoolVar(&diskMultiCheck, "diskmc", false, "Enable/Disable multiple disk checks, e.g., -diskmc=false")
|
|
goecsFlag.StringVar(&nt3Location, "nt3loc", "GZ", "Specify NT3 test location (supported: GZ, SH, BJ, CD for Guangzhou, Shanghai, Beijing, Chengdu)")
|
|
goecsFlag.StringVar(&nt3CheckType, "nt3t", "ipv4", "Set NT3 test type (supported: both, ipv4, ipv6)")
|
|
goecsFlag.IntVar(&spNum, "spnum", 2, "Set the number of servers per operator for speed test")
|
|
goecsFlag.BoolVar(&enableLogger, "log", false, "Enable/Disable logging in the current path")
|
|
goecsFlag.BoolVar(&enabelUpload, "upload", true, "Enable/Disable upload the result")
|
|
goecsFlag.Parse(os.Args[1:])
|
|
}
|
|
|
|
func handleHelpAndVersion() bool {
|
|
if help {
|
|
fmt.Printf("Usage: %s [options]\n", os.Args[0])
|
|
goecsFlag.PrintDefaults()
|
|
return true
|
|
}
|
|
if showVersion {
|
|
fmt.Println(ecsVersion)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func initLogger() {
|
|
if enableLogger {
|
|
gostunmodel.EnableLoger = true
|
|
basicmodel.EnableLoger = true
|
|
cputestmodel.EnableLoger = true
|
|
memorytestmodel.EnableLoger = true
|
|
disktestmodel.EnableLoger = true
|
|
commediatests.EnableLoger = true
|
|
unlocktestmodel.EnableLoger = true
|
|
ptmodel.EnableLoger = true
|
|
backtracemodel.EnableLoger = true
|
|
nt3model.EnableLoger = true
|
|
speedtestmodel.EnableLoger = true
|
|
}
|
|
}
|
|
|
|
func handleMenuMode(preCheck utils.NetCheckResult) {
|
|
basicStatus, cpuTestStatus, memoryTestStatus, diskTestStatus = false, false, false, false
|
|
commTestStatus, utTestStatus, securityTestStatus, emailTestStatus = false, false, false, false
|
|
backtraceStatus, nt3Status, speedTestStatus = false, false, false
|
|
autoChangeDiskTestMethod = true
|
|
printMenuOptions()
|
|
Loop:
|
|
for {
|
|
choice = getMenuChoice(language)
|
|
switch choice {
|
|
case "1":
|
|
setFullTestStatus(preCheck)
|
|
onlyChinaTest = utils.CheckChina(enableLogger)
|
|
break Loop
|
|
case "2":
|
|
setMinimalTestStatus(preCheck)
|
|
break Loop
|
|
case "3":
|
|
setStandardTestStatus(preCheck)
|
|
break Loop
|
|
case "4":
|
|
setNetworkFocusedTestStatus(preCheck)
|
|
break Loop
|
|
case "5":
|
|
setUnlockFocusedTestStatus(preCheck)
|
|
break Loop
|
|
case "6":
|
|
if !preCheck.Connected {
|
|
fmt.Println("Can not test without network connection!")
|
|
return
|
|
}
|
|
setNetworkOnlyTestStatus()
|
|
break Loop
|
|
case "7":
|
|
if !preCheck.Connected {
|
|
fmt.Println("Can not test without network connection!")
|
|
return
|
|
}
|
|
setUnlockOnlyTestStatus()
|
|
break Loop
|
|
case "8":
|
|
setHardwareOnlyTestStatus(preCheck)
|
|
break Loop
|
|
case "9":
|
|
if !preCheck.Connected {
|
|
fmt.Println("Can not test without network connection!")
|
|
return
|
|
}
|
|
setIPQualityTestStatus()
|
|
break Loop
|
|
case "10":
|
|
if !preCheck.Connected {
|
|
fmt.Println("Can not test without network connection!")
|
|
return
|
|
}
|
|
setRouteTestStatus()
|
|
break Loop
|
|
default:
|
|
printInvalidChoice()
|
|
}
|
|
}
|
|
}
|
|
|
|
func printMenuOptions() {
|
|
switch language {
|
|
case "zh":
|
|
fmt.Println("VPS融合怪版本: ", ecsVersion)
|
|
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质量检测+三网回程+三网路由与延迟+测速节点11个)")
|
|
fmt.Println("7. 解锁单项(御三家解锁+常用流媒体解锁)")
|
|
fmt.Println("8. 硬件单项(系统信息+CPU+内存+dd磁盘测试+fio磁盘测试)")
|
|
fmt.Println("9. IP质量检测(15个数据库的IP检测+邮件端口检测)")
|
|
fmt.Println("10. 三网回程线路+广州三网路由+全国三网延迟")
|
|
case "en":
|
|
fmt.Println("VPS Fusion Monster Test Version: ", ecsVersion)
|
|
fmt.Println("1. VPS Fusion Monster Test Comprehensive Test Suite")
|
|
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 + 5 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)")
|
|
}
|
|
}
|
|
|
|
func setFullTestStatus(preCheck utils.NetCheckResult) {
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
if preCheck.Connected {
|
|
commTestStatus = true
|
|
utTestStatus = true
|
|
securityTestStatus = true
|
|
emailTestStatus = true
|
|
backtraceStatus = true
|
|
nt3Status = true
|
|
speedTestStatus = true
|
|
}
|
|
}
|
|
|
|
func setMinimalTestStatus(preCheck utils.NetCheckResult) {
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
if preCheck.Connected {
|
|
speedTestStatus = true
|
|
}
|
|
}
|
|
|
|
func setStandardTestStatus(preCheck utils.NetCheckResult) {
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
if preCheck.Connected {
|
|
utTestStatus = true
|
|
nt3Status = true
|
|
speedTestStatus = true
|
|
}
|
|
}
|
|
|
|
func setNetworkFocusedTestStatus(preCheck utils.NetCheckResult) {
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
if preCheck.Connected {
|
|
backtraceStatus = true
|
|
nt3Status = true
|
|
speedTestStatus = true
|
|
}
|
|
}
|
|
|
|
func setUnlockFocusedTestStatus(preCheck utils.NetCheckResult) {
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
if preCheck.Connected {
|
|
commTestStatus = true
|
|
utTestStatus = true
|
|
speedTestStatus = true
|
|
}
|
|
}
|
|
|
|
func setNetworkOnlyTestStatus() {
|
|
securityTestStatus = true
|
|
speedTestStatus = true
|
|
backtraceStatus = true
|
|
nt3Status = true
|
|
}
|
|
|
|
func setUnlockOnlyTestStatus() {
|
|
commTestStatus = true
|
|
utTestStatus = true
|
|
enabelUpload = false
|
|
}
|
|
|
|
func setHardwareOnlyTestStatus(preCheck utils.NetCheckResult) {
|
|
_ = preCheck
|
|
basicStatus = true
|
|
cpuTestStatus = true
|
|
memoryTestStatus = true
|
|
diskTestStatus = true
|
|
securityTestStatus = false
|
|
autoChangeDiskTestMethod = false
|
|
}
|
|
|
|
func setIPQualityTestStatus() {
|
|
securityTestStatus = true
|
|
emailTestStatus = true
|
|
}
|
|
|
|
func setRouteTestStatus() {
|
|
backtraceStatus = true
|
|
nt3Status = true
|
|
pingTestStatus = true
|
|
enabelUpload = false
|
|
}
|
|
|
|
func printInvalidChoice() {
|
|
if language == "zh" {
|
|
fmt.Println("无效的选项")
|
|
} else {
|
|
fmt.Println("Invalid choice")
|
|
}
|
|
}
|
|
|
|
func handleLanguageSpecificSettings() {
|
|
if language == "en" {
|
|
backtraceStatus = false
|
|
nt3Status = false
|
|
}
|
|
if !enabelUpload {
|
|
securityTestStatus = false
|
|
}
|
|
}
|
|
|
|
func handleSignalInterrupt(sig chan os.Signal, startTime *time.Time, output *string, tempOutput string, uploadDone chan bool, outputMutex *sync.Mutex) {
|
|
select {
|
|
case <-sig:
|
|
if !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("", width)
|
|
if 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("", width)
|
|
}, "", "")
|
|
*output += timeInfo
|
|
finalOutput := *output
|
|
outputMutex.Unlock()
|
|
resultChan := make(chan struct {
|
|
httpURL string
|
|
httpsURL string
|
|
}, 1)
|
|
if enabelUpload {
|
|
go func() {
|
|
httpURL, httpsURL := utils.ProcessAndUpload(finalOutput, filePath, enabelUpload)
|
|
resultChan <- struct {
|
|
httpURL string
|
|
httpsURL string
|
|
}{httpURL, httpsURL}
|
|
uploadDone <- true
|
|
}()
|
|
select {
|
|
case result := <-resultChan:
|
|
if result.httpURL != "" || result.httpsURL != "" {
|
|
if 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 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)
|
|
}
|
|
}
|
|
|
|
func runChineseTests(preCheck utils.NetCheckResult, wg1, wg2, wg3 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
|
*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
|
*output = runCPUTest(*output, tempOutput, outputMutex)
|
|
*output = runMemoryTest(*output, tempOutput, outputMutex)
|
|
*output = runDiskTest(*output, tempOutput, outputMutex)
|
|
if (onlyChinaTest || pingTestStatus) && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
wg3.Add(1)
|
|
go func() {
|
|
defer wg3.Done()
|
|
*ptInfo = pt.PingTest()
|
|
}()
|
|
}
|
|
if emailTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
wg2.Add(1)
|
|
go func() {
|
|
defer wg2.Done()
|
|
*emailInfo = email.EmailCheck()
|
|
}()
|
|
}
|
|
if utTestStatus && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" && !onlyChinaTest {
|
|
wg1.Add(1)
|
|
go func() {
|
|
defer wg1.Done()
|
|
*mediaInfo = unlocktest.MediaTest(language)
|
|
}()
|
|
}
|
|
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex)
|
|
*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex)
|
|
*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex)
|
|
}
|
|
if runtime.GOOS != "windows" && preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
*output = runNetworkTests(wg3, ptInfo, *output, tempOutput, outputMutex)
|
|
}
|
|
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
*output = runSpeedTests(*output, tempOutput, outputMutex)
|
|
}
|
|
*output = appendTimeInfo(*output, tempOutput, startTime, outputMutex)
|
|
}
|
|
|
|
func runEnglishTests(preCheck utils.NetCheckResult, wg1, wg2 *sync.WaitGroup, basicInfo, securityInfo, emailInfo, mediaInfo *string, output *string, tempOutput string, startTime time.Time, outputMutex *sync.Mutex) {
|
|
*output = runBasicTests(preCheck, basicInfo, securityInfo, *output, tempOutput, outputMutex)
|
|
*output = runCPUTest(*output, tempOutput, outputMutex)
|
|
*output = runMemoryTest(*output, tempOutput, outputMutex)
|
|
*output = runDiskTest(*output, tempOutput, outputMutex)
|
|
if preCheck.Connected && preCheck.StackType != "" && preCheck.StackType != "None" {
|
|
if utTestStatus {
|
|
wg1.Add(1)
|
|
go func() {
|
|
defer wg1.Done()
|
|
*mediaInfo = unlocktest.MediaTest(language)
|
|
}()
|
|
}
|
|
if emailTestStatus {
|
|
wg2.Add(1)
|
|
go func() {
|
|
defer wg2.Done()
|
|
*emailInfo = email.EmailCheck()
|
|
}()
|
|
}
|
|
*output = runStreamingTests(wg1, mediaInfo, *output, tempOutput, outputMutex)
|
|
*output = runSecurityTests(*securityInfo, *output, tempOutput, outputMutex)
|
|
*output = runEmailTests(wg2, emailInfo, *output, tempOutput, outputMutex)
|
|
*output = runEnglishSpeedTests(*output, tempOutput, outputMutex)
|
|
}
|
|
*output = appendTimeInfo(*output, tempOutput, startTime, outputMutex)
|
|
}
|
|
|
|
func runBasicTests(preCheck utils.NetCheckResult, basicInfo, securityInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
utils.PrintHead(language, width, ecsVersion)
|
|
if basicStatus || securityTestStatus {
|
|
if basicStatus {
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle("系统基础信息", width)
|
|
} else {
|
|
utils.PrintCenteredTitle("System-Basic-Information", width)
|
|
}
|
|
}
|
|
if preCheck.Connected && preCheck.StackType == "DualStack" {
|
|
*basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, nt3CheckType, securityTestStatus)
|
|
} else if preCheck.Connected && preCheck.StackType == "IPv4" {
|
|
*basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "ipv4", securityTestStatus)
|
|
} else if preCheck.Connected && preCheck.StackType == "IPv6" {
|
|
*basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "ipv6", securityTestStatus)
|
|
} else {
|
|
*basicInfo, *securityInfo, nt3CheckType = utils.BasicsAndSecurityCheck(language, "", false)
|
|
securityTestStatus = false
|
|
}
|
|
if basicStatus {
|
|
fmt.Printf("%s", *basicInfo)
|
|
} else if (input == "6" || input == "9") && securityTestStatus {
|
|
scanner := bufio.NewScanner(strings.NewReader(*basicInfo))
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.Contains(line, "IPV") {
|
|
fmt.Println(line)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runCPUTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if cpuTestStatus {
|
|
realTestMethod, res := cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", realTestMethod), width)
|
|
} else {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("CPU-Test--%s-Method", realTestMethod), width)
|
|
}
|
|
fmt.Print(res)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runMemoryTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if memoryTestStatus {
|
|
realTestMethod, res := memorytest.MemoryTest(language, memoryTestMethod)
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", realTestMethod), width)
|
|
} else {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("Memory-Test--%s-Method", realTestMethod), width)
|
|
}
|
|
fmt.Print(res)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runDiskTest(output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if diskTestStatus && autoChangeDiskTestMethod {
|
|
realTestMethod, res := disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", realTestMethod), width)
|
|
} else {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", realTestMethod), width)
|
|
}
|
|
fmt.Print(res)
|
|
} else if diskTestStatus && !autoChangeDiskTestMethod {
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "dd"), width)
|
|
_, res := disktest.DiskTest(language, "dd", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
|
fmt.Print(res)
|
|
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", "fio"), width)
|
|
_, res = disktest.DiskTest(language, "fio", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
|
fmt.Print(res)
|
|
} else {
|
|
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "dd"), width)
|
|
_, res := disktest.DiskTest(language, "dd", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
|
fmt.Print(res)
|
|
utils.PrintCenteredTitle(fmt.Sprintf("Disk-Test--%s-Method", "fio"), width)
|
|
_, res = disktest.DiskTest(language, "fio", diskTestPath, diskMultiCheck, autoChangeDiskTestMethod)
|
|
fmt.Print(res)
|
|
}
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runStreamingTests(wg1 *sync.WaitGroup, mediaInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if language == "zh" {
|
|
if commTestStatus && !onlyChinaTest {
|
|
utils.PrintCenteredTitle("御三家流媒体解锁", width)
|
|
fmt.Printf("%s", commediatests.MediaTests(language))
|
|
}
|
|
}
|
|
if utTestStatus && (language == "zh" && !onlyChinaTest || language == "en") {
|
|
wg1.Wait()
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle("跨国流媒体解锁", width)
|
|
} else {
|
|
utils.PrintCenteredTitle("Cross-Border-Streaming-Media-Unlock", width)
|
|
}
|
|
fmt.Printf("%s", *mediaInfo)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runSecurityTests(securityInfo, output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if securityTestStatus {
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle("IP质量检测", width)
|
|
} else {
|
|
utils.PrintCenteredTitle("IP-Quality-Check", width)
|
|
}
|
|
fmt.Printf("%s", securityInfo)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runEmailTests(wg2 *sync.WaitGroup, emailInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if emailTestStatus {
|
|
wg2.Wait()
|
|
if language == "zh" {
|
|
utils.PrintCenteredTitle("邮件端口检测", width)
|
|
} else {
|
|
utils.PrintCenteredTitle("Email-Port-Check", width)
|
|
}
|
|
fmt.Println(*emailInfo)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runNetworkTests(wg3 *sync.WaitGroup, ptInfo *string, output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
output = utils.PrintAndCapture(func() {
|
|
if backtraceStatus && !onlyChinaTest {
|
|
utils.PrintCenteredTitle("三网回程线路检测", width)
|
|
if uts.IPV6 {
|
|
backtrace.BackTrace(true)
|
|
} else {
|
|
backtrace.BackTrace(false)
|
|
}
|
|
}
|
|
}, tempOutput, output)
|
|
output = utils.PrintAndCapture(func() {
|
|
if nt3Status && !onlyChinaTest {
|
|
utils.PrintCenteredTitle("三网回程路由检测", width)
|
|
nt.TraceRoute(language, nt3Location, nt3CheckType)
|
|
}
|
|
}, tempOutput, output)
|
|
return utils.PrintAndCapture(func() {
|
|
if onlyChinaTest || pingTestStatus {
|
|
wg3.Wait()
|
|
utils.PrintCenteredTitle("三网ICMP的PING值检测", width)
|
|
fmt.Println(*ptInfo)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if speedTestStatus {
|
|
utils.PrintCenteredTitle("就近节点测速", width)
|
|
speedtest.ShowHead(language)
|
|
if choice == "1" || !menuMode {
|
|
speedtest.NearbySP()
|
|
speedtest.CustomSP("net", "global", 2, language)
|
|
speedtest.CustomSP("net", "cu", spNum, language)
|
|
speedtest.CustomSP("net", "ct", spNum, language)
|
|
speedtest.CustomSP("net", "cmcc", spNum, language)
|
|
} else if choice == "2" || choice == "3" || choice == "4" || choice == "5" {
|
|
speedtest.CustomSP("net", "global", 4, language)
|
|
} else if choice == "6" {
|
|
speedtest.CustomSP("net", "global", 11, language)
|
|
}
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func runEnglishSpeedTests(output, tempOutput string, outputMutex *sync.Mutex) string {
|
|
outputMutex.Lock()
|
|
defer outputMutex.Unlock()
|
|
return utils.PrintAndCapture(func() {
|
|
if speedTestStatus {
|
|
utils.PrintCenteredTitle("Speed-Test", width)
|
|
speedtest.ShowHead(language)
|
|
speedtest.NearbySP()
|
|
speedtest.CustomSP("net", "global", -1, language)
|
|
}
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func appendTimeInfo(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("", width)
|
|
if 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("", width)
|
|
}, tempOutput, output)
|
|
}
|
|
|
|
func handleUploadResults(output string) {
|
|
httpURL, httpsURL := utils.ProcessAndUpload(output, filePath, enabelUpload)
|
|
if httpURL != "" || httpsURL != "" {
|
|
if language == "en" {
|
|
fmt.Printf("Upload successfully!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
|
} else {
|
|
fmt.Printf("上传成功!\nHttp URL: %s\nHttps URL: %s\n", httpURL, httpsURL)
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
parseFlags()
|
|
if handleHelpAndVersion() {
|
|
return
|
|
}
|
|
initLogger()
|
|
go func() {
|
|
http.Get("https://hits.spiritlhl.net/goecs.svg?action=hit&title=Hits&title_bg=%23555555&count_bg=%230eecf8&edge_flat=false")
|
|
}()
|
|
preCheck := utils.CheckPublicAccess(3 * time.Second)
|
|
if menuMode {
|
|
handleMenuMode(preCheck)
|
|
}
|
|
handleLanguageSpecificSettings()
|
|
if !preCheck.Connected {
|
|
enabelUpload = false
|
|
}
|
|
var (
|
|
wg1, wg2, wg3 sync.WaitGroup
|
|
basicInfo, securityInfo, emailInfo, mediaInfo, ptInfo string
|
|
output, tempOutput string
|
|
outputMutex sync.Mutex
|
|
)
|
|
startTime := time.Now()
|
|
uploadDone := make(chan bool, 1)
|
|
sig := make(chan os.Signal, 1)
|
|
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
|
|
go handleSignalInterrupt(sig, &startTime, &output, tempOutput, uploadDone, &outputMutex)
|
|
switch language {
|
|
case "zh":
|
|
runChineseTests(preCheck, &wg1, &wg2, &wg3, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &ptInfo, &output, tempOutput, startTime, &outputMutex)
|
|
case "en":
|
|
runEnglishTests(preCheck, &wg1, &wg2, &basicInfo, &securityInfo, &emailInfo, &mediaInfo, &output, tempOutput, startTime, &outputMutex)
|
|
default:
|
|
fmt.Println("Unsupported language")
|
|
}
|
|
if preCheck.Connected {
|
|
handleUploadResults(output)
|
|
}
|
|
finish = true
|
|
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
|
fmt.Println("Press Enter to exit...")
|
|
fmt.Scanln()
|
|
}
|
|
}
|