ProofedMesh/services/attest-reconciler/internal/reconcile/scheduler_test.go
CTO 2e44147a71
All checks were successful
validate / JSON Schema (ajv) (push) Successful in 19s
validate / Go (vet + test) (push) Successful in 19s
validate / Rego (opa fmt + opa test) (push) Successful in 14s
services: add attest-reconciler Go service (periodic worker re-signs per_diem_rates rows without rate_change_attestation_ref via Signer+TLog, 11/11 go tests pass, go vet clean)
- services/attest-reconciler/ as its own go.mod (admin-api internal/ is not importable; shared code gets extracted when a 3rd consumer appears).
- Scheduler accepts "@every <dur>" or a bare Go duration; context-cancellation stops the loop cleanly.
- Store client defines PendingRateStore + Postgres skeleton for SELECT ... WHERE rate_change_attestation_ref IS NULL.
- Orchestrator + HTTPSigner + tlog.HTTPSubmitter mirror admin-api byte-for-byte so the TLog idempotency key collides on resubmits (kein Doppelsignieren).
- Prometheus text-format /metrics endpoint, dependency-free: attest_reconciler_dirty_rows_total, _reconciliation_attempts_total, _reconciliation_failures_total, _idempotent_noop_total.
- Tests with fake store + fake signer + fake submitter cover: happy path, already-attested rows are NOT re-signed, TLog idempotency across ticks, TLog-down failure path, pre-cancelled ctx.
- Top-level README reflects the new service; CI auto-discovers services/*/go.mod so no workflow change needed.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-25 18:06:36 +00:00

40 lines
790 B
Go

package reconcile
import (
"testing"
"time"
)
func TestParseSpec(t *testing.T) {
cases := []struct {
in string
want time.Duration
wantErr bool
}{
{"@every 30s", 30 * time.Second, false},
{"@every 2m", 2 * time.Minute, false},
{"5m", 5 * time.Minute, false},
{"1h30m", 90 * time.Minute, false},
{"", 0, true},
{"@every", 0, true},
{"@every 0s", 0, true},
{"-1m", 0, true},
{"* * * * *", 0, true},
}
for _, c := range cases {
got, err := ParseSpec(c.in)
if c.wantErr {
if err == nil {
t.Errorf("ParseSpec(%q) err=nil; want error", c.in)
}
continue
}
if err != nil {
t.Errorf("ParseSpec(%q) err=%v; want nil", c.in, err)
continue
}
if got != c.want {
t.Errorf("ParseSpec(%q) = %v; want %v", c.in, got, c.want)
}
}
}