package controller import ( "errors" "sync/atomic" "testing" "time" "ezops/cloud" ) type countInstancesProvider struct { counts map[string]int failures map[string]bool activeCalls atomic.Int32 maxCalls atomic.Int32 } func (p *countInstancesProvider) Name() string { return "fake" } func (p *countInstancesProvider) ListRegions() ([]cloud.CloudRegion, error) { return nil, nil } func (p *countInstancesProvider) ListInstances(regionID string) ([]cloud.CloudInstance, error) { active := p.activeCalls.Add(1) defer p.activeCalls.Add(-1) for { maximum := p.maxCalls.Load() if active <= maximum || p.maxCalls.CompareAndSwap(maximum, active) { break } } time.Sleep(5 * time.Millisecond) if p.failures[regionID] { return nil, errors.New("区域请求失败") } return make([]cloud.CloudInstance, p.counts[regionID]), nil } func TestCountCloudInstances(t *testing.T) { provider := &countInstancesProvider{ counts: map[string]int{"a": 2, "b": 3, "c": 4, "d": 5, "e": 6}, failures: map[string]bool{"c": true}, } regions := []cloud.CloudRegion{{RegionID: "a"}, {RegionID: "b"}, {RegionID: "c"}, {RegionID: "d"}, {RegionID: "e"}} total, succeeded := countCloudInstances(provider, regions) if total != 16 || succeeded != 4 { t.Fatalf("实例统计错误: total=%d succeeded=%d", total, succeeded) } if maximum := provider.maxCalls.Load(); maximum > 4 { t.Fatalf("并发数超过限制: %d", maximum) } }