PortRelay:把内网服务临时、可控地开放给同事
边缘网关 + Agent 的端口中继:Agent 主动连出到网关,把内网目标挂到网关端口上; 通过邀请链接按设备授权,可选审批,首次连接起计时,到期、闲置自动收回。 - portrelay-server:边缘网关(端口池、白名单与授权租约、邀请与授权网页) - portrelay-agent:Agent(yamux 隧道、本地 API 与网页面板、流量统计) - mac-native:SwiftUI 菜单栏 App
This commit is contained in:
commit
86e159b3f0
67 files changed
+13888
No files matched your search
@@ -0,0 +1,52 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRateHistoryBucketsAndWindow(t *testing.T) {
|
||||
r := newRateRecorder()
|
||||
base := time.Unix(1_700_000_000, 0).Truncate(rateStep)
|
||||
|
||||
// 同一个 5 秒桶内的多个采样取平均
|
||||
r.record(base, map[string][2]int64{"a": {100, 1000}})
|
||||
r.record(base.Add(1*time.Second), map[string][2]int64{"a": {300, 3000}})
|
||||
// 跳过 3 个桶(中间无数据,应为 0)
|
||||
r.record(base.Add(20*time.Second), map[string][2]int64{"a": {50, 500}})
|
||||
|
||||
s := r.series("a", base.Add(21*time.Second))
|
||||
if len(s.Up) != ratePoints || len(s.Down) != ratePoints || s.Step != 5 {
|
||||
t.Fatalf("series must be fixed length %d with step 5: %d/%d step %d", ratePoints, len(s.Up), len(s.Down), s.Step)
|
||||
}
|
||||
last := ratePoints - 1
|
||||
if s.Up[last] != 50 || s.Down[last] != 500 {
|
||||
t.Fatalf("last point should be the current bucket: %d/%d", s.Up[last], s.Down[last])
|
||||
}
|
||||
if s.Up[last-4] != 200 || s.Down[last-4] != 2000 {
|
||||
t.Fatalf("first bucket should average samples: %d/%d", s.Up[last-4], s.Down[last-4])
|
||||
}
|
||||
for i := last - 3; i < last; i++ {
|
||||
if s.Up[i] != 0 || s.Down[i] != 0 {
|
||||
t.Fatalf("gap bucket %d should be zero: %d/%d", i, s.Up[i], s.Down[i])
|
||||
}
|
||||
}
|
||||
|
||||
// 合计曲线
|
||||
total := r.series(totalSeries, base.Add(21*time.Second))
|
||||
if total.Down[last] != 500 {
|
||||
t.Fatalf("total should sum tunnels: %d", total.Down[last])
|
||||
}
|
||||
|
||||
// 11 分钟后旧数据滑出窗口
|
||||
later := base.Add(11 * time.Minute)
|
||||
if s2 := r.series("a", later); s2.Up[0] != 0 || s2.Down[last] != 0 {
|
||||
t.Fatalf("old data should slide out of the 10 minute window: first=%d last=%d", s2.Up[0], s2.Down[last])
|
||||
}
|
||||
|
||||
// 关闭的通道清除曲线
|
||||
r.retain(map[string]bool{})
|
||||
if s3 := r.series("a", base.Add(21*time.Second)); s3.Down[last] != 0 {
|
||||
t.Fatal("history of a disabled tunnel should be dropped")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user