Add url speed test for outbound (#3767)

* add outbound testing functionality with configurable test URL

* use no kernel tun for conflict errors
This commit is contained in:
surbiks
2026-02-10 00:13:17 +03:30
committed by GitHub
parent 4a455aa532
commit 4779939424
22 changed files with 746 additions and 102 deletions

View File

@@ -110,6 +110,15 @@ func NewProcess(xrayConfig *Config) *Process {
return p
}
// NewTestProcess creates a new Xray process that uses a specific config file path.
// Used for test runs (e.g. outbound test) so the main config.json is not overwritten.
// The config file at configPath is removed when the process is stopped.
func NewTestProcess(xrayConfig *Config, configPath string) *Process {
p := &Process{newTestProcess(xrayConfig, configPath)}
runtime.SetFinalizer(p, stopProcess)
return p
}
type process struct {
cmd *exec.Cmd
@@ -118,10 +127,11 @@ type process struct {
onlineClients []string
config *Config
logWriter *LogWriter
exitErr error
startTime time.Time
config *Config
configPath string // if set, use this path instead of GetConfigPath() and remove on Stop
logWriter *LogWriter
exitErr error
startTime time.Time
}
// newProcess creates a new internal process struct for Xray.
@@ -134,6 +144,13 @@ func newProcess(config *Config) *process {
}
}
// newTestProcess creates a process that writes and runs with a specific config path.
func newTestProcess(config *Config, configPath string) *process {
p := newProcess(config)
p.configPath = configPath
return p
}
// IsRunning returns true if the Xray process is currently running.
func (p *process) IsRunning() bool {
if p.cmd == nil || p.cmd.Process == nil {
@@ -238,6 +255,9 @@ func (p *process) Start() (err error) {
}
configPath := GetConfigPath()
if p.configPath != "" {
configPath = p.configPath
}
err = os.WriteFile(configPath, data, fs.ModePerm)
if err != nil {
return common.NewErrorf("Failed to write configuration file: %v", err)
@@ -278,6 +298,16 @@ func (p *process) Stop() error {
return errors.New("xray is not running")
}
// Remove temporary config file used for test runs so main config is never touched
if p.configPath != "" {
if p.configPath != GetConfigPath() {
// Check if file exists before removing
if _, err := os.Stat(p.configPath); err == nil {
_ = os.Remove(p.configPath)
}
}
}
if runtime.GOOS == "windows" {
return p.cmd.Process.Kill()
} else {