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  }