@@ -2,10 +2,13 @@ package connmetadata
22
33import (
44 "testing"
5+ "time"
56
67 "github.com/google/uuid"
78 "github.com/jackc/pgx/v5"
89 "github.com/stretchr/testify/require"
10+ "google.golang.org/protobuf/proto"
11+ "google.golang.org/protobuf/types/known/timestamppb"
912
1013 "github.com/PeerDB-io/peerdb/flow/generated/protos"
1114 "github.com/PeerDB-io/peerdb/flow/internal"
@@ -20,56 +23,87 @@ func TestOffloadRestoreSensitivePartitionRanges(t *testing.T) {
2023 pool , err := internal .GetCatalogConnectionPoolFromEnv (ctx )
2124 require .NoError (t , err )
2225
23- parentMirrorName := "test_offload_restore_sensitive_partition_ranges"
24- runUUID := uuid .NewString ()
25- t .Cleanup (func () {
26- _ , _ = pool .Exec (ctx , `DELETE FROM ` + qrepPartitionRangesTableName + ` WHERE parent_mirror_name=$1` , parentMirrorName )
27- })
28-
29- p1Start , p1End , p2Start , p2End := "bar" , "foo" , "hello" , "world"
30- partitions := []* protos.QRepPartition {
26+ for _ , tc := range []struct {
27+ name string
28+ ranges []* protos.PartitionRange
29+ }{
3130 {
32- PartitionId : uuid .NewString (),
33- Range : & protos.PartitionRange {Range : & protos.PartitionRange_StringRange {
34- StringRange : & protos.StringPartitionRange {Start : p1Start , End : p1End },
35- }},
31+ name : "int" ,
32+ ranges : []* protos.PartitionRange {
33+ {Range : & protos.PartitionRange_IntRange {IntRange : & protos.IntPartitionRange {Start : 1 , End : 100 }}},
34+ {Range : & protos.PartitionRange_IntRange {IntRange : & protos.IntPartitionRange {Start : 101 , End : 200 }}},
35+ },
3636 },
3737 {
38- PartitionId : uuid .NewString (),
39- Range : & protos.PartitionRange {Range : & protos.PartitionRange_StringRange {
40- StringRange : & protos.StringPartitionRange {Start : p2Start , End : p2End , EndInclusive : true },
41- }},
38+ name : "timestamp" ,
39+ ranges : []* protos.PartitionRange {
40+ {Range : & protos.PartitionRange_TimestampRange {TimestampRange : & protos.TimestampPartitionRange {
41+ Start : timestamppb .New (time .Date (2026 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC )),
42+ End : timestamppb .New (time .Date (2026 , 6 , 30 , 23 , 59 , 59 , 0 , time .UTC )),
43+ }}},
44+ {Range : & protos.PartitionRange_TimestampRange {TimestampRange : & protos.TimestampPartitionRange {
45+ Start : timestamppb .New (time .Date (2026 , 7 , 1 , 0 , 0 , 0 , 0 , time .UTC )),
46+ End : timestamppb .New (time .Date (2026 , 12 , 31 , 23 , 59 , 59 , 0 , time .UTC )),
47+ }}},
48+ },
4249 },
43- }
50+ {
51+ name : "string_uuid" ,
52+ ranges : []* protos.PartitionRange {
53+ {Range : & protos.PartitionRange_StringRange {
54+ StringRange : & protos.StringPartitionRange {Start : uuid .NewString (), End : uuid .NewString ()},
55+ }},
56+ {Range : & protos.PartitionRange_StringRange {
57+ StringRange : & protos.StringPartitionRange {Start : uuid .NewString (), End : uuid .NewString (), EndInclusive : true },
58+ }},
59+ },
60+ },
61+ } {
62+ t .Run (tc .name , func (t * testing.T ) {
63+ parentMirrorName := "test_offload_restore_partition_ranges_" + tc .name
64+ runUUID := uuid .NewString ()
65+ t .Cleanup (func () {
66+ _ , _ = pool .Exec (ctx , `DELETE FROM ` + qrepPartitionRangesTableName + ` WHERE parent_mirror_name=$1` , parentMirrorName )
67+ })
4468
45- require .NoError (t , OffloadSensitivePartitionRanges (ctx , pool , parentMirrorName , runUUID , partitions ))
46- for _ , p := range partitions {
47- require .Empty (t , p .Range .GetStringRange ().Start )
48- require .Empty (t , p .Range .GetStringRange ().End )
49- }
69+ partitions := make ([]* protos.QRepPartition , len (tc .ranges ))
70+ expectedRanges := make ([]* protos.PartitionRange , len (tc .ranges ))
71+ for i , r := range tc .ranges {
72+ partitions [i ] = & protos.QRepPartition {PartitionId : uuid .NewString (), Range : r }
73+ expectedRanges [i ] = proto .Clone (r ).(* protos.PartitionRange )
74+ }
5075
51- rows , err := pool .Query (ctx ,
52- `SELECT enc_key_id, range_payload FROM ` + qrepPartitionRangesTableName + ` WHERE parent_mirror_name=$1` ,
53- parentMirrorName )
54- require .NoError (t , err )
55- results , err := pgx .CollectRows (rows , pgx.RowToStructByPos [struct {
56- KeyID string
57- Payload []byte
58- }])
59- require .NoError (t , err )
60- require .Len (t , results , len (partitions ))
61- for _ , res := range results {
62- require .Equal (t , encKeyID , res .KeyID )
63- for _ , plaintext := range []string {p1Start , p1End , p2Start , p2End } {
64- require .NotContains (t , string (res .Payload ), plaintext )
65- }
66- }
76+ require .NoError (t , OffloadPartitionRanges (ctx , pool , parentMirrorName , runUUID , partitions ))
77+ for _ , p := range partitions {
78+ require .Nil (t , p .Range )
79+ require .True (t , p .RangeOffloaded )
80+ }
6781
68- require .NoError (t , RestoreSensitivePartitionRanges (ctx , pool , runUUID , partitions ))
69- require .Equal (t , p1Start , partitions [0 ].Range .GetStringRange ().Start )
70- require .Equal (t , p1End , partitions [0 ].Range .GetStringRange ().End )
71- require .False (t , partitions [0 ].Range .GetStringRange ().EndInclusive )
72- require .Equal (t , p2Start , partitions [1 ].Range .GetStringRange ().Start )
73- require .Equal (t , p2End , partitions [1 ].Range .GetStringRange ().End )
74- require .True (t , partitions [1 ].Range .GetStringRange ().EndInclusive )
82+ rows , err := pool .Query (ctx ,
83+ `SELECT enc_key_id, range_payload FROM ` + qrepPartitionRangesTableName + ` WHERE parent_mirror_name=$1` ,
84+ parentMirrorName )
85+ require .NoError (t , err )
86+ results , err := pgx .CollectRows (rows , pgx.RowToStructByPos [struct {
87+ KeyID string
88+ Payload []byte
89+ }])
90+ require .NoError (t , err )
91+ require .Len (t , results , len (partitions ))
92+ for _ , res := range results {
93+ require .Equal (t , encKeyID , res .KeyID )
94+ require .NotEmpty (t , res .Payload )
95+ for _ , r := range expectedRanges {
96+ unencrypted , err := proto .Marshal (r )
97+ require .NoError (t , err )
98+ require .NotContains (t , string (res .Payload ), string (unencrypted ))
99+ }
100+ }
101+
102+ require .NoError (t , RestoreOffloadedPartitionRanges (ctx , pool , runUUID , partitions ))
103+ for i , p := range partitions {
104+ require .Truef (t , proto .Equal (expectedRanges [i ], p .Range ),
105+ "partition %d range mismatch after restore: want %v, got %v" , i , expectedRanges [i ], p .Range )
106+ }
107+ })
108+ }
75109}
0 commit comments