package starnet import ( "fmt" "net/http" "net/http/httptest" "sync" "sync/atomic" "testing" "time" ) func TestConcurrentRequests(t *testing.T) { var counter int64 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { atomic.AddInt64(&counter, 1) w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) })) defer server.Close() client := NewClientNoErr() concurrency := 100 var wg sync.WaitGroup wg.Add(concurrency) for i := 0; i < concurrency; i++ { go func() { defer wg.Done() resp, err := client.Get(server.URL) if err != nil { t.Errorf("Get() error: %v", err) return } resp.Close() }() } wg.Wait() if atomic.LoadInt64(&counter) != int64(concurrency) { t.Errorf("counter = %v; want %v", counter, concurrency) } } func TestConcurrentClientModification(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer server.Close() client := NewClientNoErr() var wg sync.WaitGroup wg.Add(200) // 100 goroutines reading for i := 0; i < 100; i++ { go func() { defer wg.Done() resp, err := client.Get(server.URL) if err != nil { t.Errorf("Get() error: %v", err) return } resp.Close() }() } // 100 goroutines modifying options for i := 0; i < 100; i++ { go func(i int) { defer wg.Done() if i%2 == 0 { client.AddOptions(WithTimeout(5 * time.Second)) } else { _ = client.RequestOptions() } }(i) } wg.Wait() } func TestConcurrentRequestClone(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer server.Close() baseReq := NewSimpleRequest(server.URL, "GET").SetHeader("X-Base", "value") var wg sync.WaitGroup wg.Add(50) for i := 0; i < 50; i++ { go func(i int) { defer wg.Done() cloned := baseReq.Clone() // 修复:使用有效的 header 值 cloned.SetHeader("X-Index", fmt.Sprintf("%d", i)) resp, err := cloned.Do() if err != nil { t.Errorf("Do() error: %v", err) return } resp.Close() }(i) } wg.Wait() }