Merge feat/singbox-b5 (test contract update)
CI / go-test (push) Waiting to run
CI / postgres-durable-first (push) Waiting to run
CI / codegen (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / race (push) Waiting to run
CI / fuzz-smoke (push) Waiting to run
CI / golangci (push) Waiting to run
CI / frontend (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (amd64) (push) Waiting to run
Release 3X-UI / Publish rolling dev release (push) Blocked by required conditions
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CI / go-test (push) Waiting to run
CI / postgres-durable-first (push) Waiting to run
CI / codegen (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / race (push) Waiting to run
CI / fuzz-smoke (push) Waiting to run
CI / golangci (push) Waiting to run
CI / frontend (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (amd64) (push) Waiting to run
Release 3X-UI / Publish rolling dev release (push) Blocked by required conditions
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
This commit is contained in:
@@ -14,9 +14,13 @@ import (
|
|||||||
// UpdateAllSetting under the settings.trafficStatsSwitches key) is the
|
// UpdateAllSetting under the settings.trafficStatsSwitches key) is the
|
||||||
// same value the sing-box generator consumes
|
// same value the sing-box generator consumes
|
||||||
// (SingboxService.GetTrafficStatsSwitches), and the generated agent
|
// (SingboxService.GetTrafficStatsSwitches), and the generated agent
|
||||||
// config's experimental/v2ray_api stats block follows the B2 category
|
// config carries an experimental/v2ray_api stats block whenever at
|
||||||
// gates (a category appears only when both of its direction switches
|
// least one category gate is on (both direction switches; all four
|
||||||
// are on; all four off → no experimental block at all).
|
// off → no experimental block at all). Since the ITEM6 B5 fix, the
|
||||||
|
// block always lists inbounds, users and outbounds together — the
|
||||||
|
// core registers no counters otherwise — and the per-category
|
||||||
|
// counting policy is enforced by the master at recording time, not
|
||||||
|
// by omission here.
|
||||||
func TestTrafficStatsSwitchesPlumbing(t *testing.T) {
|
func TestTrafficStatsSwitchesPlumbing(t *testing.T) {
|
||||||
dbDir := t.TempDir()
|
dbDir := t.TempDir()
|
||||||
if err := database.InitDB(filepath.Join(dbDir, "x-ui.db")); err != nil {
|
if err := database.InitDB(filepath.Join(dbDir, "x-ui.db")); err != nil {
|
||||||
@@ -82,8 +86,8 @@ func TestTrafficStatsSwitchesPlumbing(t *testing.T) {
|
|||||||
}
|
}
|
||||||
if stats := statsOf(gen()); stats == nil || stats["inbounds"] == nil {
|
if stats := statsOf(gen()); stats == nil || stats["inbounds"] == nil {
|
||||||
t.Errorf("default: stats.inbounds missing")
|
t.Errorf("default: stats.inbounds missing")
|
||||||
} else if _, ok := stats["outbounds"]; ok {
|
} else if _, ok := stats["outbounds"]; !ok {
|
||||||
t.Errorf("default: stats.outbounds generated although outbound switches are off")
|
t.Errorf("default: stats.outbounds must accompany the block (core registers no counters without all three lists)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// All four off: read path returns the saved string verbatim, the
|
// All four off: read path returns the saved string verbatim, the
|
||||||
@@ -105,16 +109,17 @@ func TestTrafficStatsSwitchesPlumbing(t *testing.T) {
|
|||||||
t.Errorf("all-off: experimental block generated anyway: %v", cfg["experimental"])
|
t.Errorf("all-off: experimental block generated anyway: %v", cfg["experimental"])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inbound half-on (uplink only) closes the inbound category;
|
// Inbound half-on (uplink only) closes the inbound category gate;
|
||||||
// outbound both-on opens the outbound category.
|
// outbound both-on opens its gate. Either gate on → the block is
|
||||||
|
// generated with all three lists (registration requirement).
|
||||||
mixed := `{"inboundUplink":true,"inboundDownlink":false,"outboundUplink":true,"outboundDownlink":true}`
|
mixed := `{"inboundUplink":true,"inboundDownlink":false,"outboundUplink":true,"outboundDownlink":true}`
|
||||||
save(mixed)
|
save(mixed)
|
||||||
stats := statsOf(gen())
|
stats := statsOf(gen())
|
||||||
if stats == nil {
|
if stats == nil {
|
||||||
t.Fatalf("mixed: no stats block although outbound category is on")
|
t.Fatalf("mixed: no stats block although outbound category is on")
|
||||||
}
|
}
|
||||||
if _, ok := stats["inbounds"]; ok {
|
if _, ok := stats["inbounds"]; !ok {
|
||||||
t.Errorf("mixed: inbound half-on still generated stats.inbounds")
|
t.Errorf("mixed: stats.inbounds must accompany the block (registration requirement; recording gate enforces the policy)")
|
||||||
}
|
}
|
||||||
if _, ok := stats["outbounds"]; !ok {
|
if _, ok := stats["outbounds"]; !ok {
|
||||||
t.Errorf("mixed: outbound both-on did not generate stats.outbounds")
|
t.Errorf("mixed: outbound both-on did not generate stats.outbounds")
|
||||||
|
|||||||
Reference in New Issue
Block a user