Files
go-sip/deploys/test/saas-mock/main_test.go
T

148 lines
4.5 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"git.ipao.vip/rogee/go-sip/internal/configread"
)
const testDispatcher = "c046b893-8628-4589-ae50-619d049248a6"
func testDataDir(t *testing.T) string {
t.Helper()
root := t.TempDir()
if err := os.Mkdir(filepath.Join(root, "tasks"), 0700); err != nil {
t.Fatal(err)
}
for target, source := range map[string]string{
"sip.json": "config-read-sip.json",
"providers.json": "config-read-providers.json",
"quota.json": "config-read-quota.json",
"tasks/task-full.json": "config-read-task-full.json",
} {
original, err := os.ReadFile(filepath.Join("..", "..", "..", "contracts", "local", "examples", source))
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(root, target), original, 0600); err != nil {
t.Fatal(err)
}
}
return root
}
func TestSaaSMockServesFormalReadContract(t *testing.T) {
data, err := loadDataset(testDataDir(t), testDispatcher)
if err != nil {
t.Fatal(err)
}
server := httptest.NewServer(data.handler("test-only-secret"))
defer server.Close()
client, err := configread.NewClient(server.URL, testDispatcher, "test-only-secret", server.Client())
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
sip, err := client.ReadSIP(ctx)
if err != nil {
t.Fatal(err)
}
providers, err := client.ReadProviders(ctx)
if err != nil {
t.Fatal(err)
}
tasks, cursor, err := client.ReadAllTasks(ctx)
if err != nil || len(tasks) != 1 || tasks[0].TaskID != "task-full" || cursor == "" {
t.Fatalf("formal task discovery: count=%d cursor=%q err=%v", len(tasks), cursor, err)
}
snapshot, err := client.ReadTask(ctx, "task-full", 1001, sip, providers)
if err != nil || snapshot.Task.TaskID != "task-full" || snapshot.Quota.TenantID != snapshot.Task.TenantID {
t.Fatalf("formal task/quota read: task=%q quota=%d err=%v", snapshot.Task.TaskID, snapshot.Quota.TenantID, err)
}
if _, err := client.ReadTask(ctx, "absent", 1001, sip, providers); err == nil {
t.Fatal("unknown task must fail closed")
}
wrong, err := configread.NewClient(server.URL, testDispatcher, "wrong-secret", server.Client())
if err != nil {
t.Fatal(err)
}
if _, err := wrong.ReadSIP(ctx); err == nil || !strings.Contains(err.Error(), "HTTP 403") {
t.Fatalf("wrong dispatcher identity should be rejected: %v", err)
}
request, err := http.NewRequest(http.MethodPost, server.URL+"/internal/v1/dispatcher/sip", nil)
if err != nil {
t.Fatal(err)
}
request.Header.Set("X-DISPATCHER-id", testDispatcher)
request.Header.Set("X-DISPATCHER-SECRET-KEY", "test-only-secret")
response, err := server.Client().Do(request)
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
if response.StatusCode != http.StatusMethodNotAllowed {
t.Fatalf("configuration must stay read-only: HTTP %d", response.StatusCode)
}
}
func TestSaaSMockDiscoversSixDistinctTasks(t *testing.T) {
root := testDataDir(t)
original, err := os.ReadFile(filepath.Join(root, "tasks", "task-full.json"))
if err != nil {
t.Fatal(err)
}
for n := 2; n <= 6; n++ {
var task map[string]any
if err := json.Unmarshal(original, &task); err != nil {
t.Fatal(err)
}
id := fmt.Sprintf("task-%d", n)
task["task_id"] = id
body, err := json.Marshal(task)
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(root, "tasks", id+".json"), body, 0600); err != nil {
t.Fatal(err)
}
}
data, err := loadDataset(root, testDispatcher)
if err != nil {
t.Fatal(err)
}
server := httptest.NewServer(data.handler("test-only-secret"))
defer server.Close()
client, err := configread.NewClient(server.URL, testDispatcher, "test-only-secret", server.Client())
if err != nil {
t.Fatal(err)
}
tasks, cursor, err := client.ReadAllTasks(context.Background())
if err != nil || len(tasks) != 6 || cursor != "mock-complete" {
t.Fatalf("six independent formal tasks were not discovered: count=%d cursor=%q err=%v", len(tasks), cursor, err)
}
}
func TestSaaSMockRejectsInvalidOwnerAtStartup(t *testing.T) {
root := testDataDir(t)
path := filepath.Join(root, "tasks", "task-full.json")
original, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
bad := strings.Replace(string(original), testDispatcher, "00000000-0000-4000-8000-000000000000", 1)
if err := os.WriteFile(path, []byte(bad), 0600); err != nil {
t.Fatal(err)
}
if _, err := loadDataset(root, testDispatcher); err == nil {
t.Fatal("a task assigned to another dispatcher cannot be served")
}
}