@@ -0,0 +1,212 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
"vctp/db"
|
||||
"vctp/internal/settings"
|
||||
)
|
||||
|
||||
func TestSnapshotTableCompatModeSettingControlsTaskBehaviorFlag(t *testing.T) {
|
||||
task := &CronTask{}
|
||||
if !task.snapshotTableCompatModeEnabled() {
|
||||
t.Fatal("expected default snapshot_table_compat_mode=true when settings are absent")
|
||||
}
|
||||
|
||||
task.Settings = &settings.Settings{Values: &settings.SettingsYML{}}
|
||||
if !task.snapshotTableCompatModeEnabled() {
|
||||
t.Fatal("expected default snapshot_table_compat_mode=true when value is unset")
|
||||
}
|
||||
|
||||
disabled := false
|
||||
task.Settings.Values.Settings.SnapshotTableCompatMode = &disabled
|
||||
if task.snapshotTableCompatModeEnabled() {
|
||||
t.Fatal("expected snapshot_table_compat_mode=false to disable legacy snapshot-table writes")
|
||||
}
|
||||
|
||||
enabled := true
|
||||
task.Settings.Values.Settings.SnapshotTableCompatMode = &enabled
|
||||
if !task.snapshotTableCompatModeEnabled() {
|
||||
t.Fatal("expected snapshot_table_compat_mode=true to enable legacy snapshot-table writes")
|
||||
}
|
||||
}
|
||||
|
||||
func TestManualDailyAggregate_SQLFallback_LegacyTablesAndReport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
dbConn := newTasksTestDB(t)
|
||||
task := newTasksTestCronTaskForAggregateFlow(t, dbConn)
|
||||
t.Setenv("DAILY_AGG_SQL", "1")
|
||||
t.Setenv("DAILY_AGG_GO", "")
|
||||
|
||||
dayStart := time.Date(2026, time.March, 15, 0, 0, 0, 0, time.UTC)
|
||||
t1 := dayStart.Add(1 * time.Hour).Unix()
|
||||
t2 := dayStart.Add(2 * time.Hour).Unix()
|
||||
|
||||
table1, err := hourlyInventoryTableName(time.Unix(t1, 0).UTC())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build first hourly table name: %v", err)
|
||||
}
|
||||
table2, err := hourlyInventoryTableName(time.Unix(t2, 0).UTC())
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build second hourly table name: %v", err)
|
||||
}
|
||||
for _, table := range []string{table1, table2} {
|
||||
if err := db.EnsureSnapshotTable(ctx, dbConn, table); err != nil {
|
||||
t.Fatalf("failed to ensure hourly snapshot table %s: %v", table, err)
|
||||
}
|
||||
}
|
||||
|
||||
seeds := []hourlySeedRow{
|
||||
{SnapshotTime: t1, Name: "vm-a", Vcenter: "vc-a", VmID: "vm-a", VmUUID: "uuid-a", ResourcePool: "Tin", Datacenter: "dc-a", Cluster: "cluster-a", Folder: "/prod", ProvisionedDisk: 100, VcpuCount: 2, RamGB: 8, CreationTime: dayStart.Add(-24 * time.Hour).Unix(), IsTemplate: "FALSE", PoweredOn: "TRUE", SrmPlaceholder: "FALSE"},
|
||||
{SnapshotTime: t2, Name: "vm-a", Vcenter: "vc-a", VmID: "vm-a", VmUUID: "uuid-a", ResourcePool: "Gold", Datacenter: "dc-a", Cluster: "cluster-a", Folder: "/prod", ProvisionedDisk: 120, VcpuCount: 4, RamGB: 8, CreationTime: dayStart.Add(-24 * time.Hour).Unix(), IsTemplate: "FALSE", PoweredOn: "TRUE", SrmPlaceholder: "FALSE"},
|
||||
{SnapshotTime: t2, Name: "vm-b", Vcenter: "vc-a", VmID: "vm-b", VmUUID: "uuid-b", ResourcePool: "Bronze", Datacenter: "dc-a", Cluster: "cluster-a", Folder: "/prod", ProvisionedDisk: 40, VcpuCount: 1, RamGB: 4, CreationTime: dayStart.Add(-48 * time.Hour).Unix(), IsTemplate: "FALSE", PoweredOn: "TRUE", SrmPlaceholder: "FALSE"},
|
||||
}
|
||||
for _, row := range seeds {
|
||||
table, tableErr := hourlyInventoryTableName(time.Unix(row.SnapshotTime, 0).UTC())
|
||||
if tableErr != nil {
|
||||
t.Fatalf("failed to build hourly table for seed row: %v", tableErr)
|
||||
}
|
||||
if err := insertHourlySnapshotSeedRow(ctx, dbConn, table, row); err != nil {
|
||||
t.Fatalf("failed to insert hourly snapshot seed row: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := task.aggregateDailySummaryWithMode(ctx, dayStart, true, false); err != nil {
|
||||
t.Fatalf("aggregateDailySummaryWithMode (legacy SQL fallback) failed: %v", err)
|
||||
}
|
||||
|
||||
summaryTable, err := dailySummaryTableName(dayStart)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build daily summary table name: %v", err)
|
||||
}
|
||||
rows, err := loadDailySummaryRows(ctx, dbConn, summaryTable)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load daily summary rows: %v", err)
|
||||
}
|
||||
if len(rows) != 2 {
|
||||
t.Fatalf("unexpected daily summary row count: got %d want %d", len(rows), 2)
|
||||
}
|
||||
|
||||
assertSnapshotRegistryRow(t, ctx, dbConn, "daily", summaryTable, dayStart.Unix(), int64(len(rows)))
|
||||
assertSummaryCacheMatchesByVcenter(t, ctx, dbConn, summaryTable, "daily", dayStart.Unix())
|
||||
|
||||
reportPath := filepath.Join(task.Settings.Values.Settings.ReportsDir, summaryTable+".xlsx")
|
||||
if _, err := os.Stat(reportPath); err != nil {
|
||||
t.Fatalf("expected daily report file at %s: %v", reportPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestManualMonthlyAggregate_SQLFallback_LegacyTablesAndReport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
dbConn := newTasksTestDB(t)
|
||||
task := newTasksTestCronTaskForAggregateFlow(t, dbConn)
|
||||
t.Setenv("MONTHLY_AGG_SQL", "1")
|
||||
t.Setenv("MONTHLY_AGG_GO", "")
|
||||
|
||||
monthStart := time.Date(2026, time.April, 1, 0, 0, 0, 0, time.UTC)
|
||||
day1 := monthStart.AddDate(0, 0, 2)
|
||||
day2 := monthStart.AddDate(0, 0, 3)
|
||||
|
||||
day1Table, err := dailySummaryTableName(day1)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build day1 summary table name: %v", err)
|
||||
}
|
||||
day2Table, err := dailySummaryTableName(day2)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build day2 summary table name: %v", err)
|
||||
}
|
||||
for _, table := range []string{day1Table, day2Table} {
|
||||
if err := db.EnsureSummaryTable(ctx, dbConn, table); err != nil {
|
||||
t.Fatalf("failed to ensure daily summary table %s: %v", table, err)
|
||||
}
|
||||
}
|
||||
|
||||
seeds := []dailySeedRow{
|
||||
{
|
||||
SnapshotTime: day1.Unix(),
|
||||
Name: "vm-a",
|
||||
Vcenter: "vc-a",
|
||||
VmID: "vm-a",
|
||||
VmUUID: "uuid-a",
|
||||
ResourcePool: "Bronze",
|
||||
Datacenter: "dc-a",
|
||||
Cluster: "cluster-a",
|
||||
Folder: "/prod",
|
||||
ProvisionedDisk: 100,
|
||||
VcpuCount: 2,
|
||||
RamGB: 8,
|
||||
CreationTime: monthStart.Add(-72 * time.Hour).Unix(),
|
||||
IsTemplate: "FALSE",
|
||||
PoweredOn: "TRUE",
|
||||
SrmPlaceholder: "FALSE",
|
||||
SamplesPresent: 2,
|
||||
AvgVcpuCount: 2,
|
||||
AvgRamGB: 8,
|
||||
AvgProvisionedDisk: 100,
|
||||
AvgIsPresent: 1.0,
|
||||
PoolBronzePct: 100,
|
||||
Bronze: 100,
|
||||
},
|
||||
{
|
||||
SnapshotTime: day2.Unix(),
|
||||
Name: "vm-a",
|
||||
Vcenter: "vc-a",
|
||||
VmID: "vm-a",
|
||||
VmUUID: "uuid-a",
|
||||
ResourcePool: "Tin",
|
||||
Datacenter: "dc-a",
|
||||
Cluster: "cluster-a",
|
||||
Folder: "/prod",
|
||||
ProvisionedDisk: 120,
|
||||
VcpuCount: 4,
|
||||
RamGB: 12,
|
||||
CreationTime: monthStart.Add(-72 * time.Hour).Unix(),
|
||||
IsTemplate: "FALSE",
|
||||
PoweredOn: "TRUE",
|
||||
SrmPlaceholder: "FALSE",
|
||||
SamplesPresent: 2,
|
||||
AvgVcpuCount: 4,
|
||||
AvgRamGB: 12,
|
||||
AvgProvisionedDisk: 120,
|
||||
AvgIsPresent: 1.0,
|
||||
PoolTinPct: 100,
|
||||
Tin: 100,
|
||||
},
|
||||
}
|
||||
for _, seed := range seeds {
|
||||
targetTable := day1Table
|
||||
if seed.SnapshotTime == day2.Unix() {
|
||||
targetTable = day2Table
|
||||
}
|
||||
if err := insertDailySummarySeedRow(ctx, dbConn, targetTable, seed); err != nil {
|
||||
t.Fatalf("failed to insert daily summary seed row: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := task.aggregateMonthlySummaryWithMode(ctx, monthStart, true, false); err != nil {
|
||||
t.Fatalf("aggregateMonthlySummaryWithMode (legacy SQL fallback) failed: %v", err)
|
||||
}
|
||||
|
||||
summaryTable, err := monthlySummaryTableName(monthStart)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build monthly summary table name: %v", err)
|
||||
}
|
||||
rows, err := loadMonthlySummaryRows(ctx, dbConn, summaryTable)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load monthly summary rows: %v", err)
|
||||
}
|
||||
if len(rows) != 1 {
|
||||
t.Fatalf("unexpected monthly summary row count: got %d want %d", len(rows), 1)
|
||||
}
|
||||
|
||||
assertSnapshotRegistryRow(t, ctx, dbConn, "monthly", summaryTable, monthStart.Unix(), int64(len(rows)))
|
||||
assertSummaryCacheMatchesByVcenter(t, ctx, dbConn, summaryTable, "monthly", monthStart.Unix())
|
||||
|
||||
reportPath := filepath.Join(task.Settings.Values.Settings.ReportsDir, summaryTable+".xlsx")
|
||||
if _, err := os.Stat(reportPath); err != nil {
|
||||
t.Fatalf("expected monthly report file at %s: %v", reportPath, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user