@@ -5,9 +5,99 @@ package wal
55import (
66 "testing"
77
8+ jsonlib "github.com/xataio/pgstream/internal/json"
9+
810 "github.com/stretchr/testify/require"
911)
1012
13+ const testDDLContent = `{
14+ "ddl": "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)",
15+ "schema_name": "public",
16+ "command_tag": "CREATE TABLE",
17+ "objects": [{
18+ "type": "table",
19+ "identity": "public.users",
20+ "schema": "public",
21+ "oid": "16384",
22+ "pgstream_id": "ck7s8u4000001"
23+ }]
24+ }`
25+
26+ func TestWalDataToDDLEvent_memoisation (t * testing.T ) {
27+ t .Parallel ()
28+
29+ data := & Data {
30+ Action : "M" ,
31+ Prefix : "pgstream.ddl" ,
32+ Content : testDDLContent ,
33+ }
34+
35+ first , err := WalDataToDDLEvent (data )
36+ require .NoError (t , err )
37+ require .NotNil (t , first )
38+
39+ second , err := WalDataToDDLEvent (data )
40+ require .NoError (t , err )
41+
42+ // repeat calls must return the exact same cached pointer, i.e. the content
43+ // is parsed only once.
44+ require .Same (t , first , second )
45+
46+ // the error path is memoised too.
47+ notDDL := & Data {Action : "I" }
48+ _ , err1 := WalDataToDDLEvent (notDDL )
49+ _ , err2 := WalDataToDDLEvent (notDDL )
50+ require .ErrorIs (t , err1 , ErrNotDDLEvent )
51+ require .ErrorIs (t , err2 , ErrNotDDLEvent )
52+ }
53+
54+ func BenchmarkWalDataToDDLEvent_memoised (b * testing.B ) {
55+ data := & Data {
56+ Action : "M" ,
57+ Prefix : "pgstream.ddl" ,
58+ Content : testDDLContent ,
59+ }
60+ // prime the memo so the benchmarked calls only hit the cached fast path.
61+ if _ , err := WalDataToDDLEvent (data ); err != nil {
62+ b .Fatal (err )
63+ }
64+
65+ b .ReportAllocs ()
66+ for i := 0 ; i < b .N ; i ++ {
67+ if _ , err := WalDataToDDLEvent (data ); err != nil {
68+ b .Fatal (err )
69+ }
70+ }
71+ }
72+
73+ func TestWalDataToDDLEvent_serialisationUnaffected (t * testing.T ) {
74+ t .Parallel ()
75+
76+ // a Data whose DDL event has been memoised must serialise byte-identically
77+ // to one that has not: the memo fields are unexported and excluded from JSON.
78+ plain := & Data {
79+ Action : "M" ,
80+ Prefix : "pgstream.ddl" ,
81+ Content : testDDLContent ,
82+ Schema : "public" ,
83+ }
84+ memoised := & Data {
85+ Action : "M" ,
86+ Prefix : "pgstream.ddl" ,
87+ Content : testDDLContent ,
88+ Schema : "public" ,
89+ }
90+ _ , err := WalDataToDDLEvent (memoised )
91+ require .NoError (t , err )
92+
93+ plainBytes , err := jsonlib .Marshal (plain )
94+ require .NoError (t , err )
95+ memoisedBytes , err := jsonlib .Marshal (memoised )
96+ require .NoError (t , err )
97+
98+ require .Equal (t , plainBytes , memoisedBytes )
99+ }
100+
11101func TestData_IsDDLEvent (t * testing.T ) {
12102 t .Parallel ()
13103
0 commit comments