soteria/internal/server/b2_refresh_test.go

187 lines
5.8 KiB
Go
Raw Permalink Normal View History

package server
import (
"context"
"encoding/json"
"strings"
"testing"
"time"
"net/http"
"net/http/httptest"
"scm.bstein.dev/bstein/soteria/internal/api"
"scm.bstein.dev/bstein/soteria/internal/config"
)
func TestRefreshB2UsageRecordsCredentialResolutionErrors(t *testing.T) {
srv := &Server{
cfg: &config.Config{
B2Enabled: true,
B2ScanTimeout: time.Second,
},
client: &fakeKubeClient{},
metrics: newTelemetry(),
}
srv.refreshB2Usage(context.Background())
usage := srv.getB2Usage()
if !usage.Enabled || usage.Error == "" || !strings.Contains(usage.Error, "B2 endpoint is not configured") {
t.Fatalf("expected B2 credential resolution error snapshot, got %#v", usage)
}
if usage.ScannedAt == "" {
t.Fatalf("expected failed refresh to record scanned timestamp, got %#v", usage)
}
if srv.metrics.b2ScanSuccess != 0 || srv.metrics.b2ScanTimestamp == 0 {
t.Fatalf("expected failed B2 scan metrics to be recorded, got success=%f timestamp=%f", srv.metrics.b2ScanSuccess, srv.metrics.b2ScanTimestamp)
}
}
func TestRefreshB2UsageHandlesDisabledAndSuccessfulScans(t *testing.T) {
t.Run("disabled", func(t *testing.T) {
srv := &Server{
cfg: &config.Config{
B2Enabled: false,
B2Endpoint: "https://cached-endpoint",
B2Region: "us-west-001",
B2ScanTimeout: time.Second,
},
client: &fakeKubeClient{},
metrics: newTelemetry(),
}
srv.refreshB2Usage(context.Background())
usage := srv.getB2Usage()
if usage.Enabled || usage.Error != "" || usage.Endpoint != "https://cached-endpoint" {
t.Fatalf("expected disabled snapshot without scan error, got %#v", usage)
}
if srv.metrics.b2ScanSuccess != 0 || srv.metrics.b2AccountBytes != 0 {
t.Fatalf("expected disabled metrics snapshot, got success=%f bytes=%f", srv.metrics.b2ScanSuccess, srv.metrics.b2AccountBytes)
}
})
t.Run("successful scan", func(t *testing.T) {
now := time.Now().UTC()
server := newFakeS3Server(t,
[]string{"atlas"},
map[string][]fakeS3Object{
"atlas": {
{key: "fresh", size: 7, lastModified: now.Add(-1 * time.Hour)},
{key: "stale", size: 11, lastModified: now.Add(-48 * time.Hour)},
},
},
nil,
)
defer server.Close()
srv := &Server{
cfg: &config.Config{
B2Enabled: true,
B2Endpoint: server.URL,
B2Region: "us-west-001",
B2AccessKeyID: "atlas-key",
B2SecretAccessKey: "atlas-secret",
B2ScanTimeout: 2 * time.Second,
},
client: &fakeKubeClient{},
metrics: newTelemetry(),
}
srv.refreshB2Usage(context.Background())
usage := srv.getB2Usage()
if !usage.Enabled || !usage.Available || usage.Error != "" {
t.Fatalf("expected successful B2 scan snapshot, got %#v", usage)
}
if usage.Endpoint != server.URL || usage.Region != "us-west-001" || usage.TotalObjects != 2 || usage.RecentObjects24h != 1 {
t.Fatalf("expected successful usage totals, got %#v", usage)
}
if usage.ScannedAt == "" || usage.ScanDurationMS < 0 {
t.Fatalf("expected scan metadata, got %#v", usage)
}
if srv.metrics.b2ScanSuccess != 1 || srv.metrics.b2AccountBytes != 18 {
t.Fatalf("expected success metrics to be recorded, got success=%f bytes=%f", srv.metrics.b2ScanSuccess, srv.metrics.b2AccountBytes)
}
})
}
func TestRefreshB2UsageRecordsScanErrorsAfterCredentialsResolve(t *testing.T) {
srv := &Server{
cfg: &config.Config{
B2Enabled: true,
B2Endpoint: "https://",
B2AccessKeyID: "atlas-key",
B2SecretAccessKey: "atlas-secret",
B2ScanTimeout: time.Second,
},
client: &fakeKubeClient{},
metrics: newTelemetry(),
}
srv.refreshB2Usage(context.Background())
usage := srv.getB2Usage()
if usage.Endpoint != "https://" {
t.Fatalf("expected resolved endpoint to be preserved in failed snapshot, got %#v", usage)
}
if usage.Error == "" || !strings.Contains(usage.Error, "S3 endpoint host is empty") {
t.Fatalf("expected B2 scan error snapshot, got %#v", usage)
}
if usage.ScannedAt == "" || usage.ScanDurationMS < 0 {
t.Fatalf("expected scan metadata on failure, got %#v", usage)
}
if srv.metrics.b2ScanSuccess != 0 || srv.metrics.b2ScanDurationSeconds < 0 {
t.Fatalf("expected failure metrics after scan error, got success=%f duration=%f", srv.metrics.b2ScanSuccess, srv.metrics.b2ScanDurationSeconds)
}
}
func TestHandleB2UsageRefreshesWhenForcedAndQueryBoolRecognizesTruthyValues(t *testing.T) {
for _, raw := range []string{"1", "true", "yes", "y", "on", "TRUE"} {
if !queryBool(raw) {
t.Fatalf("expected %q to be treated as truthy", raw)
}
}
if queryBool("nope") {
t.Fatalf("expected invalid truthy value to be false")
}
srv := &Server{
cfg: &config.Config{
B2Enabled: true,
B2Endpoint: "https://",
B2AccessKeyID: "atlas-key",
B2SecretAccessKey: "atlas-secret",
B2ScanTimeout: time.Second,
},
client: &fakeKubeClient{},
metrics: newTelemetry(),
}
srv.handler = http.HandlerFunc(srv.route)
srv.setB2Usage(api.B2UsageResponse{
Enabled: true,
Available: true,
ScannedAt: time.Now().UTC().Add(-1 * time.Hour).Format(time.RFC3339),
Endpoint: "cached-endpoint",
})
req := httptest.NewRequest(http.MethodGet, "/v1/b2?refresh=yes", nil)
res := httptest.NewRecorder()
srv.Handler().ServeHTTP(res, req)
if res.Code != http.StatusOK {
t.Fatalf("expected forced refresh request to succeed, got %d: %s", res.Code, res.Body.String())
}
var payload api.B2UsageResponse
if err := json.Unmarshal(res.Body.Bytes(), &payload); err != nil {
t.Fatalf("decode forced refresh payload: %v", err)
}
if payload.Error == "" || !strings.Contains(payload.Error, "S3 endpoint host is empty") {
t.Fatalf("expected refreshed B2 failure payload, got %#v", payload)
}
if payload.Endpoint != "https://" {
t.Fatalf("expected refreshed endpoint to replace cached snapshot, got %#v", payload)
}
}