quorate/services/short/tunnel/native_test.go

75 lines
1.6 KiB
Go
Raw Permalink Normal View History

//go:build integration
package tunnel
import (
"context"
"encoding/json"
"net"
"net/http"
"os"
"sync/atomic"
"testing"
"time"
)
func TestNativeReload(t *testing.T) {
nativeLoop(t, false)
}
func TestNativeRuntime(t *testing.T) {
nativeLoop(t, true)
}
func nativeLoop(t *testing.T, observe bool) {
t.Helper()
file := os.Getenv("SHORT_RUNTIME")
if file == "" {
t.Skip("SHORT_RUNTIME requires an isolated native IPsec fixture")
}
ctx, cancel := context.WithTimeout(context.Background(), 240*time.Second)
defer cancel()
var ready atomic.Bool
var published atomic.Bool
if observe {
listener, err := net.Listen("tcp", "127.0.0.1:9091")
if err != nil {
t.Fatal(err)
}
server := &http.Server{ReadHeaderTimeout: time.Second, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/status" {
http.NotFound(w, r)
return
}
json.NewEncoder(w).Encode(map[string]bool{"ready": ready.Load(), "published": published.Load()})
})}
go server.Serve(listener)
defer server.Close()
}
done := make(chan error, 1)
go func() {
done <- serve(ctx, file, &ready, func(context.Context) error {
published.Store(true)
return nil
})
}()
ticker := time.NewTicker(100 * time.Millisecond)
defer ticker.Stop()
for {
select {
case err := <-done:
t.Fatalf("tunnel ended before fixture completion: %v", err)
case <-ctx.Done():
<-done
t.Fatal("native fixture did not finish within its bound")
case <-ticker.C:
if _, err := os.Stat(file + ".done"); err == nil {
cancel()
if err := <-done; err != nil {
t.Fatal(err)
}
return
}
}
}
}