mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 10:35:51 +00:00
125 lines
3.9 KiB
Go
125 lines
3.9 KiB
Go
package resourceapi
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/api/apicontext"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
unifiedresources "github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
)
|
|
|
|
func TestPruneResourceForListResponseDoesNotMutateSharedPMG(t *testing.T) {
|
|
sharedPMG := &unifiedresources.PMGData{
|
|
InstanceID: "pmg-1",
|
|
RelayDomains: []unifiedresources.PMGRelayDomainMeta{{Domain: "example.com"}},
|
|
DomainStatsAsOf: time.Date(2026, 8, 5, 12, 0, 0, 0, time.UTC),
|
|
}
|
|
resource := unifiedresources.Resource{ID: "pmg-resource", PMG: sharedPMG}
|
|
|
|
pruneResourceForListResponse(&resource)
|
|
|
|
if resource.PMG == sharedPMG {
|
|
t.Fatal("expected prune to clone the PMG struct before clearing it")
|
|
}
|
|
if resource.PMG.RelayDomains != nil || !resource.PMG.DomainStatsAsOf.IsZero() {
|
|
t.Fatal("expected the pruned copy to be cleared")
|
|
}
|
|
if len(sharedPMG.RelayDomains) != 1 || sharedPMG.DomainStatsAsOf.IsZero() {
|
|
t.Fatal("expected the shared PMG struct to remain untouched")
|
|
}
|
|
}
|
|
|
|
func TestSharedResourceListsCachedPerGenerationAndImmuneToRequestDecoration(t *testing.T) {
|
|
now := time.Date(2026, 8, 5, 12, 0, 0, 0, time.UTC)
|
|
h := NewQueryService(&config.Config{DataPath: t.TempDir()})
|
|
h.SetStateProvider(resourceUnifiedSeedProvider{
|
|
snapshot: models.StateSnapshot{LastUpdate: now},
|
|
resources: []unifiedresources.Resource{
|
|
{
|
|
ID: "vm-1",
|
|
Type: unifiedresources.ResourceTypeVM,
|
|
Name: "worker",
|
|
Status: unifiedresources.StatusOnline,
|
|
LastSeen: now,
|
|
Sources: []unifiedresources.DataSource{unifiedresources.SourceProxmox},
|
|
},
|
|
{
|
|
ID: "pmg-1",
|
|
Type: unifiedresources.ResourceTypePMG,
|
|
Name: "mailgw",
|
|
Status: unifiedresources.StatusOnline,
|
|
LastSeen: now,
|
|
Sources: []unifiedresources.DataSource{unifiedresources.SourceProxmox},
|
|
PMG: &unifiedresources.PMGData{
|
|
InstanceID: "pmg-1",
|
|
RelayDomains: []unifiedresources.PMGRelayDomainMeta{{Domain: "example.com"}},
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
orgID := ""
|
|
first, _, err := h.sharedPresentationResources(orgID)
|
|
if err != nil {
|
|
t.Fatalf("sharedPresentationResources: %v", err)
|
|
}
|
|
if len(first) == 0 {
|
|
t.Fatal("expected seeded resources")
|
|
}
|
|
second, _, err := h.sharedPresentationResources(orgID)
|
|
if err != nil {
|
|
t.Fatalf("sharedPresentationResources: %v", err)
|
|
}
|
|
if &first[0] != &second[0] {
|
|
t.Fatal("expected the cached shared list for an unchanged registry generation")
|
|
}
|
|
|
|
// A full list request prunes PMG detail in its response; the shared cache
|
|
// must keep the untouched data for later consumers.
|
|
req := httptest.NewRequest(http.MethodGet, "/api/resources", nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), apicontext.OrgIDContextKey, orgID))
|
|
rec := httptest.NewRecorder()
|
|
h.HandleListResources(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
|
|
after, _, err := h.sharedPresentationResources(orgID)
|
|
if err != nil {
|
|
t.Fatalf("sharedPresentationResources: %v", err)
|
|
}
|
|
if &first[0] != &after[0] {
|
|
t.Fatal("expected the request to serve from the cached list, not rebuild it")
|
|
}
|
|
foundPMG := false
|
|
for i := range after {
|
|
if after[i].PMG == nil {
|
|
continue
|
|
}
|
|
foundPMG = true
|
|
if len(after[i].PMG.RelayDomains) != 1 {
|
|
t.Fatal("expected the shared cache to retain PMG relay domains after a list request pruned its response copy")
|
|
}
|
|
}
|
|
if !foundPMG {
|
|
t.Fatal("expected a PMG-bearing resource in the shared list")
|
|
}
|
|
|
|
rawFirst, _, err := h.sharedRawResources(orgID)
|
|
if err != nil {
|
|
t.Fatalf("sharedRawResources: %v", err)
|
|
}
|
|
rawSecond, _, err := h.sharedRawResources(orgID)
|
|
if err != nil {
|
|
t.Fatalf("sharedRawResources: %v", err)
|
|
}
|
|
if len(rawFirst) == 0 || &rawFirst[0] != &rawSecond[0] {
|
|
t.Fatal("expected the cached shared raw list for an unchanged registry generation")
|
|
}
|
|
}
|