From 90c8eec3900eac9e38a8e8198f0fd2b28d561a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?= Date: Tue, 16 Jul 2019 19:30:53 +0000 Subject: tests: add a lot more tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Asbjørn Sloth Tønnesen --- test/inet.lua | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 172 insertions(+), 18 deletions(-) diff --git a/test/inet.lua b/test/inet.lua index 705715a..587a0b7 100644 --- a/test/inet.lua +++ b/test/inet.lua @@ -1,6 +1,8 @@ local inet = require 'inet' local test = require 'test' +local insert = table.insert + local function parse(addr) local ret, err = inet(addr) assert(ret, (err or '')..' '..addr) @@ -11,7 +13,98 @@ local function dontparse(...) test.fail(parse, ...) end -return test.new(function() +local function all_the_same(t) + local first + for i=1,#t do + local ip = parse(t[i]) + if not first then + first = ip + else + assert(first == ip) + end + end +end + +local function rfc4291() + -- RFC 4291 - IP Version 6 Addressing Architecture + assert(tostring(parse('2001:DB8:0:0:8:800:200C:417A')) + == string.lower('2001:DB8::8:800:200C:417A')) + assert(tostring(parse('FF01:0:0:0:0:0:0:101')) == string.lower('FF01::101')) + assert(tostring(parse('0:0:0:0:0:0:0:1')) == '::1') + assert(tostring(parse('0:0:0:0:0:0:0:0')) == '::') + assert(tostring(parse('::')) == '::') +end + +local function rfc5952() + -- RFC 5952 - A Recommendation for IPv6 Address Text Representation + -- 1. Introduction + all_the_same { + '2001:db8:0:0:1:0:0:1', + '2001:0db8:0:0:1:0:0:1', + '2001:db8::1:0:0:1', + '2001:db8::0:1:0:0:1', + '2001:0db8::1:0:0:1', + '2001:db8:0:0:1::1', + '2001:db8:0000:0:1::1', + '2001:DB8:0:0:1::1', + } + + -- 2.1. Leading Zeros in a 16-Bit Field + all_the_same { + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001', + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:001', + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:01', + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:1', + } + + -- 2.2. Zero Compression + all_the_same { + '2001:db8:aaaa:bbbb:cccc:dddd::1', + '2001:db8:aaaa:bbbb:cccc:dddd:0:1', + } + all_the_same { + '2001:db8:0:0:0::1', + '2001:db8:0:0::1', + '2001:db8:0::1', + '2001:db8::1', + } + all_the_same { + '2001:db8::aaaa:0:0:1', + '2001:db8:0:0:aaaa::1', + } + + -- 2.3. Uppercase or Lowercase + all_the_same { + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa', + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA', + '2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa', + } + + -- 4.1. Handling Leading Zeros in a 16-Bit Field + assert(parse('2001:0db8::0001'):ipstring() == '2001:db8::1') + assert(parse('2001:0db8:0000:1::0001'):ipstring() == '2001:db8:0:1::1') + + -- 4.2.1. Shorten as Much as Possible + assert(parse('2001:db8:0:0:0:0:2:1'):ipstring() == '2001:db8::2:1') + assert(parse('2001:db8::0:1'):ipstring() == '2001:db8::1') + + -- 4.2.2. Handling One 16-Bit 0 Field + assert(parse('2001:db8::1:1:1:1:1'):ipstring() == '2001:db8:0:1:1:1:1:1') + + -- 4.2.3. Choice in Placement of "::" + assert(parse('2001:db8:0:0:1::1'):ipstring() == '2001:db8::1:0:0:1') + + -- 4.3. Lowercase + assert(parse('2001:DB8::ABCD:EF'):ipstring() == '2001:db8::abcd:ef') + + -- 5. Text Representation of Special Addresses + assert(parse('::ffff:192.0.2.1'):ipstring4() == '::ffff:192.0.2.1') + assert(parse('0:0:0:0:0:ffff:192.0.2.1'):ipstring4() == '::ffff:192.0.2.1') + assert(parse('1:2:3:0:0:ffff:0.0.0.0'):ipstring4() == '1:2:3::ffff:0.0.0.0') + assert(parse('1:2:3:0:0:ffff::'):ipstring4() == '1:2:3::ffff:0.0.0.0') +end + +local function misc() local ip -- parsing parse('1:2:3:4:5:6:7:8') @@ -24,12 +117,21 @@ return test.new(function() dontparse('::1/33a') dontparse('::1/150') dontparse('1:2:3:4::2:3:4:5:6:7:8/33') + + --print(parse('0:0:0:0:0:0:13.1.68.3')) + assert(tostring(parse('2001:0DB8:0000:CD30:0000:0000:0000:0000/60')) + == '2001:db8:0:cd30::/60') + assert(tostring(parse('2001:0DB8::CD30:0:0:0:0/60')) == '2001:db8:0:cd30::/60') + assert(tostring(parse('2001:0DB8:0:CD30::/60')) == '2001:db8:0:cd30::/60') + dontparse('2001:0DB8:0:CD3/60') + assert(tostring(parse('1:0:0:1::/64') * 1) == '1:0:0:2::/64') assert(tostring(parse('1::/64') * 5 / 32 * 3) == '1:3:0:5::/32') assert(tostring(parse('5::64') / 32 * -3) == '4:fffd::64/32') assert(tostring(parse('2::/32') ^ 1) == '2::/33') assert(tostring(parse('2::/32') ^ -1) == '2::/31') assert(tostring(parse('2::/128') * 5) == '2::5') + assert(tostring(parse('2::/127') * 5) == '2::a/127') assert(tostring(parse('2::/49') - 1) == '1:ffff:ffff:ffff:ffff:ffff:ffff:ffff/49') assert(tostring(parse('2::/49') - 1 + 2) == '2::1/49') @@ -55,12 +157,12 @@ return test.new(function() assert(tostring(ip^1) == '10.0.0.0/25', 'ip power is broken') -- test inet4.__lt - assert(inet('10.0.0.0/24') > inet('10.0.0.0/30'), 'inet less than is broken') + assert(inet('10.0.0.0/24') < inet('10.0.0.0/30'), 'inet less than is broken') assert(not (inet('10.0.0.0/30') > inet('10.0.0.0/30')), 'inet less than is broken') assert(inet('10.0.0.0/30') >= inet('10.0.0.0/30'), 'inet less than is broken') assert(inet('10.0.0.0/30') <= inet('10.0.0.0/30'), 'inet less than is broken') - assert(inet('10.0.0.0/30') < inet('10.0.0.0/24'), 'inet less than is broken') - assert(not (inet('10.0.0.0/24') < inet('10.0.0.0/30')), 'inet less than is broken') + assert(inet('10.0.0.0/30') > inet('10.0.0.0/24'), 'inet less than is broken') + assert(not (inet('10.0.0.0/24') > inet('10.0.0.0/30')), 'inet less than is broken') assert(not (inet('10.0.0.0/30') < inet('10.0.0.0/30')), 'inet less than is broken') assert(not (inet('20.0.0.0/30') < inet('10.0.0.0/24')), 'inet less than is broken') @@ -70,7 +172,6 @@ return test.new(function() assert(inet('127.0.0.1/8'):netmask() == inet('255.0.0.0')) - -- test inet*.__eq assert(inet('10.0.0.0/30') == inet('10.0.0.0/30'), 'inet4 eq is broken') assert(inet('10.0.1.0/30') ~= inet('10.0.0.0/30'), 'inet4 eq is broken') @@ -90,7 +191,7 @@ return test.new(function() assert((ip/22):network() == inet('ffff:fc00::/22'), 'inet6.network() is broken') assert((ip/27):network() == inet('ffff:ffe0::/27'), 'inet6.network() is broken') - --- test inet4:flip + -- test inet4:flip assert(inet('10.0.0.1/24'):flip() == inet('10.0.1.1/24'), 'inet4.flip() is broken') assert(inet('10.0.0.0/24'):flip() == inet('10.0.1.0/24'), 'inet4.flip() is broken') assert(inet('10.0.0.0/24'):flip():flip() == inet('10.0.0.0/24'), 'inet4.flip() is broken') @@ -98,24 +199,71 @@ return test.new(function() assert(inet('10.20.30.5/24'):flip() == inet('10.20.31.5/24')) assert(inet('10.20.30.5/32'):flip() == inet('10.20.30.4/32')) assert(inet('0.0.0.0/0'):flip() == nil) - local ips = { - inet('::'), - inet('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), - } assert(inet('::/0'):flip() == nil) assert(inet('::1/32'):flip() == inet('0:1::1/32')) assert(inet('::1/48'):flip() == inet('0:0:1::1/48')) - for i=1,#ips do - ip = ips[i] - for j=1,128 do - local foo = ip / j - local bar = foo:flip() - assert(foo ~= bar) - assert(foo == bar:flip()) + + assert(inet('2001:db8::/35'):contains(inet('2001:db8::/35'))) + assert(inet('2001:db8::/35'):contains(inet('2001:db8::/64'))) + assert(inet('2001:db8::/35'):contains(inet('2001:db8:1::/64'))) + assert(inet('::/0'):contains(inet('::/0'))) + assert(inet('::/0'):contains(inet('2001:db8::/35'))) + + assert(#inet('::/0') == 0, 'incorrect netmask') + + assert(inet('2001:db8::/64') < inet('2001:db8:1::/64')) + assert(inet('2001:db8:1::/64') <= inet('2001:db8:1::/64')) + assert(inet('2001:db8:1::/48') < inet('2001:db8:2::/48')) + assert(inet('2001:db8:1::/48') <= inet('2001:db8:2::/48')) + assert(inet('2001:db8:1::/48') <= inet('2001:db8:1::/48')) + assert(inet('2001:db8:2::/48') >= inet('2001:db8:1::/48')) + assert(inet('2001:db8:1::/32') < inet('2001:db8:1::/48')) + assert(inet('2001:db8:1::/32') <= inet('2001:db8:1::/48')) + + --XXX assert(inet('2001:db8:1:2:3:4:10/64') - inet('2001:db8:1::/64') == 42) + + do + local ips = { + inet('::'), + inet('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + } + for i=1,#ips do + ip = ips[i] + for j=1,128 do + local foo = ip / j + local bar = foo:flip() + assert(foo ~= bar) + assert(foo == bar:flip()) + end + end + end + + do + local nets = {} + for i=0,128,16 do + local net = inet('::', i) + insert(nets, net * i) end + for i=2,#nets do + local net = nets[i] + insert(nets, net*-i) + insert(nets, net*i) + end + for i=1,#nets do + local net = nets[i] + insert(nets, net-i) + insert(nets, net+i) + end + table.sort(nets) + --[[ + for i=1,#nets do + print(i, nets[i]:cidrstring()) + end + ]]-- end -- test inspectablity of metatable + assert(#(getmetatable(inet('0.0.0.0/0'))) ~= nil) assert(#(getmetatable(inet('::/0'))) ~= nil) -- TODO inet6.__le @@ -138,4 +286,10 @@ return test.new(function() assert(not inet.is(42)) assert(inet.is(inet('0.0.0.0'))) assert(inet.is(inet('::'))) -end) +end + +local t = test.new() +t:depend(test.new(rfc4291)) +t:depend(test.new(rfc5952)) +t:depend(test.new(misc)) +return t -- cgit v1.2.1