Files
oci-portal/internal/service/scopecache_test.go
T

230 lines
7.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"context"
"testing"
"oci-portal/internal/model"
"oci-portal/internal/oci"
)
func multiScopeClient() *fakeClient {
return &fakeClient{
tenancy: oci.TenancyInfo{Name: "t", HomeRegionKey: "FRA"},
regionSubs: []oci.RegionSubscription{
{Key: "FRA", Name: "eu-frankfurt-1", Status: "READY", IsHomeRegion: true},
{Key: "AMS", Name: "eu-amsterdam-1", Status: "READY"},
},
compartments: []oci.Compartment{
{ID: "ocid1.compartment..a", Name: "instances", ParentID: "ocid1.tenancy..root", LifecycleState: "ACTIVE"},
},
}
}
func importMultiConfig(t *testing.T, svc *OciConfigService) *model.OciConfig {
t.Helper()
in := trialImportInput()
in.MultiRegion = true
in.MultiCompartment = true
cfg, err := svc.Import(context.Background(), in)
if err != nil {
t.Fatalf("Import: %v", err)
}
return cfg
}
func TestImportSyncsScopeCaches(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importMultiConfig(t, svc)
if !cfg.MultiRegion || !cfg.MultiCompartment {
t.Fatalf("cfg switches = %v/%v, want true/true", cfg.MultiRegion, cfg.MultiCompartment)
}
var regions []model.RegionCache
svc.db.Where("oci_config_id = ?", cfg.ID).Find(&regions)
if len(regions) != 2 {
t.Errorf("region cache rows = %d, want 2", len(regions))
}
var comps []model.CompartmentCache
svc.db.Where("oci_config_id = ?", cfg.ID).Find(&comps)
if len(comps) != 1 || comps[0].OCID != "ocid1.compartment..a" {
t.Errorf("compartment cache = %+v, want 1 row ocid1.compartment..a", comps)
}
}
func TestImportWithoutSwitchesSkipsCaches(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importAliveConfig(t, svc)
var count int64
svc.db.Model(&model.RegionCache{}).Where("oci_config_id = ?", cfg.ID).Count(&count)
if count != 0 {
t.Errorf("region cache rows = %d, want 0(未开启不入库)", count)
}
}
func TestCachedRegions(t *testing.T) {
tests := []struct {
name string
prepare func(svc *OciConfigService, cfg *model.OciConfig, client *fakeClient)
wantNames []string
wantCalls int // 缓存读取阶段期望的 SDK 调用次数
}{
{
name: "全 READY 直接用缓存",
prepare: func(*OciConfigService, *model.OciConfig, *fakeClient) {},
wantNames: []string{"eu-frankfurt-1", "eu-amsterdam-1"},
wantCalls: 0,
},
{
name: "存在非 READY 强制实时刷新",
prepare: func(svc *OciConfigService, cfg *model.OciConfig, client *fakeClient) {
svc.db.Model(&model.RegionCache{}).
Where("oci_config_id = ? AND key = ?", cfg.ID, "AMS").
Update("status", "IN_PROGRESS")
client.regionSubs[1].Status = "READY" // SDK 已完成
},
wantNames: []string{"eu-frankfurt-1", "eu-amsterdam-1"},
wantCalls: 1,
},
{
name: "缓存为空实时拉取入库",
prepare: func(svc *OciConfigService, cfg *model.OciConfig, client *fakeClient) {
svc.db.Where("oci_config_id = ?", cfg.ID).Delete(&model.RegionCache{})
},
wantNames: []string{"eu-frankfurt-1", "eu-amsterdam-1"},
wantCalls: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importMultiConfig(t, svc)
tt.prepare(svc, cfg, client)
client.regionSubsCalls = 0
views, err := svc.CachedRegions(context.Background(), cfg.ID)
if err != nil {
t.Fatalf("CachedRegions: %v", err)
}
got := make([]string, 0, len(views))
for _, v := range views {
got = append(got, v.Name)
}
if len(got) != len(tt.wantNames) {
t.Fatalf("regions = %v, want %v", got, tt.wantNames)
}
if client.regionSubsCalls != tt.wantCalls {
t.Errorf("SDK calls = %d, want %d", client.regionSubsCalls, tt.wantCalls)
}
})
}
}
func TestCachedRegionsWithoutMultiRegion(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importAliveConfig(t, svc)
client.regionSubsCalls = 0
views, err := svc.CachedRegions(context.Background(), cfg.ID)
if err != nil {
t.Fatalf("CachedRegions: %v", err)
}
if len(views) != 1 || views[0].Name != "eu-frankfurt-1" || !views[0].IsHomeRegion {
t.Errorf("views = %+v, want 仅默认区域且标记主区域", views)
}
if client.regionSubsCalls != 0 {
t.Errorf("SDK calls = %d, want 0(未开启不实时请求)", client.regionSubsCalls)
}
}
func TestCachedCompartments(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
multiCfg := importMultiConfig(t, svc)
comps, err := svc.CachedCompartments(context.Background(), multiCfg.ID)
if err != nil {
t.Fatalf("CachedCompartments: %v", err)
}
if len(comps) != 1 || comps[0].ID != "ocid1.compartment..a" {
t.Errorf("comps = %+v, want 缓存中的 1 项", comps)
}
if comps[0].ParentID != "ocid1.tenancy..root" {
t.Errorf("ParentID = %q, want 缓存透传 parentId", comps[0].ParentID)
}
in := trialImportInput()
in.Alias = "未开启"
plainCfg, err := svc.Import(context.Background(), in)
if err != nil {
t.Fatalf("Import: %v", err)
}
comps, err = svc.CachedCompartments(context.Background(), plainCfg.ID)
if err != nil {
t.Fatalf("CachedCompartments: %v", err)
}
if len(comps) != 0 {
t.Errorf("comps = %+v, want 空(未开启多区间)", comps)
}
}
// TestCachedCompartmentsHealsLegacyRows 旧版缓存(未存 parentId)应实时刷新自愈并回写。
func TestCachedCompartmentsHealsLegacyRows(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importMultiConfig(t, svc)
// 模拟旧版残留:抹掉缓存行的 parentId
if err := svc.db.Model(&model.CompartmentCache{}).Where("oci_config_id = ?", cfg.ID).
Update("ParentOCID", "").Error; err != nil {
t.Fatalf("清空 parentId: %v", err)
}
comps, err := svc.CachedCompartments(context.Background(), cfg.ID)
if err != nil {
t.Fatalf("CachedCompartments: %v", err)
}
if len(comps) != 1 || comps[0].ParentID != "ocid1.tenancy..root" {
t.Errorf("comps = %+v, want 自愈刷新后带 parentId", comps)
}
var rows []model.CompartmentCache
svc.db.Where("oci_config_id = ?", cfg.ID).Find(&rows)
if len(rows) != 1 || rows[0].ParentOCID != "ocid1.tenancy..root" {
t.Errorf("cache rows = %+v, want 缓存已回写 parentId", rows)
}
}
func TestRegionSubscriptionsReconcilesCache(t *testing.T) {
client := multiScopeClient()
svc := newTestService(t, client)
cfg := importMultiConfig(t, svc)
// SDK 侧新订阅一个区域,订阅 Tab 实时读取后缓存应跟进
client.regionSubs = append(client.regionSubs,
oci.RegionSubscription{Key: "ICN", Name: "ap-seoul-1", Status: "IN_PROGRESS"})
if _, err := svc.RegionSubscriptions(context.Background(), cfg.ID); err != nil {
t.Fatalf("RegionSubscriptions: %v", err)
}
var rows []model.RegionCache
svc.db.Where("oci_config_id = ?", cfg.ID).Find(&rows)
if len(rows) != 3 {
t.Fatalf("cache rows = %d, want 3diff 后跟进)", len(rows))
}
// 关闭开关的配置不应回写缓存
off := false
if _, _, err := svc.Update(context.Background(), cfg.ID, UpdateInput{MultiRegion: &off}); err != nil {
t.Fatalf("Update: %v", err)
}
var count int64
svc.db.Model(&model.RegionCache{}).Where("oci_config_id = ?", cfg.ID).Count(&count)
if count != 0 {
t.Errorf("cache rows = %d, want 0(关闭开关清空缓存)", count)
}
}