alt/services/worker/internal/storage/postgres/mapping_test.go
toki f762d2abd9 feat: worker persistence layer and socket session updates
- Add worker storage layer with PostgreSQL/sqlc setup
- Add migration files for worker backbone schema
- Add job runner and built-in jobs implementation
- Add Redis key definitions for worker state management
- Archive socket-session-loop milestone (completed/renamed)
- Update roadmap current.md and foundation-alignment phase
- Add socket endpoint integration and runtime smoke tests
- Add infra-check, worker-storage-check, worker-storage-gen CLI tools
- Update API socket server and config
- Add pubspec dependencies and client socket endpoint changes
- Add config tests for API and worker services
2026-05-28 19:05:10 +09:00

118 lines
3.5 KiB
Go

package postgres
import (
"testing"
"time"
"git.toki-labs.com/toki/alt/packages/domain/backtest"
"git.toki-labs.com/toki/alt/packages/domain/market"
"git.toki-labs.com/toki/alt/services/worker/internal/storage/postgres/sqlc"
)
func TestBacktestRunMappingRoundTrip(t *testing.T) {
now := time.Now().UTC().Truncate(time.Microsecond) // Truncate because postgres timestamptz resolves to microsecond precision
run := backtest.Run{
ID: backtest.RunID("run-123"),
Spec: backtest.RunSpec{
StrategyID: backtest.StrategyID("strat-abc"),
Market: market.MarketKR,
Timeframe: market.TimeframeDaily,
From: now.Add(-24 * time.Hour),
To: now,
},
Status: backtest.RunStatusSucceeded,
CreatedAt: now.Add(-25 * time.Hour),
UpdatedAt: now,
}
params, err := mapRunToParams(run)
if err != nil {
t.Fatalf("failed to map run to params: %v", err)
}
row := sqlc.BacktestRun{
ID: params.ID,
StrategyID: params.StrategyID,
Market: params.Market,
Timeframe: params.Timeframe,
FromTime: params.FromTime,
ToTime: params.ToTime,
Status: params.Status,
CreatedAt: params.CreatedAt,
UpdatedAt: params.UpdatedAt,
}
mappedBack, err := mapRowToRun(row)
if err != nil {
t.Fatalf("failed to map row back to run: %v", err)
}
if mappedBack.ID != run.ID {
t.Errorf("ID mismatch: got %v, want %v", mappedBack.ID, run.ID)
}
if mappedBack.Spec.StrategyID != run.Spec.StrategyID {
t.Errorf("StrategyID mismatch: got %v, want %v", mappedBack.Spec.StrategyID, run.Spec.StrategyID)
}
if mappedBack.Spec.Market != run.Spec.Market {
t.Errorf("Market mismatch: got %v, want %v", mappedBack.Spec.Market, run.Spec.Market)
}
if mappedBack.Spec.Timeframe != run.Spec.Timeframe {
t.Errorf("Timeframe mismatch: got %v, want %v", mappedBack.Spec.Timeframe, run.Spec.Timeframe)
}
if !mappedBack.Spec.From.Equal(run.Spec.From) {
t.Errorf("From mismatch: got %v, want %v", mappedBack.Spec.From, run.Spec.From)
}
if !mappedBack.Spec.To.Equal(run.Spec.To) {
t.Errorf("To mismatch: got %v, want %v", mappedBack.Spec.To, run.Spec.To)
}
if mappedBack.Status != run.Status {
t.Errorf("Status mismatch: got %v, want %v", mappedBack.Status, run.Status)
}
if !mappedBack.CreatedAt.Equal(run.CreatedAt) {
t.Errorf("CreatedAt mismatch: got %v, want %v", mappedBack.CreatedAt, run.CreatedAt)
}
if !mappedBack.UpdatedAt.Equal(run.UpdatedAt) {
t.Errorf("UpdatedAt mismatch: got %v, want %v", mappedBack.UpdatedAt, run.UpdatedAt)
}
}
func TestMarketBarMappingRejectsInvalidDecimal(t *testing.T) {
now := time.Now().UTC()
bar := market.Bar{
InstrumentID: market.InstrumentID("KRX:005930"),
Timeframe: market.TimeframeDaily,
Timestamp: now,
Open: market.Price{
Currency: market.CurrencyKRW,
Amount: market.Decimal{Value: "invalid_decimal"},
},
High: market.Price{
Currency: market.CurrencyKRW,
Amount: market.Decimal{Value: "50000"},
},
Low: market.Price{
Currency: market.CurrencyKRW,
Amount: market.Decimal{Value: "49000"},
},
Close: market.Price{
Currency: market.CurrencyKRW,
Amount: market.Decimal{Value: "49500"},
},
Volume: market.Quantity{
Amount: market.Decimal{Value: "1000000"},
},
}
_, err := mapBarToParams(bar)
if err == nil {
t.Fatal("expected error when mapping bar with invalid open decimal, got nil")
}
// Make Open valid but Volume invalid
bar.Open.Amount.Value = "50000"
bar.Volume.Amount.Value = "abc"
_, err = mapBarToParams(bar)
if err == nil {
t.Fatal("expected error when mapping bar with invalid volume decimal, got nil")
}
}