1 package pgtype_test
2
3 import (
4 "net"
5 "reflect"
6 "testing"
7
8 "github.com/jackc/pgtype"
9 "github.com/jackc/pgtype/testutil"
10 )
11
12 func TestCIDRArrayTranscode(t *testing.T) {
13 testutil.TestSuccessfulTranscode(t, "cidr[]", []interface{}{
14 &pgtype.CIDRArray{
15 Elements: nil,
16 Dimensions: nil,
17 Status: pgtype.Present,
18 },
19 &pgtype.CIDRArray{
20 Elements: []pgtype.CIDR{
21 {IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present},
22 {Status: pgtype.Null},
23 },
24 Dimensions: []pgtype.ArrayDimension{{Length: 2, LowerBound: 1}},
25 Status: pgtype.Present,
26 },
27 &pgtype.CIDRArray{Status: pgtype.Null},
28 &pgtype.CIDRArray{
29 Elements: []pgtype.CIDR{
30 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
31 {IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present},
32 {IPNet: mustParseCIDR(t, "192.168.0.1/32"), Status: pgtype.Present},
33 {IPNet: mustParseCIDR(t, "2607:f8b0:4009:80b::200e/128"), Status: pgtype.Present},
34 {Status: pgtype.Null},
35 {IPNet: mustParseCIDR(t, "255.0.0.0/8"), Status: pgtype.Present},
36 },
37 Dimensions: []pgtype.ArrayDimension{{Length: 3, LowerBound: 1}, {Length: 2, LowerBound: 1}},
38 Status: pgtype.Present,
39 },
40 &pgtype.CIDRArray{
41 Elements: []pgtype.CIDR{
42 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
43 {IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present},
44 {IPNet: mustParseCIDR(t, "192.168.0.1/32"), Status: pgtype.Present},
45 {IPNet: mustParseCIDR(t, "2607:f8b0:4009:80b::200e/128"), Status: pgtype.Present},
46 },
47 Dimensions: []pgtype.ArrayDimension{
48 {Length: 2, LowerBound: 4},
49 {Length: 2, LowerBound: 2},
50 },
51 Status: pgtype.Present,
52 },
53 })
54 }
55
56 func TestCIDRArraySet(t *testing.T) {
57 successfulTests := []struct {
58 source interface{}
59 result pgtype.CIDRArray
60 }{
61 {
62 source: []*net.IPNet{mustParseCIDR(t, "127.0.0.1/32")},
63 result: pgtype.CIDRArray{
64 Elements: []pgtype.CIDR{{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
65 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
66 Status: pgtype.Present},
67 },
68 {
69 source: (([]*net.IPNet)(nil)),
70 result: pgtype.CIDRArray{Status: pgtype.Null},
71 },
72 {
73 source: []net.IP{mustParseCIDR(t, "127.0.0.1/32").IP},
74 result: pgtype.CIDRArray{
75 Elements: []pgtype.CIDR{{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
76 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
77 Status: pgtype.Present},
78 },
79 {
80 source: (([]net.IP)(nil)),
81 result: pgtype.CIDRArray{Status: pgtype.Null},
82 },
83 {
84 source: [][]net.IP{{mustParseCIDR(t, "127.0.0.1/32").IP}, {mustParseCIDR(t, "10.0.0.1/32").IP}},
85 result: pgtype.CIDRArray{
86 Elements: []pgtype.CIDR{
87 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
88 {IPNet: mustParseCIDR(t, "10.0.0.1/32"), Status: pgtype.Present}},
89 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
90 Status: pgtype.Present},
91 },
92 {
93 source: [][][][]*net.IPNet{
94 {{{
95 mustParseCIDR(t, "127.0.0.1/24"),
96 mustParseCIDR(t, "10.0.0.1/24"),
97 mustParseCIDR(t, "172.16.0.1/16")}}},
98 {{{
99 mustParseCIDR(t, "192.168.0.1/16"),
100 mustParseCIDR(t, "224.0.0.1/24"),
101 mustParseCIDR(t, "169.168.0.1/16")}}}},
102 result: pgtype.CIDRArray{
103 Elements: []pgtype.CIDR{
104 {IPNet: mustParseCIDR(t, "127.0.0.1/24"), Status: pgtype.Present},
105 {IPNet: mustParseCIDR(t, "10.0.0.1/24"), Status: pgtype.Present},
106 {IPNet: mustParseCIDR(t, "172.16.0.1/16"), Status: pgtype.Present},
107 {IPNet: mustParseCIDR(t, "192.168.0.1/16"), Status: pgtype.Present},
108 {IPNet: mustParseCIDR(t, "224.0.0.1/24"), Status: pgtype.Present},
109 {IPNet: mustParseCIDR(t, "169.168.0.1/16"), Status: pgtype.Present}},
110 Dimensions: []pgtype.ArrayDimension{
111 {LowerBound: 1, Length: 2},
112 {LowerBound: 1, Length: 1},
113 {LowerBound: 1, Length: 1},
114 {LowerBound: 1, Length: 3}},
115 Status: pgtype.Present},
116 },
117 {
118 source: [2][1]net.IP{{mustParseCIDR(t, "127.0.0.1/32").IP}, {mustParseCIDR(t, "10.0.0.1/32").IP}},
119 result: pgtype.CIDRArray{
120 Elements: []pgtype.CIDR{
121 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
122 {IPNet: mustParseCIDR(t, "10.0.0.1/32"), Status: pgtype.Present}},
123 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
124 Status: pgtype.Present},
125 },
126 {
127 source: [2][1][1][3]*net.IPNet{
128 {{{
129 mustParseCIDR(t, "127.0.0.1/24"),
130 mustParseCIDR(t, "10.0.0.1/24"),
131 mustParseCIDR(t, "172.16.0.1/16")}}},
132 {{{
133 mustParseCIDR(t, "192.168.0.1/16"),
134 mustParseCIDR(t, "224.0.0.1/24"),
135 mustParseCIDR(t, "169.168.0.1/16")}}}},
136 result: pgtype.CIDRArray{
137 Elements: []pgtype.CIDR{
138 {IPNet: mustParseCIDR(t, "127.0.0.1/24"), Status: pgtype.Present},
139 {IPNet: mustParseCIDR(t, "10.0.0.1/24"), Status: pgtype.Present},
140 {IPNet: mustParseCIDR(t, "172.16.0.1/16"), Status: pgtype.Present},
141 {IPNet: mustParseCIDR(t, "192.168.0.1/16"), Status: pgtype.Present},
142 {IPNet: mustParseCIDR(t, "224.0.0.1/24"), Status: pgtype.Present},
143 {IPNet: mustParseCIDR(t, "169.168.0.1/16"), Status: pgtype.Present}},
144 Dimensions: []pgtype.ArrayDimension{
145 {LowerBound: 1, Length: 2},
146 {LowerBound: 1, Length: 1},
147 {LowerBound: 1, Length: 1},
148 {LowerBound: 1, Length: 3}},
149 Status: pgtype.Present},
150 },
151 }
152
153 for i, tt := range successfulTests {
154 var r pgtype.CIDRArray
155 err := r.Set(tt.source)
156 if err != nil {
157 t.Errorf("%d: %v", i, err)
158 }
159
160 if !reflect.DeepEqual(r, tt.result) {
161 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
162 }
163 }
164 }
165
166 func TestCIDRArrayAssignTo(t *testing.T) {
167 var ipnetSlice []*net.IPNet
168 var ipSlice []net.IP
169 var ipSliceDim2 [][]net.IP
170 var ipnetSliceDim4 [][][][]*net.IPNet
171 var ipArrayDim2 [2][1]net.IP
172 var ipnetArrayDim4 [2][1][1][3]*net.IPNet
173
174 simpleTests := []struct {
175 src pgtype.CIDRArray
176 dst interface{}
177 expected interface{}
178 }{
179 {
180 src: pgtype.CIDRArray{
181 Elements: []pgtype.CIDR{{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
182 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
183 Status: pgtype.Present,
184 },
185 dst: &ipnetSlice,
186 expected: []*net.IPNet{mustParseCIDR(t, "127.0.0.1/32")},
187 },
188 {
189 src: pgtype.CIDRArray{
190 Elements: []pgtype.CIDR{{Status: pgtype.Null}},
191 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
192 Status: pgtype.Present,
193 },
194 dst: &ipnetSlice,
195 expected: []*net.IPNet{nil},
196 },
197 {
198 src: pgtype.CIDRArray{
199 Elements: []pgtype.CIDR{{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}},
200 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
201 Status: pgtype.Present,
202 },
203 dst: &ipSlice,
204 expected: []net.IP{mustParseCIDR(t, "127.0.0.1/32").IP},
205 },
206 {
207 src: pgtype.CIDRArray{
208 Elements: []pgtype.CIDR{{Status: pgtype.Null}},
209 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 1}},
210 Status: pgtype.Present,
211 },
212 dst: &ipSlice,
213 expected: []net.IP{nil},
214 },
215 {
216 src: pgtype.CIDRArray{Status: pgtype.Null},
217 dst: &ipnetSlice,
218 expected: (([]*net.IPNet)(nil)),
219 },
220 {
221 src: pgtype.CIDRArray{Status: pgtype.Present},
222 dst: &ipnetSlice,
223 expected: []*net.IPNet{},
224 },
225 {
226 src: pgtype.CIDRArray{Status: pgtype.Null},
227 dst: &ipSlice,
228 expected: (([]net.IP)(nil)),
229 },
230 {
231 src: pgtype.CIDRArray{Status: pgtype.Present},
232 dst: &ipSlice,
233 expected: []net.IP{},
234 },
235 {
236 src: pgtype.CIDRArray{
237 Elements: []pgtype.CIDR{
238 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
239 {IPNet: mustParseCIDR(t, "10.0.0.1/32"), Status: pgtype.Present}},
240 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
241 Status: pgtype.Present},
242 dst: &ipSliceDim2,
243 expected: [][]net.IP{{mustParseCIDR(t, "127.0.0.1/32").IP}, {mustParseCIDR(t, "10.0.0.1/32").IP}},
244 },
245 {
246 src: pgtype.CIDRArray{
247 Elements: []pgtype.CIDR{
248 {IPNet: mustParseCIDR(t, "127.0.0.1/24"), Status: pgtype.Present},
249 {IPNet: mustParseCIDR(t, "10.0.0.1/24"), Status: pgtype.Present},
250 {IPNet: mustParseCIDR(t, "172.16.0.1/16"), Status: pgtype.Present},
251 {IPNet: mustParseCIDR(t, "192.168.0.1/16"), Status: pgtype.Present},
252 {IPNet: mustParseCIDR(t, "224.0.0.1/24"), Status: pgtype.Present},
253 {IPNet: mustParseCIDR(t, "169.168.0.1/16"), Status: pgtype.Present}},
254 Dimensions: []pgtype.ArrayDimension{
255 {LowerBound: 1, Length: 2},
256 {LowerBound: 1, Length: 1},
257 {LowerBound: 1, Length: 1},
258 {LowerBound: 1, Length: 3}},
259 Status: pgtype.Present},
260 dst: &ipnetSliceDim4,
261 expected: [][][][]*net.IPNet{
262 {{{
263 mustParseCIDR(t, "127.0.0.1/24"),
264 mustParseCIDR(t, "10.0.0.1/24"),
265 mustParseCIDR(t, "172.16.0.1/16")}}},
266 {{{
267 mustParseCIDR(t, "192.168.0.1/16"),
268 mustParseCIDR(t, "224.0.0.1/24"),
269 mustParseCIDR(t, "169.168.0.1/16")}}}},
270 },
271 {
272 src: pgtype.CIDRArray{
273 Elements: []pgtype.CIDR{
274 {IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
275 {IPNet: mustParseCIDR(t, "10.0.0.1/32"), Status: pgtype.Present}},
276 Dimensions: []pgtype.ArrayDimension{{LowerBound: 1, Length: 2}, {LowerBound: 1, Length: 1}},
277 Status: pgtype.Present},
278 dst: &ipArrayDim2,
279 expected: [2][1]net.IP{{mustParseCIDR(t, "127.0.0.1/32").IP}, {mustParseCIDR(t, "10.0.0.1/32").IP}},
280 },
281 {
282 src: pgtype.CIDRArray{
283 Elements: []pgtype.CIDR{
284 {IPNet: mustParseCIDR(t, "127.0.0.1/24"), Status: pgtype.Present},
285 {IPNet: mustParseCIDR(t, "10.0.0.1/24"), Status: pgtype.Present},
286 {IPNet: mustParseCIDR(t, "172.16.0.1/16"), Status: pgtype.Present},
287 {IPNet: mustParseCIDR(t, "192.168.0.1/16"), Status: pgtype.Present},
288 {IPNet: mustParseCIDR(t, "224.0.0.1/24"), Status: pgtype.Present},
289 {IPNet: mustParseCIDR(t, "169.168.0.1/16"), Status: pgtype.Present}},
290 Dimensions: []pgtype.ArrayDimension{
291 {LowerBound: 1, Length: 2},
292 {LowerBound: 1, Length: 1},
293 {LowerBound: 1, Length: 1},
294 {LowerBound: 1, Length: 3}},
295 Status: pgtype.Present},
296 dst: &ipnetArrayDim4,
297 expected: [2][1][1][3]*net.IPNet{
298 {{{
299 mustParseCIDR(t, "127.0.0.1/24"),
300 mustParseCIDR(t, "10.0.0.1/24"),
301 mustParseCIDR(t, "172.16.0.1/16")}}},
302 {{{
303 mustParseCIDR(t, "192.168.0.1/16"),
304 mustParseCIDR(t, "224.0.0.1/24"),
305 mustParseCIDR(t, "169.168.0.1/16")}}}},
306 },
307 }
308
309 for i, tt := range simpleTests {
310 err := tt.src.AssignTo(tt.dst)
311 if err != nil {
312 t.Errorf("%d: %v", i, err)
313 }
314
315 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); !reflect.DeepEqual(dst, tt.expected) {
316 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
317 }
318 }
319 }
320
View as plain text