speed up vm trace pages
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-09 14:19:24 +11:00
parent c4097ca608
commit 59b16db04f
12 changed files with 702 additions and 208 deletions

View File

@@ -126,6 +126,20 @@ INSERT INTO vm_hourly_stats (
if traceRows[0].SnapshotTime != 1000 || traceRows[1].SnapshotTime != 2000 {
t.Fatalf("trace rows are not sorted by snapshot time: %#v", traceRows)
}
traceRowsByName, err := FetchVmTrace(ctx, dbConn, "", "", "DEMO-VM")
if err != nil {
t.Fatalf("FetchVmTrace by name failed: %v", err)
}
if len(traceRowsByName) != 2 {
t.Fatalf("expected 2 trace rows by name, got %d", len(traceRowsByName))
}
emptyTraceRows, err := FetchVmTrace(ctx, dbConn, "", "", "")
if err != nil {
t.Fatalf("FetchVmTrace with empty identifier failed: %v", err)
}
if len(emptyTraceRows) != 0 {
t.Fatalf("expected 0 trace rows for empty identifier, got %d", len(emptyTraceRows))
}
lifecycle, err := FetchVmLifecycle(ctx, dbConn, "vm-1", "", "")
if err != nil {
@@ -143,6 +157,125 @@ INSERT INTO vm_hourly_stats (
if lifecycle.DeletionTime != 2500 {
t.Fatalf("expected DeletionTime=2500 from lifecycle cache, got %d", lifecycle.DeletionTime)
}
lifecycleByName, err := FetchVmLifecycle(ctx, dbConn, "", "", "DEMO-VM")
if err != nil {
t.Fatalf("FetchVmLifecycle by name failed: %v", err)
}
if lifecycleByName.FirstSeen != 900 || lifecycleByName.LastSeen != 2000 {
t.Fatalf("unexpected lifecycle for name lookup: %#v", lifecycleByName)
}
emptyLifecycle, err := FetchVmLifecycle(ctx, dbConn, "", "", "")
if err != nil {
t.Fatalf("FetchVmLifecycle with empty identifier failed: %v", err)
}
if emptyLifecycle.FirstSeen != 0 || emptyLifecycle.LastSeen != 0 || emptyLifecycle.CreationTime != 0 || emptyLifecycle.DeletionTime != 0 {
t.Fatalf("expected empty lifecycle for empty identifier, got %#v", emptyLifecycle)
}
}
func TestFetchVmTraceDailyFromRollup(t *testing.T) {
ctx := context.Background()
dbConn := newTestSQLiteDB(t)
if err := EnsureVmDailyRollup(ctx, dbConn); err != nil {
t.Fatalf("failed to ensure vm_daily_rollup: %v", err)
}
if err := UpsertVmDailyRollup(ctx, dbConn, 1700000000, VmDailyRollupRow{
Vcenter: "vc-a",
VmId: "vm-1",
VmUuid: "uuid-1",
Name: "demo-vm",
CreationTime: 1699999000,
SamplesPresent: 8,
SumVcpu: 32,
SumRam: 64,
LastVcpuCount: 4,
LastRamGB: 8,
LastResourcePool: "Tin",
}); err != nil {
t.Fatalf("failed to insert daily rollup row 1: %v", err)
}
if err := UpsertVmDailyRollup(ctx, dbConn, 1700086400, VmDailyRollupRow{
Vcenter: "vc-a",
VmId: "vm-1",
VmUuid: "uuid-1",
Name: "demo-vm",
CreationTime: 1699999000,
SamplesPresent: 4,
SumVcpu: 20,
SumRam: 36,
LastVcpuCount: 5,
LastRamGB: 9,
LastResourcePool: "Gold",
LastProvisionedDisk: 150.5,
}); err != nil {
t.Fatalf("failed to insert daily rollup row 2: %v", err)
}
rows, err := FetchVmTraceDaily(ctx, dbConn, "vm-1", "", "")
if err != nil {
t.Fatalf("FetchVmTraceDaily failed: %v", err)
}
if len(rows) != 2 {
t.Fatalf("expected 2 daily trace rows, got %d", len(rows))
}
if rows[0].SnapshotTime != 1700000000 || rows[0].VcpuCount != 4 || rows[0].RamGB != 8 {
t.Fatalf("unexpected first daily row: %#v", rows[0])
}
if rows[1].SnapshotTime != 1700086400 || rows[1].VcpuCount != 5 || rows[1].RamGB != 9 || rows[1].ProvisionedDisk != 150.5 {
t.Fatalf("unexpected second daily row: %#v", rows[1])
}
}
func TestFetchVmTraceDailyFallbackToSummaryTables(t *testing.T) {
ctx := context.Background()
dbConn := newTestSQLiteDB(t)
if _, err := dbConn.ExecContext(ctx, `
CREATE TABLE snapshot_registry (
snapshot_type TEXT,
table_name TEXT,
snapshot_time BIGINT
)`); err != nil {
t.Fatalf("failed to create snapshot_registry: %v", err)
}
summaryTable := "inventory_daily_summary_20260106"
if _, err := dbConn.ExecContext(ctx, fmt.Sprintf(`
CREATE TABLE %s (
"Name" TEXT,
"Vcenter" TEXT,
"VmId" TEXT,
"VmUuid" TEXT,
"ResourcePool" TEXT,
"AvgVcpuCount" REAL,
"AvgRamGB" REAL,
"AvgProvisionedDisk" REAL,
"CreationTime" BIGINT,
"DeletionTime" BIGINT
)`, summaryTable)); err != nil {
t.Fatalf("failed to create summary table: %v", err)
}
if _, err := dbConn.ExecContext(ctx, fmt.Sprintf(`
INSERT INTO %s ("Name","Vcenter","VmId","VmUuid","ResourcePool","AvgVcpuCount","AvgRamGB","AvgProvisionedDisk","CreationTime","DeletionTime")
VALUES (?,?,?,?,?,?,?,?,?,?)
`, summaryTable), "demo-vm", "vc-a", "vm-1", "uuid-1", "Silver", 3.2, 6.7, 123.4, int64(1699999000), int64(0)); err != nil {
t.Fatalf("failed to insert summary row: %v", err)
}
if _, err := dbConn.ExecContext(ctx, `INSERT INTO snapshot_registry (snapshot_type, table_name, snapshot_time) VALUES (?,?,?)`, "daily", summaryTable, int64(1700500000)); err != nil {
t.Fatalf("failed to insert snapshot_registry row: %v", err)
}
rows, err := FetchVmTraceDaily(ctx, dbConn, "", "uuid-1", "")
if err != nil {
t.Fatalf("FetchVmTraceDaily fallback failed: %v", err)
}
if len(rows) != 1 {
t.Fatalf("expected 1 fallback daily row, got %d", len(rows))
}
if rows[0].SnapshotTime != 1700500000 || rows[0].VcpuCount != 3 || rows[0].RamGB != 6 {
t.Fatalf("unexpected fallback daily row: %#v", rows[0])
}
}
func TestParseHourlySnapshotUnix(t *testing.T) {