750 lines
28 KiB
Go
750 lines
28 KiB
Go
package sqlite
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
func TestImportBatchesRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostID := createTestHost(t, store)
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
|
|
id, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
if id <= 0 {
|
|
t.Fatalf("Create() id = %d, want positive", id)
|
|
}
|
|
|
|
got, _ := store.ImportBatches().GetByID(context.Background(), id)
|
|
if got.Mode != "partial" || got.BatchStatus != "running" {
|
|
t.Fatalf("GetByID() = %+v, want running batch", got)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoUpdateStatus(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostID := createTestHost(t, store)
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
id, _ := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
})
|
|
|
|
err := store.ImportBatches().UpdateStatus(context.Background(), id, "succeeded", "subscription_ready")
|
|
if err != nil {
|
|
t.Fatalf("UpdateStatus() error = %v", err)
|
|
}
|
|
got, _ := store.ImportBatches().GetByID(context.Background(), id)
|
|
if got.BatchStatus != "succeeded" || got.AccessStatus != "subscription_ready" {
|
|
t.Fatalf("status = %+v, want succeeded/subscription_ready", got)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoGetLatestByProviderID(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostID := createTestHost(t, store)
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
|
|
store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
})
|
|
id2, _ := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
|
|
got, _ := store.ImportBatches().GetLatestByProviderID(context.Background(), providerID)
|
|
if got.ID != id2 {
|
|
t.Fatalf("latest id = %d, want %d", got.ID, id2)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoListByProviderID(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostID := createTestHost(t, store)
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
|
|
olderID, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create older batch error = %v", err)
|
|
}
|
|
newerID, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostID, PackID: packID, ProviderID: providerID,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create newer batch error = %v", err)
|
|
}
|
|
|
|
batches, err := store.ImportBatches().ListByProviderID(context.Background(), providerID)
|
|
if err != nil {
|
|
t.Fatalf("ListByProviderID() error = %v", err)
|
|
}
|
|
if len(batches) != 2 {
|
|
t.Fatalf("ListByProviderID() len = %d, want 2", len(batches))
|
|
}
|
|
if batches[0].ID != newerID || batches[1].ID != olderID {
|
|
t.Fatalf("ListByProviderID() ids = [%d %d], want [%d %d]", batches[0].ID, batches[1].ID, newerID, olderID)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoGetLatestByProviderIDAndHostID(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostA := createTestHost(t, store)
|
|
hostB := createTestHostWithBaseURL(t, store, "host-b-"+sanitizeTestName(t.Name()), "https://host-b.example.com")
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
}); err != nil {
|
|
t.Fatalf("Create(hostA older) error = %v", err)
|
|
}
|
|
latestA, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packID, ProviderID: providerID,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(hostA newer) error = %v", err)
|
|
}
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "partially_succeeded", AccessStatus: "degraded",
|
|
}); err != nil {
|
|
t.Fatalf("Create(hostB) error = %v", err)
|
|
}
|
|
|
|
got, err := store.ImportBatches().GetLatestByProviderIDAndHostID(context.Background(), providerID, hostA)
|
|
if err != nil {
|
|
t.Fatalf("GetLatestByProviderIDAndHostID() error = %v", err)
|
|
}
|
|
if got.ID != latestA {
|
|
t.Fatalf("GetLatestByProviderIDAndHostID() id = %d, want %d", got.ID, latestA)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoListByProviderIDAndHostID(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostA := createTestHost(t, store)
|
|
hostB := createTestHostWithBaseURL(t, store, "host-b-"+sanitizeTestName(t.Name()), "https://host-b2.example.com")
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
|
|
olderA, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(hostA older) error = %v", err)
|
|
}
|
|
newerA, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packID, ProviderID: providerID,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(hostA newer) error = %v", err)
|
|
}
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packID, ProviderID: providerID,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
}); err != nil {
|
|
t.Fatalf("Create(hostB) error = %v", err)
|
|
}
|
|
|
|
batches, err := store.ImportBatches().ListByProviderIDAndHostID(context.Background(), providerID, hostA)
|
|
if err != nil {
|
|
t.Fatalf("ListByProviderIDAndHostID() error = %v", err)
|
|
}
|
|
if len(batches) != 2 {
|
|
t.Fatalf("ListByProviderIDAndHostID() len = %d, want 2", len(batches))
|
|
}
|
|
if batches[0].ID != newerA || batches[1].ID != olderA {
|
|
t.Fatalf("ListByProviderIDAndHostID() ids = [%d %d], want [%d %d]", batches[0].ID, batches[1].ID, newerA, olderA)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoListLatestReconcilable(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostA := createTestHost(t, store)
|
|
hostB := createTestHostWithBaseURL(t, store, "host-b-"+sanitizeTestName(t.Name()), "https://host-b3.example.com")
|
|
packAID := createTestPack(t, store)
|
|
packBID := createTestPackWithSuffix(t, store, "reconcile")
|
|
providerA := createTestProviderWithPack(t, store, packAID)
|
|
providerB := createTestProviderWithPack(t, store, packBID)
|
|
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packAID, ProviderID: providerA,
|
|
Mode: "partial", BatchStatus: "running", AccessStatus: "pending",
|
|
}); err != nil {
|
|
t.Fatalf("Create(providerA older) error = %v", err)
|
|
}
|
|
latestA, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packAID, ProviderID: providerA,
|
|
Mode: "strict", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(providerA latest) error = %v", err)
|
|
}
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packBID, ProviderID: providerB,
|
|
Mode: "strict", BatchStatus: "partially_succeeded", AccessStatus: "degraded",
|
|
}); err != nil {
|
|
t.Fatalf("Create(providerB latest) error = %v", err)
|
|
}
|
|
if _, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packBID, ProviderID: providerB,
|
|
Mode: "strict", BatchStatus: "failed", AccessStatus: "broken",
|
|
}); err != nil {
|
|
t.Fatalf("Create(providerB newer failed) error = %v", err)
|
|
}
|
|
|
|
batches, err := store.ImportBatches().ListLatestReconcilable(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("ListLatestReconcilable() error = %v", err)
|
|
}
|
|
if len(batches) != 1 {
|
|
t.Fatalf("ListLatestReconcilable() len = %d, want 1 because providerB latest batch is not reconcilable", len(batches))
|
|
}
|
|
if batches[0].ID != latestA {
|
|
t.Fatalf("ListLatestReconcilable() id = %d, want %d", batches[0].ID, latestA)
|
|
}
|
|
|
|
batchID, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packBID, ProviderID: providerB,
|
|
Mode: "strict", BatchStatus: "partially_succeeded", AccessStatus: "degraded",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(providerB new reconcilable) error = %v", err)
|
|
}
|
|
|
|
batches, err = store.ImportBatches().ListLatestReconcilable(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("ListLatestReconcilable() second call error = %v", err)
|
|
}
|
|
if len(batches) != 2 {
|
|
t.Fatalf("ListLatestReconcilable() second len = %d, want 2", len(batches))
|
|
}
|
|
if batches[0].ID != batchID || batches[1].ID != latestA {
|
|
t.Fatalf("ListLatestReconcilable() ids = [%d %d], want [%d %d]", batches[0].ID, batches[1].ID, batchID, latestA)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoGetByIDNotFound(t *testing.T) {
|
|
store := openTestDB(t)
|
|
_, err := store.ImportBatches().GetByID(context.Background(), 999)
|
|
if err == nil {
|
|
t.Fatal("GetByID(999) error = nil, want error")
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoCreateValidationErrors(t *testing.T) {
|
|
store := openTestDB(t)
|
|
for _, tt := range []struct {
|
|
name string
|
|
batch ImportBatch
|
|
}{
|
|
{"host_id zero", ImportBatch{HostID: 0, PackID: 1, ProviderID: 1, Mode: "m", BatchStatus: "s", AccessStatus: "s"}},
|
|
{"pack_id zero", ImportBatch{HostID: 1, PackID: 0, ProviderID: 1, Mode: "m", BatchStatus: "s", AccessStatus: "s"}},
|
|
{"provider_id zero", ImportBatch{HostID: 1, PackID: 1, ProviderID: 0, Mode: "m", BatchStatus: "s", AccessStatus: "s"}},
|
|
{"empty mode", ImportBatch{HostID: 1, PackID: 1, ProviderID: 1, Mode: "", BatchStatus: "s", AccessStatus: "s"}},
|
|
{"empty batch_status", ImportBatch{HostID: 1, PackID: 1, ProviderID: 1, Mode: "m", BatchStatus: "", AccessStatus: "s"}},
|
|
{"empty access_status", ImportBatch{HostID: 1, PackID: 1, ProviderID: 1, Mode: "m", BatchStatus: "s", AccessStatus: ""}},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, err := store.ImportBatches().Create(context.Background(), tt.batch)
|
|
if err == nil {
|
|
t.Fatal("Create() error = nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestImportBatchesRepoUpdateStatusValidation(t *testing.T) {
|
|
store := openTestDB(t)
|
|
if err := store.ImportBatches().UpdateStatus(context.Background(), 0, "s", "s"); err == nil {
|
|
t.Fatal("UpdateStatus id=0 error = nil")
|
|
}
|
|
if err := store.ImportBatches().UpdateStatus(context.Background(), 1, "", "s"); err == nil {
|
|
t.Fatal("UpdateStatus empty batch_status error = nil")
|
|
}
|
|
}
|
|
|
|
// --- ImportBatchItems Repo Tests ---
|
|
|
|
func TestImportBatchItemsRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
|
|
id, err := store.ImportBatchItems().Create(context.Background(), ImportBatchItem{
|
|
BatchID: batchID,
|
|
KeyFingerprint: "sha256:abc",
|
|
AccountStatus: "passed",
|
|
ProbeSummaryJSON: `{"ok":true}`,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
if id <= 0 {
|
|
t.Fatalf("Create() id = %d, want positive", id)
|
|
}
|
|
|
|
items, _ := store.ImportBatchItems().GetByBatchID(context.Background(), batchID)
|
|
if len(items) != 1 || items[0].AccountStatus != "passed" {
|
|
t.Fatalf("items = %+v, want 1 with passed status", items)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchItemsRepoMultipleItems(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
|
|
for _, status := range []string{"passed", "failed"} {
|
|
store.ImportBatchItems().Create(context.Background(), ImportBatchItem{
|
|
BatchID: batchID, KeyFingerprint: "sha256:" + status, AccountStatus: status,
|
|
})
|
|
}
|
|
|
|
items, _ := store.ImportBatchItems().GetByBatchID(context.Background(), batchID)
|
|
if len(items) != 2 {
|
|
t.Fatalf("count = %d, want 2", len(items))
|
|
}
|
|
}
|
|
|
|
func TestImportBatchItemsRepoUpdateResult(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
itemID, _ := store.ImportBatchItems().Create(context.Background(), ImportBatchItem{
|
|
BatchID: batchID, KeyFingerprint: "sha256:x", AccountStatus: "pending",
|
|
})
|
|
|
|
store.ImportBatchItems().UpdateResult(context.Background(), itemID, "passed", `{"ok":true}`)
|
|
items, _ := store.ImportBatchItems().GetByBatchID(context.Background(), batchID)
|
|
if items[0].AccountStatus != "passed" {
|
|
t.Fatalf("AccountStatus = %q, want passed", items[0].AccountStatus)
|
|
}
|
|
}
|
|
|
|
func TestImportBatchItemsRepoGetByBatchIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
items, err := store.ImportBatchItems().GetByBatchID(context.Background(), 999)
|
|
if err != nil {
|
|
t.Fatalf("GetByBatchID() error = %v, want empty result", err)
|
|
}
|
|
if len(items) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(items))
|
|
}
|
|
}
|
|
|
|
func TestImportBatchItemsRepoValidation(t *testing.T) {
|
|
store := openTestDB(t)
|
|
_, err := store.ImportBatchItems().Create(context.Background(), ImportBatchItem{
|
|
BatchID: 0, KeyFingerprint: "k", AccountStatus: "s",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Create batch_id=0 error = nil")
|
|
}
|
|
}
|
|
|
|
// --- Managed Resources Repo Tests ---
|
|
|
|
func TestManagedResourcesRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
batch, _ := store.ImportBatches().GetByID(context.Background(), batchID)
|
|
|
|
id, err := store.ManagedResources().Create(context.Background(), ManagedResource{
|
|
BatchID: batchID, HostID: batch.HostID, ResourceType: "group", HostResourceID: "g_01", ResourceName: "test-group",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
resources, _ := store.ManagedResources().GetByBatchID(context.Background(), batchID)
|
|
if len(resources) != 1 || resources[0].HostResourceID != "g_01" {
|
|
t.Fatalf("resources = %+v, want 1 with g_01", resources)
|
|
}
|
|
_ = id
|
|
}
|
|
|
|
func TestManagedResourcesRepoMultipleResources(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
batch, _ := store.ImportBatches().GetByID(context.Background(), batchID)
|
|
|
|
for _, r := range []ManagedResource{
|
|
{BatchID: batchID, HostID: batch.HostID, ResourceType: "group", HostResourceID: "g_01", ResourceName: "group-1"},
|
|
{BatchID: batchID, HostID: batch.HostID, ResourceType: "channel", HostResourceID: "c_01", ResourceName: "channel-1"},
|
|
{BatchID: batchID, HostID: batch.HostID, ResourceType: "account", HostResourceID: "a_01", ResourceName: "account-1"},
|
|
} {
|
|
store.ManagedResources().Create(context.Background(), r)
|
|
}
|
|
|
|
resources, _ := store.ManagedResources().GetByBatchID(context.Background(), batchID)
|
|
if len(resources) != 3 {
|
|
t.Fatalf("count = %d, want 3", len(resources))
|
|
}
|
|
}
|
|
|
|
func TestManagedResourcesRepoGetByBatchIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
resources, _ := store.ManagedResources().GetByBatchID(context.Background(), 999)
|
|
if len(resources) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(resources))
|
|
}
|
|
}
|
|
|
|
func TestManagedResourcesRepoGetByResourceIdentity(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
batch, err := store.ImportBatches().GetByID(context.Background(), batchID)
|
|
if err != nil {
|
|
t.Fatalf("GetByID() error = %v", err)
|
|
}
|
|
if _, err := store.ManagedResources().Create(context.Background(), ManagedResource{
|
|
BatchID: batchID, HostID: batch.HostID, ResourceType: "channel", HostResourceID: "channel-1", ResourceName: "Channel 1",
|
|
}); err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
|
|
resource, err := store.ManagedResources().GetByResourceIdentity(context.Background(), batch.HostID, "channel", "channel-1")
|
|
if err != nil {
|
|
t.Fatalf("GetByResourceIdentity() error = %v", err)
|
|
}
|
|
if resource.ResourceName != "Channel 1" {
|
|
t.Fatalf("GetByResourceIdentity() resource_name = %q, want Channel 1", resource.ResourceName)
|
|
}
|
|
}
|
|
|
|
func TestManagedResourcesRepoListByProviderScopes(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostA := createTestHost(t, store)
|
|
hostB := createTestHostWithBaseURL(t, store, "host-b-"+sanitizeTestName(t.Name()), "https://managed-host-b.example.com")
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
otherProviderID := createTestProviderWithPack(t, store, createTestPackWithSuffix(t, store, "managed"))
|
|
|
|
batchA, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostA, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(batchA) error = %v", err)
|
|
}
|
|
batchB, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packID, ProviderID: providerID,
|
|
Mode: "partial", BatchStatus: "partially_succeeded", AccessStatus: "degraded",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(batchB) error = %v", err)
|
|
}
|
|
otherBatch, err := store.ImportBatches().Create(context.Background(), ImportBatch{
|
|
HostID: hostB, PackID: packID, ProviderID: otherProviderID,
|
|
Mode: "partial", BatchStatus: "succeeded", AccessStatus: "subscription_ready",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create(otherBatch) error = %v", err)
|
|
}
|
|
|
|
for _, resource := range []ManagedResource{
|
|
{BatchID: batchA, HostID: hostA, ResourceType: "group", HostResourceID: "g-a", ResourceName: "Group A"},
|
|
{BatchID: batchB, HostID: hostB, ResourceType: "account", HostResourceID: "a-b", ResourceName: "Account B"},
|
|
{BatchID: otherBatch, HostID: hostB, ResourceType: "channel", HostResourceID: "c-other", ResourceName: "Other"},
|
|
} {
|
|
if _, err := store.ManagedResources().Create(context.Background(), resource); err != nil {
|
|
t.Fatalf("Create(%s) error = %v", resource.HostResourceID, err)
|
|
}
|
|
}
|
|
|
|
byProvider, err := store.ManagedResources().ListByProviderID(context.Background(), providerID)
|
|
if err != nil {
|
|
t.Fatalf("ListByProviderID() error = %v", err)
|
|
}
|
|
if len(byProvider) != 2 {
|
|
t.Fatalf("ListByProviderID() len = %d, want 2", len(byProvider))
|
|
}
|
|
|
|
byProviderHost, err := store.ManagedResources().ListByProviderIDAndHostID(context.Background(), providerID, hostB)
|
|
if err != nil {
|
|
t.Fatalf("ListByProviderIDAndHostID() error = %v", err)
|
|
}
|
|
if len(byProviderHost) != 1 {
|
|
t.Fatalf("ListByProviderIDAndHostID() len = %d, want 1", len(byProviderHost))
|
|
}
|
|
if byProviderHost[0].HostResourceID != "a-b" {
|
|
t.Fatalf("ListByProviderIDAndHostID() resource = %q, want a-b", byProviderHost[0].HostResourceID)
|
|
}
|
|
}
|
|
|
|
func TestManagedResourcesRepoQueryValidationErrors(t *testing.T) {
|
|
store := openTestDB(t)
|
|
|
|
if _, err := store.ManagedResources().GetByResourceIdentity(context.Background(), 0, "group", "g-1"); err == nil {
|
|
t.Fatal("GetByResourceIdentity() host_id=0 error = nil")
|
|
}
|
|
if _, err := store.ManagedResources().ListByProviderID(context.Background(), 0); err == nil {
|
|
t.Fatal("ListByProviderID() provider_id=0 error = nil")
|
|
}
|
|
if _, err := store.ManagedResources().ListByProviderIDAndHostID(context.Background(), 1, 0); err == nil {
|
|
t.Fatal("ListByProviderIDAndHostID() host_id=0 error = nil")
|
|
}
|
|
}
|
|
|
|
func TestManagedResourcesRepoValidationErrors(t *testing.T) {
|
|
store := openTestDB(t)
|
|
for _, tt := range []struct {
|
|
name string
|
|
r ManagedResource
|
|
}{
|
|
{"batch_id zero", ManagedResource{HostID: 1, ResourceType: "g", HostResourceID: "h", ResourceName: "n"}},
|
|
{"host_id zero", ManagedResource{BatchID: 1, ResourceType: "g", HostResourceID: "h", ResourceName: "n"}},
|
|
{"empty resource_type", ManagedResource{BatchID: 1, HostID: 1, HostResourceID: "h", ResourceName: "n"}},
|
|
{"empty host_resource_id", ManagedResource{BatchID: 1, HostID: 1, ResourceType: "g", ResourceName: "n"}},
|
|
{"empty resource_name", ManagedResource{BatchID: 1, HostID: 1, ResourceType: "g", HostResourceID: "h"}},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, err := store.ManagedResources().Create(context.Background(), tt.r)
|
|
if err == nil {
|
|
t.Fatal("Create() error = nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// --- Probe Results Repo Tests ---
|
|
|
|
func TestProbeResultsRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
itemID := createTestBatchItem(t, store, batchID)
|
|
|
|
id, err := store.ProbeResults().Create(context.Background(), ProbeResult{
|
|
BatchItemID: itemID, ProbeType: "account_smoke", Status: "passed", SummaryJSON: `{"ok":true}`,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
results, _ := store.ProbeResults().GetByBatchItemID(context.Background(), itemID)
|
|
if len(results) != 1 || results[0].ProbeType != "account_smoke" {
|
|
t.Fatalf("results = %+v, want 1 with account_smoke", results)
|
|
}
|
|
_ = id
|
|
}
|
|
|
|
func TestProbeResultsRepoMultipleResults(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
itemID := createTestBatchItem(t, store, batchID)
|
|
|
|
for _, p := range []ProbeResult{
|
|
{BatchItemID: itemID, ProbeType: "account_smoke", Status: "passed", SummaryJSON: `{"ok":true}`},
|
|
{BatchItemID: itemID, ProbeType: "model_list", Status: "passed", SummaryJSON: `{"models":["m1"]}`},
|
|
} {
|
|
store.ProbeResults().Create(context.Background(), p)
|
|
}
|
|
|
|
results, _ := store.ProbeResults().GetByBatchItemID(context.Background(), itemID)
|
|
if len(results) != 2 {
|
|
t.Fatalf("count = %d, want 2", len(results))
|
|
}
|
|
}
|
|
|
|
func TestProbeResultsRepoGetByBatchItemIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
results, _ := store.ProbeResults().GetByBatchItemID(context.Background(), 999)
|
|
if len(results) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(results))
|
|
}
|
|
}
|
|
|
|
func TestProbeResultsRepoValidationErrors(t *testing.T) {
|
|
store := openTestDB(t)
|
|
for _, tt := range []struct {
|
|
name string
|
|
probe ProbeResult
|
|
}{
|
|
{"batch_item_id zero", ProbeResult{ProbeType: "t", Status: "s"}},
|
|
{"empty probe_type", ProbeResult{BatchItemID: 1, Status: "s"}},
|
|
{"empty status", ProbeResult{BatchItemID: 1, ProbeType: "t"}},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, err := store.ProbeResults().Create(context.Background(), tt.probe)
|
|
if err == nil {
|
|
t.Fatal("Create() error = nil")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// --- Access Closures Repo Tests ---
|
|
|
|
func TestAccessClosureRecordsRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
|
|
id, err := store.AccessClosures().Create(context.Background(), AccessClosureRecord{
|
|
BatchID: batchID, ClosureType: "subscription", Status: "subscription_ready", DetailsJSON: `{"status_code":200}`,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
records, _ := store.AccessClosures().GetByBatchID(context.Background(), batchID)
|
|
if len(records) != 1 || records[0].ClosureType != "subscription" {
|
|
t.Fatalf("records = %+v, want 1 subscription", records)
|
|
}
|
|
_ = id
|
|
}
|
|
|
|
func TestAccessClosureRecordsRepoMultiple(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
store.AccessClosures().Create(context.Background(), AccessClosureRecord{BatchID: batchID, ClosureType: "subscription", Status: "subscription_ready", DetailsJSON: "{}"})
|
|
store.AccessClosures().Create(context.Background(), AccessClosureRecord{BatchID: batchID, ClosureType: "self_service", Status: "self_service_ready", DetailsJSON: "{}"})
|
|
records, _ := store.AccessClosures().GetByBatchID(context.Background(), batchID)
|
|
if len(records) != 2 {
|
|
t.Fatalf("count = %d, want 2", len(records))
|
|
}
|
|
}
|
|
|
|
func TestAccessClosureRecordsRepoGetByBatchIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
records, _ := store.AccessClosures().GetByBatchID(context.Background(), 999)
|
|
if len(records) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(records))
|
|
}
|
|
}
|
|
|
|
func TestAccessClosureRecordsRepoValidation(t *testing.T) {
|
|
store := openTestDB(t)
|
|
_, err := store.AccessClosures().Create(context.Background(), AccessClosureRecord{BatchID: 0, ClosureType: "t", Status: "s"})
|
|
if err == nil {
|
|
t.Fatal("Create batch_id=0 error = nil")
|
|
}
|
|
}
|
|
|
|
// --- Reconcile Runs Repo Tests ---
|
|
|
|
func createTestProviderWithPack(t *testing.T, store *DB, packID int64) int64 {
|
|
t.Helper()
|
|
id, err := store.Providers().Create(context.Background(), Provider{
|
|
PackID: packID, ProviderID: "test-provider-" + sanitizeTestName(t.Name()), DisplayName: "TP",
|
|
BaseURL: "https://tp.com", Platform: "openai",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("createTestProviderWithPack error = %v", err)
|
|
}
|
|
return id
|
|
}
|
|
|
|
func createTestProvider(t *testing.T, store *DB) int64 {
|
|
t.Helper()
|
|
packID := createTestPack(t, store)
|
|
return createTestProviderWithPack(t, store, packID)
|
|
}
|
|
|
|
func TestReconcileRunsRepoCreateAndGet(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
batch, err := store.ImportBatches().GetByID(context.Background(), batchID)
|
|
if err != nil {
|
|
t.Fatalf("ImportBatches().GetByID() error = %v", err)
|
|
}
|
|
|
|
id, err := store.ReconcileRuns().Create(context.Background(), ReconcileRun{
|
|
BatchID: batchID, HostID: batch.HostID, ProviderID: batch.ProviderID, Status: "active", SummaryJSON: `{"drifted":false}`,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
runs, _ := store.ReconcileRuns().GetByBatchID(context.Background(), batchID)
|
|
if len(runs) != 1 || runs[0].Status != "active" {
|
|
t.Fatalf("runs = %+v, want 1 active", runs)
|
|
}
|
|
_ = id
|
|
}
|
|
|
|
func TestReconcileRunsRepoMultipleRunsOrderedDesc(t *testing.T) {
|
|
store := openTestDB(t)
|
|
batchID := createTestBatch(t, store)
|
|
batch, err := store.ImportBatches().GetByID(context.Background(), batchID)
|
|
if err != nil {
|
|
t.Fatalf("ImportBatches().GetByID() error = %v", err)
|
|
}
|
|
|
|
id1, _ := store.ReconcileRuns().Create(context.Background(), ReconcileRun{BatchID: batchID, HostID: batch.HostID, ProviderID: batch.ProviderID, Status: "first", SummaryJSON: "{}"})
|
|
id2, _ := store.ReconcileRuns().Create(context.Background(), ReconcileRun{BatchID: batchID, HostID: batch.HostID, ProviderID: batch.ProviderID, Status: "second", SummaryJSON: "{}"})
|
|
runs, _ := store.ReconcileRuns().GetByBatchID(context.Background(), batchID)
|
|
if len(runs) != 2 || runs[0].ID != id2 || runs[1].ID != id1 {
|
|
t.Fatalf("order: got %d, %d; want %d, %d (DESC)", runs[0].ID, runs[1].ID, id2, id1)
|
|
}
|
|
}
|
|
|
|
func TestReconcileRunsRepoSeparatesHosts(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostA := createTestHost(t, store)
|
|
hostB := createTestHostWithBaseURL(t, store, "host-b", "https://host-b.example.com")
|
|
packID := createTestPack(t, store)
|
|
providerID := createTestProviderWithPack(t, store, packID)
|
|
batchA, err := store.ImportBatches().Create(context.Background(), ImportBatch{HostID: hostA, PackID: packID, ProviderID: providerID, Mode: "partial", BatchStatus: "running", AccessStatus: "pending"})
|
|
if err != nil {
|
|
t.Fatalf("ImportBatches().Create(hostA) error = %v", err)
|
|
}
|
|
batchB, err := store.ImportBatches().Create(context.Background(), ImportBatch{HostID: hostB, PackID: packID, ProviderID: providerID, Mode: "partial", BatchStatus: "running", AccessStatus: "pending"})
|
|
if err != nil {
|
|
t.Fatalf("ImportBatches().Create(hostB) error = %v", err)
|
|
}
|
|
|
|
if _, err := store.ReconcileRuns().Create(context.Background(), ReconcileRun{BatchID: batchA, HostID: hostA, ProviderID: providerID, Status: "drifted", SummaryJSON: `{"host":"a"}`}); err != nil {
|
|
t.Fatalf("Create(hostA) error = %v", err)
|
|
}
|
|
if _, err := store.ReconcileRuns().Create(context.Background(), ReconcileRun{BatchID: batchB, HostID: hostB, ProviderID: providerID, Status: "active", SummaryJSON: `{"host":"b"}`}); err != nil {
|
|
t.Fatalf("Create(hostB) error = %v", err)
|
|
}
|
|
|
|
runs, _ := store.ReconcileRuns().GetByProviderIDAndHostID(context.Background(), providerID, hostA)
|
|
if len(runs) != 1 {
|
|
t.Fatalf("len(runs) = %d, want 1", len(runs))
|
|
}
|
|
if runs[0].Status != "drifted" {
|
|
t.Fatalf("runs[0].Status = %q, want drifted", runs[0].Status)
|
|
}
|
|
}
|
|
|
|
func TestReconcileRunsRepoGetByProviderIDAndHostIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
runs, _ := store.ReconcileRuns().GetByProviderIDAndHostID(context.Background(), 999, 1)
|
|
if len(runs) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(runs))
|
|
}
|
|
}
|
|
|
|
func TestReconcileRunsRepoGetByBatchIDEmpty(t *testing.T) {
|
|
store := openTestDB(t)
|
|
runs, _ := store.ReconcileRuns().GetByBatchID(context.Background(), 999)
|
|
if len(runs) != 0 {
|
|
t.Fatalf("count = %d, want 0", len(runs))
|
|
}
|
|
}
|
|
|
|
func TestReconcileRunsRepoValidation(t *testing.T) {
|
|
store := openTestDB(t)
|
|
hostID := createTestHost(t, store)
|
|
_, err := store.ReconcileRuns().Create(context.Background(), ReconcileRun{BatchID: 1, HostID: hostID, ProviderID: 0, Status: "s"})
|
|
if err == nil {
|
|
t.Fatal("Create provider_id=0 error = nil")
|
|
}
|
|
}
|