carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package objstore
2
3import (
4 "context"
5 "errors"
6 "testing"
7
8 "github.com/carlosframework/platform/internal/release"
9)
10
11func TestScanKey(t *testing.T) {
12 if got := ScanKey("bab", "titogo"); got != "apps/bab/titogo/scan.json" {
13 t.Fatalf("ScanKey = %q", got)
14 }
15}
16
17func TestSidecarRoundTrip(t *testing.T) {
18 ctx := context.Background()
19 s := release.NewDirStore(t.TempDir())
20 sc := &ScanSidecar{
21 LastComplete: &Sweep{
22 Objects: 12481, Scanned: 12479, Skipped: 2, Engine: "clamav",
23 Signature: "ClamAV 1.4.1/27500/Mon Sep 1 08:00:00 2026",
24 },
25 }
26 if _, err := PutSidecar(ctx, s, "bab", "titogo", sc, ""); err != nil {
27 t.Fatal(err)
28 }
29 back, etag, err := GetSidecar(ctx, s, "bab", "titogo")
30 if err != nil {
31 t.Fatal(err)
32 }
33 if etag == "" {
34 t.Fatal("GetSidecar returned no etag, so no caller can CAS against it")
35 }
36 if back.LastComplete == nil || back.LastComplete.Objects != 12481 {
37 t.Fatalf("rollup did not round-trip: %+v", back)
38 }
39 if back.LastComplete.Skipped != 2 {
40 t.Fatalf("skipped = %d, want 2 — skipped must never be folded into scanned",
41 back.LastComplete.Skipped)
42 }
43 if back.Schema != SidecarSchema || back.Account != "bab" || back.App != "titogo" {
44 t.Fatalf("PutSidecar did not stamp identity: %+v", back)
45 }
46}
47
48// Absent is (nil, "", nil): a store nobody has swept has no sidecar, and that
49// is a state rather than an error.
50func TestSidecarAbsentIsNotAnError(t *testing.T) {
51 sc, etag, err := GetSidecar(context.Background(),
52 release.NewDirStore(t.TempDir()), "bab", "titogo")
53 if err != nil || sc != nil || etag != "" {
54 t.Fatalf("absent sidecar = (%v, %q, %v), want (nil, \"\", nil)", sc, etag, err)
55 }
56}
57
58// accounts migrate copies every key under an app's prefix, so a sidecar can
59// arrive under an account it was never written for, still carrying rollups for
60// a bucket named after the old one. Refusing beats reporting one account's
61// coverage as another's.
62func TestSidecarRefusesAccountMismatch(t *testing.T) {
63 ctx := context.Background()
64 s := release.NewDirStore(t.TempDir())
65 if _, err := PutSidecar(ctx, s, "bab", "titogo", &ScanSidecar{}, ""); err != nil {
66 t.Fatal(err)
67 }
68 raw, _, err := s.Get(ctx, ScanKey("bab", "titogo"))
69 if err != nil {
70 t.Fatal(err)
71 }
72 // Exactly what a migration does: the same bytes under a new prefix.
73 if _, err := s.Put(ctx, ScanKey("zed", "titogo"), raw, ""); err != nil {
74 t.Fatal(err)
75 }
76 if _, _, err := GetSidecar(ctx, s, "zed", "titogo"); !errors.Is(err, ErrSidecarMismatch) {
77 t.Fatalf("migrated sidecar error = %v, want ErrSidecarMismatch", err)
78 }
79}
80
81// An unknown schema is refused, not guessed at.
82func TestSidecarRefusesUnknownSchema(t *testing.T) {
83 ctx := context.Background()
84 s := release.NewDirStore(t.TempDir())
85 if _, err := s.Put(ctx, ScanKey("bab", "titogo"),
86 []byte(`{"schema":99,"account":"bab","app":"titogo"}`), ""); err != nil {
87 t.Fatal(err)
88 }
89 if _, _, err := GetSidecar(ctx, s, "bab", "titogo"); err == nil {
90 t.Fatal("an unknown sidecar schema must be refused")
91 }
92}
93
94// Current and LastComplete are separate fields so a finished sweep survives
95// the start of the next one. With a single field the tick after completion
96// would overwrite the audit answer with page-one partials.
97func TestSidecarKeepsLastCompleteWhileCurrentRuns(t *testing.T) {
98 ctx := context.Background()
99 s := release.NewDirStore(t.TempDir())
100 done := &Sweep{Objects: 100, Scanned: 100, Engine: "clamav"}
101 if _, err := PutSidecar(ctx, s, "bab", "titogo",
102 &ScanSidecar{LastComplete: done}, ""); err != nil {
103 t.Fatal(err)
104 }
105 stored, etag, err := GetSidecar(ctx, s, "bab", "titogo")
106 if err != nil {
107 t.Fatal(err)
108 }
109 // A fresh sweep begins: Current starts at page one, LastComplete must not
110 // move.
111 stored.Current = &Sweep{Objects: 7, Scanned: 7, Engine: "clamav", After: "g.txt"}
112 if _, err := PutSidecar(ctx, s, "bab", "titogo", stored, etag); err != nil {
113 t.Fatal(err)
114 }
115 back, _, err := GetSidecar(ctx, s, "bab", "titogo")
116 if err != nil {
117 t.Fatal(err)
118 }
119 if back.LastComplete == nil || back.LastComplete.Objects != 100 {
120 t.Fatalf("a running sweep destroyed the last completed one: %+v", back.LastComplete)
121 }
122 if back.Current == nil || back.Current.After != "g.txt" {
123 t.Fatalf("current sweep did not round-trip: %+v", back.Current)
124 }
125}
126