mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-09-15 04:21:06 +00:00
Operator-run tooling that moves durable Cloudflare KV data into the live AWS DynamoDB table, plus a runtime swap of the `value` attribute from Binary to String so payloads are human-readable in the AWS console. - cmd/migrate_cf_data: subcommands inventory, kv-import (idempotent via attribute_not_exists), trading-audit-dump, convert-value-to-string - internal/migration: policy allowlist, CF KV+D1 REST clients, DynamoDB writer, report formatter with per-prefix counts + tests - internal/storage/dynamodb_kv.go: Put writes MemberS, Get reads MemberS; dropped empty-bytes sentinel (DynamoDB allows empty strings)
53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
package migration
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestReportFormat(t *testing.T) {
|
|
r := NewReport()
|
|
r.AddImported("wordle:stats:")
|
|
r.AddImported("wordle:stats:")
|
|
r.AddImported("trading:user:")
|
|
r.AddSkippedExisting("loldle:stats:")
|
|
r.AddSkippedPolicy("cache")
|
|
r.AddSkippedPolicy("cache")
|
|
r.AddSkippedPolicy("retired")
|
|
r.AddFailed("twentyq:stats:")
|
|
|
|
var buf bytes.Buffer
|
|
r.Format(&buf)
|
|
got := buf.String()
|
|
|
|
// Spot-check structure and totals.
|
|
for _, want := range []string{
|
|
"Imported:",
|
|
"wordle:stats: 2",
|
|
"trading:user: 1",
|
|
"Skipped (already present):",
|
|
"loldle:stats: 1",
|
|
"Skipped (policy):",
|
|
"cache 2",
|
|
"retired 1",
|
|
"Failed:",
|
|
"twentyq:stats: 1",
|
|
"TOTAL imported=3 skipped_existing=1 skipped_policy=3 failed=1",
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Errorf("missing %q in output:\n%s", want, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReportEmptySection(t *testing.T) {
|
|
r := NewReport()
|
|
r.AddImported("wordle:stats:")
|
|
var buf bytes.Buffer
|
|
r.Format(&buf)
|
|
if !strings.Contains(buf.String(), "Failed:\n (none)") {
|
|
t.Errorf("empty section missing (none) marker:\n%s", buf.String())
|
|
}
|
|
}
|