Files
observatory/internal/storage/dashboards_test.go
T
gamertan 92a66db3df docs: publish Preview 19 dogfood evidence
Export the reviewed allowlisted snapshot from private source commit 05928cebd01b586cf9e9d4b8c8537a7605a6068c. This records the exact candidate, bounded capacity result, stateful migration scratch requirement, authenticated batch identity proof, and immediate live acceptance evidence.

AI-Assisted: OpenAI Codex
Signed-off-by: Cole Speelman <crspeelman@gmail.com>
2026-08-18 21:47:08 -04:00

185 lines
8.9 KiB
Go

// SPDX-License-Identifier: AGPL-3.0-only
package storage
import (
"context"
"encoding/json"
"errors"
"strings"
"testing"
"time"
)
func TestSavedQueriesAreTypedVersionedAndOptimisticallyUpdated(t *testing.T) {
ctx := context.Background()
store := testStore(t)
defer store.Close()
now := time.Date(2026, 8, 17, 10, 0, 0, 0, time.UTC)
input := SavedQueryInput{
OrganizationID: "organization-a", Name: "Recent failures",
Description: "Recent failed application requests grouped by route.",
Query: `logs | where status >= 500 | window 1h | summarize count() by route | sort count desc | limit 50`,
Scope: ResourceScope{ProjectID: "project-a", EnvironmentID: "production", ServiceID: "service-a"},
ActorUserID: "operator-a", MaxRows: 1000,
}
created, err := store.SaveQuery(ctx, input, now)
if err != nil {
t.Fatal(err)
}
if created.Version != SavedQueryVersion || created.Revision != 1 || created.ID == "" || created.AST.Signal != "logs" || created.AST.Window != time.Hour || created.CreatedAt != now || created.UpdatedAt != now {
t.Fatalf("created=%+v", created)
}
input.ID, input.ExpectedRevision = created.ID, created.Revision
input.Description = "Reviewed application failures grouped by normalized route."
updated, err := store.SaveQuery(ctx, input, now.Add(time.Minute))
if err != nil {
t.Fatal(err)
}
if updated.Revision != 2 || updated.Description != input.Description || updated.UpdatedBy != "operator-a" || !updated.UpdatedAt.Equal(now.Add(time.Minute)) {
t.Fatalf("updated=%+v", updated)
}
if _, err = store.SaveQuery(ctx, input, now.Add(2*time.Minute)); err == nil {
t.Fatal("stale saved-query revision was accepted")
}
queries, err := store.SavedQueries(ctx, "organization-a")
if err != nil || len(queries) != 1 || queries[0].Revision != 2 {
t.Fatalf("queries=%+v err=%v", queries, err)
}
if _, err = store.control.Exec(`UPDATE saved_queries SET ast_json='{}' WHERE organization_id='organization-a' AND id=?`, created.ID); err != nil {
t.Fatal(err)
}
if _, err = store.SavedQuery(ctx, "organization-a", created.ID); err == nil {
t.Fatal("query text and stored AST disagreement was accepted")
}
}
func TestDashboardPanelsRemainOrganizationScopedAndExportSafeDefinitions(t *testing.T) {
ctx := context.Background()
store := testStore(t)
defer store.Close()
now := time.Date(2026, 8, 17, 10, 0, 0, 0, time.UTC)
queryA, err := store.SaveQuery(ctx, SavedQueryInput{OrganizationID: "organization-a", Name: "Request rate", Description: "Five-minute request counts.", Query: `logs | window 1h | summarize count() by window(5m) | limit 50`, ActorUserID: "operator-a", MaxRows: 1000}, now)
if err != nil {
t.Fatal(err)
}
queryB, err := store.SaveQuery(ctx, SavedQueryInput{OrganizationID: "organization-b", Name: "Other organization", Description: "Must not cross the tenant boundary.", Query: `logs | limit 10`, ActorUserID: "operator-b", MaxRows: 1000}, now)
if err != nil {
t.Fatal(err)
}
input := DashboardInput{
OrganizationID: "organization-a", Slug: "operations", Name: "Operations",
Description: "Recent service activity and evidence.", ActorUserID: "operator-a",
Panels: []DashboardPanel{{Position: 0, Title: "Request rate", Visualization: "timeseries", SavedQueryID: queryA.ID}},
}
created, err := store.SaveDashboard(ctx, input, now)
if err != nil {
t.Fatal(err)
}
if created.Version != DashboardVersion || created.Revision != 1 || len(created.Panels) != 1 || created.Panels[0].ID == "" {
t.Fatalf("created=%+v", created)
}
unsafe := input
unsafe.Slug = "cross-tenant"
unsafe.Panels = []DashboardPanel{{Position: 0, Title: "Other", Visualization: "table", SavedQueryID: queryB.ID}}
if _, err = store.SaveDashboard(ctx, unsafe, now); err == nil {
t.Fatal("cross-organization saved query entered dashboard")
}
input.ID, input.ExpectedRevision = created.ID, created.Revision
input.Name = "Service operations"
input.Panels[0].ID = created.Panels[0].ID
updated, err := store.SaveDashboard(ctx, input, now.Add(time.Minute))
if err != nil {
t.Fatal(err)
}
if updated.Revision != 2 || updated.Name != input.Name {
t.Fatalf("updated=%+v", updated)
}
if _, err = store.SaveDashboard(ctx, input, now.Add(2*time.Minute)); !errors.Is(err, ErrDashboardRevisionConflict) {
t.Fatalf("stale dashboard revision err=%v", err)
}
exported, err := store.ExportDashboard(ctx, "organization-a", "operations")
if err != nil {
t.Fatal(err)
}
body, err := json.Marshal(exported)
if err != nil {
t.Fatal(err)
}
for _, forbidden := range []string{"organization-a", "operator-a", "created_at", "updated_at", "ast"} {
if strings.Contains(string(body), forbidden) {
t.Fatalf("private runtime metadata %q entered export: %s", forbidden, body)
}
}
if !strings.Contains(string(body), `"version":1`) || !strings.Contains(string(body), `"query":"logs | window 1h`) {
t.Fatalf("export=%s", body)
}
}
func TestDashboardValidationBoundsScopePanelsAndServerGeneratedIdentity(t *testing.T) {
ctx := context.Background()
store := testStore(t)
defer store.Close()
now := time.Date(2026, 8, 17, 10, 0, 0, 0, time.UTC)
if _, err := store.SaveQuery(ctx, SavedQueryInput{OrganizationID: "organization-a", Name: "Invalid scope", Query: `logs | limit 10`, Scope: ResourceScope{ServiceID: "service-a"}, ActorUserID: "operator-a", MaxRows: 1000}, now); err == nil {
t.Fatal("service-only query scope was accepted")
}
queryValue, err := store.SaveQuery(ctx, SavedQueryInput{OrganizationID: "organization-a", Name: "Valid", Query: `logs | limit 10`, ActorUserID: "operator-a", MaxRows: 1000}, now)
if err != nil {
t.Fatal(err)
}
if _, err = store.SaveDashboard(ctx, DashboardInput{ID: "caller-selected", OrganizationID: "organization-a", Slug: "invalid-id", Name: "Invalid", ActorUserID: "operator-a"}, now); err == nil {
t.Fatal("caller-selected new dashboard identity was accepted")
}
duplicate := DashboardInput{OrganizationID: "organization-a", Slug: "duplicate-panels", Name: "Duplicate panels", ActorUserID: "operator-a", Panels: []DashboardPanel{
{Position: 0, Title: "First", Visualization: "table", SavedQueryID: queryValue.ID},
{Position: 0, Title: "Second", Visualization: "stat", SavedQueryID: queryValue.ID},
}}
if _, err = store.SaveDashboard(ctx, duplicate, now); err == nil {
t.Fatal("duplicate dashboard panel positions were accepted")
}
}
func TestDashboardImportIsAtomicTenantIndependentAndRevalidated(t *testing.T) {
ctx := context.Background()
store := testStore(t)
defer store.Close()
now := time.Date(2026, 8, 17, 11, 0, 0, 0, time.UTC)
bundle := DashboardExport{
Version: DashboardVersion,
Dashboard: DashboardDefinition{Slug: "operations", Name: "Operations", Description: "A portable service view.", Panels: []DashboardPanel{
{ID: "old-panel-1", Position: 0, Title: "Recent failures", Visualization: "table", SavedQueryID: "portable-query-1"},
}},
SavedQueries: []SavedQueryDefinition{{ID: "portable-query-1", Name: "Recent failures", Description: "Bounded failures.", Query: `logs | where status >= 500 | window 1h | limit 50`}},
}
imported, err := store.ImportDashboard(ctx, DashboardImportInput{OrganizationID: "organization-b", ActorUserID: "operator-b", MaxRows: 1_000, Bundle: bundle}, now)
if err != nil {
t.Fatal(err)
}
if imported.OrganizationID != "organization-b" || imported.CreatedBy != "operator-b" || imported.ID == "" || len(imported.Panels) != 1 || imported.Panels[0].ID == "old-panel-1" || imported.Panels[0].SavedQueryID == "portable-query-1" {
t.Fatalf("imported=%+v", imported)
}
queries, err := store.SavedQueries(ctx, "organization-b")
if err != nil || len(queries) != 1 || queries[0].OrganizationID != "organization-b" || queries[0].CreatedBy != "operator-b" || queries[0].ID != imported.Panels[0].SavedQueryID {
t.Fatalf("queries=%+v err=%v", queries, err)
}
invalid := bundle
invalid.Dashboard.Slug = "partial-import"
invalid.SavedQueries = append(invalid.SavedQueries, SavedQueryDefinition{ID: "unused-query-2", Name: "Unused", Query: `logs | limit 10`})
if _, err = store.ImportDashboard(ctx, DashboardImportInput{OrganizationID: "organization-b", ActorUserID: "operator-b", MaxRows: 1_000, Bundle: invalid}, now); err == nil {
t.Fatal("unreferenced imported query was accepted")
}
if dashboards, listErr := store.Dashboards(ctx, "organization-b"); listErr != nil || len(dashboards) != 1 {
t.Fatalf("failed import left partial dashboard: dashboards=%+v err=%v", dashboards, listErr)
}
if queries, listErr := store.SavedQueries(ctx, "organization-b"); listErr != nil || len(queries) != 1 {
t.Fatalf("failed import left partial queries: queries=%+v err=%v", queries, listErr)
}
incompatible := bundle
incompatible.Dashboard.Slug = "invalid-presentation"
incompatible.Dashboard.Panels[0].Visualization = "timeseries"
if _, err = store.ImportDashboard(ctx, DashboardImportInput{OrganizationID: "organization-b", ActorUserID: "operator-b", MaxRows: 1_000, Bundle: incompatible}, now); err == nil {
t.Fatal("timeseries dashboard without a bucketed summary was accepted")
}
}