mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-01 14:46:36 +08:00
2f60329886
代码质量全量清理,零行为变化:golangci 扩展集 13 类 linter(gosec/modernize/perfsprint/canonicalheader/usestdlibvars/wastedassign/intrange/errorlint/forcetypeassert/recvcheck/exhaustive/unparam)全量修复,测试代码质量(testifylint/thelper/usetesting)25→0,frpc 进程生命周期真 bug(进程组击杀)、全仓 go test -race 6 类数据竞争(含 1 个生产竞争)、SPDX license 头补齐 131 文件、前端测试套件 next-intl 迁移后 44 失败→全绿、过期 swagger 文档重新生成、pnpm-workspace 构建审批。 Experiments: #2-#17, #18, #20, #21, #23 Metric: total_issues 108 → 8 (-92.6%)
154 lines
4.1 KiB
Go
154 lines
4.1 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package state
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestEnsureNodeIDPersists(t *testing.T) {
|
|
store := NewStore(filepath.Join(t.TempDir(), "state.json"))
|
|
nodeID1, err := store.EnsureNodeID()
|
|
if err != nil {
|
|
t.Fatalf("EnsureNodeID failed: %v", err)
|
|
}
|
|
nodeID2, err := store.EnsureNodeID()
|
|
if err != nil {
|
|
t.Fatalf("EnsureNodeID second call failed: %v", err)
|
|
}
|
|
if nodeID1 == "" || nodeID1 != nodeID2 {
|
|
t.Fatal("expected node id to persist across calls")
|
|
}
|
|
}
|
|
|
|
func TestStore_Load_NonExistentFile(t *testing.T) {
|
|
// Loading from a non-existent path should succeed and return an empty Snapshot
|
|
tempFile := filepath.Join(t.TempDir(), "nonexistent.json")
|
|
store := NewStore(tempFile)
|
|
|
|
snap, err := store.Load()
|
|
if err != nil {
|
|
t.Fatalf("expected Load to succeed for non-existent file, got err: %v", err)
|
|
}
|
|
if snap == nil {
|
|
t.Fatal("expected non-nil snapshot")
|
|
}
|
|
if snap.NodeID != "" || snap.CurrentVersion != "" {
|
|
t.Errorf("expected empty snapshot, got: %+v", snap)
|
|
}
|
|
}
|
|
|
|
func TestStore_Load_EmptyFile(t *testing.T) {
|
|
// Loading from an empty file should succeed and return an empty Snapshot
|
|
tempFile := filepath.Join(t.TempDir(), "empty.json")
|
|
if err := os.WriteFile(tempFile, []byte(""), 0644); err != nil {
|
|
t.Fatalf("failed to create empty file: %v", err)
|
|
}
|
|
|
|
store := NewStore(tempFile)
|
|
snap, err := store.Load()
|
|
if err != nil {
|
|
t.Fatalf("expected Load to succeed for empty file, got err: %v", err)
|
|
}
|
|
if snap == nil {
|
|
t.Fatal("expected non-nil snapshot")
|
|
}
|
|
if snap.NodeID != "" {
|
|
t.Errorf("expected empty snapshot, got: %+v", snap)
|
|
}
|
|
}
|
|
|
|
func TestStore_Load_InvalidJSON(t *testing.T) {
|
|
// Loading from a corrupted file with invalid JSON should fail with parsing error
|
|
tempFile := filepath.Join(t.TempDir(), "corrupted.json")
|
|
if err := os.WriteFile(tempFile, []byte("{invalid-json"), 0644); err != nil {
|
|
t.Fatalf("failed to create corrupted file: %v", err)
|
|
}
|
|
|
|
store := NewStore(tempFile)
|
|
_, err := store.Load()
|
|
if err == nil {
|
|
t.Fatal("expected Load to fail for corrupted JSON file")
|
|
}
|
|
}
|
|
|
|
func TestStore_SaveAndLoad(t *testing.T) {
|
|
tempFile := filepath.Join(t.TempDir(), "state.json")
|
|
store := NewStore(tempFile)
|
|
|
|
original := &Snapshot{
|
|
NodeID: "node-test-123",
|
|
CurrentVersion: "20260531-001",
|
|
CurrentChecksum: "chk-active-xyz",
|
|
BlockedVersion: "20260531-002",
|
|
BlockedChecksum: "chk-blocked-abc",
|
|
BlockedReason: "invalid upstream domain name",
|
|
LastError: "configuration reload timeout",
|
|
OpenrestyStatus: "unhealthy",
|
|
}
|
|
|
|
if err := store.Save(original); err != nil {
|
|
t.Fatalf("expected Save to succeed, got: %v", err)
|
|
}
|
|
|
|
loaded, err := store.Load()
|
|
if err != nil {
|
|
t.Fatalf("expected Load to succeed, got: %v", err)
|
|
}
|
|
|
|
if loaded.NodeID != original.NodeID ||
|
|
loaded.CurrentVersion != original.CurrentVersion ||
|
|
loaded.CurrentChecksum != original.CurrentChecksum ||
|
|
loaded.BlockedVersion != original.BlockedVersion ||
|
|
loaded.BlockedChecksum != original.BlockedChecksum ||
|
|
loaded.BlockedReason != original.BlockedReason ||
|
|
loaded.LastError != original.LastError ||
|
|
loaded.OpenrestyStatus != original.OpenrestyStatus {
|
|
t.Errorf("loaded snapshot does not match original: %+v vs %+v", loaded, original)
|
|
}
|
|
}
|
|
|
|
func TestStore_ConcurrencySafety(t *testing.T) {
|
|
tempFile := filepath.Join(t.TempDir(), "state.json")
|
|
store := NewStore(tempFile)
|
|
|
|
var wg sync.WaitGroup
|
|
workers := 20
|
|
iterations := 50
|
|
|
|
// Run concurrent writers and readers
|
|
for i := 0; i < workers; i++ {
|
|
wg.Add(1)
|
|
go func(workerID int) {
|
|
defer wg.Done()
|
|
for j := 0; j < iterations; j++ {
|
|
// Concurrently save
|
|
snap := &Snapshot{
|
|
NodeID: fmt.Sprintf("node-%d", workerID),
|
|
CurrentVersion: fmt.Sprintf("v-%d", j),
|
|
}
|
|
if err := store.Save(snap); err != nil {
|
|
t.Errorf("Save failed under concurrency: %v", err)
|
|
}
|
|
|
|
// Concurrently load
|
|
if _, err := store.Load(); err != nil {
|
|
t.Errorf("Load failed under concurrency: %v", err)
|
|
}
|
|
|
|
// Concurrently ensure ID
|
|
if _, err := store.EnsureNodeID(); err != nil {
|
|
t.Errorf("EnsureNodeID failed under concurrency: %v", err)
|
|
}
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|