97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/pem"
|
|
"git.ipao.vip/rogee/go-sip/internal/logging"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestDispatcherSaaSHTTPClientAllowsRealTargetsAndKeepsMockLocal(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
_, _ = io.WriteString(w, "configuration reached")
|
|
}))
|
|
defer server.Close()
|
|
trustServer := httptest.NewTLSServer(http.NotFoundHandler())
|
|
trustPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: trustServer.Certificate().Raw})
|
|
trustServer.Close()
|
|
|
|
// Resolve the nonlocal SaaS hostname to the isolated test server. No request
|
|
// leaves this machine; Mock must still reject the original target hostname.
|
|
original := http.DefaultTransport
|
|
transport, err := logging.CloneDefaultTransport()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
transport.Proxy = nil
|
|
transport.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
if address == "saas.example.invalid:80" {
|
|
address = server.Listener.Addr().String()
|
|
}
|
|
return (&net.Dialer{}).DialContext(ctx, network, address)
|
|
}
|
|
http.DefaultTransport = transport
|
|
t.Cleanup(func() {
|
|
http.DefaultTransport = original
|
|
transport.CloseIdleConnections()
|
|
})
|
|
|
|
for _, mode := range []string{"nonprod-real", "sip-only", "mock"} {
|
|
t.Run(mode, func(t *testing.T) {
|
|
client, err := dispatcherSaaSHTTPClient(mode, trustPEM)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if client.Timeout != 10*time.Second {
|
|
t.Fatalf("configuration timeout = %v", client.Timeout)
|
|
}
|
|
response, err := client.Get("http://saas.example.invalid/internal/v1/dispatcher/sip")
|
|
if mode == "mock" {
|
|
if response != nil {
|
|
_ = response.Body.Close()
|
|
}
|
|
if err == nil || !strings.Contains(err.Error(), "Mock upload target is not local") {
|
|
t.Fatalf("Mock must reject a nonlocal configuration target: %v", err)
|
|
}
|
|
response, err = client.Get(server.URL)
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("%s configuration request failed: %v", mode, err)
|
|
}
|
|
defer response.Body.Close()
|
|
body, err := io.ReadAll(response.Body)
|
|
if err != nil || string(body) != "configuration reached" {
|
|
t.Fatalf("configuration response = %q, error = %v", body, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDispatcherSaaSHTTPClientDoesNotUseAgentCAForRealSaaS(t *testing.T) {
|
|
for _, mode := range []string{"nonprod-real", "sip-only"} {
|
|
t.Run(mode, func(t *testing.T) {
|
|
client, err := dispatcherSaaSHTTPClient(mode, []byte("not a SaaS CA"))
|
|
if err != nil {
|
|
t.Fatalf("real SaaS must use system trust, not the Agent CA: %v", err)
|
|
}
|
|
if client.Transport != nil {
|
|
t.Fatal("real SaaS must use the standard HTTP transport")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDispatcherSaaSHTTPClientRejectsUnsupportedMode(t *testing.T) {
|
|
for _, mode := range []string{"", "real", "mixed"} {
|
|
if _, err := dispatcherSaaSHTTPClient(mode, nil); err == nil {
|
|
t.Fatalf("unsupported mode %q was accepted", mode)
|
|
}
|
|
}
|
|
}
|