Files
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

71 lines
3.1 KiB
Go

package forecast
import (
"context"
"encoding/json"
"fmt"
"os"
"testing"
"time"
"github.com/itworx/pulse/internal/agentstore"
"github.com/itworx/pulse/internal/database"
"github.com/itworx/pulse/internal/pool"
"github.com/itworx/pulse/internal/share"
)
func TestStorageForecastPostgreSQLHistory(t *testing.T) {
dsn := os.Getenv("PULSE_TEST_DATABASE_URL")
if dsn == "" {
t.Skip("PULSE_TEST_DATABASE_URL is not set")
}
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
db, err := database.NewPool(ctx, database.Config{URL: dsn})
if err != nil {
t.Fatal(err)
}
defer db.Close()
if err := database.Migrate(ctx, db); err != nil {
t.Fatal(err)
}
run := fmt.Sprintf("forecast-%x", time.Now().UnixNano())
now := time.Now().UTC().Truncate(time.Second)
for _, point := range []struct {
at time.Time
used int64
}{{now.Add(-14 * 24 * time.Hour), 200}, {now.Add(-7 * 24 * time.Hour), 300}, {now, 400}} {
_, err := db.Exec(ctx, `INSERT INTO capacity_samples (entity_kind,entity_id,entity_name,source_id,sampled_at,observed_at,used_bytes,capacity_bytes) VALUES ('share',$1,'Media',$2,$3,$3,$4,0)`, run, run, point.at, point.used)
if err != nil {
t.Fatal(err)
}
}
store := agentstore.PostgresStore{Pool: db, Clock: func() time.Time { return now }}
sharePayload, err := json.Marshal(share.RawSnapshot{Source: share.Source{ID: "forecast-test", Type: "test"}, ObservedAt: now, ReceivedAt: now, Shares: []share.RawShare{{ID: run, Name: "Media forecast", UsedBytes: 400, SizeObservedAt: now, SizeState: share.SizeAvailable, Placements: []share.RawPlacement{{PoolID: "cache"}}}}})
if err != nil {
t.Fatal(err)
}
poolPayload, err := json.Marshal(pool.RawSnapshot{Source: pool.Source{ID: "forecast-test", Type: "test"}, ObservedAt: now, ReceivedAt: now, Pools: []pool.RawPool{{ID: "cache", Name: "Cache", State: pool.StateHealthy, UsableBytes: 1000, UsedBytes: 400, Capabilities: pool.Capabilities{Capacity: pool.CapabilityAvailable}}}})
if err != nil {
t.Fatal(err)
}
if err := store.Put(ctx, agentstore.Snapshot{AgentID: run, Capability: agentstore.CapabilityShares, ObservedAt: now, Payload: sharePayload}); err != nil {
t.Fatal(err)
}
if err := store.Put(ctx, agentstore.Snapshot{AgentID: run, Capability: agentstore.CapabilityPools, ObservedAt: now, Payload: poolPayload}); err != nil {
t.Fatal(err)
}
provider := StorageProvider{
Shares: staticShares{share.Snapshot{Source: share.Source{Freshness: share.Fresh}, Shares: []share.Share{{ID: run, Name: "Media", UsedBytes: 400, SizeObservedAt: now, SizeState: share.SizeAvailable, Placements: []share.Placement{{PoolID: "cache"}}}}}},
Pools: staticPools{pool.Snapshot{Pools: []pool.Pool{{ID: "cache", UsableBytes: 1000}}}},
History: PostgresHistory{Pool: db}, Policy: Policy{Enabled: true}, Now: func() time.Time { return now },
}
snapshot, err := provider.Snapshot(ctx)
if err != nil {
t.Fatal(err)
}
if snapshot.QualifiedCount != 1 || len(snapshot.Items) != 1 || snapshot.Items[0].DataPoints != 3 || snapshot.Items[0].ProjectedAt == nil {
t.Fatalf("persisted history did not produce a qualified forecast: %+v", snapshot)
}
}