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>
185 lines
8.9 KiB
Go
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")
|
|
}
|
|
}
|