-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconformance_test.go
More file actions
113 lines (101 loc) · 3.51 KB
/
conformance_test.go
File metadata and controls
113 lines (101 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package babelqueue_test
import (
"encoding/json"
"os"
"path/filepath"
"reflect"
"testing"
babelqueue "github.com/babelqueue/babelqueue-go"
)
type conformanceExpect struct {
URN string `json:"urn"`
Data map[string]any `json:"data"`
Attempts int `json:"attempts"`
Lang string `json:"lang"`
SchemaVersion int `json:"schema_version"`
DeadLetter map[string]any `json:"dead_letter"`
}
type conformanceCase struct {
Name string `json:"name"`
File string `json:"file"`
Valid bool `json:"valid"`
Reason string `json:"reason"`
Expect conformanceExpect `json:"expect"`
}
type conformanceManifest struct {
SchemaVersion int `json:"schema_version"`
Cases []conformanceCase `json:"cases"`
}
// TestConformance runs the shared cross-SDK suite (vendored under
// testdata/conformance) against this core — the same fixtures every BabelQueue
// SDK must satisfy. Per-message fields (meta.id, trace_id, meta.created_at) are
// intrinsically unique and are checked for presence, not value.
func TestConformance(t *testing.T) {
suite := filepath.Join("testdata", "conformance")
raw, err := os.ReadFile(filepath.Join(suite, "manifest.json"))
if err != nil {
t.Fatalf("read manifest: %v", err)
}
var m conformanceManifest
if err := json.Unmarshal(raw, &m); err != nil {
t.Fatalf("parse manifest: %v", err)
}
if m.SchemaVersion != babelqueue.SchemaVersion {
t.Fatalf("manifest schema_version %d != core %d", m.SchemaVersion, babelqueue.SchemaVersion)
}
if len(m.Cases) == 0 {
t.Fatal("manifest has no cases")
}
for _, c := range m.Cases {
c := c
t.Run(c.Name, func(t *testing.T) {
body, err := os.ReadFile(filepath.Join(suite, c.File))
if err != nil {
t.Fatalf("read fixture: %v", err)
}
env, derr := babelqueue.Decode(body)
if !c.Valid {
if derr == nil && env.Accepts() {
t.Fatalf("invalid fixture must be rejected (%s)", c.Reason)
}
return
}
if derr != nil {
t.Fatalf("valid fixture failed to decode: %v", derr)
}
if !env.Accepts() {
t.Fatal("valid fixture must be accepted")
}
if env.URN() != c.Expect.URN {
t.Errorf("urn = %q, want %q", env.URN(), c.Expect.URN)
}
if env.Attempts != c.Expect.Attempts {
t.Errorf("attempts = %d, want %d", env.Attempts, c.Expect.Attempts)
}
if env.Meta.Lang != c.Expect.Lang {
t.Errorf("lang = %q, want %q", env.Meta.Lang, c.Expect.Lang)
}
if env.Meta.SchemaVersion != c.Expect.SchemaVersion {
t.Errorf("schema_version = %d, want %d", env.Meta.SchemaVersion, c.Expect.SchemaVersion)
}
if c.Expect.Data != nil && !reflect.DeepEqual(env.Data, c.Expect.Data) {
t.Errorf("data = %#v, want %#v", env.Data, c.Expect.Data)
}
// per-message fields are unique but must be present
if env.TraceID == "" || env.Meta.ID == "" || env.Meta.CreatedAt == 0 {
t.Error("per-message fields (trace_id, meta.id, meta.created_at) must be present")
}
if c.Expect.DeadLetter != nil {
if env.DeadLetter == nil {
t.Fatal("expected a dead_letter block")
}
if want, ok := c.Expect.DeadLetter["reason"].(string); ok && env.DeadLetter.Reason != want {
t.Errorf("dead_letter.reason = %q, want %q", env.DeadLetter.Reason, want)
}
if want, ok := c.Expect.DeadLetter["original_queue"].(string); ok && env.DeadLetter.OriginalQueue != want {
t.Errorf("dead_letter.original_queue = %q, want %q", env.DeadLetter.OriginalQueue, want)
}
}
})
}
}