github.com/chainreactors/fingers@v1.2.1/xray/concurrent_race_test.go (about) 1 package xray 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "sync" 7 "testing" 8 ) 9 10 // TestHTTPActiveMatchConcurrentRace exercises HTTPActiveMatch from many 11 // goroutines that share a single engine (the way the SDK drives active 12 // probing across concurrent targets). HTTPActiveMatch mutates shared 13 // template state (req.SetHTTPClient on tmpl.RequestsHTTP) and runs the same 14 // tmpl.Execute concurrently, so this is expected to trip the race detector 15 // and/or a "concurrent map writes" fatal — which recover() cannot catch. 16 func TestHTTPActiveMatchConcurrentRace(t *testing.T) { 17 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 18 w.Header().Set("Server", "nginx") 19 w.WriteHeader(http.StatusOK) 20 _, _ = w.Write([]byte("<center>nginx</center> Welcome to nginx!")) 21 })) 22 defer srv.Close() 23 24 engine, err := NewXrayEngine(nil) 25 if err != nil { 26 t.Fatalf("new engine: %v", err) 27 } 28 tmplJSON := []byte(`[{"id":"f5-nginx","info":{"name":"Nginx","severity":"info"},` + 29 `"http":[{"method":"GET","path":["{{BaseURL}}/"],` + 30 `"matchers":[{"type":"word","words":["nginx"]}]}]}]`) 31 if err := engine.LoadFromJSON(tmplJSON); err != nil { 32 t.Fatalf("load template: %v", err) 33 } 34 if engine.Len() == 0 { 35 t.Fatalf("no templates loaded; cannot exercise active match") 36 } 37 38 transport := &http.Transport{DisableKeepAlives: true} 39 const workers = 50 40 var wg sync.WaitGroup 41 for i := 0; i < workers; i++ { 42 wg.Add(1) 43 go func() { 44 defer wg.Done() 45 engine.HTTPActiveMatch(srv.URL, 1, transport, nil) 46 }() 47 } 48 wg.Wait() 49 }