mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
test with race detector (#852)
* middleware tests * test with race detector
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@ dist: focal
|
||||
language: go
|
||||
go: 1.14
|
||||
|
||||
script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.14)' && go test ./... -v -timeout 120s"
|
||||
script: sudo -E bash -c "source /etc/profile && eval '$(gimme 1.14)' && go test ./... -v -timeout 120s -race"
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install libpcap-dev -y
|
||||
|
||||
+179
-178
@@ -1,225 +1,226 @@
|
||||
package main
|
||||
|
||||
// import (
|
||||
// "bytes"
|
||||
// "crypto/rand"
|
||||
// "encoding/hex"
|
||||
// "io"
|
||||
// "net/http"
|
||||
// "net/http/httptest"
|
||||
// "strings"
|
||||
// "sync"
|
||||
// "testing"
|
||||
// "time"
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
// "github.com/buger/goreplay/capture"
|
||||
// "github.com/buger/goreplay/proto"
|
||||
// )
|
||||
"github.com/buger/goreplay/capture"
|
||||
"github.com/buger/goreplay/proto"
|
||||
)
|
||||
|
||||
// type fakeServiceCb func(string, int, []byte)
|
||||
type fakeServiceCb func(string, int, []byte)
|
||||
|
||||
// // Simple service that generate token on request, and require this token for accesing to secure area
|
||||
// func NewFakeSecureService(wg *sync.WaitGroup, cb fakeServiceCb) *httptest.Server {
|
||||
// active_tokens := make([]string, 0)
|
||||
// var mu sync.Mutex
|
||||
// Simple service that generate token on request, and require this token for accesing to secure area
|
||||
func NewFakeSecureService(wg *sync.WaitGroup, cb fakeServiceCb) *httptest.Server {
|
||||
activeTokens := make([]string, 0)
|
||||
var mu sync.Mutex
|
||||
|
||||
// server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// mu.Lock()
|
||||
// defer mu.Unlock()
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
// switch req.URL.Path {
|
||||
// case "/token":
|
||||
// // Generate random token
|
||||
// token_length := 10
|
||||
// buf := make([]byte, token_length)
|
||||
// rand.Read(buf)
|
||||
// token := hex.EncodeToString(buf)
|
||||
// active_tokens = append(active_tokens, token)
|
||||
switch req.URL.Path {
|
||||
case "/token":
|
||||
// Generate random token
|
||||
tokenLength := 10
|
||||
buf := make([]byte, tokenLength)
|
||||
rand.Read(buf)
|
||||
token := hex.EncodeToString(buf)
|
||||
activeTokens = append(activeTokens, token)
|
||||
|
||||
// w.Write([]byte(token))
|
||||
w.Write([]byte(token))
|
||||
|
||||
// cb(req.URL.Path, 200, []byte(token))
|
||||
// case "/secure":
|
||||
// token := req.URL.Query().Get("token")
|
||||
// token_found := false
|
||||
cb(req.URL.Path, 200, []byte(token))
|
||||
case "/secure":
|
||||
token := req.URL.Query().Get("token")
|
||||
tokenFound := false
|
||||
|
||||
// for _, t := range active_tokens {
|
||||
// if t == token {
|
||||
// token_found = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
for _, t := range activeTokens {
|
||||
if t == token {
|
||||
tokenFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// if token_found {
|
||||
// w.WriteHeader(http.StatusAccepted)
|
||||
// cb(req.URL.Path, 202, []byte(nil))
|
||||
// } else {
|
||||
// w.WriteHeader(http.StatusForbidden)
|
||||
// cb(req.URL.Path, 403, []byte(nil))
|
||||
// }
|
||||
// }
|
||||
if tokenFound {
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
cb(req.URL.Path, 202, nil)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
cb(req.URL.Path, 403, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// wg.Done()
|
||||
// }))
|
||||
wg.Done()
|
||||
}))
|
||||
|
||||
// return server
|
||||
// }
|
||||
return server
|
||||
}
|
||||
|
||||
// func TestFakeSecureService(t *testing.T) {
|
||||
// var resp, token []byte
|
||||
func TestFakeSecureService(t *testing.T) {
|
||||
var resp, token []byte
|
||||
|
||||
// wg := new(sync.WaitGroup)
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
// server := NewFakeSecureService(wg, func(path string, status int, resp []byte) {
|
||||
// })
|
||||
// defer server.Close()
|
||||
server := NewFakeSecureService(wg, func(path string, status int, resp []byte) {
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
// wg.Add(3)
|
||||
wg.Add(3)
|
||||
|
||||
// client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: true})
|
||||
// resp, _ = client.Get("/token")
|
||||
// token = proto.Body(resp)
|
||||
client := NewHTTPClient(&HTTPOutputConfig{}).Client
|
||||
rep, _ := client.Get(server.URL + "/token")
|
||||
resp, _ = httputil.DumpResponse(rep, true)
|
||||
token = proto.Body(resp)
|
||||
|
||||
// // Right token
|
||||
// resp, _ = client.Get("/secure?token=" + string(token))
|
||||
// if !bytes.Equal(proto.Status(resp), []byte("202")) {
|
||||
// t.Error("Valid token should return status 202:", string(proto.Status(resp)))
|
||||
// }
|
||||
// Right token
|
||||
rep, _ = client.Get(server.URL + "/secure?token=" + string(token))
|
||||
resp, _ = httputil.DumpResponse(rep, true)
|
||||
if !bytes.Equal(proto.Status(resp), []byte("202")) {
|
||||
t.Error("Valid token should return status 202:", string(proto.Status(resp)))
|
||||
}
|
||||
|
||||
// // Wrong tokens forbidden
|
||||
// resp, _ = client.Get("/secure?token=wrong")
|
||||
// if !bytes.Equal(proto.Status(resp), []byte("403")) {
|
||||
// t.Error("Wrong token should returns status 403:", string(proto.Status(resp)))
|
||||
// }
|
||||
// Wrong tokens forbidden
|
||||
rep, _ = client.Get(server.URL + "/secure?token=wrong")
|
||||
resp, _ = httputil.DumpResponse(rep, true)
|
||||
if !bytes.Equal(proto.Status(resp), []byte("403")) {
|
||||
t.Error("Wrong token should returns status 403:", string(proto.Status(resp)))
|
||||
}
|
||||
|
||||
// wg.Wait()
|
||||
// }
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// func TestEchoMiddleware(t *testing.T) {
|
||||
// wg := new(sync.WaitGroup)
|
||||
func TestEchoMiddleware(t *testing.T) {
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
// from := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Header().Set("Env", "prod")
|
||||
// w.Header().Set("RequestPath", r.URL.Path)
|
||||
// wg.Done()
|
||||
// }))
|
||||
// defer from.Close()
|
||||
from := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Env", "prod")
|
||||
w.Header().Set("RequestPath", r.URL.Path)
|
||||
wg.Done()
|
||||
}))
|
||||
defer from.Close()
|
||||
|
||||
// to := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Header().Set("Env", "test")
|
||||
// w.Header().Set("RequestPath", r.URL.Path)
|
||||
// wg.Done()
|
||||
// }))
|
||||
// defer to.Close()
|
||||
to := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Env", "test")
|
||||
w.Header().Set("RequestPath", r.URL.Path)
|
||||
wg.Done()
|
||||
}))
|
||||
defer to.Close()
|
||||
|
||||
// quit := make(chan int)
|
||||
// Catch traffic from one service
|
||||
fromAddr := strings.Replace(from.Listener.Addr().String(), "[::]", "127.0.0.1", -1)
|
||||
conf := RAWInputConfig{
|
||||
Engine: capture.EnginePcap,
|
||||
Expire: testRawExpire,
|
||||
Protocol: ProtocolHTTP,
|
||||
TrackResponse: true,
|
||||
}
|
||||
input := NewRAWInput(fromAddr, conf)
|
||||
|
||||
// // Catch traffic from one service
|
||||
// fromAddr := strings.Replace(from.Listener.Addr().String(), "[::]", "127.0.0.1", -1)
|
||||
// conf := RAWInputConfig{
|
||||
// engine: capture.EnginePcap,
|
||||
// expire: testRawExpire,
|
||||
// protocol: ProtocolHTTP,
|
||||
// trackResponse: true,
|
||||
// }
|
||||
// input := NewRAWInput(fromAddr, conf)
|
||||
// And redirect to another
|
||||
output := NewHTTPOutput(to.URL, &HTTPOutputConfig{})
|
||||
|
||||
// // And redirect to another
|
||||
// output := NewHTTPOutput(to.URL, &HTTPOutputConfig{Debug: false})
|
||||
plugins := &InOutPlugins{
|
||||
Inputs: []PluginReader{input},
|
||||
Outputs: []PluginWriter{output},
|
||||
}
|
||||
plugins.All = append(plugins.All, input, output)
|
||||
|
||||
// plugins := &InOutPlugins{
|
||||
// Inputs: []io.Reader{input},
|
||||
// Outputs: []io.Writer{output},
|
||||
// }
|
||||
// plugins.All = append(plugins.All, input, output)
|
||||
// Start Gor
|
||||
emitter := NewEmitter()
|
||||
emitter.Start(plugins, "echo -n && GOR_TEST=true && ./examples/middleware/echo.sh")
|
||||
|
||||
// // Start Gor
|
||||
// emitter := NewEmitter(quit)
|
||||
// go emitter.Start(plugins, "echo -n && GOR_TEST=true && ./examples/middleware/echo.sh")
|
||||
// Wait till middleware initialization
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// // Wait till middleware initialization
|
||||
// time.Sleep(100 * time.Millisecond)
|
||||
// Should receive 2 requests from original + 2 from replayed
|
||||
client := NewHTTPClient(output.(*HTTPOutput).config).Client
|
||||
|
||||
// // Should receive 2 requests from original + 2 from replayed
|
||||
// client := NewHTTPClient(from.URL, &HTTPClientConfig{Debug: false})
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(2)
|
||||
// Request should be echoed
|
||||
client.Get(to.URL + "/a")
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
client.Get(to.URL + "/b")
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
|
||||
// for i := 0; i < 10; i++ {
|
||||
// wg.Add(2)
|
||||
// // Request should be echoed
|
||||
// client.Get("/a")
|
||||
// time.Sleep(5 * time.Millisecond)
|
||||
// client.Get("/b")
|
||||
// time.Sleep(5 * time.Millisecond)
|
||||
// }
|
||||
wg.Wait()
|
||||
emitter.Close()
|
||||
}
|
||||
|
||||
// wg.Wait()
|
||||
// emitter.Close()
|
||||
// }
|
||||
func TestTokenMiddleware(t *testing.T) {
|
||||
var resp, token []byte
|
||||
|
||||
// func TestTokenMiddleware(t *testing.T) {
|
||||
// var resp, token []byte
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
// wg := new(sync.WaitGroup)
|
||||
from := NewFakeSecureService(wg, func(path string, status int, tok []byte) {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
})
|
||||
defer from.Close()
|
||||
|
||||
// from := NewFakeSecureService(wg, func(path string, status int, tok []byte) {
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
// })
|
||||
// defer from.Close()
|
||||
to := NewFakeSecureService(wg, func(path string, status int, tok []byte) {
|
||||
switch path {
|
||||
case "/secure":
|
||||
if status != 202 {
|
||||
t.Error("Server should receive valid rewritten token")
|
||||
}
|
||||
}
|
||||
|
||||
// to := NewFakeSecureService(wg, func(path string, status int, tok []byte) {
|
||||
// switch path {
|
||||
// case "/secure":
|
||||
// if status != 202 {
|
||||
// t.Error("Server should receive valid rewritten token")
|
||||
// }
|
||||
// }
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
})
|
||||
defer to.Close()
|
||||
|
||||
// time.Sleep(10 * time.Millisecond)
|
||||
// })
|
||||
// defer to.Close()
|
||||
Settings.Middleware = "echo -n && GOR_TEST=true && go run ./examples/middleware/token_modifier.go"
|
||||
|
||||
// quit := make(chan int)
|
||||
fromAddr := strings.Replace(from.Listener.Addr().String(), "[::]", "127.0.0.1", -1)
|
||||
conf := RAWInputConfig{
|
||||
Engine: capture.EnginePcap,
|
||||
Expire: testRawExpire,
|
||||
Protocol: ProtocolHTTP,
|
||||
TrackResponse: true,
|
||||
}
|
||||
// Catch traffic from one service
|
||||
input := NewRAWInput(fromAddr, conf)
|
||||
|
||||
// Settings.middleware = "echo -n && GOR_TEST=true && go run ./examples/middleware/token_modifier.go"
|
||||
// And redirect to another
|
||||
output := NewHTTPOutput(to.URL, &HTTPOutputConfig{})
|
||||
|
||||
// fromAddr := strings.Replace(from.Listener.Addr().String(), "[::]", "127.0.0.1", -1)
|
||||
// conf := RAWInputConfig{
|
||||
// engine: capture.EnginePcap,
|
||||
// expire: testRawExpire,
|
||||
// protocol: ProtocolHTTP,
|
||||
// trackResponse: true,
|
||||
// }
|
||||
// // Catch traffic from one service
|
||||
// input := NewRAWInput(fromAddr, conf)
|
||||
plugins := &InOutPlugins{
|
||||
Inputs: []PluginReader{input},
|
||||
Outputs: []PluginWriter{output},
|
||||
}
|
||||
plugins.All = append(plugins.All, input, output)
|
||||
|
||||
// // And redirect to another
|
||||
// output := NewHTTPOutput(to.URL, &HTTPOutputConfig{Debug: true})
|
||||
// Start Gor
|
||||
emitter := NewEmitter()
|
||||
emitter.Start(plugins, Settings.Middleware)
|
||||
|
||||
// plugins := &InOutPlugins{
|
||||
// Inputs: []io.Reader{input},
|
||||
// Outputs: []io.Writer{output},
|
||||
// }
|
||||
// plugins.All = append(plugins.All, input, output)
|
||||
// Should receive 2 requests from original + 2 from replayed
|
||||
wg.Add(2)
|
||||
|
||||
// // Start Gor
|
||||
// emitter := NewEmitter(quit)
|
||||
// go emitter.Start(plugins, Settings.middleware)
|
||||
client := NewHTTPClient(&HTTPOutputConfig{}).Client
|
||||
|
||||
// // Should receive 2 requests from original + 2 from replayed
|
||||
// wg.Add(2)
|
||||
// Sending traffic to original service
|
||||
rep, _ := client.Get(to.URL + "/token")
|
||||
resp, _ = httputil.DumpResponse(rep, true)
|
||||
token = proto.Body(resp)
|
||||
|
||||
// client := NewHTTPClient(from.URL, &HTTPClientConfig{Debug: true})
|
||||
rep, _ = client.Get(to.URL + "/secure?token=" + string(token))
|
||||
resp, _ = httputil.DumpResponse(rep, true)
|
||||
if !bytes.Equal(proto.Status(resp), []byte("202")) {
|
||||
t.Error("Valid token should return 202:", proto.Status(resp))
|
||||
}
|
||||
|
||||
// // Sending traffic to original service
|
||||
// resp, _ = client.Get("/token")
|
||||
// token = proto.Body(resp)
|
||||
|
||||
// resp, _ = client.Get("/secure?token=" + string(token))
|
||||
// if !bytes.Equal(proto.Status(resp), []byte("202")) {
|
||||
// t.Error("Valid token should return 202:", proto.Status(resp))
|
||||
// }
|
||||
|
||||
// wg.Wait()
|
||||
// emitter.Close()
|
||||
// Settings.middleware = ""
|
||||
// }
|
||||
wg.Wait()
|
||||
emitter.Close()
|
||||
Settings.Middleware = ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user