feat: bootstrap supply intelligence baseline
This commit is contained in:
219
internal/probe/executor_test.go
Normal file
219
internal/probe/executor_test.go
Normal file
@@ -0,0 +1,219 @@
|
||||
package probe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// mockHTTPClient records requests and returns configurable responses
|
||||
type mockHTTPClient struct {
|
||||
Resp *http.Response
|
||||
Err error
|
||||
}
|
||||
|
||||
func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
|
||||
// Simulate context cancellation: if the request context is done, return context error
|
||||
select {
|
||||
case <-req.Context().Done():
|
||||
return nil, req.Context().Err()
|
||||
default:
|
||||
}
|
||||
return m.Resp, m.Err
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_Success(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"status":"ok"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil) // nil → uses real http.Client
|
||||
|
||||
outcome, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 1,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
AuthHeader: "Bearer test-key",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outcome.StatusCode != http.StatusOK {
|
||||
t.Fatalf("expected 200, got: %d", outcome.StatusCode)
|
||||
}
|
||||
if outcome.LatencyMs < 0 {
|
||||
t.Fatalf("expected latency >= 0, got: %d", outcome.LatencyMs)
|
||||
}
|
||||
if outcome.RequestID == "" {
|
||||
t.Fatal("expected request_id to be set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_ExplicitFailure(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
outcome, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 2,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outcome.StatusCode != http.StatusUnauthorized {
|
||||
t.Fatalf("expected 401, got: %d", outcome.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_Inconclusive_429(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusTooManyRequests)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
outcome, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 3,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outcome.StatusCode != http.StatusTooManyRequests {
|
||||
t.Fatalf("expected 429, got: %d", outcome.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_TransportError(t *testing.T) {
|
||||
client := &mockHTTPClient{
|
||||
Err: errors.New("connection refused"),
|
||||
}
|
||||
executor := NewProbeExecutor(client)
|
||||
|
||||
outcome, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 4,
|
||||
Platform: "openai",
|
||||
Endpoint: "http://localhost:9999",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outcome.TransportError == nil {
|
||||
t.Fatal("expected transport error to be set")
|
||||
}
|
||||
if outcome.StatusCode != 0 {
|
||||
t.Fatalf("expected status 0 on transport error, got: %d", outcome.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_InvalidTarget(t *testing.T) {
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
_, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 5,
|
||||
Platform: "openai",
|
||||
Endpoint: "", // empty endpoint
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
t.Fatal("expected error for empty endpoint")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_ContextCanceled(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
time.Sleep(5 * time.Second) // delay longer than context
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
outcome, err := executor.ExecuteProbe(ctx, ProbeTarget{
|
||||
AccountID: 6,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outcome.TransportError == nil {
|
||||
t.Fatal("expected context deadline exceeded transport error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_ExecuteProbe_ResponseBodyTruncated(t *testing.T) {
|
||||
largeBody := strings.Repeat("x", 10*1024) // 10KB
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(largeBody))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
outcome, err := executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 7,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(outcome.ResponseBody) > 1024 {
|
||||
t.Fatalf("expected body truncated to <=1024, got: %d", len(outcome.ResponseBody))
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbeExecutor_SetsUserAgentAndAcceptHeader(t *testing.T) {
|
||||
var receivedHeaders http.Header
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
receivedHeaders = r.Header.Clone()
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
executor := NewProbeExecutor(nil)
|
||||
|
||||
_, _ = executor.ExecuteProbe(context.Background(), ProbeTarget{
|
||||
AccountID: 8,
|
||||
Platform: "openai",
|
||||
Endpoint: server.URL,
|
||||
AuthHeader: "Bearer my-key",
|
||||
})
|
||||
|
||||
if receivedHeaders == nil {
|
||||
t.Fatal("server handler was not called — check test setup")
|
||||
}
|
||||
if receivedHeaders.Get("User-Agent") == "" {
|
||||
t.Fatal("expected User-Agent header to be set")
|
||||
}
|
||||
if receivedHeaders.Get("Accept") != "application/json" {
|
||||
t.Fatalf("expected Accept: application/json, got: %s", receivedHeaders.Get("Accept"))
|
||||
}
|
||||
if receivedHeaders.Get("Authorization") != "Bearer my-key" {
|
||||
t.Fatalf("expected Authorization header to be set")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user