blackwinter-ipaddress 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,525 @@
1
+ require 'test_helper'
2
+
3
+ class IPv4Test < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @klass = IPAddress::IPv4
7
+
8
+ @valid_ipv4 = {
9
+ '0.0.0.0/0' => ['0.0.0.0', 0],
10
+ '10.0.0.0' => ['10.0.0.0', 32],
11
+ '10.0.0.1' => ['10.0.0.1', 32],
12
+ '10.0.0.1/24' => ['10.0.0.1', 24],
13
+ '10.0.0.1/255.255.255.0' => ['10.0.0.1', 24]
14
+ }
15
+
16
+ @invalid_ipv4 = %w[10.0.0.256 10.0.0.0.0 10.0.0 10.0 2001:db8::8:800:200c:417a]
17
+
18
+ @valid_ipv4_range = %w[10.0.0.1-254 10.0.1-254.0 10.1-254.0.0]
19
+
20
+ @netmask_values = {
21
+ '0.0.0.0/0' => '0.0.0.0',
22
+ '10.0.0.0/8' => '255.0.0.0',
23
+ '172.16.0.0/16' => '255.255.0.0',
24
+ '192.168.0.0/24' => '255.255.255.0',
25
+ '192.168.100.4/30' => '255.255.255.252'
26
+ }
27
+
28
+ @decimal_values = {
29
+ '0.0.0.0/0' => 0,
30
+ '10.0.0.0/8' => 167772160,
31
+ '172.16.0.0/16' => 2886729728,
32
+ '192.168.0.0/24' => 3232235520,
33
+ '192.168.100.4/30' => 3232261124
34
+ }
35
+
36
+ @ip = @klass.new('172.16.10.1/24')
37
+ @network = @klass.new('172.16.10.0/24')
38
+
39
+ @broadcast = {
40
+ '10.0.0.0/8' => '10.255.255.255/8',
41
+ '172.16.0.0/16' => '172.16.255.255/16',
42
+ '192.168.0.0/24' => '192.168.0.255/24',
43
+ '192.168.100.4/30' => '192.168.100.7/30'
44
+ }
45
+
46
+ @networks = {
47
+ '10.5.4.3/8' => '10.0.0.0/8',
48
+ '172.16.5.4/16' => '172.16.0.0/16',
49
+ '192.168.4.3/24' => '192.168.4.0/24',
50
+ '192.168.100.5/30' => '192.168.100.4/30'
51
+ }
52
+
53
+ @class_a = @klass.new('10.0.0.1/8')
54
+ @class_b = @klass.new('172.16.0.1/16')
55
+ @class_c = @klass.new('192.168.0.1/24')
56
+
57
+ @classful = {
58
+ '10.1.1.1' => 8,
59
+ '150.1.1.1' => 16,
60
+ '200.1.1.1' => 24
61
+ }
62
+ end
63
+
64
+ def test_initialize
65
+ @valid_ipv4.each_key { |i| assert_instance_of @klass, @klass.new(i) }
66
+ assert_instance_of IPAddress::Prefix32, @ip.prefix
67
+ end
68
+
69
+ def test_initialize_format_error
70
+ @invalid_ipv4.each { |i| assert_raise(ArgumentError) { @klass.new(i) } }
71
+ assert_raise(ArgumentError) { @klass.new('10.0.0.0/asd') }
72
+ end
73
+
74
+ def test_initialize_without_prefix
75
+ ip = @klass.new('10.10.0.0')
76
+ assert_instance_of IPAddress::Prefix32, ip.prefix
77
+ assert_equal 32, ip.prefix.prefix
78
+ end
79
+
80
+ def test_attributes
81
+ @valid_ipv4.each { |arg, attr|
82
+ ip = @klass.new(arg)
83
+ assert_equal attr.first, ip.address
84
+ assert_equal attr.last, ip.prefix.prefix
85
+ }
86
+ end
87
+
88
+ def test_octets
89
+ assert_equal [10, 1, 2, 3], @klass.new('10.1.2.3/8').octets
90
+ end
91
+
92
+ def test_initialize_should_require_ip
93
+ assert_raise(ArgumentError) { @klass.new }
94
+ end
95
+
96
+ def test_method_data
97
+ assert_equal "\254\020\n\001", @ip.data
98
+ end
99
+
100
+ def test_method_to_string
101
+ @valid_ipv4.each { |arg, attr|
102
+ assert_equal attr.join('/'), @klass.new(arg).to_string
103
+ }
104
+ end
105
+
106
+ def test_method_to_s
107
+ @valid_ipv4.each { |arg, attr|
108
+ assert_equal attr.first, @klass.new(arg).to_s
109
+ }
110
+ end
111
+
112
+ def test_netmask
113
+ @netmask_values.each { |addr, mask|
114
+ assert_equal mask, @klass.new(addr).netmask
115
+ }
116
+ end
117
+
118
+ def test_method_to_u32
119
+ @decimal_values.each { |addr, int|
120
+ ip = @klass.new(addr)
121
+ assert_equal int, ip.to_u32
122
+ assert_equal int, ip.to_i
123
+ }
124
+ end
125
+
126
+ def test_method_network?
127
+ assert @network.network?
128
+ refute @ip.network?
129
+ end
130
+
131
+ def test_method_broadcast
132
+ @broadcast.each { |addr, bcast|
133
+ ip = @klass.new(addr)
134
+ assert_instance_of @klass, ip.broadcast
135
+ assert_equal bcast, ip.broadcast.to_string
136
+ }
137
+ end
138
+
139
+ def test_method_network
140
+ @networks.each { |addr, net|
141
+ ip = @klass.new addr
142
+ assert_instance_of @klass, ip.network
143
+ assert_equal net, ip.network.to_string
144
+ }
145
+ end
146
+
147
+ def test_method_bits
148
+ ip = @klass.new('127.0.0.1')
149
+ assert_equal '01111111000000000000000000000001', ip.bits
150
+ end
151
+
152
+ def test_method_first
153
+ ip = @klass.new('192.168.100.0/24')
154
+ assert_instance_of @klass, ip.first
155
+ assert_equal '192.168.100.1', ip.first.to_s
156
+
157
+ ip = @klass.new('192.168.100.50/24')
158
+ assert_instance_of @klass, ip.first
159
+ assert_equal '192.168.100.1', ip.first.to_s
160
+ end
161
+
162
+ def test_method_last
163
+ ip = @klass.new('192.168.100.0/24')
164
+ assert_instance_of @klass, ip.last
165
+ assert_equal '192.168.100.254', ip.last.to_s
166
+
167
+ ip = @klass.new('192.168.100.50/24')
168
+ assert_instance_of @klass, ip.last
169
+ assert_equal '192.168.100.254', ip.last.to_s
170
+ end
171
+
172
+ def test_method_each_host
173
+ ary = []
174
+ @klass.new('10.0.0.1/29').each_host { |i| ary << i.to_s }
175
+
176
+ assert_equal %w[
177
+ 10.0.0.1 10.0.0.2 10.0.0.3
178
+ 10.0.0.4 10.0.0.5 10.0.0.6
179
+ ], ary
180
+ end
181
+
182
+ def test_method_each
183
+ ary = []
184
+ @klass.new('10.0.0.1/29').each { |i| ary << i.to_s }
185
+
186
+ assert_equal %w[
187
+ 10.0.0.0 10.0.0.1 10.0.0.2
188
+ 10.0.0.3 10.0.0.4 10.0.0.5
189
+ 10.0.0.6 10.0.0.7
190
+ ], ary
191
+ end
192
+
193
+ def test_method_size
194
+ assert_equal 8, @klass.new('10.0.0.1/29').size
195
+ end
196
+
197
+ def test_method_hosts
198
+ assert_equal %w[
199
+ 10.0.0.1 10.0.0.2 10.0.0.3
200
+ 10.0.0.4 10.0.0.5 10.0.0.6
201
+ ], @klass.new('10.0.0.1/29').hosts.map { |i| i.to_s }
202
+ end
203
+
204
+ def test_method_network_u32
205
+ assert_equal 2886732288, @ip.network_u32
206
+ assert_equal 2886732288, @ip.network_i
207
+ end
208
+
209
+ def test_method_broadcast_u32
210
+ assert_equal 2886732543, @ip.broadcast_u32
211
+ assert_equal 2886732543, @ip.broadcast_i
212
+ end
213
+
214
+ def test_method_include?
215
+ ip = @klass.new('192.168.10.100/24')
216
+ assert ip.include?(@klass.new('192.168.10.102/24'))
217
+ refute ip.include?(@klass.new('172.16.0.48'))
218
+
219
+ ip = @klass.new('10.0.0.0/8')
220
+ assert ip.include?(@klass.new('10.0.0.0/9'))
221
+ assert ip.include?(@klass.new('10.1.1.1/32'))
222
+ assert ip.include?(@klass.new('10.1.1.1/9'))
223
+ refute ip.include?(@klass.new('172.16.0.0/16'))
224
+ refute ip.include?(@klass.new('10.0.0.0/7'))
225
+ refute ip.include?(@klass.new('5.5.5.5/32'))
226
+ refute ip.include?(@klass.new('11.0.0.0/8'))
227
+
228
+ ip = @klass.new('13.13.0.0/13')
229
+ refute ip.include?(@klass.new('13.16.0.0/32'))
230
+ end
231
+
232
+ def test_method_include_all?
233
+ ip = @klass.new('192.168.10.100/24')
234
+ addr1 = @klass.new('192.168.10.102/24')
235
+ addr2 = @klass.new('192.168.10.103/24')
236
+
237
+ assert ip.include_all?(addr1, addr2)
238
+ refute ip.include_all?(addr1, @klass.new('13.16.0.0/32'))
239
+ end
240
+
241
+ def test_method_ipv4?
242
+ assert @ip.ipv4?
243
+ end
244
+
245
+ def test_method_ipv6?
246
+ refute @ip.ipv6?
247
+ end
248
+
249
+ def test_method_private?
250
+ %w[
251
+ 192.168.10.50/24 192.168.10.50/16 172.16.77.40/24
252
+ 172.16.10.50/14 10.10.10.10/10 10.0.0.0/8
253
+ ].each { |i| assert @klass.new(i).private? }
254
+
255
+ %w[
256
+ 192.168.10.50/12 3.3.3.3 10.0.0.0/7
257
+ 172.32.0.0/12 172.16.0.0/11 192.0.0.2/24
258
+ ].each { |i| refute @klass.new(i).private? }
259
+ end
260
+
261
+ def test_method_octet
262
+ assert_equal 172, @ip[0]
263
+ assert_equal 16, @ip[1]
264
+ assert_equal 10, @ip[2]
265
+ assert_equal 1, @ip[3]
266
+ end
267
+
268
+ def test_method_a?
269
+ assert @class_a.a?
270
+ refute @class_b.a?
271
+ refute @class_c.a?
272
+ end
273
+
274
+ def test_method_b?
275
+ assert @class_b.b?
276
+ refute @class_a.b?
277
+ refute @class_c.b?
278
+ end
279
+
280
+ def test_method_c?
281
+ assert @class_c.c?
282
+ refute @class_a.c?
283
+ refute @class_b.c?
284
+ end
285
+
286
+ def test_method_to_ipv6
287
+ assert_equal 'ac10:0a01', @ip.to_ipv6
288
+ end
289
+
290
+ def test_method_reverse
291
+ assert_equal '1.10.16.172.in-addr.arpa', @ip.reverse
292
+ end
293
+
294
+ def test_method_compare
295
+ ip1 = @klass.new('10.1.1.1/8')
296
+ ip2 = @klass.new('10.1.1.1/16')
297
+ ip3 = @klass.new('172.16.1.1/14')
298
+ ip4 = @klass.new('10.1.1.1/8')
299
+
300
+ assert ip1 < ip2
301
+ refute ip1 > ip2
302
+ refute ip2 < ip1
303
+ assert ip2 < ip3
304
+ refute ip2 > ip3
305
+ assert ip1 < ip3
306
+ refute ip1 > ip3
307
+ refute ip3 < ip1
308
+ assert ip1 == ip1
309
+ assert ip1 == ip4
310
+
311
+ ary = %w[10.1.1.1/8 10.1.1.1/16 172.16.1.1/14]
312
+ assert_equal_ary ary, [ip1, ip2, ip3].sort
313
+
314
+ ip1 = @klass.new('10.0.0.0/24')
315
+ ip2 = @klass.new('10.0.0.0/16')
316
+ ip3 = @klass.new('10.0.0.0/8')
317
+ ary = %w[10.0.0.0/8 10.0.0.0/16 10.0.0.0/24]
318
+ assert_equal_ary ary, [ip1, ip2, ip3].sort
319
+ end
320
+
321
+ def test_method_distance
322
+ ip1 = @klass.new('10.1.1.1/8')
323
+ ip2 = @klass.new('10.1.1.10/8')
324
+ assert_equal 9, ip2.distance(ip1)
325
+ assert_equal 9, ip1.distance(ip2)
326
+ end
327
+
328
+ def test_method_plus
329
+ ip1 = @klass.new('172.16.10.1/24')
330
+ ip2 = @klass.new('172.16.11.2/24')
331
+ assert_equal_ary %w[172.16.10.0/23], ip1 + ip2
332
+
333
+ ip2 = @klass.new('172.16.12.2/24')
334
+ assert_equal_ary [ip1.network.to_string, ip2.network.to_string], ip1 + ip2
335
+
336
+ ip1 = @klass.new('10.0.0.0/23')
337
+ ip2 = @klass.new('10.0.2.0/24')
338
+ assert_equal_ary %w[10.0.0.0/23 10.0.2.0/24], ip1 + ip2
339
+
340
+ ip1 = @klass.new('10.0.0.0/23')
341
+ ip2 = @klass.new('10.0.2.0/24')
342
+ assert_equal_ary %w[10.0.0.0/23 10.0.2.0/24], ip2 + ip1
343
+
344
+ ip1 = @klass.new('10.0.0.0/16')
345
+ ip2 = @klass.new('10.0.2.0/24')
346
+ assert_equal_ary %w[10.0.0.0/16], ip1 + ip2
347
+
348
+ ip1 = @klass.new('10.0.0.0/23')
349
+ ip2 = @klass.new('10.1.0.0/24')
350
+ assert_equal_ary %w[10.0.0.0/23 10.1.0.0/24], ip1 + ip2
351
+ end
352
+
353
+ def test_method_netmask_equal
354
+ ip = @klass.new('10.1.1.1/16')
355
+ assert_equal 16, ip.prefix.prefix
356
+ assert_raise(NoMethodError) { ip.netmask = '255.255.255.0' }
357
+
358
+ ip2 = ip.new_netmask('255.255.255.0')
359
+ assert_equal 16, ip.prefix.prefix
360
+ assert_equal 24, ip2.prefix.prefix
361
+ end
362
+
363
+ def test_method_split
364
+ assert_raise(ArgumentError) { @ip.split(0) }
365
+ assert_raise(ArgumentError) { @ip.split(257) }
366
+
367
+ assert_equal @ip.network, @ip.split(1).first
368
+
369
+ {
370
+ 8 => %w[
371
+ 172.16.10.0/27 172.16.10.32/27 172.16.10.64/27
372
+ 172.16.10.96/27 172.16.10.128/27 172.16.10.160/27
373
+ 172.16.10.192/27 172.16.10.224/27
374
+ ],
375
+ 7 => %w[
376
+ 172.16.10.0/27 172.16.10.32/27 172.16.10.64/27
377
+ 172.16.10.96/27 172.16.10.128/27 172.16.10.160/27
378
+ 172.16.10.192/26
379
+ ],
380
+ 6 => %w[
381
+ 172.16.10.0/27 172.16.10.32/27 172.16.10.64/27
382
+ 172.16.10.96/27 172.16.10.128/26 172.16.10.192/26
383
+ ],
384
+ 5 => %w[
385
+ 172.16.10.0/27 172.16.10.32/27 172.16.10.64/27
386
+ 172.16.10.96/27 172.16.10.128/25
387
+ ],
388
+ 4 => %w[
389
+ 172.16.10.0/26 172.16.10.64/26 172.16.10.128/26
390
+ 172.16.10.192/26
391
+ ],
392
+ 3 => %w[
393
+ 172.16.10.0/26 172.16.10.64/26 172.16.10.128/25
394
+ ],
395
+ 2 => %w[
396
+ 172.16.10.0/25 172.16.10.128/25
397
+ ],
398
+ 1 => %w[
399
+ 172.16.10.0/24
400
+ ]
401
+ }.each { |i, a| assert_equal_ary a, @network.split(i) }
402
+ end
403
+
404
+ def test_method_subnet
405
+ assert_raise(ArgumentError) { @network.subnet(23) }
406
+ assert_raise(ArgumentError) { @network.subnet(33) }
407
+
408
+ {
409
+ 26 => %w[
410
+ 172.16.10.0/26 172.16.10.64/26 172.16.10.128/26
411
+ 172.16.10.192/26
412
+ ],
413
+ 25 => %w[
414
+ 172.16.10.0/25 172.16.10.128/25
415
+ ],
416
+ 24 => %w[
417
+ 172.16.10.0/24
418
+ ]
419
+ }.each { |i, a| assert_equal_ary a, @network.subnet(i) }
420
+ end
421
+
422
+ def test_method_supernet
423
+ assert_raise(ArgumentError) { @ip.supernet(24) }
424
+
425
+ {
426
+ 0 => '0.0.0.0/0',
427
+ -2 => '0.0.0.0/0',
428
+ 23 => '172.16.10.0/23',
429
+ 22 => '172.16.8.0/22'
430
+ }.each { |i, s| assert_equal s, @ip.supernet(i).to_string }
431
+ end
432
+
433
+ def test_classmethod_parse_u32
434
+ @decimal_values.each { |addr, int|
435
+ ip = @klass.parse_u32(int, addr.split('/').last.to_i)
436
+ assert_equal ip.to_string, addr
437
+ }
438
+ end
439
+
440
+ def test_classmethod_extract
441
+ str = 'foobar172.16.10.1barbaz1.2.3.4/24'
442
+ assert_equal '172.16.10.1/32', @klass.extract(str).to_string
443
+ end
444
+
445
+ def test_classmethod_extract_all
446
+ str = 'foobar172.16.10.1barbaz1.2.3.4/24'
447
+ assert_equal_ary %w[172.16.10.1/32 1.2.3.4/32], @klass.extract_all(str)
448
+ end
449
+
450
+ def test_classmethod_summarize
451
+ assert_equal [@ip.network], @klass.summarize(@ip)
452
+
453
+ # Summarize homogeneous networks
454
+ assert_equal_ary %w[172.16.10.0/23], @klass.summarize(
455
+ @klass.new('172.16.10.1/24'), @klass.new('172.16.11.2/24')
456
+ )
457
+
458
+ ips = [
459
+ @klass.new('10.0.0.1/24'), @klass.new('10.0.1.1/24'),
460
+ @klass.new('10.0.2.1/24'), @klass.new('10.0.3.1/24')
461
+ ]
462
+ assert_equal_ary %w[10.0.0.0/22], @klass.summarize(*ips)
463
+ assert_equal_ary %w[10.0.0.0/22], @klass.summarize(*ips.reverse)
464
+
465
+ # Summarize non homogeneous networks
466
+ assert_equal_ary %w[10.0.0.0/23 10.0.2.0/24], @klass.summarize(
467
+ @klass.new('10.0.0.0/23'), @klass.new('10.0.2.0/24')
468
+ )
469
+
470
+ assert_equal_ary %w[10.0.0.0/16], @klass.summarize(
471
+ @klass.new('10.0.0.0/16'), @klass.new('10.0.2.0/24')
472
+ )
473
+
474
+ assert_equal_ary %w[10.0.0.0/23 10.1.0.0/24], @klass.summarize(
475
+ @klass.new('10.0.0.0/23'), @klass.new('10.1.0.0/24')
476
+ )
477
+
478
+ assert_equal_ary %w[10.0.0.0/22 10.0.4.0/24 10.0.6.0/24], @klass.summarize(
479
+ @klass.new('10.0.0.0/23'), @klass.new('10.0.2.0/23'),
480
+ @klass.new('10.0.4.0/24'), @klass.new('10.0.6.0/24')
481
+ )
482
+
483
+ res, ips = %w[10.0.1.0/24 10.0.2.0/23 10.0.4.0/24], [
484
+ @klass.new('10.0.1.1/24'), @klass.new('10.0.2.1/24'),
485
+ @klass.new('10.0.3.1/24'), @klass.new('10.0.4.1/24')
486
+ ]
487
+ assert_equal_ary res, @klass.summarize(*ips)
488
+ assert_equal_ary res, @klass.summarize(*ips.reverse)
489
+
490
+ assert_equal_ary %w[10.0.1.0/24 10.10.2.0/24 172.16.0.0/23], @klass.summarize(
491
+ @klass.new('10.0.1.1/24'), @klass.new('10.10.2.1/24'),
492
+ @klass.new('172.16.0.1/24'), @klass.new('172.16.1.1/24')
493
+ )
494
+
495
+ assert_equal_ary %w[10.0.0.12/30 10.0.100.0/24], @klass.summarize(
496
+ @klass.new('10.0.0.12/30'), @klass.new('10.0.100.0/24')
497
+ )
498
+
499
+ assert_equal_ary %w[10.10.2.1/32 172.16.0.0/31], @klass.summarize(
500
+ @klass.new('172.16.0.0/31'), @klass.new('10.10.2.1/32')
501
+ )
502
+
503
+ assert_equal_ary %w[10.10.2.1/32 172.16.0.0/32], @klass.summarize(
504
+ @klass.new('172.16.0.0/32'), @klass.new('10.10.2.1/32')
505
+ )
506
+ end
507
+
508
+ def test_classmethod_parse_data
509
+ ip = @klass.parse_data("\254\020\n\001")
510
+ assert_instance_of @klass, ip
511
+ assert_equal '172.16.10.1', ip.to_s
512
+ assert_equal '172.16.10.1/32', ip.to_string
513
+ end
514
+
515
+ def test_classmethod_parse_classful
516
+ @classful.each { |ip, prefix|
517
+ res = @klass.parse_classful(ip)
518
+ assert_equal prefix, res.prefix.prefix
519
+ assert_equal "#{ip}/#{prefix}", res.to_string
520
+ }
521
+
522
+ assert_raise(ArgumentError) { @klass.parse_classful('192.168.256.257') }
523
+ end
524
+
525
+ end