ECS
ECS is the Go-based benchmark and diagnostics suite from the oneclickvirt project.
Repository: https://github.com/oneclickvirt/ecs
Issue tracker: https://github.com/oneclickvirt/ecs/issues
Shell edition: https://github.com/spiritLHLS/ecs/blob/main/README_EN.md
Overview
- Collects system and network basics through basics and gostun
- Runs CPU, memory, and disk tests through cputest, memorytest, and disktest
- Checks media unlock status with UnlockTests
- Queries IP quality and security details through securityCheck
- Tests mail ports with portchecker
- Runs route and network tests through backtrace, nt3, speedtest, and pingtest
speedtest v0.0.25pinsshowwin/speedtest-go v1.8.2; its user-configuration request uses a per-request cache-bypass query value so a shared CDN cannot return another client's configuration- Supports root/admin environments, non-root/non-admin environments, and offline execution
- Supports online execution when local DNS is confirmed unavailable through a process-local DoH/DoT fallback; transient network failures preserve system DNS and no resolver files are rewritten
First-time users should read the upstream getting-started guide first:
https://github.com/oneclickvirt/ecs/blob/master/README_NEW_USER.md
Online Without Local DNS
The default -dns-mode=auto preserves system DNS unless independent probes confirm that the local resolver is unavailable. A successful answer or NXDOMAIN proves system DNS responded; timeouts, SERVFAIL, packet loss, and transient network errors are inconclusive and do not switch resolvers.
After confirmed local DNS failure, ECS validates real TLS DNS queries through fixed addresses for its embedded public upstream catalog and selects the lowest-latency non-filtering DoH or DoT service. Fixed addresses bootstrap only the upstream endpoint; normal test hostnames still resolve dynamically through the selected service.
-dns-mode=auto: default; automatically selects the fastest validated DoH or DoT endpoint only after confirmed local DNS failure.-dns-mode=system: system DNS only. The existing Android/Termux resolver-file repair remains limited to this mode.-dns-mode=doh: force built-in DoH.-dns-mode=dot: force built-in DoT.
The fallback is process-local and never edits /etc/resolv.conf or /etc/hosts. -ut-dns remains the streaming-unlock module's separate explicit DNS override and is never replaced; leave it empty for that module to inherit the process resolver. The endpoint catalog is embedded by basics v0.0.34: a candidate enters it only after fixed-address TLS and real DNS-message validation, never merely because it appears on a public list. Release-tag and scheduled CI runs refresh, validate, and synchronize the catalog.
Before the installer script is downloaded, program-local fallback is not available. On an online host without local DNS, use a DoH-capable curl build (for example curl 7.62+) to bootstrap the script:
export noninteractive=true && curl --doh-url https://cloudflare-dns.com/dns-query --resolve cloudflare-dns.com:443:1.1.1.1,1.0.0.1 -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs -l enOnce downloaded, goecs.sh and standalone ipcheck.sh still make each network request normally first. They use the embedded, fixed-address DoH bootstrap only when curl explicitly reports Could not resolve host; then they probe the catalog with real DNS messages and cache the lowest-latency usable upstream for that run. Timeouts, TLS/HTTP/CDN/proxy errors, packet loss, and similar transient failures are not treated as missing DNS and keep their original failure behavior.
Supported Systems And Architectures
| Supported for Compilation | Tested on | Supported OS for Compilation | Tested OS |
|---|---|---|---|
| amd64 | amd64 | Linux | Linux |
| arm64 | arm64 | Windows | Windows |
| arm | macOS (Darwin) | macOS | |
| 386 | FreeBSD | ||
| mips, mipsle | Android | ||
| mips64, mips64le | |||
| ppc64, ppc64le | |||
| s390x | s390x | ||
| riscv64 |
Systems still pending support:
| OS | Notes |
|---|---|
| OpenBSD / NetBSD | Some official Golang libraries are still unsupported there, especially network-related ones. |
Quick Start
The one-line installer below defaults to:
- no dependency installation
- no package manager update
- non-interactive mode
export noninteractive=true && curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs -l enShort link:
export noninteractive=true && curl -L https://bash.spiritlhl.net/goecs -o goecs.sh && chmod +x goecs.sh && ./goecs.sh install && goecs -l enStep-By-Step Usage
- Download the installer script:
curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh- Optionally install dependencies and prepare the environment:
./goecs.sh envNon-interactive mode:
export noninteractive=true && ./goecs.sh env- Install the
goecsbinary:
./goecs.sh install- Upgrade
goecs:
./goecs.sh upgrade- Uninstall
goecs:
./goecs.sh uninstall- Show installer help:
./goecs.sh -h- Launch the menu directly:
goecs -l enCommon Runtime Flags
Use goecs -h to view the full parameter list. The most commonly used options are:
-menu=false: run without the interactive menu-l enor-l zh: set the interface language-cpu-method sysbench|geekbench|winsat: choose the CPU test backend-cpu-thread single|multi: switch between single-core and multi-core CPU tests-memory-method stream|sysbench|dd|winsat|auto: choose the memory test method-disk-method fio|dd|winsat: choose the disk test method-diskp /path/to/test: choose the disk test path-speed=false,-security=false,-ut=false: disable individual modules when needed-spnum 2: set the number of speed test servers per carrier-upload=false: do not upload the share result-dns-mode=auto|system|doh|dot: select conservative automatic fallback, system DNS only, forced DoH, or forced DoT
Windows
- Download the release archive that contains the
.exebinary: Releases - Extract it, then run it as Administrator.
Notes:
- In virtual machines, running without Administrator privileges is often still acceptable because ECS will fall back to substitute test methods when native tools are unavailable.
- Avoid the builds labeled with
GUIfor now. The standard CI release archives are the stable choice.
Docker
Docker image: https://hub.docker.com/r/spiritlhl/goecs
Make sure Docker is already installed before running the examples below.
Privileged mode with host networking:
docker run --rm --privileged --network host spiritlhl/goecs:latest -menu=false -l=enUnprivileged mode without host networking:
docker run --rm spiritlhl/goecs:latest -menu=false -l=enDocker-based runs are convenient, but hardware-related results and virtualization detection can be less accurate. Direct execution on the host remains the recommended approach.
Build From Source
- Clone the public branch:
git clone -b public https://github.com/oneclickvirt/ecs.git
cd ecs2
Install Go 1.25.4 or newer.
Build the binary:
go build -o goecs- Run a non-interactive English test:
./goecs -menu=false -l=enSupported compile targets:
GOOS:linux,windows,darwin,freebsd,openbsdGOARCH:amd64,arm,arm64,386,mips,mipsle,s390x,riscv64
Cross-compile examples:
GOOS=windows GOARCH=amd64 go build -o goecs.exe
GOOS=darwin GOARCH=amd64 go build -o goecs_darwin2
FAQ
Why does ECS use sysbench by default instead of geekbench?
sysbench is lighter, more stable across environments, and easier to compare historically. geekbench is still supported, but it requires a heavier online environment and its scores vary more across major versions.
Why was the project rewritten in Golang instead of Rust?
Most upstream tooling and surrounding ecosystem components are already maintained in Golang, so it is the more practical choice for this project.
Why not continue with the Shell edition only?
Prebuilt binaries are much easier to run across inconsistent environments. That reduces environment-specific failures and makes the tool easier to distribute.
Are there explanations for every individual test item?
Yes. Each test module has its own upstream repository. Follow the component links in the overview section for implementation details and project-specific notes.
How do I stop a running test?
Press Ctrl+C. ECS will still keep the already collected results in the current directory and retain the generated share link information.
How can I use ECS in a non-root environment?
Try the manual installation flow first. If dependency installation is not possible, download the matching release archive, extract it, and run the binary directly. Docker is another fallback when it is available.
Notes
- The upstream repository remains the source of truth for the latest release assets and low-level usage details: https://github.com/oneclickvirt/ecs
- The shell implementation remains available separately: https://github.com/spiritLHLS/ecs
