From 084a85df5c88b8aca0646e9dde9897dd24fe4922 Mon Sep 17 00:00:00 2001 From: nathan Date: Mon, 6 Nov 2017 17:47:18 +0100 Subject: [PATCH] Added xbill derrived DNS tests - WIP --- test/dorkbox/network/DnsTests.java | 117 -- test/dorkbox/network/dns/AddressTest.java | 339 +++++ test/dorkbox/network/dns/CompressionTest.java | 62 + test/dorkbox/network/dns/DClassTest.java | 86 ++ test/dorkbox/network/dns/DNSInputTest.java | 306 ++++ test/dorkbox/network/dns/ExceptionTest.java | 113 ++ .../network/dns/ExtendedFlagsTest.java | 82 ++ test/dorkbox/network/dns/FlagsTest.java | 112 ++ .../network/dns/FormattedTimeTest.java | 90 ++ test/dorkbox/network/dns/NameTest.java | 1302 +++++++++++++++++ test/dorkbox/network/dns/OpcodeTest.java | 82 ++ test/dorkbox/network/dns/OptionsTest.java | 149 ++ test/dorkbox/network/dns/RcodeTest.java | 112 ++ test/dorkbox/network/dns/ReverseMapTest.java | 114 ++ test/dorkbox/network/dns/TokenizerTest.java | 609 ++++++++ test/dorkbox/network/dns/TypeTest.java | 83 ++ .../network/dns/records/A6RecordTest.java | 253 ++++ .../network/dns/records/AAAARecordTest.java | 165 +++ .../network/dns/records/AFSDBRecordTest.java | 65 + .../network/dns/records/APLRecordTest.java | 696 +++++++++ .../network/dns/records/ARecordTest.java | 163 +++ .../network/dns/records/CNAMERecordTest.java | 73 + .../network/dns/records/DNAMERecordTest.java | 73 + .../network/dns/records/DNSKEYRecordTest.java | 116 ++ .../network/dns/records/DNSOutputTest.java | 263 ++++ .../network/dns/records/DNSSECSIG0Test.java | 55 + .../dns/records/DNSSECWithProviderTest.java | 49 + .../network/dns/records/DSRecordTest.java | 243 +++ .../network/dns/records/EmptyRecordTest.java | 105 ++ .../network/dns/records/GPOSRecordTest.java | 401 +++++ .../network/dns/records/HINFORecordTest.java | 200 +++ .../network/dns/records/HeaderTest.java | 455 ++++++ .../network/dns/records/KEYBaseTest.java | 202 +++ .../network/dns/records/KEYRecordTest.java | 202 +++ .../network/dns/records/KXRecordTest.java | 66 + .../network/dns/records/MBRecordTest.java | 73 + .../network/dns/records/MDRecordTest.java | 73 + .../network/dns/records/MFRecordTest.java | 73 + .../network/dns/records/MGRecordTest.java | 71 + .../network/dns/records/MRRecordTest.java | 71 + .../network/dns/records/MXRecordTest.java | 91 ++ .../network/dns/records/MessageTest.java | 124 ++ .../network/dns/records/MnemonicTest.java | 314 ++++ .../dns/records/NSAP_PTRRecordTest.java | 71 + .../network/dns/records/NSRecordTest.java | 73 + .../network/dns/records/OPTRecordTest.java | 39 + .../network/dns/records/RRsetTest.java | 343 +++++ .../network/dns/records/RTRecordTest.java | 65 + .../network/dns/records/RecordTest.java | 971 ++++++++++++ .../network/dns/records/SOARecordTest.java | 455 ++++++ .../network/dns/records/SectionTest.java | 100 ++ .../records/SingleCompressedNameBaseTest.java | 118 ++ .../dns/records/SingleNameBaseTest.java | 178 +++ .../dorkbox/network/dns/records/TSIGTest.java | 90 ++ test/dorkbox/network/dns/records/TTLTest.java | 146 ++ .../network/dns/records/TypeBitmapTest.java | 57 + .../network/dns/records/U16NameBaseTest.java | 216 +++ .../network/dns/records/URIRecordTest.java | 125 ++ 58 files changed, 11423 insertions(+), 117 deletions(-) delete mode 100644 test/dorkbox/network/DnsTests.java create mode 100644 test/dorkbox/network/dns/AddressTest.java create mode 100644 test/dorkbox/network/dns/CompressionTest.java create mode 100644 test/dorkbox/network/dns/DClassTest.java create mode 100644 test/dorkbox/network/dns/DNSInputTest.java create mode 100644 test/dorkbox/network/dns/ExceptionTest.java create mode 100644 test/dorkbox/network/dns/ExtendedFlagsTest.java create mode 100644 test/dorkbox/network/dns/FlagsTest.java create mode 100644 test/dorkbox/network/dns/FormattedTimeTest.java create mode 100644 test/dorkbox/network/dns/NameTest.java create mode 100644 test/dorkbox/network/dns/OpcodeTest.java create mode 100644 test/dorkbox/network/dns/OptionsTest.java create mode 100644 test/dorkbox/network/dns/RcodeTest.java create mode 100644 test/dorkbox/network/dns/ReverseMapTest.java create mode 100644 test/dorkbox/network/dns/TokenizerTest.java create mode 100644 test/dorkbox/network/dns/TypeTest.java create mode 100644 test/dorkbox/network/dns/records/A6RecordTest.java create mode 100644 test/dorkbox/network/dns/records/AAAARecordTest.java create mode 100644 test/dorkbox/network/dns/records/AFSDBRecordTest.java create mode 100644 test/dorkbox/network/dns/records/APLRecordTest.java create mode 100644 test/dorkbox/network/dns/records/ARecordTest.java create mode 100644 test/dorkbox/network/dns/records/CNAMERecordTest.java create mode 100644 test/dorkbox/network/dns/records/DNAMERecordTest.java create mode 100644 test/dorkbox/network/dns/records/DNSKEYRecordTest.java create mode 100644 test/dorkbox/network/dns/records/DNSOutputTest.java create mode 100644 test/dorkbox/network/dns/records/DNSSECSIG0Test.java create mode 100644 test/dorkbox/network/dns/records/DNSSECWithProviderTest.java create mode 100644 test/dorkbox/network/dns/records/DSRecordTest.java create mode 100644 test/dorkbox/network/dns/records/EmptyRecordTest.java create mode 100644 test/dorkbox/network/dns/records/GPOSRecordTest.java create mode 100644 test/dorkbox/network/dns/records/HINFORecordTest.java create mode 100644 test/dorkbox/network/dns/records/HeaderTest.java create mode 100644 test/dorkbox/network/dns/records/KEYBaseTest.java create mode 100644 test/dorkbox/network/dns/records/KEYRecordTest.java create mode 100644 test/dorkbox/network/dns/records/KXRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MBRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MDRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MFRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MGRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MRRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MXRecordTest.java create mode 100644 test/dorkbox/network/dns/records/MessageTest.java create mode 100644 test/dorkbox/network/dns/records/MnemonicTest.java create mode 100644 test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java create mode 100644 test/dorkbox/network/dns/records/NSRecordTest.java create mode 100644 test/dorkbox/network/dns/records/OPTRecordTest.java create mode 100644 test/dorkbox/network/dns/records/RRsetTest.java create mode 100644 test/dorkbox/network/dns/records/RTRecordTest.java create mode 100644 test/dorkbox/network/dns/records/RecordTest.java create mode 100644 test/dorkbox/network/dns/records/SOARecordTest.java create mode 100644 test/dorkbox/network/dns/records/SectionTest.java create mode 100644 test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java create mode 100644 test/dorkbox/network/dns/records/SingleNameBaseTest.java create mode 100644 test/dorkbox/network/dns/records/TSIGTest.java create mode 100644 test/dorkbox/network/dns/records/TTLTest.java create mode 100644 test/dorkbox/network/dns/records/TypeBitmapTest.java create mode 100644 test/dorkbox/network/dns/records/U16NameBaseTest.java create mode 100644 test/dorkbox/network/dns/records/URIRecordTest.java diff --git a/test/dorkbox/network/DnsTests.java b/test/dorkbox/network/DnsTests.java deleted file mode 100644 index 719e5318..00000000 --- a/test/dorkbox/network/DnsTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2014 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.network; - -import static org.junit.Assert.fail; - -import java.net.UnknownHostException; -import java.util.List; - -import org.junit.Test; - -import dorkbox.network.dns.record.MailExchangerRecord; -import dorkbox.network.dns.record.ServiceRecord; -import dorkbox.network.dns.record.StartOfAuthorityRecord; - -public class DnsTests { - - @Test - public - void decode_A_Record() throws UnknownHostException { - //DnsClient dnsClient = new DnsClient("127.0.1.1"); - DnsClient dnsClient = new DnsClient(); - String answer = dnsClient.resolveA("google.com"); - dnsClient.stop(); - - if (answer == null) { - fail("Error fetching answer for DNS"); - } - } - - @Test - public void decode_PTR_Record() { - // PTR absolutely MUST end in '.in-addr.arpa' in order for the DNS server to understand it. - // our DNS client will FIX THIS, so that end-users do NOT have to know this! - - DnsClient dnsClient = new DnsClient(); - String answer = dnsClient.resolvePTR("204.228.150.3"); - dnsClient.stop(); - - if (answer == null) { - fail("Error fetching answer for DNS"); - } - } - - @Test - public void decode_CNAME_Record() { - DnsClient dnsClient = new DnsClient(); - String answer = dnsClient.resolveCNAME("www.atmos.org"); - dnsClient.stop(); - - if (answer == null) { - fail("Error fetching answer for DNS"); - } - } - - @Test - public void decode_MX_Record() { - DnsClient dnsClient = new DnsClient(); - MailExchangerRecord answer = dnsClient.resolveMX("bbc.co.uk"); - final String name = answer.name(); - dnsClient.stop(); - - if (name == null || name.isEmpty()) { - fail("Error fetching answer for DNS"); - } - } - - @Test - public void decode_SRV_Record() { - DnsClient dnsClient = new DnsClient(); - ServiceRecord answer = dnsClient.resolveSRV("_pop3._tcp.fudo.org"); - final String name = answer.name(); - dnsClient.stop(); - - if (name == null || name.isEmpty()) { - fail("Error fetching answer for DNS"); - } - } - - @Test - public void decode_SOA_Record() { - DnsClient dnsClient = new DnsClient(); - StartOfAuthorityRecord answer = dnsClient.resolveSOA("google.com"); - final String nameServer = answer.primaryNameServer(); - dnsClient.stop(); - - if (nameServer == null || nameServer.isEmpty()) { - fail("Error fetching answer for DNS"); - } - } - - - @Test - public void decode_TXT_Record() { - DnsClient dnsClient = new DnsClient(); - List answer = dnsClient.resolveTXT("real-world-systems.com"); - final String name = answer.get(0); - dnsClient.stop(); - - if (name == null || name.isEmpty()) { - fail("Error fetching answer for DNS"); - } - } -} diff --git a/test/dorkbox/network/dns/AddressTest.java b/test/dorkbox/network/dns/AddressTest.java new file mode 100644 index 00000000..3fdd94ff --- /dev/null +++ b/test/dorkbox/network/dns/AddressTest.java @@ -0,0 +1,339 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.utils.Address; +import junit.framework.TestCase; + +public +class AddressTest extends TestCase { + public + void test_toByteArray_invalid() { + try { + Address.toByteArray("doesn't matter", 3); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_toByteArray_IPv4() { + byte[] exp = new byte[] {(byte) 198, (byte) 121, (byte) 10, (byte) 234}; + byte[] ret = Address.toByteArray("198.121.10.234", Address.IPv4); + assertEquals(exp, ret); + + exp = new byte[] {0, 0, 0, 0}; + ret = Address.toByteArray("0.0.0.0", Address.IPv4); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + ret = Address.toByteArray("255.255.255.255", Address.IPv4); + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(Arrays.equals(exp, act)); + } + + public + void test_toByteArray_IPv4_invalid() { + assertNull(Address.toByteArray("A.B.C.D", Address.IPv4)); + + assertNull(Address.toByteArray("128...", Address.IPv4)); + assertNull(Address.toByteArray("128.121", Address.IPv4)); + assertNull(Address.toByteArray("128.111.8", Address.IPv4)); + assertNull(Address.toByteArray("128.198.10.", Address.IPv4)); + + assertNull(Address.toByteArray("128.121.90..10", Address.IPv4)); + assertNull(Address.toByteArray("128.121..90.10", Address.IPv4)); + assertNull(Address.toByteArray("128..121.90.10", Address.IPv4)); + assertNull(Address.toByteArray(".128.121.90.10", Address.IPv4)); + + assertNull(Address.toByteArray("128.121.90.256", Address.IPv4)); + assertNull(Address.toByteArray("128.121.256.10", Address.IPv4)); + assertNull(Address.toByteArray("128.256.90.10", Address.IPv4)); + assertNull(Address.toByteArray("256.121.90.10", Address.IPv4)); + + assertNull(Address.toByteArray("128.121.90.-1", Address.IPv4)); + assertNull(Address.toByteArray("128.121.-1.10", Address.IPv4)); + assertNull(Address.toByteArray("128.-1.90.10", Address.IPv4)); + assertNull(Address.toByteArray("-1.121.90.10", Address.IPv4)); + + assertNull(Address.toByteArray("120.121.90.10.10", Address.IPv4)); + + assertNull(Address.toByteArray("120.121.90.010", Address.IPv4)); + assertNull(Address.toByteArray("120.121.090.10", Address.IPv4)); + assertNull(Address.toByteArray("120.021.90.10", Address.IPv4)); + assertNull(Address.toByteArray("020.121.90.10", Address.IPv4)); + + assertNull(Address.toByteArray("1120.121.90.10", Address.IPv4)); + assertNull(Address.toByteArray("120.2121.90.10", Address.IPv4)); + assertNull(Address.toByteArray("120.121.4190.10", Address.IPv4)); + assertNull(Address.toByteArray("120.121.190.1000", Address.IPv4)); + + assertNull(Address.toByteArray("", Address.IPv4)); + } + + public + void test_toByteArray_IPv6() { + byte[] exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, + (byte) 25, (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; + byte[] ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("2001:db8:85a3:8d3:1319:8a2e:370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("2001:DB8:85A3:8D3:1319:8A2E:370:7334", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + ret = Address.toByteArray("0:0:0:0:0:0:0:0", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + ret = Address.toByteArray("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 0, (byte) 0, (byte) 8, (byte) 211, (byte) 19, (byte) 25, + (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; + ret = Address.toByteArray("2001:0db8:0000:08d3:1319:8a2e:0370:7334", Address.IPv6); + assertEquals(exp, ret); + + ret = Address.toByteArray("2001:0db8::08d3:1319:8a2e:0370:7334", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, + (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; + ret = Address.toByteArray("0000:0000:85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("::85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, + (byte) 138, (byte) 46, (byte) 0, (byte) 0, (byte) 0, (byte) 0}; + ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0:0", Address.IPv6); + assertEquals(exp, ret); + + ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e::", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, + (byte) 0, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; + ret = Address.toByteArray("2001:0db8:0000:0000:0000:0000:0370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("2001:0db8:0:0:0:0:0370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("2001:0db8::0:0370:7334", Address.IPv6); + assertEquals(exp, ret); + ret = Address.toByteArray("2001:db8::370:7334", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, + (byte) 138, (byte) 46, (byte) 0xC0, (byte) 0xA8, (byte) 0x59, (byte) 0x09}; + ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:192.168.89.9", Address.IPv6); + assertEquals(exp, ret); + + exp = new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, + (byte) 0, (byte) 0xC0, (byte) 0xA8, (byte) 0x59, (byte) 0x09}; + ret = Address.toByteArray("::192.168.89.9", Address.IPv6); + assertEquals(exp, ret); + } + + public + void test_toByteArray_IPv6_invalid() { + // not enough groups + assertNull(Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370", Address.IPv6)); + // too many groups + assertNull(Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370:193A:BCdE", Address.IPv6)); + // invalid letter + assertNull(Address.toByteArray("2001:0gb8:85a3:08d3:1319:8a2e:0370:9819", Address.IPv6)); + assertNull(Address.toByteArray("lmno:0bb8:85a3:08d3:1319:8a2e:0370:9819", Address.IPv6)); + assertNull(Address.toByteArray("11ab:0ab8:85a3:08d3:1319:8a2e:0370:qrst", Address.IPv6)); + // three consecutive colons + assertNull(Address.toByteArray("11ab:0ab8:85a3:08d3:::", Address.IPv6)); + // IPv4 in the middle + assertNull(Address.toByteArray("2001:0ab8:192.168.0.1:1319:8a2e:0370:9819", Address.IPv6)); + // invalid IPv4 + assertNull(Address.toByteArray("2001:0ab8:1212:AbAb:8a2e:345.12.22.1", Address.IPv6)); + // group with too many digits + assertNull(Address.toByteArray("2001:0ab8:85a3:128d3:1319:8a2e:0370:9819", Address.IPv6)); + + } + + public + void test_toArray() { + int[] exp = new int[] {1, 2, 3, 4}; + int[] ret = Address.toArray("1.2.3.4", Address.IPv4); + assertEquals(exp, ret); + + exp = new int[] {0, 0, 0, 0}; + ret = Address.toArray("0.0.0.0", Address.IPv4); + assertEquals(exp, ret); + + exp = new int[] {255, 255, 255, 255}; + ret = Address.toArray("255.255.255.255", Address.IPv4); + assertEquals(exp, ret); + } + + private + void assertEquals(int[] exp, int[] act) { + assertEquals(exp.length, act.length); + for (int i = 0; i < exp.length; ++i) { + assertEquals("i=" + i, exp[i], act[i]); + } + } + + public + void test_toArray_invalid() { + assertNull(Address.toArray("128.121.1", Address.IPv4)); + + assertNull(Address.toArray("")); + } + + public + void test_isDottedQuad() { + assertTrue(Address.isDottedQuad("1.2.3.4")); + assertFalse(Address.isDottedQuad("256.2.3.4")); + } + + public + void test_toDottedQuad() { + assertEquals("128.176.201.1", Address.toDottedQuad(new byte[] {(byte) 128, (byte) 176, (byte) 201, (byte) 1})); + + assertEquals("200.1.255.128", Address.toDottedQuad(new int[] {200, 1, 255, 128})); + } + + public + void test_addressLength() { + assertEquals(4, Address.addressLength(Address.IPv4)); + assertEquals(16, Address.addressLength(Address.IPv6)); + + try { + Address.addressLength(3); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_getByName() throws UnknownHostException { + InetAddress out = Address.getByName("128.145.198.231"); + assertEquals("128.145.198.231", out.getHostAddress()); + + out = Address.getByName("a.root-servers.net"); + assertEquals("198.41.0.4", out.getHostAddress()); + } + + public + void test_getByName_invalid() throws UnknownHostException { + try { + Address.getByName("example.invalid"); + fail("UnknownHostException not thrown"); + } catch (UnknownHostException ignored) { + } + + try { + InetAddress byName = Address.getByName(""); + assertEquals("127.0.0.1", byName.getHostAddress()); + } catch (UnknownHostException ignored) { + fail("UnknownHostException thrown"); + } + } + + public + void test_getAllByName() throws UnknownHostException { + InetAddress[] out = Address.getAllByName("128.145.198.231"); + assertEquals(1, out.length); + assertEquals("128.145.198.231", out[0].getHostAddress()); + + out = Address.getAllByName("a.root-servers.net"); + assertTrue(out.length == 2); + assertEquals("198.41.0.4", out[0].getHostAddress()); + assertEquals("2001:503:ba3e:0:0:0:2:30", out[1].getHostAddress()); + + out = Address.getAllByName("cnn.com"); + assertTrue(out.length > 1); + for (int i = 0; i < out.length; ++i) { + String hostName = out[i].getHostName(); + assertTrue(hostName.endsWith("cnn.com")); + } + } + + public + void test_getAllByName_invalid() throws UnknownHostException { + try { + Address.getAllByName("example.invalid"); + fail("UnknownHostException not thrown"); + } catch (UnknownHostException ignored) { + } + + try { + InetAddress[] byName = Address.getAllByName(""); + assertEquals("127.0.0.1", byName[0].getHostAddress()); + assertEquals("0:0:0:0:0:0:0:1", byName[1].getHostAddress()); + } catch (UnknownHostException ignored) { + fail("UnknownHostException thrown"); + } + } + + public + void test_familyOf() throws UnknownHostException { + assertEquals(Address.IPv4, Address.familyOf(InetAddress.getByName("192.168.0.1"))); + assertEquals(Address.IPv6, Address.familyOf(InetAddress.getByName("1:2:3:4:5:6:7:8"))); + + try { + Address.familyOf(null); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_getHostName() throws UnknownHostException { + InetAddress byName = InetAddress.getByName("198.41.0.4"); + String out = Address.getHostName(byName); + assertEquals("a.root-servers.net.", out); + + try { + Address.getHostName(InetAddress.getByName("192.168.1.1")); + fail("UnknownHostException not thrown"); + } catch (UnknownHostException ignored) { + } + } +} diff --git a/test/dorkbox/network/dns/CompressionTest.java b/test/dorkbox/network/dns/CompressionTest.java new file mode 100644 index 00000000..95b378a8 --- /dev/null +++ b/test/dorkbox/network/dns/CompressionTest.java @@ -0,0 +1,62 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Options; +import junit.framework.TestCase; + +public +class CompressionTest extends TestCase { + @Override + public + void setUp() { + Options.set("verbosecompression"); + } + + public + void test() throws TextParseException { + Compression c = new Compression(); + Name n = Name.fromString("www.amazon.com."); + + c.add(10, n); + assertEquals(10, c.get(n)); + + Name n2 = Name.fromString("www.cnn.com."); + + c.add(10, n2); + assertEquals(10, c.get(n2)); + } +} diff --git a/test/dorkbox/network/dns/DClassTest.java b/test/dorkbox/network/dns/DClassTest.java new file mode 100644 index 00000000..cd4958e5 --- /dev/null +++ b/test/dorkbox/network/dns/DClassTest.java @@ -0,0 +1,86 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.constants.DnsClass; +import junit.framework.TestCase; + +public +class DClassTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("IN", DnsClass.string(DnsClass.IN)); + + // one with an alias + assertEquals("CH", DnsClass.string(DnsClass.CH)); + + // one that doesn't exist + assertTrue(DnsClass.string(20) + .startsWith("CLASS")); + + try { + DnsClass.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // (max is 0xFFFF) + try { + DnsClass.string(0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(DnsClass.NONE, DnsClass.value("NONE")); + + // one with alias + assertEquals(DnsClass.HS, DnsClass.value("HS")); + assertEquals(DnsClass.HS, DnsClass.value("HESIOD")); + + // one thats undefined but within range + assertEquals(21, DnsClass.value("CLASS21")); + + // something that unknown + assertEquals(-1, DnsClass.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, DnsClass.value("")); + } +} diff --git a/test/dorkbox/network/dns/DNSInputTest.java b/test/dorkbox/network/dns/DNSInputTest.java new file mode 100644 index 00000000..8274db6a --- /dev/null +++ b/test/dorkbox/network/dns/DNSInputTest.java @@ -0,0 +1,306 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.util.Arrays; + +import dorkbox.network.dns.exceptions.WireParseException; +import junit.framework.TestCase; + +public +class DNSInputTest extends TestCase { + private byte[] m_raw; + private DnsInput m_di; + + @Override + public + void setUp() { + m_raw = new byte[] {0, 1, 2, 3, 4, 5, (byte) 255, (byte) 255, (byte) 255, (byte) 255}; + m_di = new DnsInput(m_raw); + } + + public + void test_initial_state() { + assertEquals(0, m_di.readIndex()); + assertEquals(10, m_di.remaining()); + } + + public + void test_jump1() { + m_di.jump(1); + assertEquals(1, m_di.readIndex()); + assertEquals(9, m_di.remaining()); + } + + public + void test_jump2() { + m_di.jump(9); + assertEquals(9, m_di.readIndex()); + assertEquals(1, m_di.remaining()); + } + + public + void test_jump_invalid() { + try { + m_di.jump(10); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_setActive() { + m_di.setActive(5); + assertEquals(0, m_di.readIndex()); + assertEquals(5, m_di.remaining()); + } + + public + void test_setActive_boundary1() { + m_di.setActive(10); + assertEquals(0, m_di.readIndex()); + assertEquals(10, m_di.remaining()); + } + + public + void test_setActive_boundary2() { + m_di.setActive(0); + assertEquals(0, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + } + + public + void test_setActive_invalid() { + try { + m_di.setActive(11); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_clearActive() { + // first without setting active: + m_di.restoreActive(); + assertEquals(0, m_di.readIndex()); + assertEquals(10, m_di.remaining()); + + m_di.setActive(5); + m_di.restoreActive(); + assertEquals(0, m_di.readIndex()); + assertEquals(10, m_di.remaining()); + } + + public + void test_restore_invalid() { + try { + m_di.restore(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + // pass + } + } + + public + void test_save_restore() { + m_di.jump(4); + assertEquals(4, m_di.readIndex()); + assertEquals(6, m_di.remaining()); + + m_di.save(); + m_di.jump(0); + assertEquals(0, m_di.readIndex()); + assertEquals(10, m_di.remaining()); + + m_di.restore(); + assertEquals(4, m_di.readIndex()); + assertEquals(6, m_di.remaining()); + } + + public + void test_readU8_basic() throws WireParseException { + int v1 = m_di.readU8(); + assertEquals(1, m_di.readIndex()); + assertEquals(9, m_di.remaining()); + assertEquals(0, v1); + } + + public + void test_readU8_maxval() throws WireParseException { + m_di.jump(9); + int v1 = m_di.readU8(); + assertEquals(10, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + assertEquals(255, v1); + + try { + v1 = m_di.readU8(); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + // pass + } + } + + public + void test_readU16_basic() throws WireParseException { + int v1 = m_di.readU16(); + assertEquals(2, m_di.readIndex()); + assertEquals(8, m_di.remaining()); + assertEquals(1, v1); + + m_di.jump(1); + v1 = m_di.readU16(); + assertEquals(258, v1); + } + + public + void test_readU16_maxval() throws WireParseException { + m_di.jump(8); + int v = m_di.readU16(); + assertEquals(10, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + assertEquals(0xFFFF, v); + + try { + m_di.jump(9); + m_di.readU16(); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + // pass + } + } + + public + void test_readU32_basic() throws WireParseException { + long v1 = m_di.readU32(); + assertEquals(4, m_di.readIndex()); + assertEquals(6, m_di.remaining()); + assertEquals(66051, v1); + } + + public + void test_readU32_maxval() throws WireParseException { + m_di.jump(6); + long v = m_di.readU32(); + assertEquals(10, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + assertEquals(0xFFFFFFFFL, v); + + try { + m_di.jump(7); + m_di.readU32(); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + // pass + } + } + + public + void test_readByteArray_0arg() throws WireParseException { + m_di.jump(1); + byte[] out = m_di.readByteArray(); + assertEquals(10, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + assertEquals(9, out.length); + for (int i = 0; i < 9; ++i) { + assertEquals(m_raw[i + 1], out[i]); + } + } + + public + void test_readByteArray_0arg_boundary() throws WireParseException { + m_di.jump(9); + m_di.readU8(); + byte[] out = m_di.readByteArray(); + assertEquals(0, out.length); + } + + public + void test_readByteArray_1arg() throws WireParseException { + byte[] out = m_di.readByteArray(2); + assertEquals(2, m_di.readIndex()); + assertEquals(8, m_di.remaining()); + assertEquals(2, out.length); + assertEquals(0, out[0]); + assertEquals(1, out[1]); + } + + public + void test_readByteArray_1arg_boundary() throws WireParseException { + byte[] out = m_di.readByteArray(10); + assertEquals(10, m_di.readIndex()); + assertEquals(0, m_di.remaining()); + assertEquals(m_raw, out); + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(Arrays.equals(exp, act)); + } + + public + void test_readByteArray_1arg_invalid() { + try { + m_di.readByteArray(11); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + // pass + } + } + + public + void test_readByteArray_3arg() throws WireParseException { + byte[] data = new byte[5]; + m_di.jump(4); + + m_di.readByteArray(data, 1, 4); + assertEquals(8, m_di.readIndex()); + assertEquals(0, data[0]); + for (int i = 0; i < 4; ++i) { + assertEquals(m_raw[i + 4], data[i + 1]); + } + } + + public + void test_readCountedSting() throws WireParseException { + m_di.jump(1); + byte[] out = m_di.readCountedString(); + assertEquals(1, out.length); + assertEquals(3, m_di.readIndex()); + assertEquals(out[0], 2); + } +} diff --git a/test/dorkbox/network/dns/ExceptionTest.java b/test/dorkbox/network/dns/ExceptionTest.java new file mode 100644 index 00000000..176f3bcb --- /dev/null +++ b/test/dorkbox/network/dns/ExceptionTest.java @@ -0,0 +1,113 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.io.IOException; + +import dorkbox.network.dns.exceptions.InvalidDClassException; +import dorkbox.network.dns.exceptions.InvalidTTLException; +import dorkbox.network.dns.exceptions.InvalidTypeException; +import dorkbox.network.dns.exceptions.NameTooLongException; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.exceptions.WireParseException; +import dorkbox.network.dns.exceptions.ZoneTransferException; +import junit.framework.TestCase; + +public +class ExceptionTest extends TestCase { + public + void test_InvalidDClassException() { + IllegalArgumentException e = new InvalidDClassException(10); + assertEquals("Invalid DNS class: 10", e.getMessage()); + } + + public + void test_InvalidTTLException() { + IllegalArgumentException e = new InvalidTTLException(32345); + assertEquals("Invalid DNS TTL: 32345", e.getMessage()); + } + + public + void test_InvalidTypeException() { + IllegalArgumentException e = new InvalidTypeException(32345); + assertEquals("Invalid DNS type: 32345", e.getMessage()); + } + + public + void test_NameTooLongException() { + WireParseException e = new NameTooLongException(); + assertNull(e.getMessage()); + + e = new NameTooLongException("This is my too long name"); + assertEquals("This is my too long name", e.getMessage()); + } + + public + void test_RelativeNameException() throws TextParseException { + IllegalArgumentException e = new RelativeNameException("This is my relative name"); + assertEquals("This is my relative name", e.getMessage()); + + e = new RelativeNameException(Name.fromString("relative")); + assertEquals("'relative' is not an absolute name", e.getMessage()); + } + + public + void test_TextParseException() { + IOException e = new TextParseException(); + assertNull(e.getMessage()); + + e = new TextParseException("This is my message"); + assertEquals("This is my message", e.getMessage()); + } + + public + void test_WireParseException() { + IOException e = new WireParseException(); + assertNull(e.getMessage()); + + e = new WireParseException("This is my message"); + assertEquals("This is my message", e.getMessage()); + } + + public + void test_ZoneTransferException() { + Exception e = new ZoneTransferException(); + assertNull(e.getMessage()); + + e = new ZoneTransferException("This is my message"); + assertEquals("This is my message", e.getMessage()); + } +} diff --git a/test/dorkbox/network/dns/ExtendedFlagsTest.java b/test/dorkbox/network/dns/ExtendedFlagsTest.java new file mode 100644 index 00000000..477d6391 --- /dev/null +++ b/test/dorkbox/network/dns/ExtendedFlagsTest.java @@ -0,0 +1,82 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.records.ExtendedFlags; +import junit.framework.TestCase; + +public +class ExtendedFlagsTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("do", ExtendedFlags.string(ExtendedFlags.DO)); + + // one that doesn't exist + assertTrue(ExtendedFlags.string(1) + .startsWith("flag")); + + try { + ExtendedFlags.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // (max is 0xFFFF) + try { + ExtendedFlags.string(0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(ExtendedFlags.DO, ExtendedFlags.value("do")); + + // one thats undefined but within range + assertEquals(16, ExtendedFlags.value("FLAG16")); + + // one thats undefined but out of range + assertEquals(-1, ExtendedFlags.value("FLAG" + 0x10000)); + + // something that unknown + assertEquals(-1, ExtendedFlags.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, ExtendedFlags.value("")); + } +} diff --git a/test/dorkbox/network/dns/FlagsTest.java b/test/dorkbox/network/dns/FlagsTest.java new file mode 100644 index 00000000..54cfaead --- /dev/null +++ b/test/dorkbox/network/dns/FlagsTest.java @@ -0,0 +1,112 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.constants.Flags; +import junit.framework.TestCase; + +public +class FlagsTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("aa", Flags.string(Flags.AA)); + + // one that doesn't exist + assertTrue(Flags.string(12) + .startsWith("flag")); + + try { + Flags.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // (max is 0xF) + try { + Flags.string(0x10); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(Flags.CD, Flags.value("cd")); + + // one thats undefined but within range + assertEquals(13, Flags.value("FLAG13")); + + // one thats undefined but out of range + assertEquals(-1, Flags.value("FLAG" + 0x10)); + + // something that unknown + assertEquals(-1, Flags.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, Flags.value("")); + } + + public + void test_isFlag() { + try { + Flags.isFlag(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + assertTrue(Flags.isFlag(0)); + assertFalse(Flags.isFlag(1)); // opcode + assertFalse(Flags.isFlag(2)); + assertFalse(Flags.isFlag(3)); + assertFalse(Flags.isFlag(4)); + assertTrue(Flags.isFlag(5)); + assertTrue(Flags.isFlag(6)); + assertTrue(Flags.isFlag(7)); + assertTrue(Flags.isFlag(8)); + assertTrue(Flags.isFlag(9)); + assertTrue(Flags.isFlag(10)); + assertTrue(Flags.isFlag(11)); + assertFalse(Flags.isFlag(12)); + assertFalse(Flags.isFlag(13)); + assertFalse(Flags.isFlag(14)); + assertFalse(Flags.isFlag(14)); + try { + Flags.isFlag(16); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } +} diff --git a/test/dorkbox/network/dns/FormattedTimeTest.java b/test/dorkbox/network/dns/FormattedTimeTest.java new file mode 100644 index 00000000..7a8bc2fb --- /dev/null +++ b/test/dorkbox/network/dns/FormattedTimeTest.java @@ -0,0 +1,90 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.FormattedTime; +import junit.framework.TestCase; + +public +class FormattedTimeTest extends TestCase { + public + void test_format() { + GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + cal.set(2005, 2, 19, 4, 4, 5); + String out = FormattedTime.format(cal.getTime()); + assertEquals("20050319040405", out); + } + + public + void test_parse() throws TextParseException { + // have to make sure to clear out the milliseconds since there + // is occasionally a difference between when cal and cal2 are + // instantiated. + GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + cal.set(2005, 2, 19, 4, 4, 5); + cal.set(Calendar.MILLISECOND, 0); + + Date out = FormattedTime.parse("20050319040405"); + GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + cal2.setTimeInMillis(out.getTime()); + cal2.set(Calendar.MILLISECOND, 0); + assertEquals(cal, cal2); + } + + public + void test_parse_invalid() { + try { + FormattedTime.parse("2004010101010"); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + try { + FormattedTime.parse("200401010101010"); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + try { + FormattedTime.parse("2004010101010A"); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } +} diff --git a/test/dorkbox/network/dns/NameTest.java b/test/dorkbox/network/dns/NameTest.java new file mode 100644 index 00000000..871495cc --- /dev/null +++ b/test/dorkbox/network/dns/NameTest.java @@ -0,0 +1,1302 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.exceptions.NameTooLongException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.exceptions.WireParseException; +import dorkbox.network.dns.records.DNAMERecord; +import dorkbox.network.dns.utils.Options; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class NameTest extends TestCase { + public static + class Test_String_init extends TestCase { + private final String m_abs = "WWW.DnsJava.org."; + private Name m_abs_origin; + private final String m_rel = "WWW.DnsJava"; + private Name m_rel_origin; + + @Override + protected + void setUp() throws TextParseException { + m_abs_origin = Name.fromString("Orig."); + m_rel_origin = Name.fromString("Orig"); + } + + public + void test_ctor_empty() { + try { + new Name(""); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_at_null_origin() throws TextParseException { + Name n = new Name("@"); + assertFalse(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(0, n.labels()); + assertEquals(0, n.length()); + } + + public + void test_ctor_at_abs_origin() throws TextParseException { + Name n = new Name("@", m_abs_origin); + assertEquals(m_abs_origin, n); + } + + public + void test_ctor_at_rel_origin() throws TextParseException { + Name n = new Name("@", m_rel_origin); + assertEquals(m_rel_origin, n); + } + + public + void test_ctor_dot() throws TextParseException { + Name n = new Name("."); + assertEquals(Name.root, n); + assertNotSame(Name.root, n); + assertEquals(1, n.labels()); + assertEquals(1, n.length()); + } + + public + void test_ctor_wildcard() throws TextParseException { + Name n = new Name("*"); + assertFalse(n.isAbsolute()); + assertTrue(n.isWild()); + assertEquals(1, n.labels()); + assertEquals(2, n.length()); + assertTrue(Arrays.equals(new byte[] {1, '*'}, n.getLabel(0))); + assertEquals("*", n.getLabelString(0)); + } + + public + void test_ctor_abs() throws TextParseException { + Name n = new Name(m_abs); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(4, n.labels()); + assertEquals(17, n.length()); + assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); + assertEquals("WWW", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); + assertEquals("DnsJava", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); + assertEquals("org", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); + assertEquals("", n.getLabelString(3)); + } + + public + void test_ctor_rel() throws TextParseException { + Name n = new Name(m_rel); + assertFalse(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(2, n.labels()); + assertEquals(12, n.length()); + assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); + assertEquals("WWW", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); + assertEquals("DnsJava", n.getLabelString(1)); + } + + public + void test_ctor_7label() throws TextParseException { + // 7 is the number of label positions that are cached + Name n = new Name("a.b.c.d.e.f."); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(7, n.labels()); + assertEquals(13, n.length()); + assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(0))); + assertEquals("a", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); + assertEquals("b", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {1, 'c'}, n.getLabel(2))); + assertEquals("c", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {1, 'd'}, n.getLabel(3))); + assertEquals("d", n.getLabelString(3)); + assertTrue(Arrays.equals(new byte[] {1, 'e'}, n.getLabel(4))); + assertEquals("e", n.getLabelString(4)); + assertTrue(Arrays.equals(new byte[] {1, 'f'}, n.getLabel(5))); + assertEquals("f", n.getLabelString(5)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(6))); + assertEquals("", n.getLabelString(6)); + } + + public + void test_ctor_8label() throws TextParseException { + // 7 is the number of label positions that are cached + Name n = new Name("a.b.c.d.e.f.g."); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(8, n.labels()); + assertEquals(15, n.length()); + assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(0))); + assertEquals("a", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); + assertEquals("b", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {1, 'c'}, n.getLabel(2))); + assertEquals("c", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {1, 'd'}, n.getLabel(3))); + assertEquals("d", n.getLabelString(3)); + assertTrue(Arrays.equals(new byte[] {1, 'e'}, n.getLabel(4))); + assertEquals("e", n.getLabelString(4)); + assertTrue(Arrays.equals(new byte[] {1, 'f'}, n.getLabel(5))); + assertEquals("f", n.getLabelString(5)); + assertTrue(Arrays.equals(new byte[] {1, 'g'}, n.getLabel(6))); + assertEquals("g", n.getLabelString(6)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(7))); + assertEquals("", n.getLabelString(7)); + } + + public + void test_ctor_removed_label() throws TextParseException, NameTooLongException { + String pre = "prepend"; + Name stripped = new Name(Name.fromString("sub.domain.example."), 1); + Name concat = new Name(pre, stripped); + assertEquals(Name.concatenate(Name.fromString(pre), stripped), concat); + assertEquals(Name.fromString(pre, stripped), concat); + assertEquals("prepend.domain.example.", concat.toString()); + } + + public + void test_ctor_abs_abs_origin() throws TextParseException { + Name n = new Name(m_abs, m_abs_origin); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(4, n.labels()); + assertEquals(17, n.length()); + assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); + assertEquals("WWW", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); + assertEquals("DnsJava", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); + assertEquals("org", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); + assertEquals("", n.getLabelString(3)); + } + + public + void test_ctor_abs_rel_origin() throws TextParseException { + Name n = new Name(m_abs, m_rel_origin); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(4, n.labels()); + assertEquals(17, n.length()); + assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); + assertEquals("WWW", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); + assertEquals("DnsJava", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); + assertEquals("org", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); + assertEquals("", n.getLabelString(3)); + } + + public + void test_ctor_rel_abs_origin() throws TextParseException { + Name n = new Name(m_rel, m_abs_origin); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(4, n.labels()); + assertEquals(18, n.length()); + assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); + assertEquals("WWW", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); + assertEquals("DnsJava", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {4, 'O', 'r', 'i', 'g'}, n.getLabel(2))); + assertEquals("Orig", n.getLabelString(2)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); + assertEquals("", n.getLabelString(3)); + } + + public + void test_ctor_invalid_label() { + try { + new Name("junk..junk."); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_max_label() throws TextParseException { + // name with a 63 char label + Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(3, n.labels()); + assertEquals(67, n.length()); + assertTrue(Arrays.equals(new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}, n.getLabel(0))); + assertEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", n.getLabelString(0)); + assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); + assertEquals("b", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(2))); + assertEquals("", n.getLabelString(2)); + } + + public + void test_ctor_toobig_label() { + // name with a 64 char label + try { + new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_max_length_rel() throws TextParseException { + // relative name with three 63-char labels and a 62-char label + Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"); + assertFalse(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(4, n.labels()); + assertEquals(255, n.length()); + } + + public + void test_ctor_max_length_abs() throws TextParseException { + // absolute name with three 63-char labels and a 61-char label + Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(5, n.labels()); + assertEquals(255, n.length()); + } + + public + void test_ctor_escaped() throws TextParseException { + Name n = new Name("ab\\123cd"); + assertFalse(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(1, n.labels()); + assertEquals(6, n.length()); + assertTrue(Arrays.equals(new byte[] {5, 'a', 'b', (byte) 123, 'c', 'd'}, n.getLabel(0))); + } + + public + void test_ctor_escaped_end() throws TextParseException { + Name n = new Name("abcd\\123"); + assertFalse(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(1, n.labels()); + assertEquals(6, n.length()); + assertTrue(Arrays.equals(new byte[] {5, 'a', 'b', 'c', 'd', (byte) 123}, n.getLabel(0))); + } + + public + void test_ctor_short_escaped() throws TextParseException { + try { + new Name("ab\\12cd"); + fail("TextParseException not throw"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_short_escaped_end() throws TextParseException { + try { + new Name("ab\\12"); + fail("TextParseException not throw"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_empty_escaped_end() throws TextParseException { + try { + new Name("ab\\"); + fail("TextParseException not throw"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_toobig_escaped() throws TextParseException { + try { + new Name("ab\\256cd"); + fail("TextParseException not throw"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_toobig_escaped_end() throws TextParseException { + try { + new Name("ab\\256"); + fail("TextParseException not throw"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_max_label_escaped() throws TextParseException { + // name with a 63 char label containing an escape + Name n = new Name("aaaa\\100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(3, n.labels()); + assertEquals(67, n.length()); + assertTrue(Arrays.equals(new byte[] {63, 'a', 'a', 'a', 'a', (byte) 100, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}, n.getLabel(0))); + assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); + assertEquals("b", n.getLabelString(1)); + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(2))); + assertEquals("", n.getLabelString(2)); + } + + public + void test_ctor_max_labels() throws TextParseException { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < 127; ++i) { + sb.append("a."); + } + Name n = new Name(sb.toString()); + assertTrue(n.isAbsolute()); + assertFalse(n.isWild()); + assertEquals(128, n.labels()); + assertEquals(255, n.length()); + for (int i = 0; i < 127; ++i) { + assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(i))); + assertEquals("a", n.getLabelString(i)); + } + assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(127))); + assertEquals("", n.getLabelString(127)); + } + + public + void test_ctor_toobig_label_escaped_end() throws TextParseException { + try { + // name with a 64 char label containing an escape at the end + new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\090.b."); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_ctor_toobig_label_escaped() throws TextParseException { + try { + // name with a 64 char label containing an escape at the end + new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaa\\001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_fromString() throws TextParseException { + Name n = new Name(m_rel, m_abs_origin); + Name n2 = Name.fromString(m_rel, m_abs_origin); + assertEquals(n, n2); + } + + public + void test_fromString_at() throws TextParseException { + Name n = Name.fromString("@", m_rel_origin); + assertSame(m_rel_origin, n); + } + + public + void test_fromString_dot() throws TextParseException { + Name n = Name.fromString("."); + assertSame(Name.root, n); + } + + public + void test_fromConstantString() throws TextParseException { + Name n = new Name(m_abs); + Name n2 = Name.fromConstantString(m_abs); + assertEquals(n, n2); + } + + public + void test_fromConstantString_invalid() { + try { + Name.fromConstantString("junk..junk"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + } + + + public static + class Test_DNSInput_init extends TestCase { + public + void test_basic() throws IOException, TextParseException, WireParseException { + + final byte[] raw = new byte[] {3, 'W', 'w', 'w', 7, 'D', 'n', 's', 'J', 'a', 'v', 'a', 3, 'o', 'r', 'g', 0}; + Name e = Name.fromString("Www.DnsJava.org."); + + Name n = new Name(raw); + assertEquals(e, n); + } + + public + void test_incomplete() throws IOException { + try { + new Name(new byte[] {3, 'W', 'w', 'w'}); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_root() throws WireParseException { + final byte[] raw = new byte[] {0}; + Name n = new Name(new DnsInput(raw)); + assertEquals(Name.root, n); + } + + public + void test_invalid_length() throws IOException { + try { + new Name(new byte[] {4, 'W', 'w', 'w'}); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_max_label_length() throws TextParseException, WireParseException { + byte[] raw = new byte[] {63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 0}; + Name e = Name.fromString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb."); + + Name n = new Name(new DnsInput(raw)); + assertEquals(e, n); + } + + public + void test_max_name() throws TextParseException, WireParseException { + // absolute name with three 63-char labels and a 61-char label + Name e = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); + byte[] raw = new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 63, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 61, 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 0}; + + Name n = new Name(new DnsInput(raw)); + assertEquals(e, n); + } + + public + void test_toolong_name() throws TextParseException, WireParseException { + // absolute name with three 63-char labels and a 62-char label + byte[] raw = new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', + 'a', 'a', 'a', 63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', + 'b', 'b', 'b', 'b', 'b', 'b', 63, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', + 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 62, 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', + 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 0}; + + try { + new Name(new DnsInput(raw)); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_max_labels() throws TextParseException, WireParseException { + byte[] raw = new byte[] {1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 0}; + Name e = Name.fromString( + "a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a."); + Name n = new Name(new DnsInput(raw)); + assertEquals(128, n.labels()); + assertEquals(e, n); + } + + public + void test_toomany_labels() throws TextParseException, WireParseException { + byte[] raw = new byte[] {1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', + 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 0}; + try { + new Name(new DnsInput(raw)); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_basic_compression() throws TextParseException, WireParseException { + byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1}; + Name e = Name.fromString("abc."); + + DnsInput in = new DnsInput(raw); + in.jump(6); + + Options.set("verbosecompression"); + Name n = new Name(in); + Options.unset("verbosecompression"); + assertEquals(e, n); + } + + public + void test_two_pointer_compression() throws TextParseException, WireParseException { + byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1, (byte) 0xC0, 6}; + Name e = Name.fromString("abc."); + + DnsInput in = new DnsInput(raw); + in.jump(8); + + Name n = new Name(in); + assertEquals(e, n); + } + + public + void test_two_part_compression() throws TextParseException, WireParseException { + byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, 1, 'B', (byte) 0xC0, 1}; + Name e = Name.fromString("B.abc."); + + DnsInput in = new DnsInput(raw); + in.jump(6); + + Name n = new Name(in); + assertEquals(e, n); + } + + public + void test_long_jump_compression() throws TextParseException, WireParseException { + // pointer to name beginning at index 256 + byte[] raw = new byte[] {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 3, 'a', 'b', + 'c', 0, (byte) 0xC1, 0}; + Name e = Name.fromString("abc."); + + DnsInput in = new DnsInput(raw); + in.jump(261); + Name n = new Name(in); + assertEquals(e, n); + } + + public + void test_bad_compression() throws TextParseException, WireParseException { + byte[] raw = new byte[] {(byte) 0xC0, 2, 0}; + try { + new Name(new DnsInput(raw)); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_basic_compression_state_restore() throws TextParseException, WireParseException { + byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1, 3, 'd', 'e', 'f', 0}; + Name e = Name.fromString("abc."); + Name e2 = Name.fromString("def."); + + DnsInput in = new DnsInput(raw); + in.jump(6); + + Name n = new Name(in); + assertEquals(e, n); + + n = new Name(in); + assertEquals(e2, n); + } + + public + void test_two_part_compression_state_restore() throws TextParseException, WireParseException { + byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, 1, 'B', (byte) 0xC0, 1, 3, 'd', 'e', 'f', 0}; + Name e = Name.fromString("B.abc."); + Name e2 = Name.fromString("def."); + + DnsInput in = new DnsInput(raw); + in.jump(6); + + Name n = new Name(in); + assertEquals(e, n); + + n = new Name(in); + assertEquals(e2, n); + } + } + + public + void test_init_from_name() throws TextParseException { + Name n = new Name("A.B.c.d."); + Name e = new Name("B.c.d."); + Name o = new Name(n, 1); + assertEquals(e, o); + } + + public + void test_init_from_name_root() throws TextParseException { + Name n = new Name("A.B.c.d."); + Name o = new Name(n, 4); + assertEquals(Name.root, o); + } + + public + void test_init_from_name_empty() throws TextParseException { + Name n = new Name("A.B.c.d."); + Name n2 = new Name(n, 5); + + assertFalse(n2.isAbsolute()); + assertFalse(n2.isWild()); + assertEquals(0, n2.labels()); + assertEquals(0, n2.length()); + } + + public + void test_concatenate_basic() throws NameTooLongException, TextParseException { + Name p = Name.fromString("A.B"); + Name s = Name.fromString("c.d."); + Name e = Name.fromString("A.B.c.d."); + + Name n = Name.concatenate(p, s); + assertEquals(e, n); + } + + public + void test_concatenate_abs_prefix() throws NameTooLongException, TextParseException { + Name p = Name.fromString("A.B."); + Name s = Name.fromString("c.d."); + Name e = Name.fromString("A.B."); + + Name n = Name.concatenate(p, s); + assertEquals(e, n); + } + + public + void test_concatenate_too_long() throws TextParseException { + Name p = Name.fromString( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + Name s = Name.fromString( + "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); + + try { + Name.concatenate(p, s); + fail("NameTooLongException not thrown"); + } catch (NameTooLongException e) { + } + } + + public + void test_relativize() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name dom = Name.fromString("c."); + Name exp = Name.fromString("a.b"); + + Name n = sub.relativize(dom); + assertEquals(exp, n); + } + + public + void test_relativize_null_origin() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name dom = null; + + Name n = sub.relativize(dom); + assertEquals(sub, n); + } + + public + void test_relativize_disjoint() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name dom = Name.fromString("e.f."); + + Name n = sub.relativize(dom); + assertEquals(sub, n); + } + + public + void test_relativize_root() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name dom = Name.fromString("."); + Name exp = Name.fromString("a.b.c"); + + Name n = sub.relativize(dom); + assertEquals(exp, n); + } + + public + void test_wild() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name exp = Name.fromString("*.b.c."); + + Name n = sub.wild(1); + assertEquals(exp, n); + } + + public + void test_wild_abs() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + Name exp = Name.fromString("*."); + + Name n = sub.wild(3); + assertEquals(exp, n); + } + + public + void test_wild_toobig() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + try { + sub.wild(4); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_wild_toosmall() throws TextParseException { + Name sub = Name.fromString("a.b.c."); + try { + sub.wild(0); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_fromDNAME() throws NameTooLongException, TextParseException { + Name own = new Name("the.owner."); + Name alias = new Name("the.alias."); + DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); + Name sub = new Name("sub.the.owner."); + Name exp = new Name("sub.the.alias."); + + Name n = sub.fromDNAME(dnr); + assertEquals(exp, n); + } + + public + void test_fromDNAME_toobig() throws NameTooLongException, TextParseException { + Name own = new Name("the.owner."); + Name alias = new Name("the.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc."); + DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); + Name sub = new Name("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.the.owner."); + + try { + sub.fromDNAME(dnr); + fail("NameTooLongException not thrown"); + } catch (NameTooLongException e) { + } + } + + public + void test_fromDNAME_disjoint() throws NameTooLongException, TextParseException { + Name own = new Name("the.owner."); + Name alias = new Name("the.alias."); + DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); + + Name sub = new Name("sub.the.other"); + + assertNull(sub.fromDNAME(dnr)); + } + + public + void test_subdomain_abs() throws TextParseException { + Name dom = new Name("the.domain."); + Name sub = new Name("sub.of.the.domain."); + assertTrue(sub.subdomain(dom)); + assertFalse(dom.subdomain(sub)); + } + + public + void test_subdomain_rel() throws TextParseException { + Name dom = new Name("the.domain"); + Name sub = new Name("sub.of.the.domain"); + assertTrue(sub.subdomain(dom)); + assertFalse(dom.subdomain(sub)); + } + + public + void test_subdomain_equal() throws TextParseException { + Name dom = new Name("the.domain"); + Name sub = new Name("the.domain"); + assertTrue(sub.subdomain(dom)); + assertTrue(dom.subdomain(sub)); + } + + public + void test_toString_abs() throws TextParseException { + String in = "This.Is.My.Absolute.Name."; + Name n = new Name(in); + + assertEquals(in, n.toString()); + } + + public + void test_toString_rel() throws TextParseException { + String in = "This.Is.My.Relative.Name"; + Name n = new Name(in); + + assertEquals(in, n.toString()); + } + + public + void test_toString_at() throws TextParseException { + Name n = new Name("@", null); + assertEquals("@", n.toString()); + } + + public + void test_toString_root() throws TextParseException { + assertEquals(".", Name.root.toString()); + } + + public + void test_toString_wild() throws TextParseException { + String in = "*.A.b.c.e"; + Name n = new Name(in); + assertEquals(in, n.toString()); + } + + public + void test_toString_escaped() throws TextParseException { + String in = "my.escaped.junk\\128.label."; + Name n = new Name(in); + assertEquals(in, n.toString()); + } + + public + void test_toString_special_char() throws TextParseException, WireParseException { + byte[] raw = new byte[] {1, '"', 1, '(', 1, ')', 1, '.', 1, ';', 1, '\\', 1, '@', 1, '$', 0}; + String exp = "\\\".\\(.\\).\\..\\;.\\\\.\\@.\\$."; + Name n = new Name(new DnsInput(raw)); + assertEquals(exp, n.toString()); + } + + public static + class Test_toWire extends TestCase { + public + void test_rel() throws TextParseException { + Name n = new Name("A.Relative.Name"); + try { + n.toWire(new DnsOutput(), null); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_null_Compression() throws TextParseException { + byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; + Name n = new Name("A.Basic.Name."); + + DnsOutput o = new DnsOutput(); + n.toWire(o, null); + + assertTrue(Arrays.equals(raw, o.toByteArray())); + } + + public + void test_empty_Compression() throws TextParseException { + byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; + Name n = new Name("A.Basic.Name."); + + Compression c = new Compression(); + DnsOutput o = new DnsOutput(); + n.toWire(o, c); + + assertTrue(Arrays.equals(raw, o.toByteArray())); + assertEquals(0, c.get(n)); + } + + public + void test_with_exact_Compression() throws TextParseException { + Name n = new Name("A.Basic.Name."); + + Compression c = new Compression(); + c.add(256, n); + byte[] exp = new byte[] {(byte) 0xC1, 0x0}; + + DnsOutput o = new DnsOutput(); + n.toWire(o, c); + assertTrue(Arrays.equals(exp, o.toByteArray())); + assertEquals(256, c.get(n)); + } + + public + void test_with_partial_Compression() throws TextParseException { + Name d = new Name("Basic.Name."); + Name n = new Name("A.Basic.Name."); + + Compression c = new Compression(); + c.add(257, d); + byte[] exp = new byte[] {1, 'A', (byte) 0xC1, 0x1}; + + DnsOutput o = new DnsOutput(); + n.toWire(o, c); + assertTrue(Arrays.equals(exp, o.toByteArray())); + assertEquals(257, c.get(d)); + assertEquals(0, c.get(n)); + } + + public + void test_0arg_rel() throws TextParseException { + Name n = new Name("A.Relative.Name"); + try { + n.toWire(); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_0arg() throws TextParseException { + byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; + Name n = new Name("A.Basic.Name."); + + byte[] out = n.toWire(); + + assertTrue(Arrays.equals(raw, out)); + } + + public + void test_root() { + byte[] out = Name.root.toWire(); + assertTrue(Arrays.equals(new byte[] {0}, out)); + } + + public + void test_3arg() throws TextParseException { + Name d = new Name("Basic.Name."); + Name n = new Name("A.Basic.Name."); + + Compression c = new Compression(); + c.add(257, d); + byte[] exp = new byte[] {1, 'A', (byte) 0xC1, 0x1}; + + DnsOutput o = new DnsOutput(); + n.toWire(o, c, false); + assertTrue(Arrays.equals(exp, o.toByteArray())); + assertEquals(257, c.get(d)); + assertEquals(0, c.get(n)); + } + } + + + public static + class Test_toWireCanonical extends TestCase { + public + void test_basic() throws TextParseException { + byte[] raw = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; + Name n = new Name("A.Basic.Name."); + + DnsOutput o = new DnsOutput(); + n.toWireCanonical(o); + + assertTrue(Arrays.equals(raw, o.toByteArray())); + } + + public + void test_0arg() throws TextParseException { + byte[] raw = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; + Name n = new Name("A.Basic.Name."); + + byte[] out = n.toWireCanonical(); + + assertTrue(Arrays.equals(raw, out)); + } + + public + void test_root() { + byte[] out = Name.root.toWireCanonical(); + assertTrue(Arrays.equals(new byte[] {0}, out)); + } + + public + void test_empty() throws TextParseException { + Name n = new Name("@", null); + byte[] out = n.toWireCanonical(); + assertTrue(Arrays.equals(new byte[0], out)); + } + + public + void test_3arg() throws TextParseException { + Name d = new Name("Basic.Name."); + Name n = new Name("A.Basic.Name."); + + Compression c = new Compression(); + c.add(257, d); + byte[] exp = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; + + DnsOutput o = new DnsOutput(); + n.toWire(o, c, true); + assertTrue(Arrays.equals(exp, o.toByteArray())); + assertEquals(257, c.get(d)); + assertEquals(-1, c.get(n)); + } + } + + + public static + class Test_equals extends TestCase { + public + void test_same() throws TextParseException { + Name n = new Name("A.Name."); + assertTrue(n.equals(n)); + } + + public + void test_null() throws TextParseException { + Name n = new Name("A.Name."); + assertFalse(n.equals(null)); + } + + public + void test_notName() throws TextParseException { + Name n = new Name("A.Name."); + assertFalse(n.equals(new Object())); + } + + public + void test_abs() throws TextParseException { + Name n = new Name("A.Name."); + Name n2 = new Name("a.name."); + + assertTrue(n.equals(n2)); + assertTrue(n2.equals(n)); + } + + public + void test_rel() throws TextParseException { + Name n1 = new Name("A.Relative.Name"); + Name n2 = new Name("a.relative.name"); + + assertTrue(n1.equals(n2)); + assertTrue(n2.equals(n1)); + } + + public + void test_mixed() throws TextParseException { + Name n1 = new Name("A.Name"); + Name n2 = new Name("a.name."); + + assertFalse(n1.equals(n2)); + assertFalse(n2.equals(n1)); + } + + public + void test_weird() throws TextParseException { + Name n1 = new Name("ab.c"); + Name n2 = new Name("abc."); + + assertFalse(n1.equals(n2)); + assertFalse(n2.equals(n1)); + } + } + + + public static + class Test_compareTo extends TestCase { + public + void test_notName() throws TextParseException { + Name n = new Name("A.Name"); + try { + n.compareTo(new Object()); + fail("ClassCastException not thrown"); + } catch (ClassCastException e) { + } + } + + public + void test_same() throws TextParseException { + Name n = new Name("A.Name"); + assertEquals(0, n.compareTo(n)); + } + + public + void test_equal() throws TextParseException { + Name n1 = new Name("A.Name."); + Name n2 = new Name("a.name."); + + assertEquals(0, n1.compareTo(n2)); + assertEquals(0, n2.compareTo(n1)); + } + + public + void test_close() throws TextParseException { + Name n1 = new Name("a.name"); + Name n2 = new Name("a.name."); + + assertTrue(n1.compareTo(n2) > 0); + assertTrue(n2.compareTo(n1) < 0); + } + + public + void test_disjoint() throws TextParseException { + Name n1 = new Name("b"); + Name n2 = new Name("c"); + + assertTrue(n1.compareTo(n2) < 0); + assertTrue(n2.compareTo(n1) > 0); + } + + public + void test_label_prefix() throws TextParseException { + Name n1 = new Name("thisIs.a."); + Name n2 = new Name("thisIsGreater.a."); + + assertTrue(n1.compareTo(n2) < 0); + assertTrue(n2.compareTo(n1) > 0); + } + + public + void test_more_labels() throws TextParseException { + Name n1 = new Name("c.b.a."); + Name n2 = new Name("d.c.b.a."); + + assertTrue(n1.compareTo(n2) < 0); + assertTrue(n2.compareTo(n1) > 0); + } + } + + public + void test_canonicalize() throws TextParseException { + Name n1 = new Name("ABC.com"); + Name n2 = new Name("abc.com"); + Name n3 = new Name("\\193.com"); + + Name cn1 = n1.canonicalize(); + Name cn2 = n2.canonicalize(); + Name cn3 = n3.canonicalize(); + + assertNotSame(n1, cn1); + assertEquals(n1, cn1); + assertSame(n2, cn2); + assertSame(n3, cn3); + assertEquals(cn1.toString(), cn2.toString()); + assertFalse(n1.toString() + .equals(n2.toString())); + assertEquals(cn1.toString(), cn2.toString()); + } + + public + void test_to_string() throws TextParseException { + Name n1 = new Name("abc.com"); + Name n2 = new Name("abc.com."); + + assertEquals(n1.toString(true), n1.toString(true)); + assertFalse(n2.toString(true) + .equals(n2.toString(false))); + assertEquals(n2.toString(true) + ".", n2.toString(false)); + assertEquals(Name.root.toString(true), Name.root.toString(false)); + assertEquals(Name.empty.toString(true), Name.empty.toString(false)); + } + + public + void test_absolute() throws TextParseException { + Name n1 = new Name("abc.com"); + Name n2 = new Name("abc.com."); + Name n3 = new Name("abc.com", Name.root); + Name n4 = new Name("abc.com", n1); + Name n5 = new Name("abc.com\\000"); + + assertFalse(n1.isAbsolute()); + assertTrue(n2.isAbsolute()); + assertTrue(n3.isAbsolute()); + assertFalse(n4.isAbsolute()); + assertFalse(n5.isAbsolute()); + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_String_init.class); + s.addTestSuite(Test_DNSInput_init.class); + s.addTestSuite(NameTest.class); + s.addTestSuite(Test_toWire.class); + s.addTestSuite(Test_toWireCanonical.class); + s.addTestSuite(Test_equals.class); + s.addTestSuite(Test_compareTo.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/OpcodeTest.java b/test/dorkbox/network/dns/OpcodeTest.java new file mode 100644 index 00000000..59c56163 --- /dev/null +++ b/test/dorkbox/network/dns/OpcodeTest.java @@ -0,0 +1,82 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.constants.DnsOpCode; +import junit.framework.TestCase; + +public +class OpcodeTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("IQUERY", DnsOpCode.string(DnsOpCode.IQUERY)); + + // one that doesn't exist + assertTrue(DnsOpCode.string(6) + .startsWith("RESERVED")); + + try { + DnsOpCode.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // (max is 0xF) + try { + DnsOpCode.string(0x10); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(DnsOpCode.STATUS, DnsOpCode.value("STATUS")); + + // one thats undefined but within range + assertEquals(6, DnsOpCode.value("RESERVED6")); + + // one thats undefined but out of range + assertEquals(-1, DnsOpCode.value("RESERVED" + 0x10)); + + // something that unknown + assertEquals(-1, DnsOpCode.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, DnsOpCode.value("")); + } +} diff --git a/test/dorkbox/network/dns/OptionsTest.java b/test/dorkbox/network/dns/OptionsTest.java new file mode 100644 index 00000000..85719a54 --- /dev/null +++ b/test/dorkbox/network/dns/OptionsTest.java @@ -0,0 +1,149 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.utils.Options; +import junit.framework.TestCase; + +public +class OptionsTest extends TestCase { + @Override + public + void setUp() { + // reset the options table before each test + Options.clear(); + } + + public + void test_set_1arg() { + Options.set("Option1"); + assertEquals("true", Options.value("option1")); + + Options.set("OPTION2"); + assertEquals("true", Options.value("option1")); + assertEquals("true", Options.value("OpTIOn2")); + + Options.set("option2"); + assertEquals("true", Options.value("option2")); + } + + public + void test_set_2arg() { + Options.set("OPTION1", "Value1"); + assertEquals("value1", Options.value("Option1")); + + Options.set("option2", "value2"); + assertEquals("value1", Options.value("Option1")); + assertEquals("value2", Options.value("OPTION2")); + + Options.set("OPTION2", "value2b"); + assertEquals("value1", Options.value("Option1")); + assertEquals("value2b", Options.value("option2")); + } + + public + void test_check() { + assertFalse(Options.check("No Options yet")); + + Options.set("First Option"); + assertFalse(Options.check("Not a valid option name")); + assertTrue(Options.check("First Option")); + assertTrue(Options.check("FIRST option")); + } + + public + void test_unset() { + // unset something non-existant + Options.unset("Not an option Name"); + + Options.set("Temporary Option"); + assertTrue(Options.check("Temporary Option")); + Options.unset("Temporary Option"); + assertFalse(Options.check("Temporary Option")); + + Options.set("Temporary Option"); + assertTrue(Options.check("Temporary Option")); + Options.unset("temporary option"); + assertFalse(Options.check("Temporary Option")); + + // unset something now that the table is non-null + Options.unset("Still Not an Option Name"); + } + + public + void test_value() { + assertNull(Options.value("Table is Null")); + + Options.set("Testing Option"); + assertNull(Options.value("Not an Option Name")); + + assertEquals("true", Options.value("Testing OPTION")); + } + + public + void test_intValue() { + assertEquals(-1, Options.intValue("Table is Null")); + + Options.set("A Boolean Option"); + Options.set("An Int Option", "13"); + Options.set("Not An Int Option", "NotAnInt"); + Options.set("A Negative Int Value", "-1000"); + + assertEquals(-1, Options.intValue("A Boolean Option")); + assertEquals(-1, Options.intValue("Not an Option NAME")); + assertEquals(13, Options.intValue("an int option")); + assertEquals(-1, Options.intValue("NOT an INT option")); + assertEquals(-1, Options.intValue("A negative int Value")); + } + + public + void test_systemProperty() { + System.setProperty("dnsjava.options", "booleanOption,valuedOption1=10,valuedOption2=NotAnInteger"); + + Options.refresh(); + + assertTrue(Options.check("booleanOPTION")); + assertTrue(Options.check("booleanOption")); + assertTrue(Options.check("valuedOption1")); + assertTrue(Options.check("ValuedOption2")); + + assertEquals("true", Options.value("booleanOption")); + assertEquals(-1, Options.intValue("BOOLEANOPTION")); + assertEquals("10", Options.value("valuedOption1")); + assertEquals(10, Options.intValue("valuedOption1")); + assertEquals("notaninteger", Options.value("VALUEDOPTION2")); + assertEquals(-1, Options.intValue("valuedOption2")); + } +} diff --git a/test/dorkbox/network/dns/RcodeTest.java b/test/dorkbox/network/dns/RcodeTest.java new file mode 100644 index 00000000..867a1cfc --- /dev/null +++ b/test/dorkbox/network/dns/RcodeTest.java @@ -0,0 +1,112 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.constants.DnsResponseCode; +import junit.framework.TestCase; + +public +class RcodeTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("NXDOMAIN", DnsResponseCode.string(DnsResponseCode.NXDOMAIN)); + + // one with an alias + assertEquals("NOTIMP", DnsResponseCode.string(DnsResponseCode.NOTIMP)); + + // one that doesn't exist + assertTrue(DnsResponseCode.string(20) + .startsWith("RESERVED")); + + try { + DnsResponseCode.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + + // (max is 0xFFF) + try { + DnsResponseCode.string(0x1000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_TSIGstring() { + // a regular one + assertEquals("BADSIG", DnsResponseCode.TSIGstring(DnsResponseCode.BADSIG)); + + // one that doesn't exist + assertTrue(DnsResponseCode.TSIGstring(22) + .startsWith("RESERVED")); + + try { + DnsResponseCode.TSIGstring(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + + // (max is 0xFFFF) + try { + DnsResponseCode.string(0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_value() { + // regular one + assertEquals(DnsResponseCode.FORMERR, DnsResponseCode.value("FORMERR")); + + // one with alias + assertEquals(DnsResponseCode.NOTIMP, DnsResponseCode.value("NOTIMP")); + assertEquals(DnsResponseCode.NOTIMP, DnsResponseCode.value("NOTIMPL")); + + // one thats undefined but within range + assertEquals(35, DnsResponseCode.value("RESERVED35")); + + // one thats undefined but out of range + assertEquals(-1, DnsResponseCode.value("RESERVED" + 0x1000)); + + // something that unknown + assertEquals(-1, DnsResponseCode.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, DnsResponseCode.value("")); + } +} diff --git a/test/dorkbox/network/dns/ReverseMapTest.java b/test/dorkbox/network/dns/ReverseMapTest.java new file mode 100644 index 00000000..eb5c000a --- /dev/null +++ b/test/dorkbox/network/dns/ReverseMapTest.java @@ -0,0 +1,114 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Address; +import dorkbox.network.dns.utils.ReverseMap; +import junit.framework.TestCase; + +public +class ReverseMapTest extends TestCase { + public + void test_fromAddress_ipv4() throws UnknownHostException, TextParseException { + Name exp = Name.fromString("1.0.168.192.in-addr.arpa."); + String addr = "192.168.0.1"; + assertEquals(exp, ReverseMap.fromAddress(addr)); + + assertEquals(exp, ReverseMap.fromAddress(addr, Address.IPv4)); + assertEquals(exp, ReverseMap.fromAddress(InetAddress.getByName(addr))); + assertEquals(exp, ReverseMap.fromAddress(new byte[] {(byte) 192, (byte) 168, (byte) 0, (byte) 1})); + assertEquals(exp, ReverseMap.fromAddress(new int[] {192, 168, 0, 1})); + } + + public + void test_fromAddress_ipv6() throws UnknownHostException, TextParseException { + Name exp = Name.fromString("4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."); + String addr = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334"; + byte[] dat = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, + (byte) 25, (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; + int[] idat = new int[] {32, 1, 13, 184, 133, 163, 8, 211, 19, 25, 138, 46, 3, 112, 115, 52}; + + + assertEquals(exp, ReverseMap.fromAddress(addr, Address.IPv6)); + assertEquals(exp, ReverseMap.fromAddress(InetAddress.getByName(addr))); + assertEquals(exp, ReverseMap.fromAddress(dat)); + assertEquals(exp, ReverseMap.fromAddress(idat)); + } + + public + void test_fromAddress_invalid() { + try { + ReverseMap.fromAddress("A.B.C.D", Address.IPv4); + fail("UnknownHostException not thrown"); + } catch (UnknownHostException e) { + } + try { + ReverseMap.fromAddress(new byte[0]); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + ReverseMap.fromAddress(new byte[3]); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + ReverseMap.fromAddress(new byte[5]); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + ReverseMap.fromAddress(new byte[15]); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + ReverseMap.fromAddress(new byte[17]); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + try { + int[] dat = new int[] {0, 1, 2, 256}; + ReverseMap.fromAddress(dat); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } +} diff --git a/test/dorkbox/network/dns/TokenizerTest.java b/test/dorkbox/network/dns/TokenizerTest.java new file mode 100644 index 00000000..54fb397b --- /dev/null +++ b/test/dorkbox/network/dns/TokenizerTest.java @@ -0,0 +1,609 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.records.TTL; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class TokenizerTest extends TestCase { + private Tokenizer m_t; + + @Override + protected + void setUp() { + m_t = null; + } + + public + void test_get() throws IOException { + m_t = new Tokenizer(new BufferedInputStream(new ByteArrayInputStream("AnIdentifier \"a quoted \\\" string\"\r\n; this is \"my\"\t(comment)\nanotherIdentifier (\ramultilineIdentifier\n)".getBytes()))); + + Tokenizer.Token tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertTrue(tt.isString()); + assertFalse(tt.isEOL()); + assertEquals("AnIdentifier", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.WHITESPACE, tt.type); + assertFalse(tt.isString()); + assertFalse(tt.isEOL()); + assertNull(tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.QUOTED_STRING, tt.type); + assertTrue(tt.isString()); + assertFalse(tt.isEOL()); + assertEquals("a quoted \\\" string", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOL, tt.type); + assertFalse(tt.isString()); + assertTrue(tt.isEOL()); + assertNull(tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.COMMENT, tt.type); + assertFalse(tt.isString()); + assertFalse(tt.isEOL()); + assertEquals(" this is \"my\"\t(comment)", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOL, tt.type); + assertFalse(tt.isString()); + assertTrue(tt.isEOL()); + assertNull(tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertTrue(tt.isString()); + assertFalse(tt.isEOL()); + assertEquals("anotherIdentifier", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.WHITESPACE, tt.type); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertTrue(tt.isString()); + assertFalse(tt.isEOL()); + assertEquals("amultilineIdentifier", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.WHITESPACE, tt.type); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOF, tt.type); + assertFalse(tt.isString()); + assertTrue(tt.isEOL()); + assertNull(tt.value); + + // should be able to do this repeatedly + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOF, tt.type); + assertFalse(tt.isString()); + assertTrue(tt.isEOL()); + assertNull(tt.value); + + m_t = new Tokenizer("onlyOneIdentifier"); + tt = m_t.get(); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("onlyOneIdentifier", tt.value); + + m_t = new Tokenizer("identifier ;"); + tt = m_t.get(); + assertEquals("identifier", tt.value); + tt = m_t.get(); + assertEquals(Tokenizer.EOF, tt.type); + + + // some ungets + m_t = new Tokenizer("identifier \nidentifier2; junk comment"); + tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("identifier", tt.value); + + m_t.unget(); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("identifier", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.WHITESPACE, tt.type); + + m_t.unget(); + tt = m_t.get(true, true); + assertEquals(Tokenizer.WHITESPACE, tt.type); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOL, tt.type); + + m_t.unget(); + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOL, tt.type); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("identifier2", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.COMMENT, tt.type); + assertEquals(" junk comment", tt.value); + + m_t.unget(); + tt = m_t.get(true, true); + assertEquals(Tokenizer.COMMENT, tt.type); + assertEquals(" junk comment", tt.value); + + tt = m_t.get(true, true); + assertEquals(Tokenizer.EOF, tt.type); + + m_t = new Tokenizer("identifier ( junk ; comment\n )"); + tt = m_t.get(); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals(Tokenizer.IDENTIFIER, m_t.get().type); + assertEquals(Tokenizer.EOF, m_t.get().type); + } + + public + void test_get_invalid() throws IOException { + m_t = new Tokenizer("(this ;"); + m_t.get(); + try { + m_t.get(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("\"bad"); + try { + m_t.get(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer(")"); + try { + m_t.get(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("\\"); + try { + m_t.get(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("\"\n"); + try { + m_t.get(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_File_input() throws IOException { + File tmp = File.createTempFile("dnsjava", "tmp"); + try { + FileWriter fw = new FileWriter(tmp); + fw.write("file\ninput; test"); + fw.close(); + + m_t = new Tokenizer(tmp); + + Tokenizer.Token tt = m_t.get(); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("file", tt.value); + + tt = m_t.get(); + assertEquals(Tokenizer.EOL, tt.type); + + tt = m_t.get(); + assertEquals(Tokenizer.IDENTIFIER, tt.type); + assertEquals("input", tt.value); + + tt = m_t.get(false, true); + assertEquals(Tokenizer.COMMENT, tt.type); + assertEquals(" test", tt.value); + + m_t.close(); + } finally { + tmp.delete(); + } + } + + public + void test_unwanted_comment() throws IOException { + m_t = new Tokenizer("; this whole thing is a comment\n"); + Tokenizer.Token tt = m_t.get(); + + assertEquals(Tokenizer.EOL, tt.type); + } + + public + void test_unwanted_ungotten_whitespace() throws IOException { + m_t = new Tokenizer(" "); + Tokenizer.Token tt = m_t.get(true, true); + m_t.unget(); + tt = m_t.get(); + assertEquals(Tokenizer.EOF, tt.type); + } + + public + void test_unwanted_ungotten_comment() throws IOException { + m_t = new Tokenizer("; this whole thing is a comment"); + Tokenizer.Token tt = m_t.get(true, true); + m_t.unget(); + tt = m_t.get(); + assertEquals(Tokenizer.EOF, tt.type); + } + + public + void test_empty_string() throws IOException { + m_t = new Tokenizer(""); + Tokenizer.Token tt = m_t.get(); + assertEquals(Tokenizer.EOF, tt.type); + + m_t = new Tokenizer(" "); + tt = m_t.get(); + assertEquals(Tokenizer.EOF, tt.type); + } + + public + void test_multiple_ungets() throws IOException { + m_t = new Tokenizer("a simple one"); + Tokenizer.Token tt = m_t.get(); + + m_t.unget(); + try { + m_t.unget(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + } + + public + void test_getString() throws IOException { + m_t = new Tokenizer("just_an_identifier"); + String out = m_t.getString(); + assertEquals("just_an_identifier", out); + + m_t = new Tokenizer("\"just a string\""); + out = m_t.getString(); + assertEquals("just a string", out); + + m_t = new Tokenizer("; just a comment"); + try { + out = m_t.getString(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getIdentifier() throws IOException { + m_t = new Tokenizer("just_an_identifier"); + String out = m_t.getIdentifier(); + assertEquals("just_an_identifier", out); + + m_t = new Tokenizer("\"just a string\""); + try { + m_t.getIdentifier(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getLong() throws IOException { + m_t = new Tokenizer((Integer.MAX_VALUE + 1L) + ""); + long out = m_t.getLong(); + assertEquals((Integer.MAX_VALUE + 1L), out); + + m_t = new Tokenizer("-10"); + try { + m_t.getLong(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("19_identifier"); + try { + m_t.getLong(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getUInt32() throws IOException { + m_t = new Tokenizer(0xABCDEF12L + ""); + long out = m_t.getUInt32(); + assertEquals(0xABCDEF12L, out); + + m_t = new Tokenizer(0x100000000L + ""); + try { + m_t.getUInt32(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("-12345"); + try { + m_t.getUInt32(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getUInt16() throws IOException { + m_t = new Tokenizer(0xABCDL + ""); + int out = m_t.getUInt16(); + assertEquals(0xABCDL, out); + + m_t = new Tokenizer(0x10000 + ""); + try { + m_t.getUInt16(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("-125"); + try { + m_t.getUInt16(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getUInt8() throws IOException { + m_t = new Tokenizer(0xCDL + ""); + int out = m_t.getUInt8(); + assertEquals(0xCDL, out); + + m_t = new Tokenizer(0x100 + ""); + try { + m_t.getUInt8(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("-12"); + try { + m_t.getUInt8(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getTTL() throws IOException { + m_t = new Tokenizer("59S"); + assertEquals(59, m_t.getTTL()); + + m_t = new Tokenizer(TTL.MAX_VALUE + ""); + assertEquals(TTL.MAX_VALUE, m_t.getTTL()); + + m_t = new Tokenizer((TTL.MAX_VALUE + 1L) + ""); + assertEquals(TTL.MAX_VALUE, m_t.getTTL()); + + m_t = new Tokenizer("Junk"); + try { + m_t.getTTL(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getTTLLike() throws IOException { + m_t = new Tokenizer("59S"); + assertEquals(59, m_t.getTTLLike()); + + m_t = new Tokenizer(TTL.MAX_VALUE + ""); + assertEquals(TTL.MAX_VALUE, m_t.getTTLLike()); + + m_t = new Tokenizer((TTL.MAX_VALUE + 1L) + ""); + assertEquals(TTL.MAX_VALUE + 1L, m_t.getTTLLike()); + + m_t = new Tokenizer("Junk"); + try { + m_t.getTTLLike(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getName() throws IOException, TextParseException { + Name root = Name.fromString("."); + m_t = new Tokenizer("junk"); + Name exp = Name.fromString("junk."); + Name out = m_t.getName(root); + assertEquals(exp, out); + + Name rel = Name.fromString("you.dig"); + m_t = new Tokenizer("junk"); + try { + m_t.getName(rel); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + m_t = new Tokenizer(""); + try { + m_t.getName(root); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getEOL() throws IOException { + m_t = new Tokenizer("id"); + m_t.getIdentifier(); + try { + m_t.getEOL(); + } catch (TextParseException e) { + fail(e.getMessage()); + } + + m_t = new Tokenizer("\n"); + try { + m_t.getEOL(); + m_t.getEOL(); + } catch (TextParseException e) { + fail(e.getMessage()); + } + + m_t = new Tokenizer("id"); + try { + m_t.getEOL(); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_getBase64() throws IOException { + byte[] exp = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + // basic + m_t = new Tokenizer("AQIDBAUGBwgJ"); + byte[] out = m_t.getBase64(); + assertEquals(exp, out); + + // with some whitespace + m_t = new Tokenizer("AQIDB AUGB wgJ"); + out = m_t.getBase64(); + assertEquals(exp, out); + + // two base64s separated by newline + m_t = new Tokenizer("AQIDBAUGBwgJ\nAB23DK"); + out = m_t.getBase64(); + assertEquals(exp, out); + + // no remaining strings + m_t = new Tokenizer("\n"); + assertNull(m_t.getBase64()); + + m_t = new Tokenizer("\n"); + try { + m_t.getBase64(true); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + // invalid encoding + m_t = new Tokenizer("not_base64"); + try { + m_t.getBase64(false); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("not_base64"); + try { + m_t.getBase64(true); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(java.util.Arrays.equals(exp, act)); + } + + public + void test_getHex() throws IOException { + byte[] exp = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + // basic + m_t = new Tokenizer("0102030405060708090A0B0C0D0E0F"); + byte[] out = m_t.getHex(); + assertEquals(exp, out); + + // with some whitespace + m_t = new Tokenizer("0102030 405 060708090A0B0C 0D0E0F"); + out = m_t.getHex(); + assertEquals(exp, out); + + // two hexs separated by newline + m_t = new Tokenizer("0102030405060708090A0B0C0D0E0F\n01AB3FE"); + out = m_t.getHex(); + assertEquals(exp, out); + + // no remaining strings + m_t = new Tokenizer("\n"); + assertNull(m_t.getHex()); + + m_t = new Tokenizer("\n"); + try { + m_t.getHex(true); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + // invalid encoding + m_t = new Tokenizer("not_hex"); + try { + m_t.getHex(false); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + m_t = new Tokenizer("not_hex"); + try { + m_t.getHex(true); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } +} diff --git a/test/dorkbox/network/dns/TypeTest.java b/test/dorkbox/network/dns/TypeTest.java new file mode 100644 index 00000000..799a5b6f --- /dev/null +++ b/test/dorkbox/network/dns/TypeTest.java @@ -0,0 +1,83 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns; + +import dorkbox.network.dns.constants.DnsRecordType; +import junit.framework.TestCase; + +public +class TypeTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("CNAME", DnsRecordType.string(DnsRecordType.CNAME)); + + // one that doesn't exist + assertTrue(DnsRecordType.string(65535) + .startsWith("TYPE")); + + try { + DnsRecordType.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(DnsRecordType.MAILB, DnsRecordType.value("MAILB")); + + // one thats undefined but within range + assertEquals(300, DnsRecordType.value("TYPE300")); + + // something that unknown + assertEquals(-1, DnsRecordType.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, DnsRecordType.value("")); + } + + public + void test_value_2arg() { + assertEquals(301, DnsRecordType.value("301", true)); + } + + public + void test_isRR() { + assertTrue(DnsRecordType.isRR(DnsRecordType.CNAME)); + assertFalse(DnsRecordType.isRR(DnsRecordType.IXFR)); + } +} diff --git a/test/dorkbox/network/dns/records/A6RecordTest.java b/test/dorkbox/network/dns/records/A6RecordTest.java new file mode 100644 index 00000000..a14c4dc1 --- /dev/null +++ b/test/dorkbox/network/dns/records/A6RecordTest.java @@ -0,0 +1,253 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class A6RecordTest extends TestCase { + Name m_an, m_an2, m_rn; + InetAddress m_addr; + String m_addr_string, m_addr_string_canonical; + byte[] m_addr_bytes; + int m_prefix_bits; + long m_ttl; + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_an2 = Name.fromString("My.Second.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_addr_string = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334"; + m_addr_string_canonical = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr = InetAddress.getByName(m_addr_string); + m_addr_bytes = m_addr.getAddress(); + m_ttl = 0x13579; + m_prefix_bits = 9; + } + + public + void test_ctor_0arg() { + A6Record ar = new A6Record(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + } + + public + void test_getObject() { + A6Record ar = new A6Record(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof A6Record); + } + + public + void test_ctor_6arg() { + A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, null); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.A6, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_prefix_bits, ar.getPrefixBits()); + assertEquals(m_addr, ar.getSuffix()); + assertNull(ar.getPrefix()); + + // with the prefix name + ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.A6, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_prefix_bits, ar.getPrefixBits()); + assertEquals(m_addr, ar.getSuffix()); + assertEquals(m_an2, ar.getPrefix()); + + // a relative name + try { + new A6Record(m_rn, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, null); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + // a relative prefix name + try { + new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_rn); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + // invalid prefix bits + try { + new A6Record(m_rn, DnsClass.IN, m_ttl, 0x100, m_addr, null); + fail("IllegalArgumentException not thrown"); + } catch (RelativeNameException e) { + } + + // an IPv4 address + try { + new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, InetAddress.getByName("192.168.0.1"), null); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } catch (UnknownHostException e) { + fail(e.getMessage()); + } + } + + public + void test_rrFromWire() throws CloneNotSupportedException, IOException, UnknownHostException { + // record with no prefix + DnsOutput dout = new DnsOutput(); + dout.writeU8(0); + dout.writeByteArray(m_addr_bytes); + + DnsInput din = new DnsInput(dout.toByteArray()); + A6Record ar = new A6Record(); + ar.rrFromWire(din); + assertEquals(0, ar.getPrefixBits()); + assertEquals(m_addr, ar.getSuffix()); + assertNull(ar.getPrefix()); + + // record with 9 bit prefix (should result in 15 bytes of the address) + dout = new DnsOutput(); + dout.writeU8(9); + dout.writeByteArray(m_addr_bytes, 1, 15); + dout.writeByteArray(m_an2.toWire()); + + din = new DnsInput(dout.toByteArray()); + ar = new A6Record(); + ar.rrFromWire(din); + assertEquals(9, ar.getPrefixBits()); + + byte[] addr_bytes = (byte[]) m_addr_bytes.clone(); + addr_bytes[0] = 0; + InetAddress exp = InetAddress.getByAddress(addr_bytes); + assertEquals(exp, ar.getSuffix()); + assertEquals(m_an2, ar.getPrefix()); + } + + public + void test_rdataFromString() throws CloneNotSupportedException, IOException, UnknownHostException { + // record with no prefix + Tokenizer t = new Tokenizer("0 " + m_addr_string); + A6Record ar = new A6Record(); + ar.rdataFromString(t, null); + assertEquals(0, ar.getPrefixBits()); + assertEquals(m_addr, ar.getSuffix()); + assertNull(ar.getPrefix()); + + // record with 9 bit prefix. In contrast to the rrFromWire method, + // rdataFromString expects the entire 128 bits to be represented + // in the string + t = new Tokenizer("9 " + m_addr_string + " " + m_an2); + ar = new A6Record(); + ar.rdataFromString(t, null); + assertEquals(9, ar.getPrefixBits()); + assertEquals(m_addr, ar.getSuffix()); + assertEquals(m_an2, ar.getPrefix()); + + // record with invalid prefixBits + t = new Tokenizer("129"); + ar = new A6Record(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + // record with invalid ipv6 address + t = new Tokenizer("0 " + m_addr_string.substring(4)); + ar = new A6Record(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_rrToString() { + A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); + String exp = "" + m_prefix_bits + " " + m_addr_string_canonical + " " + m_an2; + StringBuilder stringBuilder = new StringBuilder(); + + ar.rrToString(stringBuilder); + String out = stringBuilder.toString(); + assertEquals(exp, out); + } + + public + void test_rrToWire() { + // canonical form + A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); + DnsOutput dout = new DnsOutput(); + dout.writeU8(m_prefix_bits); + dout.writeByteArray(m_addr_bytes, 1, 15); + dout.writeByteArray(m_an2.toWireCanonical()); + + byte[] exp = dout.toByteArray(); + + dout = new DnsOutput(); + ar.rrToWire(dout, null, true); + + assertTrue(Arrays.equals(exp, dout.toByteArray())); + + // case sensitiveform + dout = new DnsOutput(); + dout.writeU8(m_prefix_bits); + dout.writeByteArray(m_addr_bytes, 1, 15); + dout.writeByteArray(m_an2.toWire()); + + exp = dout.toByteArray(); + + dout = new DnsOutput(); + ar.rrToWire(dout, null, false); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } +} diff --git a/test/dorkbox/network/dns/records/AAAARecordTest.java b/test/dorkbox/network/dns/records/AAAARecordTest.java new file mode 100644 index 00000000..ee8c1588 --- /dev/null +++ b/test/dorkbox/network/dns/records/AAAARecordTest.java @@ -0,0 +1,165 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class AAAARecordTest extends TestCase { + Name m_an, m_rn; + InetAddress m_addr; + String m_addr_string; + byte[] m_addr_bytes; + long m_ttl; + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_addr_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr = InetAddress.getByName(m_addr_string); + m_addr_bytes = m_addr.getAddress(); + m_ttl = 0x13579; + } + + public + void test_ctor_0arg() throws UnknownHostException { + AAAARecord ar = new AAAARecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertNull(ar.getAddress()); + } + + public + void test_getObject() { + AAAARecord ar = new AAAARecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof AAAARecord); + } + + public + void test_ctor_4arg() { + AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.AAAA, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_addr, ar.getAddress()); + + // a relative name + try { + new AAAARecord(m_rn, DnsClass.IN, m_ttl, m_addr); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + // an IPv4 address + try { + new AAAARecord(m_an, DnsClass.IN, m_ttl, InetAddress.getByName("192.168.0.1")); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } catch (UnknownHostException e) { + fail(e.getMessage()); + } + } + + public + void test_rrFromWire() throws IOException { + DnsInput di = new DnsInput(m_addr_bytes); + AAAARecord ar = new AAAARecord(); + + ar.rrFromWire(di); + + assertEquals(m_addr, ar.getAddress()); + } + + public + void test_rdataFromString() throws IOException { + Tokenizer t = new Tokenizer(m_addr_string); + AAAARecord ar = new AAAARecord(); + + ar.rdataFromString(t, null); + + assertEquals(m_addr, ar.getAddress()); + + // invalid address + t = new Tokenizer("193.160.232.1"); + ar = new AAAARecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_rrToString() { + AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); + StringBuilder sb = new StringBuilder(); + ar.rrToString(sb); + assertEquals(m_addr_string, sb.toString()); + } + + public + void test_rrToWire() { + AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); + + // canonical + DnsOutput dout = new DnsOutput(); + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); + + // case sensitive + dout = new DnsOutput(); + ar.rrToWire(dout, null, false); + assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); + } +} diff --git a/test/dorkbox/network/dns/records/AFSDBRecordTest.java b/test/dorkbox/network/dns/records/AFSDBRecordTest.java new file mode 100644 index 00000000..877c7923 --- /dev/null +++ b/test/dorkbox/network/dns/records/AFSDBRecordTest.java @@ -0,0 +1,65 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class AFSDBRecordTest extends TestCase { + public + void test_getObject() { + AFSDBRecord d = new AFSDBRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof AFSDBRecord); + } + + public + void test_ctor_5arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.OtherName."); + + AFSDBRecord d = new AFSDBRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.AFSDB, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(0xF1, d.getSubtype()); + assertEquals(m, d.getHost()); + } +} diff --git a/test/dorkbox/network/dns/records/APLRecordTest.java b/test/dorkbox/network/dns/records/APLRecordTest.java new file mode 100644 index 00000000..abed8038 --- /dev/null +++ b/test/dorkbox/network/dns/records/APLRecordTest.java @@ -0,0 +1,696 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.exceptions.WireParseException; +import dorkbox.network.dns.records.APLRecord.Element; +import dorkbox.network.dns.utils.Address; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class APLRecordTest { + public static + class Test_Element_init extends TestCase { + InetAddress m_addr4; + InetAddress m_addr6; + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_addr4 = InetAddress.getByName("193.160.232.5"); + m_addr6 = InetAddress.getByName("2001:db8:85a3:8d3:1319:8a2e:370:7334"); + } + + public + void test_valid_IPv4() { + Element el = new Element(true, m_addr4, 16); + assertEquals(Address.IPv4, el.family); + assertEquals(true, el.negative); + assertEquals(m_addr4, el.address); + assertEquals(16, el.prefixLength); + } + + public + void test_invalid_IPv4() { + try { + new Element(true, m_addr4, 33); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_valid_IPv6() { + Element el = new Element(false, m_addr6, 74); + assertEquals(Address.IPv6, el.family); + assertEquals(false, el.negative); + assertEquals(m_addr6, el.address); + assertEquals(74, el.prefixLength); + } + + public + void test_invalid_IPv6() { + try { + new Element(true, m_addr6, 129); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + } + + + public static + class Test_init extends TestCase { + Name m_an, m_rn; + long m_ttl; + ArrayList m_elements; + InetAddress m_addr4; + String m_addr4_string; + byte[] m_addr4_bytes; + InetAddress m_addr6; + String m_addr6_string; + byte[] m_addr6_bytes; + + public + void test_0arg() throws UnknownHostException { + APLRecord ar = new APLRecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertNull(ar.getElements()); + } + + public + void test_getObject() { + APLRecord ar = new APLRecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof APLRecord); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_ttl = 0x13579; + m_addr4_string = "193.160.232.5"; + m_addr4 = InetAddress.getByName(m_addr4_string); + m_addr4_bytes = m_addr4.getAddress(); + + m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr6 = InetAddress.getByName(m_addr6_string); + m_addr6_bytes = m_addr6.getAddress(); + + m_elements = new ArrayList(2); + Element e = new Element(true, m_addr4, 12); + m_elements.add(e); + + e = new Element(false, m_addr6, 64); + m_elements.add(e); + } + + public + void test_4arg_basic() { + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.APL, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_elements, ar.getElements()); + } + + public + void test_4arg_empty_elements() { + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, new ArrayList()); + assertEquals(new ArrayList(), ar.getElements()); + } + + public + void test_4arg_relative_name() { + try { + new APLRecord(m_rn, DnsClass.IN, m_ttl, m_elements); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + } + + public + void test_4arg_invalid_elements() { + m_elements = new ArrayList(); + m_elements.add(new Object()); + try { + new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + + + + } + + + public static + class Test_rrFromWire extends TestCase { + InetAddress m_addr4; + byte[] m_addr4_bytes; + InetAddress m_addr6; + byte[] m_addr6_bytes; + + public + void test_validIPv4() throws IOException { + byte[] raw = new byte[] {0, 1, 8, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3]}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + ArrayList exp = new ArrayList(); + exp.add(new Element(true, m_addr4, 8)); + assertEquals(exp, ar.getElements()); + } + + public + void test_validIPv4_short_address() throws IOException { + byte[] raw = new byte[] {0, 1, 20, (byte) 0x83, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2]}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + InetAddress a = InetAddress.getByName("193.160.232.0"); + + ArrayList exp = new ArrayList(); + exp.add(new Element(true, a, 20)); + assertEquals(exp, ar.getElements()); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_addr4 = InetAddress.getByName("193.160.232.5"); + m_addr4_bytes = m_addr4.getAddress(); + + m_addr6 = InetAddress.getByName("2001:db8:85a3:8d3:1319:8a2e:370:7334"); + m_addr6_bytes = m_addr6.getAddress(); + } + + public + void test_invalid_IPv4_prefix() throws IOException { + byte[] raw = new byte[] {0, 1, 33, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3]}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + try { + ar.rrFromWire(di); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_invalid_IPv4_length() throws IOException { + byte[] raw = new byte[] {0, 1, 8, (byte) 0x85, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 10}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + try { + ar.rrFromWire(di); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_multiple_validIPv4() throws IOException { + byte[] raw = new byte[] {0, 1, 8, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 0, 1, 30, + (byte) 0x4, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3],}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + ArrayList exp = new ArrayList(); + exp.add(new Element(true, m_addr4, 8)); + exp.add(new Element(false, m_addr4, 30)); + assertEquals(exp, ar.getElements()); + } + + public + void test_validIPv6() throws IOException { + byte[] raw = new byte[] {0, 2, (byte) 115, (byte) 0x10, m_addr6_bytes[0], m_addr6_bytes[1], m_addr6_bytes[2], m_addr6_bytes[3], + m_addr6_bytes[4], m_addr6_bytes[5], m_addr6_bytes[6], m_addr6_bytes[7], m_addr6_bytes[8], + m_addr6_bytes[9], m_addr6_bytes[10], m_addr6_bytes[11], m_addr6_bytes[12], m_addr6_bytes[13], + m_addr6_bytes[14], m_addr6_bytes[15]}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + ArrayList exp = new ArrayList(); + exp.add(new Element(false, m_addr6, 115)); + assertEquals(exp, ar.getElements()); + } + + public + void test_valid_nonIP() throws IOException { + byte[] raw = new byte[] {0, 3, (byte) 130, (byte) 0x85, 1, 2, 3, 4, 5}; + + DnsInput di = new DnsInput(raw); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + List l = ar.getElements(); + assertEquals(1, l.size()); + + Element el = (Element) l.get(0); + assertEquals(3, el.family); + assertEquals(true, el.negative); + assertEquals(130, el.prefixLength); + assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5}, (byte[]) el.address)); + } + + + + + } + + + public static + class Test_rdataFromString extends TestCase { + InetAddress m_addr4; + String m_addr4_string; + byte[] m_addr4_bytes; + InetAddress m_addr6; + String m_addr6_string; + byte[] m_addr6_bytes; + + public + void test_validIPv4() throws IOException { + Tokenizer t = new Tokenizer("1:" + m_addr4_string + "/11\n"); + APLRecord ar = new APLRecord(); + ar.rdataFromString(t, null); + + ArrayList exp = new ArrayList(); + exp.add(new Element(false, m_addr4, 11)); + + assertEquals(exp, ar.getElements()); + + // make sure extra token is put back + assertEquals(Tokenizer.EOL, t.get().type); + } + + public + void test_valid_multi() throws IOException { + Tokenizer t = new Tokenizer("1:" + m_addr4_string + "/11 !2:" + m_addr6_string + "/100"); + APLRecord ar = new APLRecord(); + ar.rdataFromString(t, null); + + ArrayList exp = new ArrayList(); + exp.add(new Element(false, m_addr4, 11)); + exp.add(new Element(true, m_addr6, 100)); + + assertEquals(exp, ar.getElements()); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_addr4_string = "193.160.232.5"; + m_addr4 = InetAddress.getByName(m_addr4_string); + m_addr4_bytes = m_addr4.getAddress(); + + m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr6 = InetAddress.getByName(m_addr6_string); + m_addr6_bytes = m_addr6.getAddress(); + } + + public + void test_validIPv6() throws IOException { + Tokenizer t = new Tokenizer("!2:" + m_addr6_string + "/36\n"); + APLRecord ar = new APLRecord(); + ar.rdataFromString(t, null); + + ArrayList exp = new ArrayList(); + exp.add(new Element(true, m_addr6, 36)); + + assertEquals(exp, ar.getElements()); + + // make sure extra token is put back + assertEquals(Tokenizer.EOL, t.get().type); + } + + public + void test_no_colon() throws IOException { + Tokenizer t = new Tokenizer("!1192.68.0.1/20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_colon_and_slash_swapped() throws IOException { + Tokenizer t = new Tokenizer("!1/192.68.0.1:20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_no_slash() throws IOException { + Tokenizer t = new Tokenizer("!1:192.68.0.1|20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_empty_family() throws IOException { + Tokenizer t = new Tokenizer("!:192.68.0.1/20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_malformed_family() throws IOException { + Tokenizer t = new Tokenizer("family:192.68.0.1/20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_invalid_family() throws IOException { + Tokenizer t = new Tokenizer("3:192.68.0.1/20"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_empty_prefix() throws IOException { + Tokenizer t = new Tokenizer("1:192.68.0.1/"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_malformed_prefix() throws IOException { + Tokenizer t = new Tokenizer("1:192.68.0.1/prefix"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_invalid_prefix() throws IOException { + Tokenizer t = new Tokenizer("1:192.68.0.1/33"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_empty_address() throws IOException { + Tokenizer t = new Tokenizer("1:/33"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_malformed_address() throws IOException { + Tokenizer t = new Tokenizer("1:A.B.C.D/33"); + APLRecord ar = new APLRecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + + + + } + + + public static + class Test_rrToString extends TestCase { + Name m_an, m_rn; + long m_ttl; + ArrayList m_elements; + InetAddress m_addr4; + String m_addr4_string; + byte[] m_addr4_bytes; + InetAddress m_addr6; + String m_addr6_string; + byte[] m_addr6_bytes; + + public + void test() { + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); + StringBuilder sb = new StringBuilder(); + ar.rrToString(sb); + assertEquals("!1:" + m_addr4_string + "/12 2:" + m_addr6_string + "/64", sb.toString()); + } + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_ttl = 0x13579; + m_addr4_string = "193.160.232.5"; + m_addr4 = InetAddress.getByName(m_addr4_string); + m_addr4_bytes = m_addr4.getAddress(); + + m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr6 = InetAddress.getByName(m_addr6_string); + m_addr6_bytes = m_addr6.getAddress(); + + m_elements = new ArrayList(2); + Element e = new Element(true, m_addr4, 12); + m_elements.add(e); + + e = new Element(false, m_addr6, 64); + m_elements.add(e); + } + + + } + + + public static + class Test_rrToWire extends TestCase { + Name m_an, m_rn; + long m_ttl; + ArrayList m_elements; + InetAddress m_addr4; + String m_addr4_string; + byte[] m_addr4_bytes; + InetAddress m_addr6; + String m_addr6_string; + byte[] m_addr6_bytes; + + public + void test_empty() { + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, new ArrayList()); + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(new byte[0], dout.toByteArray())); + } + + public + void test_basic() { + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); + + byte[] exp = new byte[] {0, 1, 12, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 0, 2, + 64, 0x10, m_addr6_bytes[0], m_addr6_bytes[1], m_addr6_bytes[2], m_addr6_bytes[3], m_addr6_bytes[4], + m_addr6_bytes[5], m_addr6_bytes[6], m_addr6_bytes[7], m_addr6_bytes[8], m_addr6_bytes[9], + m_addr6_bytes[10], m_addr6_bytes[11], m_addr6_bytes[12], m_addr6_bytes[13], m_addr6_bytes[14], + m_addr6_bytes[15]}; + + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_ttl = 0x13579; + m_addr4_string = "193.160.232.5"; + m_addr4 = InetAddress.getByName(m_addr4_string); + m_addr4_bytes = m_addr4.getAddress(); + + m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; + m_addr6 = InetAddress.getByName(m_addr6_string); + m_addr6_bytes = m_addr6.getAddress(); + + m_elements = new ArrayList(2); + Element e = new Element(true, m_addr4, 12); + m_elements.add(e); + + e = new Element(false, m_addr6, 64); + m_elements.add(e); + } + + public + void test_non_IP() throws IOException { + byte[] exp = new byte[] {0, 3, (byte) 130, (byte) 0x85, 1, 2, 3, 4, 5}; + + DnsInput di = new DnsInput(exp); + APLRecord ar = new APLRecord(); + ar.rrFromWire(di); + + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } + + public + void test_address_with_embedded_zero() throws UnknownHostException { + InetAddress a = InetAddress.getByName("232.0.11.1"); + ArrayList elements = new ArrayList(); + elements.add(new Element(true, a, 31)); + + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); + + byte[] exp = new byte[] {0, 1, 31, (byte) 0x84, (byte) 232, 0, 11, 1}; + + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } + + public + void test_short_address() throws UnknownHostException { + InetAddress a = InetAddress.getByName("232.0.11.0"); + ArrayList elements = new ArrayList(); + elements.add(new Element(true, a, 31)); + + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); + + byte[] exp = new byte[] {0, 1, 31, (byte) 0x83, (byte) 232, 0, 11}; + + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } + + public + void test_wildcard_address() throws UnknownHostException { + InetAddress a = InetAddress.getByName("0.0.0.0"); + ArrayList elements = new ArrayList(); + elements.add(new Element(true, a, 31)); + + APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); + + byte[] exp = new byte[] {0, 1, 31, (byte) 0x80}; + + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(exp, dout.toByteArray())); + } + + + + + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_Element_init.class); + s.addTestSuite(Test_init.class); + s.addTestSuite(Test_rrFromWire.class); + s.addTestSuite(Test_rdataFromString.class); + s.addTestSuite(Test_rrToString.class); + s.addTestSuite(Test_rrToWire.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/records/ARecordTest.java b/test/dorkbox/network/dns/records/ARecordTest.java new file mode 100644 index 00000000..711c8e67 --- /dev/null +++ b/test/dorkbox/network/dns/records/ARecordTest.java @@ -0,0 +1,163 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class ARecordTest extends TestCase { + Name m_an, m_rn; + InetAddress m_addr; + String m_addr_string; + byte[] m_addr_bytes; + long m_ttl; + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_addr_string = "193.160.232.5"; + m_addr = InetAddress.getByName(m_addr_string); + m_addr_bytes = m_addr.getAddress(); + m_ttl = 0x13579; + } + + public + void test_ctor_0arg() throws UnknownHostException { + ARecord ar = new ARecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertEquals(InetAddress.getByName("0.0.0.0"), ar.getAddress()); + } + + public + void test_getObject() { + ARecord ar = new ARecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof ARecord); + } + + public + void test_ctor_4arg() { + ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.A, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_addr, ar.getAddress()); + + // a relative name + try { + new ARecord(m_rn, DnsClass.IN, m_ttl, m_addr); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + // an IPv6 address + try { + new ARecord(m_an, DnsClass.IN, m_ttl, InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7334")); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } catch (UnknownHostException e) { + fail(e.getMessage()); + } + } + + public + void test_rrFromWire() throws IOException { + DnsInput di = new DnsInput(m_addr_bytes); + ARecord ar = new ARecord(); + + ar.rrFromWire(di); + + assertEquals(m_addr, ar.getAddress()); + } + + public + void test_rdataFromString() throws IOException { + Tokenizer t = new Tokenizer(m_addr_string); + ARecord ar = new ARecord(); + + ar.rdataFromString(t, null); + + assertEquals(m_addr, ar.getAddress()); + + // invalid address + t = new Tokenizer("193.160.232"); + ar = new ARecord(); + try { + ar.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_rrToString() { + ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); + StringBuilder sb = new StringBuilder(); + ar.rrToString(sb); + assertEquals(m_addr_string, sb.toString()); + } + + public + void test_rrToWire() { + ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); + DnsOutput dout = new DnsOutput(); + + ar.rrToWire(dout, null, true); + assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); + + dout = new DnsOutput(); + ar.rrToWire(dout, null, false); + assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); + } +} diff --git a/test/dorkbox/network/dns/records/CNAMERecordTest.java b/test/dorkbox/network/dns/records/CNAMERecordTest.java new file mode 100644 index 00000000..06147975 --- /dev/null +++ b/test/dorkbox/network/dns/records/CNAMERecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class CNAMERecordTest extends TestCase { + public + void test_ctor_0arg() { + CNAMERecord d = new CNAMERecord(); + assertNull(d.getName()); + assertNull(d.getTarget()); + assertNull(d.getAlias()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + CNAMERecord d = new CNAMERecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.CNAME, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getTarget()); + assertEquals(a, d.getAlias()); + } + + public + void test_getObject() { + CNAMERecord d = new CNAMERecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof CNAMERecord); + } +} diff --git a/test/dorkbox/network/dns/records/DNAMERecordTest.java b/test/dorkbox/network/dns/records/DNAMERecordTest.java new file mode 100644 index 00000000..41de4ab1 --- /dev/null +++ b/test/dorkbox/network/dns/records/DNAMERecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class DNAMERecordTest extends TestCase { + public + void test_ctor_0arg() { + DNAMERecord d = new DNAMERecord(); + assertNull(d.getName()); + assertNull(d.getTarget()); + assertNull(d.getAlias()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + DNAMERecord d = new DNAMERecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.DNAME, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getTarget()); + assertEquals(a, d.getAlias()); + } + + public + void test_getObject() { + DNAMERecord d = new DNAMERecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof DNAMERecord); + } +} diff --git a/test/dorkbox/network/dns/records/DNSKEYRecordTest.java b/test/dorkbox/network/dns/records/DNSKEYRecordTest.java new file mode 100644 index 00000000..8406d75f --- /dev/null +++ b/test/dorkbox/network/dns/records/DNSKEYRecordTest.java @@ -0,0 +1,116 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class DNSKEYRecordTest extends TestCase { + public + void test_ctor_0arg() throws UnknownHostException { + DNSKEYRecord ar = new DNSKEYRecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertEquals(0, ar.getAlgorithm()); + assertEquals(0, ar.getFlags()); + assertEquals(0, ar.getFootprint()); + assertEquals(0, ar.getProtocol()); + assertNull(ar.getKey()); + } + + public + void test_getObject() { + DNSKEYRecord ar = new DNSKEYRecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof DNSKEYRecord); + } + + public + void test_ctor_7arg() throws TextParseException { + Name n = Name.fromString("My.Absolute.Name."); + Name r = Name.fromString("My.Relative.Name"); + byte[] key = new byte[] {0, 1, 3, 5, 7, 9}; + + DNSKEYRecord kr = new DNSKEYRecord(n, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); + assertEquals(n, kr.getName()); + assertEquals(DnsRecordType.DNSKEY, kr.getType()); + assertEquals(DnsClass.IN, kr.getDClass()); + assertEquals(0x24AC, kr.getTTL()); + assertEquals(0x9832, kr.getFlags()); + assertEquals(0x12, kr.getProtocol()); + assertEquals(0x67, kr.getAlgorithm()); + assertTrue(Arrays.equals(key, kr.getKey())); + + // a relative name + try { + new DNSKEYRecord(r, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + } + + public + void test_rdataFromString() throws IOException, TextParseException { + // basic + DNSKEYRecord kr = new DNSKEYRecord(); + Tokenizer st = new Tokenizer(0xABCD + " " + 0x81 + " RSASHA1 AQIDBAUGBwgJ"); + kr.rdataFromString(st, null); + assertEquals(0xABCD, kr.getFlags()); + assertEquals(0x81, kr.getProtocol()); + assertEquals(DNSSEC.Algorithm.RSASHA1, kr.getAlgorithm()); + assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, kr.getKey())); + + // invalid algorithm + kr = new DNSKEYRecord(); + st = new Tokenizer(0x1212 + " " + 0xAA + " ZONE AQIDBAUGBwgJ"); + try { + kr.rdataFromString(st, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } +} diff --git a/test/dorkbox/network/dns/records/DNSOutputTest.java b/test/dorkbox/network/dns/records/DNSOutputTest.java new file mode 100644 index 00000000..2628f536 --- /dev/null +++ b/test/dorkbox/network/dns/records/DNSOutputTest.java @@ -0,0 +1,263 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.DnsOutput; +import junit.framework.TestCase; + +public +class DNSOutputTest extends TestCase { + private DnsOutput m_do; + + @Override + public + void setUp() { + m_do = new DnsOutput(1); + } + + public + void test_default_ctor() { + m_do = new DnsOutput(); + assertEquals(0, m_do.current()); + } + + public + void test_initial_state() { + assertEquals(0, m_do.current()); + try { + m_do.restore(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + // pass + } + try { + m_do.jump(1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_writeU8_basic() { + m_do.writeU8(1); + assertEquals(1, m_do.current()); + + byte[] curr = m_do.toByteArray(); + assertEquals(1, curr.length); + assertEquals(1, curr[0]); + } + + public + void test_writeU8_expand() { + // starts off at 1; + m_do.writeU8(1); + m_do.writeU8(2); + + assertEquals(2, m_do.current()); + + byte[] curr = m_do.toByteArray(); + assertEquals(2, curr.length); + assertEquals(1, curr[0]); + assertEquals(2, curr[1]); + } + + public + void test_writeU8_max() { + m_do.writeU8(0xFF); + byte[] curr = m_do.toByteArray(); + assertEquals((byte) 0xFF, (byte) curr[0]); + } + + public + void test_writeU8_toobig() { + try { + m_do.writeU8(0x1FF); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_writeU16_basic() { + m_do.writeU16(0x100); + assertEquals(2, m_do.current()); + + byte[] curr = m_do.toByteArray(); + assertEquals(2, curr.length); + assertEquals(1, curr[0]); + assertEquals(0, curr[1]); + } + + public + void test_writeU16_max() { + m_do.writeU16(0xFFFF); + byte[] curr = m_do.toByteArray(); + assertEquals((byte) 0xFF, (byte) curr[0]); + assertEquals((byte) 0XFF, (byte) curr[1]); + } + + public + void test_writeU16_toobig() { + try { + m_do.writeU16(0x1FFFF); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_writeU32_basic() { + m_do.writeU32(0x11001011); + assertEquals(4, m_do.current()); + + byte[] curr = m_do.toByteArray(); + assertEquals(4, curr.length); + assertEquals(0x11, curr[0]); + assertEquals(0x00, curr[1]); + assertEquals(0x10, curr[2]); + assertEquals(0x11, curr[3]); + } + + public + void test_writeU32_max() { + m_do.writeU32(0xFFFFFFFFL); + byte[] curr = m_do.toByteArray(); + assertEquals((byte) 0xFF, (byte) curr[0]); + assertEquals((byte) 0XFF, (byte) curr[1]); + assertEquals((byte) 0XFF, (byte) curr[2]); + assertEquals((byte) 0XFF, (byte) curr[3]); + } + + public + void test_writeU32_toobig() { + try { + m_do.writeU32(0x1FFFFFFFFL); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_jump_basic() { + m_do.writeU32(0x11223344L); + assertEquals(4, m_do.current()); + m_do.jump(2); + assertEquals(2, m_do.current()); + m_do.writeU8(0x99); + byte[] curr = m_do.toByteArray(); + assertEquals(3, curr.length); + assertEquals(0x11, curr[0]); + assertEquals(0x22, curr[1]); + assertEquals((byte) 0x99, (byte) curr[2]); + + } + + public + void test_writeByteArray_1arg() { + byte[] in = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34}; + m_do.writeByteArray(in); + assertEquals(5, m_do.current()); + byte[] curr = m_do.toByteArray(); + assertEquals(in, curr); + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(java.util.Arrays.equals(exp, act)); + } + + public + void test_writeByteArray_3arg() { + byte[] in = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34}; + m_do.writeByteArray(in, 2, 3); + assertEquals(3, m_do.current()); + byte[] exp = new byte[] {in[2], in[3], in[4]}; + byte[] curr = m_do.toByteArray(); + assertEquals(exp, curr); + } + + public + void test_writeCountedString_basic() { + byte[] in = new byte[] {'h', 'e', 'l', 'L', '0'}; + m_do.writeCountedString(in); + assertEquals(in.length + 1, m_do.current()); + byte[] curr = m_do.toByteArray(); + byte[] exp = new byte[] {(byte) (in.length), in[0], in[1], in[2], in[3], in[4]}; + assertEquals(exp, curr); + } + + public + void test_writeCountedString_empty() { + byte[] in = new byte[] {}; + m_do.writeCountedString(in); + assertEquals(in.length + 1, m_do.current()); + byte[] curr = m_do.toByteArray(); + byte[] exp = new byte[] {(byte) (in.length)}; + assertEquals(exp, curr); + } + + public + void test_writeCountedString_toobig() { + byte[] in = new byte[256]; + try { + m_do.writeCountedString(in); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + // pass + } + } + + public + void test_save_restore() { + m_do.writeU32(0x12345678L); + assertEquals(4, m_do.current()); + m_do.save(); + m_do.writeU16(0xABCD); + assertEquals(6, m_do.current()); + m_do.restore(); + assertEquals(4, m_do.current()); + try { + m_do.restore(); + fail("IllegalArgumentException not thrown"); + } catch (IllegalStateException e) { + // pass + } + } + +} diff --git a/test/dorkbox/network/dns/records/DNSSECSIG0Test.java b/test/dorkbox/network/dns/records/DNSSECSIG0Test.java new file mode 100644 index 00000000..248c133d --- /dev/null +++ b/test/dorkbox/network/dns/records/DNSSECSIG0Test.java @@ -0,0 +1,55 @@ +package dorkbox.network.dns.records; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import junit.framework.TestCase; + +public +class DNSSECSIG0Test extends TestCase { + + private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; + private static final String KEY_ALGORITHM = "RSA"; + int algorithm = DNSSEC.Algorithm.RSASHA1; + byte[] toSign = "The quick brown fox jumped over the lazy dog.".getBytes(); + + @Override + public + void setUp() { + } + + @Override + public + void tearDown() { + } + + public + void testSIG0() throws Exception { + Name sig0zoneName = new Name("sig0.invalid."); + Name sig0hostName = new Name("sometext.sig0.invalid."); + + KeyPairGenerator rsagen = KeyPairGenerator.getInstance("RSA"); + KeyPair rsapair = rsagen.generateKeyPair(); + PrivateKey privKey = rsapair.getPrivate(); + PublicKey pubKey = rsapair.getPublic(); + + KEYRecord keyRecord = new KEYRecord(sig0zoneName, + DnsClass.IN, + 0, + KEYRecord.Flags.HOST, + KEYRecord.Protocol.DNSSEC, + DNSSEC.Algorithm.RSASHA1, + pubKey); + TXTRecord txtRecord = new TXTRecord(sig0hostName, DnsClass.IN, 0, "Hello World!"); + Update updateMessage = new Update(sig0zoneName); + updateMessage.add(txtRecord); + + SIG0.signMessage(updateMessage, keyRecord, privKey, null); + DnsMessage message = new DnsMessage(updateMessage.toWire()); + SIG0.verifyMessage(message, message.toWire(), keyRecord, null); + } +} diff --git a/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java b/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java new file mode 100644 index 00000000..ab7d9642 --- /dev/null +++ b/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java @@ -0,0 +1,49 @@ +package dorkbox.network.dns.records; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.Signature; + +import junit.framework.TestCase; + + +public +class DNSSECWithProviderTest extends TestCase { + + private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; + private static final String KEY_ALGORITHM = "RSA"; + int algorithm = DNSSEC.Algorithm.RSASHA1; + byte[] toSign = "The quick brown fox jumped over the lazy dog.".getBytes(); + + @Override + public + void setUp() { + } + + @Override + public + void tearDown() { + } + + public + void testSignSoftware() throws Exception { + + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); + keyPairGenerator.initialize(512); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + Signature signer = Signature.getInstance(SIGNATURE_ALGORITHM); + signer.initSign(keyPair.getPrivate()); + signer.update(toSign); + byte[] signature = signer.sign(); + assertNotNull(signature); + + // verify the signature + Signature verifier = Signature.getInstance(SIGNATURE_ALGORITHM); + verifier.initVerify(keyPair.getPublic()); + verifier.update(toSign); + boolean verify = verifier.verify(signature); + assertTrue(verify); + + } +} diff --git a/test/dorkbox/network/dns/records/DSRecordTest.java b/test/dorkbox/network/dns/records/DSRecordTest.java new file mode 100644 index 00000000..c155214f --- /dev/null +++ b/test/dorkbox/network/dns/records/DSRecordTest.java @@ -0,0 +1,243 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class DSRecordTest extends TestCase { + public + void test_ctor_0arg() { + DSRecord dr = new DSRecord(); + assertNull(dr.getName()); + assertEquals(0, dr.getType()); + assertEquals(0, dr.getDClass()); + assertEquals(0, dr.getTTL()); + assertEquals(0, dr.getAlgorithm()); + assertEquals(0, dr.getDigestID()); + assertNull(dr.getDigest()); + assertEquals(0, dr.getFootprint()); + } + + public + void test_getObject() { + DSRecord dr = new DSRecord(); + DnsRecord r = dr.getObject(); + assertTrue(r instanceof DSRecord); + } + + public static + class Test_Ctor_7arg extends TestCase { + private Name m_n; + private long m_ttl; + private int m_footprint; + private int m_algorithm; + private int m_digestid; + private byte[] m_digest; + + @Override + protected + void setUp() throws TextParseException { + m_n = Name.fromString("The.Name."); + m_ttl = 0xABCDL; + m_footprint = 0xEF01; + m_algorithm = 0x23; + m_digestid = 0x45; + m_digest = new byte[] {(byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF}; + } + + public + void test_basic() throws TextParseException { + DSRecord dr = new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, m_digestid, m_digest); + assertEquals(m_n, dr.getName()); + assertEquals(DnsClass.IN, dr.getDClass()); + assertEquals(DnsRecordType.DS, dr.getType()); + assertEquals(m_ttl, dr.getTTL()); + assertEquals(m_footprint, dr.getFootprint()); + assertEquals(m_algorithm, dr.getAlgorithm()); + assertEquals(m_digestid, dr.getDigestID()); + assertTrue(Arrays.equals(m_digest, dr.getDigest())); + } + + public + void test_toosmall_footprint() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, -1, m_algorithm, m_digestid, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_footprint() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, 0x10000, m_algorithm, m_digestid, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_algorithm() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, -1, m_digestid, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_algorithm() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, 0x10000, m_digestid, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_digestid() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, -1, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_digestid() throws TextParseException { + try { + new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, 0x10000, m_digest); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_null_digest() { + DSRecord dr = new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, m_digestid, null); + assertEquals(m_n, dr.getName()); + assertEquals(DnsClass.IN, dr.getDClass()); + assertEquals(DnsRecordType.DS, dr.getType()); + assertEquals(m_ttl, dr.getTTL()); + assertEquals(m_footprint, dr.getFootprint()); + assertEquals(m_algorithm, dr.getAlgorithm()); + assertEquals(m_digestid, dr.getDigestID()); + assertNull(dr.getDigest()); + } + } + + public + void test_rrFromWire() throws IOException { + byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}; + DnsInput in = new DnsInput(raw); + + DSRecord dr = new DSRecord(); + dr.rrFromWire(in); + assertEquals(0xABCD, dr.getFootprint()); + assertEquals(0xEF, dr.getAlgorithm()); + assertEquals(0x01, dr.getDigestID()); + assertTrue(Arrays.equals(new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}, dr.getDigest())); + } + + public + void test_rdataFromString() throws IOException { + byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}; + Tokenizer t = new Tokenizer(0xABCD + " " + 0xEF + " " + 0x01 + " 23456789AB"); + + DSRecord dr = new DSRecord(); + dr.rdataFromString(t, null); + assertEquals(0xABCD, dr.getFootprint()); + assertEquals(0xEF, dr.getAlgorithm()); + assertEquals(0x01, dr.getDigestID()); + assertTrue(Arrays.equals(new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}, dr.getDigest())); + } + + public + void test_rrToString() throws TextParseException { + String exp = 0xABCD + " " + 0xEF + " " + 0x01 + " 23456789AB"; + + DSRecord dr = new DSRecord(Name.fromString("The.Name."), + DnsClass.IN, + 0x123, + 0xABCD, + 0xEF, + 0x01, + new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}); + + StringBuilder sb = new StringBuilder(); + dr.rrToString(sb); + assertEquals(exp, sb.toString()); + } + + public + void test_rrToWire() throws TextParseException { + DSRecord dr = new DSRecord(Name.fromString("The.Name."), + DnsClass.IN, + 0x123, + 0xABCD, + 0xEF, + 0x01, + new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}); + + byte[] exp = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, + (byte) 0xAB}; + + DnsOutput out = new DnsOutput(); + dr.rrToWire(out, null, true); + + assertTrue(Arrays.equals(exp, out.toByteArray())); + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_Ctor_7arg.class); + s.addTestSuite(DSRecordTest.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/records/EmptyRecordTest.java b/test/dorkbox/network/dns/records/EmptyRecordTest.java new file mode 100644 index 00000000..627d3606 --- /dev/null +++ b/test/dorkbox/network/dns/records/EmptyRecordTest.java @@ -0,0 +1,105 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.UnknownHostException; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class EmptyRecordTest extends TestCase { + public + void test_ctor() throws UnknownHostException { + EmptyRecord ar = new EmptyRecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + } + + public + void test_getObject() { + EmptyRecord ar = new EmptyRecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof EmptyRecord); + } + + public + void test_rrFromWire() throws IOException { + DnsInput i = new DnsInput(new byte[] {1, 2, 3, 4, 5}); + i.jump(3); + + EmptyRecord er = new EmptyRecord(); + er.rrFromWire(i); + assertEquals(3, i.readIndex()); + assertNull(er.getName()); + assertEquals(0, er.getType()); + assertEquals(0, er.getDClass()); + assertEquals(0, er.getTTL()); + } + + public + void test_rdataFromString() throws IOException { + Tokenizer t = new Tokenizer("these are the tokens"); + EmptyRecord er = new EmptyRecord(); + er.rdataFromString(t, null); + assertNull(er.getName()); + assertEquals(0, er.getType()); + assertEquals(0, er.getDClass()); + assertEquals(0, er.getTTL()); + + assertEquals("these", t.getString()); + } + + public + void test_rrToString() { + EmptyRecord er = new EmptyRecord(); + StringBuilder sb = new StringBuilder(); + er.rrToString(sb); + assertEquals("", sb.toString()); + } + + public + void test_rrToWire() { + EmptyRecord er = new EmptyRecord(); + DnsOutput out = new DnsOutput(); + er.rrToWire(out, null, true); + assertEquals(0, out.toByteArray().length); + } +} diff --git a/test/dorkbox/network/dns/records/GPOSRecordTest.java b/test/dorkbox/network/dns/records/GPOSRecordTest.java new file mode 100644 index 00000000..f4c36347 --- /dev/null +++ b/test/dorkbox/network/dns/records/GPOSRecordTest.java @@ -0,0 +1,401 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.exceptions.WireParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class GPOSRecordTest extends TestCase { + public + void test_ctor_0arg() { + GPOSRecord gr = new GPOSRecord(); + assertNull(gr.getName()); + assertEquals(0, gr.getType()); + assertEquals(0, gr.getDClass()); + assertEquals(0, gr.getTTL()); + } + + public + void test_getObject() { + GPOSRecord gr = new GPOSRecord(); + DnsRecord r = gr.getObject(); + assertTrue(r instanceof GPOSRecord); + } + + public static + class Test_Ctor_6arg_doubles extends TestCase { + private Name m_n; + private long m_ttl; + private double m_lat, m_long, m_alt; + + @Override + protected + void setUp() throws TextParseException { + m_n = Name.fromString("The.Name."); + m_ttl = 0xABCDL; + m_lat = -10.43; + m_long = 76.12; + m_alt = 100.101; + } + + public + void test_basic() throws TextParseException { + GPOSRecord gr = new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, m_lat, m_alt); + assertEquals(m_n, gr.getName()); + assertEquals(DnsClass.IN, gr.getDClass()); + assertEquals(DnsRecordType.GPOS, gr.getType()); + assertEquals(m_ttl, gr.getTTL()); + assertEquals(new Double(m_long), new Double(gr.getLongitude())); + assertEquals(new Double(m_lat), new Double(gr.getLatitude())); + assertEquals(new Double(m_alt), new Double(gr.getAltitude())); + assertEquals(new Double(m_long).toString(), gr.getLongitudeString()); + assertEquals(new Double(m_lat).toString(), gr.getLatitudeString()); + assertEquals(new Double(m_alt).toString(), gr.getAltitudeString()); + } + + public + void test_toosmall_longitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, -90.001, m_lat, m_alt); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_longitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, 90.001, m_lat, m_alt); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_latitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, -180.001, m_alt); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_latitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, 180.001, m_alt); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_invalid_string() { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "120.\\00ABC", new Double(m_alt).toString()); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + } + + + public static + class Test_Ctor_6arg_Strings extends TestCase { + private Name m_n; + private long m_ttl; + private double m_lat, m_long, m_alt; + + public + void test_basic() throws TextParseException { + GPOSRecord gr = new GPOSRecord(m_n, + DnsClass.IN, + m_ttl, + new Double(m_long).toString(), + new Double(m_lat).toString(), + new Double(m_alt).toString()); + assertEquals(m_n, gr.getName()); + assertEquals(DnsClass.IN, gr.getDClass()); + assertEquals(DnsRecordType.GPOS, gr.getType()); + assertEquals(m_ttl, gr.getTTL()); + assertEquals(new Double(m_long), new Double(gr.getLongitude())); + assertEquals(new Double(m_lat), new Double(gr.getLatitude())); + assertEquals(new Double(m_alt), new Double(gr.getAltitude())); + assertEquals(new Double(m_long).toString(), gr.getLongitudeString()); + assertEquals(new Double(m_lat).toString(), gr.getLatitudeString()); + assertEquals(new Double(m_alt).toString(), gr.getAltitudeString()); + } + + public + void test_toosmall_longitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, "-90.001", new Double(m_lat).toString(), new Double(m_alt).toString()); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } @Override + protected + void setUp() throws TextParseException { + m_n = Name.fromString("The.Name."); + m_ttl = 0xABCDL; + m_lat = -10.43; + m_long = 76.12; + m_alt = 100.101; + } + + public + void test_toobig_longitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, "90.001", new Double(m_lat).toString(), new Double(m_alt).toString()); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_latitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "-180.001", new Double(m_alt).toString()); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_latitude() throws TextParseException { + try { + new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "180.001", new Double(m_alt).toString()); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + + + + } + + + public static + class Test_rrFromWire extends TestCase { + public + void test_basic() throws IOException { + byte[] raw = new byte[] {5, '-', '8', '.', '1', '2', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; + DnsInput in = new DnsInput(raw); + + GPOSRecord gr = new GPOSRecord(); + gr.rrFromWire(in); + assertEquals(new Double(-8.12), new Double(gr.getLongitude())); + assertEquals(new Double(123.07), new Double(gr.getLatitude())); + assertEquals(new Double(0.0), new Double(gr.getAltitude())); + } + + public + void test_longitude_toosmall() throws IOException { + byte[] raw = new byte[] {5, '-', '9', '5', '.', '0', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; + DnsInput in = new DnsInput(raw); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rrFromWire(in); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_longitude_toobig() throws IOException { + byte[] raw = new byte[] {5, '1', '8', '5', '.', '0', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; + DnsInput in = new DnsInput(raw); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rrFromWire(in); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_latitude_toosmall() throws IOException { + byte[] raw = new byte[] {5, '-', '8', '5', '.', '0', 6, '-', '1', '9', '0', '.', '0', 3, '0', '.', '0'}; + DnsInput in = new DnsInput(raw); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rrFromWire(in); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + + public + void test_latitude_toobig() throws IOException { + byte[] raw = new byte[] {5, '-', '8', '5', '.', '0', 6, '2', '1', '9', '0', '.', '0', 3, '0', '.', '0'}; + DnsInput in = new DnsInput(raw); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rrFromWire(in); + fail("WireParseException not thrown"); + } catch (WireParseException e) { + } + } + } + + + public static + class Test_rdataFromString extends TestCase { + public + void test_basic() throws IOException { + Tokenizer t = new Tokenizer("10.45 171.121212 1010787"); + + GPOSRecord gr = new GPOSRecord(); + gr.rdataFromString(t, null); + assertEquals(new Double(10.45), new Double(gr.getLongitude())); + assertEquals(new Double(171.121212), new Double(gr.getLatitude())); + assertEquals(new Double(1010787), new Double(gr.getAltitude())); + } + + public + void test_longitude_toosmall() throws IOException { + Tokenizer t = new Tokenizer("-100.390 171.121212 1010787"); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rdataFromString(t, null); + fail("IOException not thrown"); + } catch (IOException e) { + } + } + + public + void test_longitude_toobig() throws IOException { + Tokenizer t = new Tokenizer("90.00001 171.121212 1010787"); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rdataFromString(t, null); + fail("IOException not thrown"); + } catch (IOException e) { + } + } + + public + void test_latitude_toosmall() throws IOException { + Tokenizer t = new Tokenizer("0.0 -180.01 1010787"); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rdataFromString(t, null); + fail("IOException not thrown"); + } catch (IOException e) { + } + } + + public + void test_latitude_toobig() throws IOException { + Tokenizer t = new Tokenizer("0.0 180.01 1010787"); + + GPOSRecord gr = new GPOSRecord(); + try { + gr.rdataFromString(t, null); + fail("IOException not thrown"); + } catch (IOException e) { + } + } + + public + void test_invalid_string() throws IOException { + Tokenizer t = new Tokenizer("1.0 2.0 \\435"); + try { + GPOSRecord gr = new GPOSRecord(); + gr.rdataFromString(t, null); + } catch (TextParseException e) { + } + } + } + + public + void test_rrToString() throws TextParseException { + String exp = "\"10.45\" \"171.121212\" \"1010787.0\""; + + GPOSRecord gr = new GPOSRecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, 10.45, 171.121212, 1010787); + + StringBuilder sb = new StringBuilder(); + gr.rrToString(sb); + assertEquals(exp, sb.toString()); + } + + public + void test_rrToWire() throws TextParseException { + GPOSRecord gr = new GPOSRecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, -10.45, 120.0, 111.0); + + byte[] exp = new byte[] {6, '-', '1', '0', '.', '4', '5', 5, '1', '2', '0', '.', '0', 5, '1', '1', '1', '.', '0'}; + + DnsOutput out = new DnsOutput(); + gr.rrToWire(out, null, true); + + byte[] bar = out.toByteArray(); + + assertEquals(exp.length, bar.length); + for (int i = 0; i < exp.length; ++i) { + assertEquals("i=" + i, exp[i], bar[i]); + } + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_Ctor_6arg_doubles.class); + s.addTestSuite(Test_Ctor_6arg_Strings.class); + s.addTestSuite(Test_rrFromWire.class); + s.addTestSuite(Test_rdataFromString.class); + s.addTestSuite(GPOSRecordTest.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/records/HINFORecordTest.java b/test/dorkbox/network/dns/records/HINFORecordTest.java new file mode 100644 index 00000000..6241e2c9 --- /dev/null +++ b/test/dorkbox/network/dns/records/HINFORecordTest.java @@ -0,0 +1,200 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class HINFORecordTest extends TestCase { + public + void test_ctor_0arg() { + HINFORecord dr = new HINFORecord(); + assertNull(dr.getName()); + assertEquals(0, dr.getType()); + assertEquals(0, dr.getDClass()); + assertEquals(0, dr.getTTL()); + } + + public + void test_getObject() { + HINFORecord dr = new HINFORecord(); + DnsRecord r = dr.getObject(); + assertTrue(r instanceof HINFORecord); + } + + public + void test_ctor_5arg() throws TextParseException { + Name n = Name.fromString("The.Name."); + long ttl = 0xABCDL; + String cpu = "i686 Intel(R) Pentium(R) M processor 1.70GHz GenuineIntel GNU/Linux"; + String os = "Linux troy 2.6.10-gentoo-r6 #8 Wed Apr 6 21:25:04 MDT 2005"; + + HINFORecord dr = new HINFORecord(n, DnsClass.IN, ttl, cpu, os); + assertEquals(n, dr.getName()); + assertEquals(DnsClass.IN, dr.getDClass()); + assertEquals(DnsRecordType.HINFO, dr.getType()); + assertEquals(ttl, dr.getTTL()); + assertEquals(cpu, dr.getCPU()); + assertEquals(os, dr.getOS()); + } + + public + void test_ctor_5arg_invalid_CPU() throws TextParseException { + Name n = Name.fromString("The.Name."); + long ttl = 0xABCDL; + String cpu = "i686 Intel(R) Pentium(R) M \\256 processor 1.70GHz GenuineIntel GNU/Linux"; + String os = "Linux troy 2.6.10-gentoo-r6 #8 Wed Apr 6 21:25:04 MDT 2005"; + + try { + new HINFORecord(n, DnsClass.IN, ttl, cpu, os); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_ctor_5arg_invalid_OS() throws TextParseException { + Name n = Name.fromString("The.Name."); + long ttl = 0xABCDL; + String cpu = "i686 Intel(R) Pentium(R) M processor 1.70GHz GenuineIntel GNU/Linux"; + String os = "Linux troy 2.6.10-gentoo-r6 \\1 #8 Wed Apr 6 21:25:04 MDT 2005"; + + try { + new HINFORecord(n, DnsClass.IN, ttl, cpu, os); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_rrFromWire() throws IOException { + String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; + String os = "Linux troy 2.6.10-gentoo-r6"; + + byte[] raw = new byte[] {39, 'I', 'n', 't', 'e', 'l', '(', 'R', ')', ' ', 'P', 'e', 'n', 't', 'i', 'u', 'm', '(', 'R', ')', ' ', + 'M', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r', ' ', '1', '.', '7', '0', 'G', 'H', 'z', 27, 'L', + 'i', 'n', 'u', 'x', ' ', 't', 'r', 'o', 'y', ' ', '2', '.', '6', '.', '1', '0', '-', 'g', 'e', 'n', 't', + 'o', 'o', '-', 'r', '6'}; + + DnsInput in = new DnsInput(raw); + + HINFORecord dr = new HINFORecord(); + dr.rrFromWire(in); + assertEquals(cpu, dr.getCPU()); + assertEquals(os, dr.getOS()); + } + + public + void test_rdataFromString() throws IOException { + String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; + String os = "Linux troy 2.6.10-gentoo-r6"; + + Tokenizer t = new Tokenizer("\"" + cpu + "\" \"" + os + "\""); + + HINFORecord dr = new HINFORecord(); + dr.rdataFromString(t, null); + assertEquals(cpu, dr.getCPU()); + assertEquals(os, dr.getOS()); + } + + public + void test_rdataFromString_invalid_CPU() throws IOException { + String cpu = "Intel(R) Pentium(R) \\388 M processor 1.70GHz"; + String os = "Linux troy 2.6.10-gentoo-r6"; + + Tokenizer t = new Tokenizer("\"" + cpu + "\" \"" + os + "\""); + + HINFORecord dr = new HINFORecord(); + try { + dr.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_rdataFromString_invalid_OS() throws IOException { + String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; + + Tokenizer t = new Tokenizer("\"" + cpu + "\""); + + HINFORecord dr = new HINFORecord(); + try { + dr.rdataFromString(t, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } + + public + void test_rrToString() throws TextParseException { + String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; + String os = "Linux troy 2.6.10-gentoo-r6"; + + String exp = "\"" + cpu + "\" \"" + os + "\""; + + HINFORecord dr = new HINFORecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, cpu, os); + StringBuilder sb = new StringBuilder(); + dr.rrToString(sb); + assertEquals(exp, sb.toString()); + } + + public + void test_rrToWire() throws TextParseException { + String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; + String os = "Linux troy 2.6.10-gentoo-r6"; + byte[] raw = new byte[] {39, 'I', 'n', 't', 'e', 'l', '(', 'R', ')', ' ', 'P', 'e', 'n', 't', 'i', 'u', 'm', '(', 'R', ')', ' ', + 'M', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r', ' ', '1', '.', '7', '0', 'G', 'H', 'z', 27, 'L', + 'i', 'n', 'u', 'x', ' ', 't', 'r', 'o', 'y', ' ', '2', '.', '6', '.', '1', '0', '-', 'g', 'e', 'n', 't', + 'o', 'o', '-', 'r', '6'}; + + HINFORecord dr = new HINFORecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, cpu, os); + + DnsOutput out = new DnsOutput(); + dr.rrToWire(out, null, true); + + assertTrue(Arrays.equals(raw, out.toByteArray())); + } +} diff --git a/test/dorkbox/network/dns/records/HeaderTest.java b/test/dorkbox/network/dns/records/HeaderTest.java new file mode 100644 index 00000000..c2f1ea4b --- /dev/null +++ b/test/dorkbox/network/dns/records/HeaderTest.java @@ -0,0 +1,455 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.constants.DnsOpCode; +import dorkbox.network.dns.constants.DnsResponseCode; +import dorkbox.network.dns.constants.Flags; +import junit.framework.TestCase; + +public +class HeaderTest extends TestCase { + private Header m_h; + + @Override + public + void setUp() { + m_h = new Header(0xABCD); // 43981 + } + + public + void test_fixture_state() { + assertEquals(0xABCD, m_h.getID()); + + boolean[] flags = m_h.getFlags(); + for (int i = 0; i < flags.length; ++i) { + assertFalse(flags[i]); + } + assertEquals(0, m_h.getRcode()); + assertEquals(0, m_h.getOpcode()); + assertEquals(0, m_h.getCount(0)); + assertEquals(0, m_h.getCount(1)); + assertEquals(0, m_h.getCount(2)); + assertEquals(0, m_h.getCount(3)); + } + + public + void test_ctor_0arg() { + m_h = new Header(); + assertTrue(0 <= m_h.getID() && m_h.getID() < 0xFFFF); + + boolean[] flags = m_h.getFlags(); + for (int i = 0; i < flags.length; ++i) { + assertFalse(flags[i]); + } + assertEquals(0, m_h.getRcode()); + assertEquals(0, m_h.getOpcode()); + assertEquals(0, m_h.getCount(0)); + assertEquals(0, m_h.getCount(1)); + assertEquals(0, m_h.getCount(2)); + assertEquals(0, m_h.getCount(3)); + } + + public + void test_ctor_DNSInput() throws IOException { + byte[] raw = new byte[] {(byte) 0x12, (byte) 0xAB, // ID + (byte) 0x8F, (byte) 0xBD, // flags: 1 0001 1 1 1 1 011 1101 + (byte) 0x65, (byte) 0x1C, // QDCOUNT + (byte) 0x10, (byte) 0xF0, // ANCOUNT + (byte) 0x98, (byte) 0xBA, // NSCOUNT + (byte) 0x71, (byte) 0x90}; // ARCOUNT + + m_h = new Header(new DnsInput(raw)); + + assertEquals(0x12AB, m_h.getID()); + + boolean[] flags = m_h.getFlags(); + + assertTrue(flags[0]); + + assertEquals(1, m_h.getOpcode()); + + assertTrue(flags[5]); + + assertTrue(flags[6]); + + assertTrue(flags[7]); + + assertTrue(flags[8]); + + assertFalse(flags[9]); + assertTrue(flags[10]); + assertTrue(flags[11]); + + assertEquals(0xD, m_h.getRcode()); + + assertEquals(0x651C, m_h.getCount(0)); + assertEquals(0x10F0, m_h.getCount(1)); + assertEquals(0x98BA, m_h.getCount(2)); + assertEquals(0x7190, m_h.getCount(3)); + } + + public + void test_toWire() throws IOException { + byte[] raw = new byte[] {(byte) 0x12, (byte) 0xAB, // ID + (byte) 0x8F, (byte) 0xBD, // flags: 1 0001 1 1 1 1 011 1101 + (byte) 0x65, (byte) 0x1C, // QDCOUNT + (byte) 0x10, (byte) 0xF0, // ANCOUNT + (byte) 0x98, (byte) 0xBA, // NSCOUNT + (byte) 0x71, (byte) 0x90}; // ARCOUNT + + m_h = new Header(raw); + + DnsOutput dout = new DnsOutput(); + m_h.toWire(dout); + + byte[] out = dout.toByteArray(); + + assertEquals(12, out.length); + for (int i = 0; i < out.length; ++i) { + assertEquals(raw[i], out[i]); + } + + m_h.setOpcode(0xA); // 1010 + assertEquals(0xA, m_h.getOpcode()); + m_h.setRcode(0x7); // 0111 + + // flags is now: 1101 0111 1011 0111 + + raw[2] = (byte) 0xD7; + raw[3] = (byte) 0xB7; + + out = m_h.toWire(); + + assertEquals(12, out.length); + for (int i = 0; i < out.length; ++i) { + assertEquals("i=" + i, raw[i], out[i]); + } + } + + public + void test_flags() { + m_h.setFlag(0); + m_h.setFlag(5); + assertTrue(m_h.getFlag(0)); + assertTrue(m_h.getFlags()[0]); + assertTrue(m_h.getFlag(5)); + assertTrue(m_h.getFlags()[5]); + + m_h.unsetFlag(0); + assertFalse(m_h.getFlag(0)); + assertFalse(m_h.getFlags()[0]); + assertTrue(m_h.getFlag(5)); + assertTrue(m_h.getFlags()[5]); + + m_h.unsetFlag(5); + assertFalse(m_h.getFlag(0)); + assertFalse(m_h.getFlags()[0]); + assertFalse(m_h.getFlag(5)); + assertFalse(m_h.getFlags()[5]); + + boolean[] flags = m_h.getFlags(); + for (int i = 0; i < flags.length; ++i) { + if ((i > 0 && i < 5) || i > 11) { + continue; + } + assertFalse(flags[i]); + } + } + + public + void test_flags_invalid() { + try { + m_h.setFlag(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setFlag(1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setFlag(16); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.unsetFlag(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.unsetFlag(13); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.unsetFlag(16); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.getFlag(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.getFlag(4); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.getFlag(16); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_ID() { + assertEquals(0xABCD, m_h.getID()); + + m_h = new Header(); + + int id = m_h.getID(); + assertEquals(id, m_h.getID()); + assertTrue(id >= 0 && id < 0xffff); + + m_h.setID(0xDCBA); + assertEquals(0xDCBA, m_h.getID()); + } + + public + void test_setID_invalid() { + try { + m_h.setID(0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setID(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_Rcode() { + assertEquals(0, m_h.getRcode()); + + m_h.setRcode(0xA); // 1010 + assertEquals(0xA, m_h.getRcode()); + for (int i = 0; i < 12; ++i) { + if ((i > 0 && i < 5) || i > 11) { + continue; + } + assertFalse(m_h.getFlag(i)); + } + } + + public + void test_setRcode_invalid() { + try { + m_h.setRcode(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setRcode(0x100); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_Opcode() { + assertEquals(0, m_h.getOpcode()); + + m_h.setOpcode(0xE); // 1110 + assertEquals(0xE, m_h.getOpcode()); + + assertFalse(m_h.getFlag(0)); + for (int i = 5; i < 12; ++i) { + assertFalse(m_h.getFlag(i)); + } + assertEquals(0, m_h.getRcode()); + } + + public + void test_setOpcode_invalid() { + try { + m_h.setOpcode(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setOpcode(0x100); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_Count() { + m_h.setCount(2, 0x1E); + assertEquals(0, m_h.getCount(0)); + assertEquals(0, m_h.getCount(1)); + assertEquals(0x1E, m_h.getCount(2)); + assertEquals(0, m_h.getCount(3)); + + m_h.incCount(0); + assertEquals(1, m_h.getCount(0)); + + m_h.decCount(2); + assertEquals(0x1E - 1, m_h.getCount(2)); + } + + public + void test_setCount_invalid() { + try { + m_h.setCount(-1, 0); + fail("ArrayIndexOutOfBoundsException not thrown"); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + m_h.setCount(4, 0); + fail("ArrayIndexOutOfBoundsException not thrown"); + } catch (ArrayIndexOutOfBoundsException e) { + } + + try { + m_h.setCount(0, -1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_h.setCount(3, 0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_getCount_invalid() { + try { + m_h.getCount(-1); + fail("ArrayIndexOutOfBoundsException not thrown"); + } catch (ArrayIndexOutOfBoundsException e) { + } + try { + m_h.getCount(4); + fail("ArrayIndexOutOfBoundsException not thrown"); + } catch (ArrayIndexOutOfBoundsException e) { + } + } + + public + void test_incCount_invalid() { + m_h.setCount(1, 0xFFFF); + try { + m_h.incCount(1); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + } + + public + void test_decCount_invalid() { + m_h.setCount(2, 0); + try { + m_h.decCount(2); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + } + + public + void test_toString() { + m_h.setOpcode(DnsOpCode.STATUS); + m_h.setRcode(DnsResponseCode.NXDOMAIN); + m_h.setFlag(Flags.QR); // qr + m_h.setFlag(Flags.RD); // rd + m_h.setFlag(Flags.RA); // ra + m_h.setFlag(Flags.CD); // cd + m_h.setCount(1, 0xFF); + m_h.setCount(2, 0x0A); + + + String text = m_h.toString(); + + assertFalse(text.indexOf("id: 43981") == -1); + assertFalse(text.indexOf("opcode: STATUS") == -1); + assertFalse(text.indexOf("status: NXDOMAIN") == -1); + assertFalse(text.indexOf(" qr ") == -1); + assertFalse(text.indexOf(" rd ") == -1); + assertFalse(text.indexOf(" ra ") == -1); + assertFalse(text.indexOf(" cd ") == -1); + assertFalse(text.indexOf("qd: 0 ") == -1); + assertFalse(text.indexOf("an: 255 ") == -1); + assertFalse(text.indexOf("au: 10 ") == -1); + assertFalse(text.indexOf("ad: 0 ") == -1); + } + + public + void test_clone() { + m_h.setOpcode(DnsOpCode.IQUERY); + m_h.setRcode(DnsResponseCode.SERVFAIL); + m_h.setFlag(Flags.QR); // qr + m_h.setFlag(Flags.RD); // rd + m_h.setFlag(Flags.RA); // ra + m_h.setFlag(Flags.CD); // cd + m_h.setCount(1, 0xFF); + m_h.setCount(2, 0x0A); + + Header h2 = (Header) m_h.clone(); + + assertNotSame(m_h, h2); + assertEquals(m_h.getID(), h2.getID()); + for (int i = 0; i < 16; ++i) { + if ((i > 0 && i < 5) || i > 11) { + continue; + } + assertEquals(m_h.getFlag(i), h2.getFlag(i)); + } + for (int i = 0; i < 4; ++i) { + assertEquals(m_h.getCount(i), h2.getCount(i)); + } + } +} diff --git a/test/dorkbox/network/dns/records/KEYBaseTest.java b/test/dorkbox/network/dns/records/KEYBaseTest.java new file mode 100644 index 00000000..d8a4e02c --- /dev/null +++ b/test/dorkbox/network/dns/records/KEYBaseTest.java @@ -0,0 +1,202 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Options; +import dorkbox.network.dns.utils.Tokenizer; +import dorkbox.util.Base64Fast; +import junit.framework.TestCase; + +public +class KEYBaseTest extends TestCase { + private static + class TestClass extends KEYBase { + public + TestClass() {} + + public + TestClass(Name name, int type, int dclass, long ttl, int flags, int proto, int alg, byte[] key) { + super(name, type, dclass, ttl, flags, proto, alg, key); + } + + @Override + public + DnsRecord getObject() { + return null; + } + + @Override + void rdataFromString(Tokenizer st, Name origin) throws IOException { + } + } + + public + void test_ctor() throws TextParseException { + TestClass tc = new TestClass(); + assertEquals(0, tc.getFlags()); + assertEquals(0, tc.getProtocol()); + assertEquals(0, tc.getAlgorithm()); + assertNull(tc.getKey()); + + Name n = Name.fromString("my.name."); + byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; + + tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, key); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.KEY, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(100L, tc.getTTL()); + assertEquals(0xFF, tc.getFlags()); + assertEquals(0xF, tc.getProtocol()); + assertEquals(0xE, tc.getAlgorithm()); + assertTrue(Arrays.equals(key, tc.getKey())); + } + + public + void test_rrFromWire() throws IOException { + byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x19, 1, 2, 3, 4, 5}; + DnsInput in = new DnsInput(raw); + + TestClass tc = new TestClass(); + tc.rrFromWire(in); + + assertEquals(0xABCD, tc.getFlags()); + assertEquals(0xEF, tc.getProtocol()); + assertEquals(0x19, tc.getAlgorithm()); + assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5}, tc.getKey())); + + + raw = new byte[] {(byte) 0xBA, (byte) 0xDA, (byte) 0xFF, (byte) 0x28}; + in = new DnsInput(raw); + + tc = new TestClass(); + tc.rrFromWire(in); + + assertEquals(0xBADA, tc.getFlags()); + assertEquals(0xFF, tc.getProtocol()); + assertEquals(0x28, tc.getAlgorithm()); + assertNull(tc.getKey()); + } + + public + void test_rrToString() throws IOException, TextParseException { + Name n = Name.fromString("my.name."); + byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; + + TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, null); + + StringBuilder sb = new StringBuilder(); + tc.rrToString(sb); + String out = sb.toString(); + + assertEquals("255 15 14", out); + + tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, key); + + sb = new StringBuilder(); + tc.rrToString(sb); + out = sb.toString(); + + assertEquals("255 15 14 " + Base64Fast.encode2(key), out); + + Options.set("multiline"); + + sb = new StringBuilder(); + tc.rrToString(sb); + out = sb.toString(); + + assertEquals("255 15 14 (\n\t" + Base64Fast.encode2(key) + " ) ; key_tag = 18509", out); + + Options.unset("multiline"); + } + + public + void test_getFootprint() throws TextParseException { + Name n = Name.fromString("my.name."); + byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; + + TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, DNSSEC.Algorithm.RSAMD5, key); + + int foot = tc.getFootprint(); + // second-to-last and third-to-last bytes of key for RSAMD5 + assertEquals(0xD0E, foot); + assertEquals(foot, tc.getFootprint()); + + // key with an odd number of bytes + tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0x89AB, 0xCD, 0xEF, new byte[] {0x12, 0x34, 0x56}); + + // rrToWire gives: { 0x89, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56 } + // 89AB + CDEF + 1234 + 5600 = 1BCFE + // 1BFCE + 1 = 1BFCF & FFFF = BFCF + foot = tc.getFootprint(); + assertEquals(0xBFCF, foot); + assertEquals(foot, tc.getFootprint()); + + // empty + tc = new TestClass(); + assertEquals(0, tc.getFootprint()); + } + + public + void test_rrToWire() throws IOException, TextParseException { + Name n = Name.fromString("my.name."); + byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; + + TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0x7689, 0xAB, 0xCD, key); + + byte[] exp = new byte[] {(byte) 0x76, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + + DnsOutput o = new DnsOutput(); + + // canonical + tc.rrToWire(o, null, true); + assertTrue(Arrays.equals(exp, o.toByteArray())); + + // not canonical + o = new DnsOutput(); + tc.rrToWire(o, null, false); + assertTrue(Arrays.equals(exp, o.toByteArray())); + } +} diff --git a/test/dorkbox/network/dns/records/KEYRecordTest.java b/test/dorkbox/network/dns/records/KEYRecordTest.java new file mode 100644 index 00000000..f42d1c3a --- /dev/null +++ b/test/dorkbox/network/dns/records/KEYRecordTest.java @@ -0,0 +1,202 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class KEYRecordTest extends TestCase { + public + void test_ctor_0arg() throws UnknownHostException { + KEYRecord ar = new KEYRecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertEquals(0, ar.getAlgorithm()); + assertEquals(0, ar.getFlags()); + assertEquals(0, ar.getFootprint()); + assertEquals(0, ar.getProtocol()); + assertNull(ar.getKey()); + } + + public + void test_getObject() { + KEYRecord ar = new KEYRecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof KEYRecord); + } + + public + void test_ctor_7arg() throws TextParseException { + Name n = Name.fromString("My.Absolute.Name."); + Name r = Name.fromString("My.Relative.Name"); + byte[] key = new byte[] {0, 1, 3, 5, 7, 9}; + + KEYRecord kr = new KEYRecord(n, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); + assertEquals(n, kr.getName()); + assertEquals(DnsRecordType.KEY, kr.getType()); + assertEquals(DnsClass.IN, kr.getDClass()); + assertEquals(0x24AC, kr.getTTL()); + assertEquals(0x9832, kr.getFlags()); + assertEquals(0x12, kr.getProtocol()); + assertEquals(0x67, kr.getAlgorithm()); + assertTrue(Arrays.equals(key, kr.getKey())); + + // a relative name + try { + new KEYRecord(r, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + } + + public + void test_Protocol_string() { + // a regular one + assertEquals("DNSSEC", KEYRecord.Protocol.string(KEYRecord.Protocol.DNSSEC)); + // a unassigned value within range + assertEquals("254", KEYRecord.Protocol.string(0xFE)); + // too low + try { + KEYRecord.Protocol.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + // too high + try { + KEYRecord.Protocol.string(0x100); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_Protocol_value() { + // a regular one + assertEquals(KEYRecord.Protocol.IPSEC, KEYRecord.Protocol.value("IPSEC")); + // a unassigned value within range + assertEquals(254, KEYRecord.Protocol.value("254")); + // too low + assertEquals(-1, KEYRecord.Protocol.value("-2")); + // too high + assertEquals(-1, KEYRecord.Protocol.value("256")); + } + + public + void test_Flags_value() { + // numeric + + // lower bound + assertEquals(-1, KEYRecord.Flags.value("-2")); + assertEquals(0, KEYRecord.Flags.value("0")); + // in the middle + assertEquals(0xAB35, KEYRecord.Flags.value(0xAB35 + "")); + // upper bound + assertEquals(0xFFFF, KEYRecord.Flags.value(0xFFFF + "")); + assertEquals(-1, KEYRecord.Flags.value(0x10000 + "")); + + // textual + + // single + assertEquals(KEYRecord.Flags.EXTEND, KEYRecord.Flags.value("EXTEND")); + // single invalid + assertEquals(-1, KEYRecord.Flags.value("NOT_A_VALID_NAME")); + // multiple + assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.ZONE, KEYRecord.Flags.value("NOAUTH|ZONE|FLAG10")); + // multiple invalid + assertEquals(-1, KEYRecord.Flags.value("NOAUTH|INVALID_NAME|FLAG10")); + // pathological + assertEquals(0, KEYRecord.Flags.value("|")); + } + + public + void test_rdataFromString() throws IOException, TextParseException { + // basic + KEYRecord kr = new KEYRecord(); + Tokenizer st = new Tokenizer("NOAUTH|ZONE|FLAG10 EMAIL RSASHA1 AQIDBAUGBwgJ"); + kr.rdataFromString(st, null); + assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.ZONE, kr.getFlags()); + assertEquals(KEYRecord.Protocol.EMAIL, kr.getProtocol()); + assertEquals(DNSSEC.Algorithm.RSASHA1, kr.getAlgorithm()); + assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, kr.getKey())); + + // basic w/o key + kr = new KEYRecord(); + st = new Tokenizer("NOAUTH|NOKEY|FLAG10 TLS 3"); + kr.rdataFromString(st, null); + assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.NOKEY, kr.getFlags()); + assertEquals(KEYRecord.Protocol.TLS, kr.getProtocol()); + assertEquals(3, kr.getAlgorithm()); // Was ECC + assertNull(kr.getKey()); + + // invalid flags + kr = new KEYRecord(); + st = new Tokenizer("NOAUTH|ZONE|JUNK EMAIL RSASHA1 AQIDBAUGBwgJ"); + try { + kr.rdataFromString(st, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + // invalid protocol + kr = new KEYRecord(); + st = new Tokenizer("NOAUTH|ZONE RSASHA1 3 AQIDBAUGBwgJ"); + try { + kr.rdataFromString(st, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + + // invalid algorithm + kr = new KEYRecord(); + st = new Tokenizer("NOAUTH|ZONE EMAIL ZONE AQIDBAUGBwgJ"); + try { + kr.rdataFromString(st, null); + fail("TextParseException not thrown"); + } catch (TextParseException e) { + } + } +} diff --git a/test/dorkbox/network/dns/records/KXRecordTest.java b/test/dorkbox/network/dns/records/KXRecordTest.java new file mode 100644 index 00000000..5213a373 --- /dev/null +++ b/test/dorkbox/network/dns/records/KXRecordTest.java @@ -0,0 +1,66 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class KXRecordTest extends TestCase { + public + void test_getObject() { + KXRecord d = new KXRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof KXRecord); + } + + public + void test_ctor_5arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.OtherName."); + + KXRecord d = new KXRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.KX, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(0xF1, d.getPreference()); + assertEquals(m, d.getTarget()); + assertEquals(m, d.getAdditionalName()); + } +} diff --git a/test/dorkbox/network/dns/records/MBRecordTest.java b/test/dorkbox/network/dns/records/MBRecordTest.java new file mode 100644 index 00000000..9cf1c26f --- /dev/null +++ b/test/dorkbox/network/dns/records/MBRecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MBRecordTest extends TestCase { + public + void test_ctor_0arg() { + MBRecord d = new MBRecord(); + assertNull(d.getName()); + assertNull(d.getAdditionalName()); + assertNull(d.getMailbox()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + MBRecord d = new MBRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MB, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getAdditionalName()); + assertEquals(a, d.getMailbox()); + } + + public + void test_getObject() { + MBRecord d = new MBRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MBRecord); + } +} diff --git a/test/dorkbox/network/dns/records/MDRecordTest.java b/test/dorkbox/network/dns/records/MDRecordTest.java new file mode 100644 index 00000000..7ab3258a --- /dev/null +++ b/test/dorkbox/network/dns/records/MDRecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MDRecordTest extends TestCase { + public + void test_ctor_0arg() { + MDRecord d = new MDRecord(); + assertNull(d.getName()); + assertNull(d.getAdditionalName()); + assertNull(d.getMailAgent()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + MDRecord d = new MDRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MD, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getAdditionalName()); + assertEquals(a, d.getMailAgent()); + } + + public + void test_getObject() { + MDRecord d = new MDRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MDRecord); + } +} diff --git a/test/dorkbox/network/dns/records/MFRecordTest.java b/test/dorkbox/network/dns/records/MFRecordTest.java new file mode 100644 index 00000000..ba735940 --- /dev/null +++ b/test/dorkbox/network/dns/records/MFRecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MFRecordTest extends TestCase { + public + void test_ctor_0arg() { + MFRecord d = new MFRecord(); + assertNull(d.getName()); + assertNull(d.getAdditionalName()); + assertNull(d.getMailAgent()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + MFRecord d = new MFRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MF, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getAdditionalName()); + assertEquals(a, d.getMailAgent()); + } + + public + void test_getObject() { + MFRecord d = new MFRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MFRecord); + } +} diff --git a/test/dorkbox/network/dns/records/MGRecordTest.java b/test/dorkbox/network/dns/records/MGRecordTest.java new file mode 100644 index 00000000..8c5b28b7 --- /dev/null +++ b/test/dorkbox/network/dns/records/MGRecordTest.java @@ -0,0 +1,71 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MGRecordTest extends TestCase { + public + void test_ctor_0arg() { + MGRecord d = new MGRecord(); + assertNull(d.getName()); + assertNull(d.getMailbox()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + MGRecord d = new MGRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MG, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getMailbox()); + } + + public + void test_getObject() { + MGRecord d = new MGRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MGRecord); + } +} diff --git a/test/dorkbox/network/dns/records/MRRecordTest.java b/test/dorkbox/network/dns/records/MRRecordTest.java new file mode 100644 index 00000000..d2c2651b --- /dev/null +++ b/test/dorkbox/network/dns/records/MRRecordTest.java @@ -0,0 +1,71 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MRRecordTest extends TestCase { + public + void test_ctor_0arg() { + MRRecord d = new MRRecord(); + assertNull(d.getName()); + assertNull(d.getNewName()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + MRRecord d = new MRRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MR, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getNewName()); + } + + public + void test_getObject() { + MRRecord d = new MRRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MRRecord); + } +} diff --git a/test/dorkbox/network/dns/records/MXRecordTest.java b/test/dorkbox/network/dns/records/MXRecordTest.java new file mode 100644 index 00000000..a998f20b --- /dev/null +++ b/test/dorkbox/network/dns/records/MXRecordTest.java @@ -0,0 +1,91 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.util.Arrays; + +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class MXRecordTest extends TestCase { + public + void test_getObject() { + MXRecord d = new MXRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof MXRecord); + } + + public + void test_ctor_5arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.OtherName."); + + MXRecord d = new MXRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.MX, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(0xF1, d.getPriority()); + assertEquals(m, d.getTarget()); + assertEquals(m, d.getAdditionalName()); + } + + public + void test_rrToWire() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("M.O.n."); + + MXRecord mr = new MXRecord(n, DnsClass.IN, 0xB12FL, 0x1F2B, m); + + // canonical + DnsOutput dout = new DnsOutput(); + mr.rrToWire(dout, null, true); + byte[] out = dout.toByteArray(); + byte[] exp = new byte[] {0x1F, 0x2B, 1, 'm', 1, 'o', 1, 'n', 0}; + assertTrue(Arrays.equals(exp, out)); + + // case sensitive + dout = new DnsOutput(); + mr.rrToWire(dout, null, false); + out = dout.toByteArray(); + exp = new byte[] {0x1F, 0x2B, 1, 'M', 1, 'O', 1, 'n', 0}; + assertTrue(Arrays.equals(exp, out)); + } +} diff --git a/test/dorkbox/network/dns/records/MessageTest.java b/test/dorkbox/network/dns/records/MessageTest.java new file mode 100644 index 00000000..5fd4f14f --- /dev/null +++ b/test/dorkbox/network/dns/records/MessageTest.java @@ -0,0 +1,124 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsOpCode; +import dorkbox.network.dns.constants.DnsSection; +import dorkbox.network.dns.constants.Flags; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class MessageTest { + public static + class Test_init extends TestCase { + public + void test_0arg() { + DnsMessage m = new DnsMessage(); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(0))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(1))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(2))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(3))); + try { + m.getSectionArray(4); + fail("IndexOutOfBoundsException not thrown"); + } catch (IndexOutOfBoundsException ignored) { + } + Header h = m.getHeader(); + assertEquals(0, h.getCount(0)); + assertEquals(0, h.getCount(1)); + assertEquals(0, h.getCount(2)); + assertEquals(0, h.getCount(3)); + } + + public + void test_1arg() { + DnsMessage m = new DnsMessage(10); + assertEquals(new Header(10).toString(), + m.getHeader() + .toString()); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(0))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(1))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(2))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(3))); + try { + m.getSectionArray(4); + fail("IndexOutOfBoundsException not thrown"); + } catch (IndexOutOfBoundsException ignored) { + } + Header h = m.getHeader(); + assertEquals(0, h.getCount(0)); + assertEquals(0, h.getCount(1)); + assertEquals(0, h.getCount(2)); + assertEquals(0, h.getCount(3)); + } + + public + void test_newQuery() throws TextParseException, UnknownHostException { + Name n = Name.fromString("The.Name."); + ARecord ar = new ARecord(n, DnsClass.IN, 1, InetAddress.getByName("192.168.101.110")); + + DnsMessage m = DnsMessage.newQuery(ar); + assertTrue(Arrays.equals(new DnsRecord[] {ar}, m.getSectionArray(DnsSection.QUESTION))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.ANSWER))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.AUTHORITY))); + assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.ADDITIONAL))); + + Header h = m.getHeader(); + assertEquals(1, h.getCount(DnsSection.QUESTION)); + assertEquals(0, h.getCount(DnsSection.ANSWER)); + assertEquals(0, h.getCount(DnsSection.AUTHORITY)); + assertEquals(0, h.getCount(DnsSection.ADDITIONAL)); + assertEquals(DnsOpCode.QUERY, h.getOpcode()); + assertEquals(true, h.getFlag(Flags.RD)); + } + + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_init.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/records/MnemonicTest.java b/test/dorkbox/network/dns/records/MnemonicTest.java new file mode 100644 index 00000000..581940dd --- /dev/null +++ b/test/dorkbox/network/dns/records/MnemonicTest.java @@ -0,0 +1,314 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +// Mnemonic has package-level access. + +import dorkbox.network.dns.Mnemonic; +import junit.framework.TestCase; + +public +class MnemonicTest extends TestCase { + private Mnemonic m_mn; + + public + MnemonicTest(String name) { + super(name); + } + + @Override + public + void setUp() { + m_mn = new Mnemonic(MnemonicTest.class.getName() + " UPPER", Mnemonic.CASE_UPPER); + } + + public + void test_toInteger() { + Integer i = Mnemonic.toInteger(64); + assertEquals(new Integer(64), i); + Integer i2 = Mnemonic.toInteger(64); + assertEquals(i, i2); + assertNotSame(i, i2); + + i = Mnemonic.toInteger(-1); + assertEquals(new Integer(-1), i); + i2 = Mnemonic.toInteger(-1); + assertEquals(i, i2); + assertNotSame(i, i2); + + i = Mnemonic.toInteger(0); + assertEquals(new Integer(0), i); + i2 = Mnemonic.toInteger(0); + assertEquals(i, i2); + assertSame(i, i2); + + i = Mnemonic.toInteger(63); + assertEquals(new Integer(63), i); + i2 = Mnemonic.toInteger(63); + assertEquals(i, i2); + assertSame(i, i2); + } + + public + void test_no_maximum() { + try { + m_mn.check(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_mn.check(0); + } catch (IllegalArgumentException e) { + fail(e.getMessage()); + } + try { + m_mn.check(Integer.MAX_VALUE); + } catch (IllegalArgumentException e) { + fail(e.getMessage()); + } + + m_mn.setNumericAllowed(true); + + int val = m_mn.getValue("-2"); + assertEquals(-1, val); + + val = m_mn.getValue("0"); + assertEquals(0, val); + + val = m_mn.getValue("" + Integer.MAX_VALUE); + assertEquals(Integer.MAX_VALUE, val); + } + + public + void test_setMaximum() { + m_mn.setMaximum(15); + try { + m_mn.check(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + try { + m_mn.check(0); + } catch (IllegalArgumentException e) { + fail(e.getMessage()); + } + try { + m_mn.check(15); + } catch (IllegalArgumentException e) { + fail(e.getMessage()); + } + try { + m_mn.check(16); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // need numericok to exercise the usage of max in parseNumeric + m_mn.setNumericAllowed(true); + + int val = m_mn.getValue("-2"); + assertEquals(-1, val); + + val = m_mn.getValue("0"); + assertEquals(0, val); + + val = m_mn.getValue("15"); + assertEquals(15, val); + + val = m_mn.getValue("16"); + assertEquals(-1, val); + } + + public + void test_setPrefix() { + final String prefix = "A mixed CASE Prefix".toUpperCase(); + m_mn.setPrefix(prefix); + + String out = m_mn.getText(10); + assertEquals(prefix + "10", out); + + int i = m_mn.getValue(out); + assertEquals(10, i); + } + + public + void test_basic_operation() { + // setUp creates Mnemonic with CASE_UPPER + m_mn.add(10, "Ten"); + m_mn.add(20, "Twenty"); + m_mn.addAlias(20, "Veinte"); + m_mn.add(30, "Thirty"); + + String text = m_mn.getText(10); + assertEquals("TEN", text); + + text = m_mn.getText(20); + assertEquals("TWENTY", text); + + text = m_mn.getText(30); + assertEquals("THIRTY", text); + + text = m_mn.getText(40); + assertEquals("40", text); + + int value = m_mn.getValue("tEn"); + assertEquals(10, value); + + value = m_mn.getValue("twenty"); + assertEquals(20, value); + + value = m_mn.getValue("VeiNTe"); + assertEquals(20, value); + + value = m_mn.getValue("THIRTY"); + assertEquals(30, value); + } + + public + void test_basic_operation_lower() { + m_mn = new Mnemonic(MnemonicTest.class.getName() + " LOWER", Mnemonic.CASE_LOWER); + m_mn.add(10, "Ten"); + m_mn.add(20, "Twenty"); + m_mn.addAlias(20, "Veinte"); + m_mn.add(30, "Thirty"); + + String text = m_mn.getText(10); + assertEquals("ten", text); + + text = m_mn.getText(20); + assertEquals("twenty", text); + + text = m_mn.getText(30); + assertEquals("thirty", text); + + text = m_mn.getText(40); + assertEquals("40", text); + + int value = m_mn.getValue("tEn"); + assertEquals(10, value); + + value = m_mn.getValue("twenty"); + assertEquals(20, value); + + value = m_mn.getValue("VeiNTe"); + assertEquals(20, value); + + value = m_mn.getValue("THIRTY"); + assertEquals(30, value); + } + + public + void test_basic_operation_sensitive() { + m_mn = new Mnemonic(MnemonicTest.class.getName() + " SENSITIVE", Mnemonic.CASE_SENSITIVE); + m_mn.add(10, "Ten"); + m_mn.add(20, "Twenty"); + m_mn.addAlias(20, "Veinte"); + m_mn.add(30, "Thirty"); + + String text = m_mn.getText(10); + assertEquals("Ten", text); + + text = m_mn.getText(20); + assertEquals("Twenty", text); + + text = m_mn.getText(30); + assertEquals("Thirty", text); + + text = m_mn.getText(40); + assertEquals("40", text); + + int value = m_mn.getValue("Ten"); + assertEquals(10, value); + + value = m_mn.getValue("twenty"); + assertEquals(-1, value); + + value = m_mn.getValue("Twenty"); + assertEquals(20, value); + + value = m_mn.getValue("VEINTE"); + assertEquals(-1, value); + + value = m_mn.getValue("Veinte"); + assertEquals(20, value); + + value = m_mn.getValue("Thirty"); + assertEquals(30, value); + } + + public + void test_invalid_numeric() { + m_mn.setNumericAllowed(true); + int value = m_mn.getValue("Not-A-Number"); + assertEquals(-1, value); + } + + public + void test_addAll() { + m_mn.add(10, "Ten"); + m_mn.add(20, "Twenty"); + + Mnemonic mn2 = new Mnemonic("second test Mnemonic", Mnemonic.CASE_UPPER); + mn2.add(20, "Twenty"); + mn2.addAlias(20, "Veinte"); + mn2.add(30, "Thirty"); + + m_mn.addAll(mn2); + + String text = m_mn.getText(10); + assertEquals("TEN", text); + + text = m_mn.getText(20); + assertEquals("TWENTY", text); + + text = m_mn.getText(30); + assertEquals("THIRTY", text); + + text = m_mn.getText(40); + assertEquals("40", text); + + int value = m_mn.getValue("tEn"); + assertEquals(10, value); + + value = m_mn.getValue("twenty"); + assertEquals(20, value); + + value = m_mn.getValue("VeiNTe"); + assertEquals(20, value); + + value = m_mn.getValue("THIRTY"); + assertEquals(30, value); + } +} diff --git a/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java b/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java new file mode 100644 index 00000000..e774b12e --- /dev/null +++ b/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java @@ -0,0 +1,71 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class NSAP_PTRRecordTest extends TestCase { + public + void test_ctor_0arg() { + NSAP_PTRRecord d = new NSAP_PTRRecord(); + assertNull(d.getName()); + assertNull(d.getTarget()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + NSAP_PTRRecord d = new NSAP_PTRRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.NSAP_PTR, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getTarget()); + } + + public + void test_getObject() { + NSAP_PTRRecord d = new NSAP_PTRRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof NSAP_PTRRecord); + } +} diff --git a/test/dorkbox/network/dns/records/NSRecordTest.java b/test/dorkbox/network/dns/records/NSRecordTest.java new file mode 100644 index 00000000..b6c2c449 --- /dev/null +++ b/test/dorkbox/network/dns/records/NSRecordTest.java @@ -0,0 +1,73 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class NSRecordTest extends TestCase { + public + void test_ctor_0arg() { + NSRecord d = new NSRecord(); + assertNull(d.getName()); + assertNull(d.getTarget()); + assertNull(d.getAdditionalName()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name a = Name.fromString("my.alias."); + + NSRecord d = new NSRecord(n, DnsClass.IN, 0xABCDEL, a); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.NS, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(a, d.getTarget()); + assertEquals(a, d.getAdditionalName()); + } + + public + void test_getObject() { + NSRecord d = new NSRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof NSRecord); + } +} diff --git a/test/dorkbox/network/dns/records/OPTRecordTest.java b/test/dorkbox/network/dns/records/OPTRecordTest.java new file mode 100644 index 00000000..137fb21d --- /dev/null +++ b/test/dorkbox/network/dns/records/OPTRecordTest.java @@ -0,0 +1,39 @@ +package dorkbox.network.dns.records; + +import junit.framework.TestCase; + +public +class OPTRecordTest extends TestCase { + + private static final int DEFAULT_EDNS_RCODE = 0; + private static final int DEFAULT_EDNS_VERSION = 0; + private static final int DEFAULT_PAYLOAD_SIZE = 1024; + + public + void testForNoEqualityWithDifferentEDNS_Versions() { + final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, 0); + final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, 1); + assertNotEqual(optRecordOne, optRecordTwo); + } + + private + void assertNotEqual(final OPTRecord optRecordOne, final OPTRecord optRecordTwo) { + assertTrue("Expecting no equality of " + optRecordOne + " compared to " + optRecordTwo, !optRecordOne.equals(optRecordTwo)); + assertTrue("Expecting no equality of " + optRecordTwo + " compared to " + optRecordOne, !optRecordTwo.equals(optRecordOne)); + } + + public + void testForNoEqualityWithDifferentEDNS_RCodes() { + final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, 0, DEFAULT_EDNS_VERSION); + final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, 1, DEFAULT_EDNS_VERSION); + assertNotEqual(optRecordOne, optRecordTwo); + } + + public + void testForEquality() { + final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, DEFAULT_EDNS_VERSION); + final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, DEFAULT_EDNS_VERSION); + assertEquals(optRecordOne, optRecordTwo); + assertEquals(optRecordTwo, optRecordOne); + } +} diff --git a/test/dorkbox/network/dns/records/RRsetTest.java b/test/dorkbox/network/dns/records/RRsetTest.java new file mode 100644 index 00000000..2b9c0b67 --- /dev/null +++ b/test/dorkbox/network/dns/records/RRsetTest.java @@ -0,0 +1,343 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Date; +import java.util.Iterator; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class RRsetTest extends TestCase { + private RRset m_rs; + Name m_name, m_name2; + long m_ttl; + ARecord m_a1, m_a2; + RRSIGRecord m_s1, m_s2; + + @Override + public + void setUp() throws TextParseException, UnknownHostException { + m_rs = new RRset(); + m_name = Name.fromString("this.is.a.test."); + m_name2 = Name.fromString("this.is.another.test."); + m_ttl = 0xABCDL; + m_a1 = new ARecord(m_name, DnsClass.IN, m_ttl, InetAddress.getByName("192.169.232.11")); + m_a2 = new ARecord(m_name, DnsClass.IN, m_ttl + 1, InetAddress.getByName("192.169.232.12")); + + m_s1 = new RRSIGRecord(m_name, + DnsClass.IN, + m_ttl, + DnsRecordType.A, + 0xF, + 0xABCDEL, + new Date(), + new Date(), + 0xA, + m_name, + new byte[0]); + m_s2 = new RRSIGRecord(m_name, + DnsClass.IN, + m_ttl, + DnsRecordType.A, + 0xF, + 0xABCDEL, + new Date(), + new Date(), + 0xA, + m_name2, + new byte[0]); + } + + public + void test_ctor_0arg() { + assertEquals(0, m_rs.size()); + try { + m_rs.getDClass(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + try { + m_rs.getType(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + try { + m_rs.getTTL(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + try { + m_rs.getName(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + try { + m_rs.first(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + } + + assertEquals("{empty}", m_rs.toString()); + + Iterator itr = m_rs.rrs(); + assertNotNull(itr); + assertFalse(itr.hasNext()); + + itr = m_rs.sigs(); + assertNotNull(itr); + assertFalse(itr.hasNext()); + } + + public + void test_basics() throws TextParseException, UnknownHostException { + m_rs.addRR(m_a1); + + assertEquals(1, m_rs.size()); + assertEquals(DnsClass.IN, m_rs.getDClass()); + assertEquals(m_a1, m_rs.first()); + assertEquals(m_name, m_rs.getName()); + assertEquals(m_ttl, m_rs.getTTL()); + assertEquals(DnsRecordType.A, m_rs.getType()); + + // add it again, and make sure nothing changed + m_rs.addRR(m_a1); + + assertEquals(1, m_rs.size()); + assertEquals(DnsClass.IN, m_rs.getDClass()); + assertEquals(m_a1, m_rs.first()); + assertEquals(m_name, m_rs.getName()); + assertEquals(m_ttl, m_rs.getTTL()); + assertEquals(DnsRecordType.A, m_rs.getType()); + + m_rs.addRR(m_a2); + + assertEquals(2, m_rs.size()); + assertEquals(DnsClass.IN, m_rs.getDClass()); + DnsRecord r = m_rs.first(); + assertEquals(m_a1, r); + assertEquals(m_name, m_rs.getName()); + assertEquals(m_ttl, m_rs.getTTL()); + assertEquals(DnsRecordType.A, m_rs.getType()); + + Iterator itr = m_rs.rrs(); + assertEquals(m_a1, itr.next()); + assertEquals(m_a2, itr.next()); + + // make sure that it rotates + itr = m_rs.rrs(); + assertEquals(m_a2, itr.next()); + assertEquals(m_a1, itr.next()); + itr = m_rs.rrs(); + assertEquals(m_a1, itr.next()); + assertEquals(m_a2, itr.next()); + + m_rs.deleteRR(m_a1); + assertEquals(1, m_rs.size()); + assertEquals(DnsClass.IN, m_rs.getDClass()); + assertEquals(m_a2, m_rs.first()); + assertEquals(m_name, m_rs.getName()); + assertEquals(m_ttl, m_rs.getTTL()); + assertEquals(DnsRecordType.A, m_rs.getType()); + + // the signature records + m_rs.addRR(m_s1); + assertEquals(1, m_rs.size()); + itr = m_rs.sigs(); + assertEquals(m_s1, itr.next()); + assertFalse(itr.hasNext()); + + m_rs.addRR(m_s1); + itr = m_rs.sigs(); + assertEquals(m_s1, itr.next()); + assertFalse(itr.hasNext()); + + m_rs.addRR(m_s2); + itr = m_rs.sigs(); + assertEquals(m_s1, itr.next()); + assertEquals(m_s2, itr.next()); + assertFalse(itr.hasNext()); + + m_rs.deleteRR(m_s1); + itr = m_rs.sigs(); + assertEquals(m_s2, itr.next()); + assertFalse(itr.hasNext()); + + + // clear it all + m_rs.clear(); + assertEquals(0, m_rs.size()); + assertFalse(m_rs.rrs() + .hasNext()); + assertFalse(m_rs.sigs() + .hasNext()); + + } + + public + void test_ctor_1arg() { + m_rs.addRR(m_a1); + m_rs.addRR(m_a2); + m_rs.addRR(m_s1); + m_rs.addRR(m_s2); + + RRset rs2 = new RRset(m_rs); + + assertEquals(2, rs2.size()); + assertEquals(m_a1, rs2.first()); + Iterator itr = rs2.rrs(); + assertEquals(m_a1, itr.next()); + assertEquals(m_a2, itr.next()); + assertFalse(itr.hasNext()); + + itr = rs2.sigs(); + assertTrue(itr.hasNext()); + assertEquals(m_s1, itr.next()); + assertTrue(itr.hasNext()); + assertEquals(m_s2, itr.next()); + assertFalse(itr.hasNext()); + } + + public + void test_toString() { + m_rs.addRR(m_a1); + m_rs.addRR(m_a2); + m_rs.addRR(m_s1); + m_rs.addRR(m_s2); + + String out = m_rs.toString(); + + assertTrue(out.indexOf(m_name.toString()) != -1); + assertTrue(out.indexOf(" IN A ") != -1); + assertTrue(out.indexOf("[192.169.232.11]") != -1); + assertTrue(out.indexOf("[192.169.232.12]") != -1); + } + + public + void test_addRR_invalidType() throws TextParseException { + m_rs.addRR(m_a1); + + CNAMERecord c = new CNAMERecord(m_name, DnsClass.IN, m_ttl, Name.fromString("an.alias.")); + + try { + m_rs.addRR(c); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_addRR_invalidName() throws TextParseException, UnknownHostException { + m_rs.addRR(m_a1); + + m_a2 = new ARecord(m_name2, DnsClass.IN, m_ttl, InetAddress.getByName("192.169.232.11")); + + try { + m_rs.addRR(m_a2); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_addRR_invalidDClass() throws TextParseException, UnknownHostException { + m_rs.addRR(m_a1); + + m_a2 = new ARecord(m_name, DnsClass.CHAOS, m_ttl, InetAddress.getByName("192.169.232.11")); + + try { + m_rs.addRR(m_a2); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_TTLcalculation() { + m_rs.addRR(m_a2); + assertEquals(m_a2.getTTL(), m_rs.getTTL()); + m_rs.addRR(m_a1); + assertEquals(m_a1.getTTL(), m_rs.getTTL()); + + Iterator itr = m_rs.rrs(); + while (itr.hasNext()) { + DnsRecord r = (DnsRecord) itr.next(); + assertEquals(m_a1.getTTL(), r.getTTL()); + } + } + + public + void test_Record_placement() { + m_rs.addRR(m_a1); + m_rs.addRR(m_s1); + m_rs.addRR(m_a2); + + Iterator itr = m_rs.rrs(); + assertTrue(itr.hasNext()); + assertEquals(m_a1, itr.next()); + assertTrue(itr.hasNext()); + assertEquals(m_a2, itr.next()); + assertFalse(itr.hasNext()); + + itr = m_rs.sigs(); + assertTrue(itr.hasNext()); + assertEquals(m_s1, itr.next()); + assertFalse(itr.hasNext()); + } + + public + void test_noncycling_iterator() { + m_rs.addRR(m_a1); + m_rs.addRR(m_a2); + + Iterator itr = m_rs.rrs(false); + assertTrue(itr.hasNext()); + assertEquals(m_a1, itr.next()); + assertTrue(itr.hasNext()); + assertEquals(m_a2, itr.next()); + + itr = m_rs.rrs(false); + assertTrue(itr.hasNext()); + assertEquals(m_a1, itr.next()); + assertTrue(itr.hasNext()); + assertEquals(m_a2, itr.next()); + } +} diff --git a/test/dorkbox/network/dns/records/RTRecordTest.java b/test/dorkbox/network/dns/records/RTRecordTest.java new file mode 100644 index 00000000..12374fca --- /dev/null +++ b/test/dorkbox/network/dns/records/RTRecordTest.java @@ -0,0 +1,65 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class RTRecordTest extends TestCase { + public + void test_getObject() { + RTRecord d = new RTRecord(); + DnsRecord r = d.getObject(); + assertTrue(r instanceof RTRecord); + } + + public + void test_ctor_5arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.OtherName."); + + RTRecord d = new RTRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); + assertEquals(n, d.getName()); + assertEquals(DnsRecordType.RT, d.getType()); + assertEquals(DnsClass.IN, d.getDClass()); + assertEquals(0xABCDEL, d.getTTL()); + assertEquals(0xF1, d.getPreference()); + assertEquals(m, d.getIntermediateHost()); + } +} diff --git a/test/dorkbox/network/dns/records/RecordTest.java b/test/dorkbox/network/dns/records/RecordTest.java new file mode 100644 index 00000000..899b5d85 --- /dev/null +++ b/test/dorkbox/network/dns/records/RecordTest.java @@ -0,0 +1,971 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Date; + +import dorkbox.network.dns.Compression; +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.constants.DnsSection; +import dorkbox.network.dns.exceptions.InvalidDClassException; +import dorkbox.network.dns.exceptions.InvalidTTLException; +import dorkbox.network.dns.exceptions.InvalidTypeException; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Options; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class RecordTest extends TestCase { + private static + class SubRecord extends DnsRecord { + public + SubRecord() {} + + public + SubRecord(Name name, int type, int dclass, long ttl) { + super(name, type, dclass, ttl); + } + + @Override + public + DnsRecord getObject() { + return null; + } + + @Override + public + void rrFromWire(DnsInput in) throws IOException {} + + @Override + public + void rrToWire(DnsOutput out, Compression c, boolean canonical) {} + + @Override + public + void rrToString(StringBuilder sb) { + sb.append("{SubRecord: rrToString}"); + } + + @Override + public + void rdataFromString(Tokenizer t, Name origin) throws IOException {} + + // makes it callable by test code + public static + byte[] byteArrayFromString(String in) throws TextParseException { + return DnsRecord.byteArrayFromString(in); + } + + // make it callable by test code + public static + String byteArrayToString(byte[] in, boolean quote) { + return DnsRecord.byteArrayToString(in, quote); + } + + // make it callable by test code + public static + String unknownToString(byte[] in) { + return DnsRecord.unknownToString(in); + } + + @Override + public + Object clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + } + + public + void test_ctor_0arg() { + SubRecord sr = new SubRecord(); + assertNull(sr.getName()); + assertEquals(0, sr.getType()); + assertEquals(0, sr.getTTL()); + assertEquals(0, sr.getDClass()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + long ttl = 0xABCDEL; + + SubRecord r = new SubRecord(n, t, d, ttl); + assertEquals(n, r.getName()); + assertEquals(t, r.getType()); + assertEquals(d, r.getDClass()); + assertEquals(ttl, r.getTTL()); + } + + public + void test_ctor_4arg_invalid() throws TextParseException { + Name n = Name.fromString("my.name."); + Name r = Name.fromString("my.relative.name"); + int t = DnsRecordType.A; + int d = DnsClass.IN; + long ttl = 0xABCDEL; + + try { + new SubRecord(r, t, d, ttl); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + + try { + new SubRecord(n, -1, d, ttl); + fail("InvalidTypeException not thrown"); + } catch (InvalidTypeException ignored) { + } + + try { + new SubRecord(n, t, -1, ttl); + fail("InvalidDClassException not thrown"); + } catch (InvalidDClassException ignored) { + } + + try { + new SubRecord(n, t, d, -1); + fail("InvalidTTLException not thrown"); + } catch (InvalidTTLException ignored) { + } + } + + public + void test_newRecord_3arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name r = Name.fromString("my.relative.name"); + int t = DnsRecordType.A; + int d = DnsClass.IN; + + DnsRecord rec = DnsRecord.newRecord(n, t, d); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(0, rec.getTTL()); + + try { + DnsRecord.newRecord(r, t, d); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_newRecord_4arg() throws TextParseException { + Name n = Name.fromString("my.name."); + Name r = Name.fromString("my.relative.name"); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + + try { + DnsRecord.newRecord(r, t, d, ttl); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_newRecord_5arg() throws TextParseException, UnknownHostException { + Name n = Name.fromString("my.name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + InetAddress exp = InetAddress.getByName("123.232.0.255"); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data); + assertTrue(rec instanceof ARecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertEquals(exp, ((ARecord) rec).getAddress()); + } + + public + void test_newRecord_6arg() throws TextParseException, UnknownHostException { + Name n = Name.fromString("my.name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + InetAddress exp = InetAddress.getByName("123.232.0.255"); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, 0, null); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + + rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + assertTrue(rec instanceof ARecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertEquals(exp, ((ARecord) rec).getAddress()); + + rec = DnsRecord.newRecord(n, DnsRecordType.NIMLOC, d, ttl, data.length, data); + assertTrue(rec instanceof UNKRecord); + assertEquals(n, rec.getName()); + assertEquals(DnsRecordType.NIMLOC, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertTrue(Arrays.equals(data, ((UNKRecord) rec).getData())); + } + + public + void test_newRecord_6arg_invalid() throws TextParseException { + Name n = Name.fromString("my.name."); + Name r = Name.fromString("my.relative.name"); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + + assertNull(DnsRecord.newRecord(n, t, d, ttl, 0, new byte[0])); + assertNull(DnsRecord.newRecord(n, t, d, ttl, 1, new byte[0])); + assertNull(DnsRecord.newRecord(n, t, d, ttl, data.length + 1, data)); + assertNull(DnsRecord.newRecord(n, t, d, ttl, 5, new byte[] {data[0], data[1], data[2], data[3], 0})); + try { + DnsRecord.newRecord(r, t, d, ttl, 0, null); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + + } + + public + void test_fromWire() throws IOException, TextParseException, UnknownHostException { + Name n = Name.fromString("my.name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + InetAddress exp = InetAddress.getByName("123.232.0.255"); + + DnsOutput out = new DnsOutput(); + n.toWire(out, null); + out.writeU16(t); + out.writeU16(d); + out.writeU32(ttl); + out.writeU16(data.length); + out.writeByteArray(data); + + byte[] bytes = out.toByteArray(); + DnsInput in = new DnsInput(bytes); + + DnsRecord rec = DnsRecord.fromWire(in, DnsSection.ANSWER, false); + assertTrue(rec instanceof ARecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertEquals(exp, ((ARecord) rec).getAddress()); + + in = new DnsInput(bytes); + rec = DnsRecord.fromWire(in, DnsSection.QUESTION, false); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(0, rec.getTTL()); + + in = new DnsInput(bytes); + rec = DnsRecord.fromWire(in, DnsSection.QUESTION); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(0, rec.getTTL()); + + rec = DnsRecord.fromWire(bytes, DnsSection.QUESTION); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(0, rec.getTTL()); + + out = new DnsOutput(); + n.toWire(out, null); + out.writeU16(t); + out.writeU16(d); + out.writeU32(ttl); + out.writeU16(0); + + in = new DnsInput(out.toByteArray()); + + rec = DnsRecord.fromWire(in, DnsSection.ANSWER, true); + assertTrue(rec instanceof EmptyRecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + + } + + public + void test_toWire() throws IOException, TextParseException, UnknownHostException + + { + Name n = Name.fromString("my.name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + + // a non-QUESTION + DnsOutput out = new DnsOutput(); + n.toWire(out, null); + out.writeU16(t); + out.writeU16(d); + out.writeU32(ttl); + out.writeU16(data.length); + out.writeByteArray(data); + + byte[] exp = out.toByteArray(); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + + out = new DnsOutput(); + + rec.toWire(out, DnsSection.ANSWER, null); + + byte[] after = out.toByteArray(); + + assertTrue(Arrays.equals(exp, after)); + + // an equivalent call + after = rec.toWire(DnsSection.ANSWER); + assertTrue(Arrays.equals(exp, after)); + + // a QUESTION entry + out = new DnsOutput(); + n.toWire(out, null); + out.writeU16(t); + out.writeU16(d); + + exp = out.toByteArray(); + out = new DnsOutput(); + rec.toWire(out, DnsSection.QUESTION, null); + after = out.toByteArray(); + + assertTrue(Arrays.equals(exp, after)); + + } + + public + void test_toWireCanonical() throws IOException, TextParseException, UnknownHostException + + { + Name n = Name.fromString("My.Name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xDBE8; + byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; + + DnsOutput out = new DnsOutput(); + n.toWireCanonical(out); + out.writeU16(t); + out.writeU16(d); + out.writeU32(ttl); + out.writeU16(data.length); + out.writeByteArray(data); + + byte[] exp = out.toByteArray(); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + + byte[] after = rec.toWireCanonical(); + assertTrue(Arrays.equals(exp, after)); + } + + public + void test_rdataToWireCanonical() throws IOException, TextParseException, UnknownHostException + + { + Name n = Name.fromString("My.Name."); + Name n2 = Name.fromString("My.Second.Name."); + int t = DnsRecordType.NS; + int d = DnsClass.IN; + int ttl = 0xABE99; + DnsOutput out = new DnsOutput(); + n2.toWire(out, null); + byte[] data = out.toByteArray(); + + out = new DnsOutput(); + n2.toWireCanonical(out); + byte[] exp = out.toByteArray(); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + assertTrue(rec instanceof NSRecord); + + byte[] after = rec.rdataToWireCanonical(); + + assertTrue(Arrays.equals(exp, after)); + } + + public + void test_rdataToString() throws IOException, TextParseException, UnknownHostException + + { + Name n = Name.fromString("My.Name."); + Name n2 = Name.fromString("My.Second.Name."); + int t = DnsRecordType.NS; + int d = DnsClass.IN; + int ttl = 0xABE99; + DnsOutput out = new DnsOutput(); + n2.toWire(out, null); + byte[] data = out.toByteArray(); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + assertTrue(rec instanceof NSRecord); + StringBuilder sa = new StringBuilder(); + rec.rrToString(sa); + + StringBuilder sb = new StringBuilder(); + rec.rdataToString(sb); + + assertEquals(sa.toString(), sb.toString()); + } + + public + void test_toString() throws TextParseException { + Name n = Name.fromString("My.N."); + Name n2 = Name.fromString("My.Second.Name."); + int t = DnsRecordType.NS; + int d = DnsClass.IN; + int ttl = 0xABE99; + DnsOutput o = new DnsOutput(); + n2.toWire(o, null); + byte[] data = o.toByteArray(); + + DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); + String out = rec.toString(); + + assertFalse(out.indexOf(n.toString()) == -1); + assertFalse(out.indexOf(n2.toString()) == -1); + assertFalse(out.indexOf("NS") == -1); + assertFalse(out.indexOf("IN") == -1); + assertFalse(out.indexOf(ttl + "") == -1); + + Options.set("BINDTTL"); + + out = rec.toString(); + assertFalse(out.indexOf(n.toString()) == -1); + assertFalse(out.indexOf(n2.toString()) == -1); + assertFalse(out.indexOf("NS") == -1); + assertFalse(out.indexOf("IN") == -1); + assertFalse(out.indexOf(TTL.format(ttl)) == -1); + + Options.set("noPrintIN"); + out = rec.toString(); + assertFalse(out.indexOf(n.toString()) == -1); + assertFalse(out.indexOf(n2.toString()) == -1); + assertFalse(out.indexOf("NS") == -1); + assertTrue(out.indexOf("IN") == -1); + assertFalse(out.indexOf(TTL.format(ttl)) == -1); + } + + public + void test_byteArrayFromString() throws TextParseException { + String in = "the 98 \" \' quick 0xAB brown"; + byte[] out = SubRecord.byteArrayFromString(in); + assertTrue(Arrays.equals(in.getBytes(), out)); + + in = " \\031Aa\\;\\\"\\\\~\\127\\255"; + byte[] exp = new byte[] {' ', 0x1F, 'A', 'a', ';', '"', '\\', 0x7E, 0x7F, (byte) 0xFF}; + out = SubRecord.byteArrayFromString(in); + assertTrue(Arrays.equals(exp, out)); + } + + public + void test_byteArrayFromString_invalid() { + StringBuffer b = new StringBuffer(); + for (int i = 0; i < 257; ++i) { + b.append('A'); + } + try { + SubRecord.byteArrayFromString(b.toString()); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + + try { + SubRecord.byteArrayFromString("\\256"); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + try { + SubRecord.byteArrayFromString("\\25a"); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + try { + SubRecord.byteArrayFromString("\\25"); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + + b.append("\\233"); + try { + SubRecord.byteArrayFromString(b.toString()); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + + } + + public + void test_byteArrayToString() { + byte[] in = new byte[] {' ', 0x1F, 'A', 'a', ';', '"', '\\', 0x7E, 0x7F, (byte) 0xFF}; + String exp = "\" \\031Aa;\\\"\\\\~\\127\\255\""; + assertEquals(exp, SubRecord.byteArrayToString(in, true)); + } + + public + void test_unknownToString() { + byte[] data = new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A, (byte) 0xBC, (byte) 0xDE, (byte) 0xFF}; + String out = SubRecord.unknownToString(data); + + assertFalse(out.indexOf("" + data.length) == -1); + assertFalse(out.indexOf("123456789ABCDEFF") == -1); + } + + public + void test_fromString() throws IOException, TextParseException { + Name n = Name.fromString("My.N."); + Name n2 = Name.fromString("My.Second.Name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xABE99; + String sa = "191.234.43.10"; + InetAddress addr = InetAddress.getByName(sa); + byte[] b = new byte[] {(byte) 191, (byte) 234, (byte) 43, (byte) 10}; + + Tokenizer st = new Tokenizer(sa); + DnsRecord rec = DnsRecord.fromString(n, t, d, ttl, st, n2); + assertTrue(rec instanceof ARecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertEquals(addr, ((ARecord) rec).getAddress()); + + String unkData = SubRecord.unknownToString(b); + st = new Tokenizer(unkData); + rec = DnsRecord.fromString(n, t, d, ttl, st, n2); + assertTrue(rec instanceof ARecord); + assertEquals(n, rec.getName()); + assertEquals(t, rec.getType()); + assertEquals(d, rec.getDClass()); + assertEquals(ttl, rec.getTTL()); + assertEquals(addr, ((ARecord) rec).getAddress()); + } + + public + void test_fromString_invalid() throws IOException, TextParseException { + Name n = Name.fromString("My.N."); + Name rel = Name.fromString("My.R"); + Name n2 = Name.fromString("My.Second.Name."); + int t = DnsRecordType.A; + int d = DnsClass.IN; + int ttl = 0xABE99; + InetAddress addr = InetAddress.getByName("191.234.43.10"); + + Tokenizer st = new Tokenizer("191.234.43.10"); + + try { + DnsRecord.fromString(rel, t, d, ttl, st, n2); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + + st = new Tokenizer("191.234.43.10 another_token"); + try { + DnsRecord.fromString(n, t, d, ttl, st, n2); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + + st = new Tokenizer("\\# 100 ABCDE"); + try { + DnsRecord.fromString(n, t, d, ttl, st, n2); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + + try { + DnsRecord.fromString(n, t, d, ttl, "\\# 100", n2); + fail("TextParseException not thrown"); + } catch (TextParseException ignored) { + } + } + + public + void test_getRRsetType() throws TextParseException { + Name n = Name.fromString("My.N."); + + DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); + assertEquals(DnsRecordType.A, r.getRRsetType()); + + r = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); + assertEquals(DnsRecordType.A, r.getRRsetType()); + } + + public + void test_sameRRset() throws TextParseException { + Name n = Name.fromString("My.N."); + Name m = Name.fromString("My.M."); + + DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); + DnsRecord r2 = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); + assertTrue(r1.sameRRset(r2)); + assertTrue(r2.sameRRset(r1)); + + r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.HS, 0); + r2 = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); + assertFalse(r1.sameRRset(r2)); + assertFalse(r2.sameRRset(r1)); + + r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); + r2 = new RRSIGRecord(m, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); + assertFalse(r1.sameRRset(r2)); + assertFalse(r2.sameRRset(r1)); + } + + public + void test_equals() throws TextParseException { + Name n = Name.fromString("My.N."); + Name n2 = Name.fromString("my.n."); + Name m = Name.fromString("My.M."); + + DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); + + assertFalse(r1.equals(null)); + assertFalse(r1.equals(new Object())); + + DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); + assertEquals(r1, r2); + assertEquals(r2, r1); + + r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0); + assertEquals(r1, r2); + assertEquals(r2, r1); + + r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE); + assertEquals(r1, r2); + assertEquals(r2, r1); + + r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE); + assertFalse(r1.equals(r2)); + assertFalse(r2.equals(r1)); + + r2 = DnsRecord.newRecord(n2, DnsRecordType.MX, DnsClass.IN, 0xABCDE); + assertFalse(r1.equals(r2)); + assertFalse(r2.equals(r1)); + + r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE); + assertFalse(r1.equals(r2)); + assertFalse(r2.equals(r1)); + + byte[] d1 = new byte[] {23, 12, 9, (byte) 129}; + byte[] d2 = new byte[] {(byte) 220, 1, (byte) 131, (byte) 212}; + + r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + + assertEquals(r1, r2); + assertEquals(r2, r1); + + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); + + assertFalse(r1.equals(r2)); + assertFalse(r2.equals(r1)); + } + + public + void test_hashCode() throws TextParseException { + Name n = Name.fromString("My.N."); + Name n2 = Name.fromString("my.n."); + Name m = Name.fromString("My.M."); + byte[] d1 = new byte[] {23, 12, 9, (byte) 129}; + byte[] d2 = new byte[] {(byte) 220, 1, (byte) 131, (byte) 212}; + + DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + + // same DnsDnsRecord has same hash code + DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + assertEquals(r1.hashCode(), r2.hashCode()); + + // case of names should not matter + r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + assertEquals(r1.hashCode(), r2.hashCode()); + + // different names + r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); + assertFalse(r1.hashCode() == r2.hashCode()); + + // different class + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE9, d1); + assertFalse(r1.hashCode() == r2.hashCode()); + + // different TTL does not matter + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE, d1); + assertEquals(r1.hashCode(), r2.hashCode()); + + // different data + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); + assertFalse(r1.hashCode() == r2.hashCode()); + } + + public + void test_cloneRecord() throws TextParseException { + Name n = Name.fromString("My.N."); + byte[] d = new byte[] {23, 12, 9, (byte) 129}; + DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + + DnsRecord r2 = r.cloneRecord(); + + assertNotSame(r, r2); + assertEquals(r, r2); + + r = new SubRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9); + + try { + r.cloneRecord(); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException ignored) { + } + } + + public + void test_withName() throws TextParseException { + Name n = Name.fromString("My.N."); + Name m = Name.fromString("My.M.Name."); + Name rel = Name.fromString("My.Relative.Name"); + byte[] d = new byte[] {23, 12, 9, (byte) 129}; + DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + + DnsRecord r1 = r.withName(m); + + assertEquals(m, r1.getName()); + assertEquals(DnsRecordType.A, r1.getType()); + assertEquals(DnsClass.IN, r1.getDClass()); + assertEquals(0xABCDE9, r1.getTTL()); + assertEquals(((ARecord) r).getAddress(), ((ARecord) r1).getAddress()); + + try { + r.withName(rel); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_withDClass() throws TextParseException { + Name n = Name.fromString("My.N."); + byte[] d = new byte[] {23, 12, 9, (byte) 129}; + DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + + DnsRecord r1 = r.withDClass(DnsClass.HESIOD, 0x9876); + + assertEquals(n, r1.getName()); + assertEquals(DnsRecordType.A, r1.getType()); + assertEquals(DnsClass.HESIOD, r1.getDClass()); + assertEquals(0x9876, r1.getTTL()); + assertEquals(((ARecord) r).getAddress(), ((ARecord) r1).getAddress()); + } + + public + void test_setTTL() throws TextParseException, UnknownHostException { + Name n = Name.fromString("My.N."); + byte[] d = new byte[] {23, 12, 9, (byte) 129}; + InetAddress exp = InetAddress.getByName("23.12.9.129"); + DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + + assertEquals(0xABCDE9, r.getTTL()); + + r.setTTL(0x9876); + + assertEquals(n, r.getName()); + assertEquals(DnsRecordType.A, r.getType()); + assertEquals(DnsClass.IN, r.getDClass()); + assertEquals(0x9876, r.getTTL()); + assertEquals(exp, ((ARecord) r).getAddress()); + } + + public + void test_compareTo() throws TextParseException { + Name n = Name.fromString("My.N."); + Name n2 = Name.fromString("my.n."); + Name m = Name.fromString("My.M."); + byte[] d = new byte[] {23, 12, 9, (byte) 129}; + byte[] d2 = new byte[] {23, 12, 9, (byte) 128}; + DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + + assertEquals(0, r1.compareTo(r1)); + + assertEquals(0, r1.compareTo(r2)); + assertEquals(0, r2.compareTo(r1)); + + // name comparison should be canonical + r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + assertEquals(0, r1.compareTo(r2)); + assertEquals(0, r2.compareTo(r1)); + + // different name + r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); + assertEquals(n.compareTo(m), r1.compareTo(r2)); + assertEquals(m.compareTo(n), r2.compareTo(r1)); + + // different DnsClass + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE9, d); + assertEquals(DnsClass.IN - DnsClass.CHAOS, r1.compareTo(r2)); + assertEquals(DnsClass.CHAOS - DnsClass.IN, r2.compareTo(r1)); + + // different DnsRecordType + r2 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, m.toWire()); + assertEquals(DnsRecordType.A - DnsRecordType.NS, r1.compareTo(r2)); + assertEquals(DnsRecordType.NS - DnsRecordType.A, r2.compareTo(r1)); + + // different data (same length) + r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); + assertEquals(1, r1.compareTo(r2)); + assertEquals(-1, r2.compareTo(r1)); + + // different data (one a prefix of the other) + m = Name.fromString("My.N.L."); + r1 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, n.toWire()); + r2 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, m.toWire()); + assertEquals(-1, r1.compareTo(r2)); + assertEquals(1, r2.compareTo(r1)); + } + + public + void test_getAdditionalName() throws TextParseException { + Name n = Name.fromString("My.N."); + DnsRecord r = new SubRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9); + + assertNull(r.getAdditionalName()); + } + + public + void test_checkU8() { + try { + DnsRecord.checkU8("field", -1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + assertEquals(0, DnsRecord.checkU8("field", 0)); + assertEquals(0x9D, DnsRecord.checkU8("field", 0x9D)); + assertEquals(0xFF, DnsRecord.checkU8("field", 0xFF)); + try { + DnsRecord.checkU8("field", 0x100); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_checkU16() { + try { + DnsRecord.checkU16("field", -1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + assertEquals(0, DnsRecord.checkU16("field", 0)); + assertEquals(0x9DA1, DnsRecord.checkU16("field", 0x9DA1)); + assertEquals(0xFFFF, DnsRecord.checkU16("field", 0xFFFF)); + try { + DnsRecord.checkU16("field", 0x10000); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_checkU32() { + try { + DnsRecord.checkU32("field", -1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + assertEquals(0, DnsRecord.checkU32("field", 0)); + assertEquals(0x9DA1F02DL, DnsRecord.checkU32("field", 0x9DA1F02DL)); + assertEquals(0xFFFFFFFFL, DnsRecord.checkU32("field", 0xFFFFFFFFL)); + try { + DnsRecord.checkU32("field", 0x100000000L); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_checkName() throws TextParseException { + Name n = Name.fromString("My.N."); + Name m = Name.fromString("My.m"); + + assertEquals(n, DnsRecord.checkName("field", n)); + + try { + DnsRecord.checkName("field", m); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } +} diff --git a/test/dorkbox/network/dns/records/SOARecordTest.java b/test/dorkbox/network/dns/records/SOARecordTest.java new file mode 100644 index 00000000..8459d8fe --- /dev/null +++ b/test/dorkbox/network/dns/records/SOARecordTest.java @@ -0,0 +1,455 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Random; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Options; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public +class SOARecordTest { + private final static Random m_random = new Random(); + + private static + long randomU16() { + return m_random.nextLong() >>> 48; + } + + private static + long randomU32() { + return m_random.nextLong() >>> 32; + } + + public static + class Test_init extends TestCase { + private Name m_an, m_rn, m_host, m_admin; + private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; + + @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_an = Name.fromString("My.Absolute.Name."); + m_rn = Name.fromString("My.Relative.Name"); + m_host = Name.fromString("My.Host.Name."); + m_admin = Name.fromString("My.Administrative.Name."); + m_ttl = randomU16(); + m_serial = randomU32(); + m_refresh = randomU32(); + m_retry = randomU32(); + m_expire = randomU32(); + m_minimum = randomU32(); + } + + public + void test_0arg() throws UnknownHostException { + SOARecord ar = new SOARecord(); + assertNull(ar.getName()); + assertEquals(0, ar.getType()); + assertEquals(0, ar.getDClass()); + assertEquals(0, ar.getTTL()); + assertNull(ar.getHost()); + assertNull(ar.getAdmin()); + assertEquals(0, ar.getSerial()); + assertEquals(0, ar.getRefresh()); + assertEquals(0, ar.getRetry()); + assertEquals(0, ar.getExpire()); + assertEquals(0, ar.getMinimum()); + } + + public + void test_getObject() { + SOARecord ar = new SOARecord(); + DnsRecord r = ar.getObject(); + assertTrue(r instanceof SOARecord); + } + + public + void test_10arg() { + SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + assertEquals(m_an, ar.getName()); + assertEquals(DnsRecordType.SOA, ar.getType()); + assertEquals(DnsClass.IN, ar.getDClass()); + assertEquals(m_ttl, ar.getTTL()); + assertEquals(m_host, ar.getHost()); + assertEquals(m_admin, ar.getAdmin()); + assertEquals(m_serial, ar.getSerial()); + assertEquals(m_refresh, ar.getRefresh()); + assertEquals(m_retry, ar.getRetry()); + assertEquals(m_expire, ar.getExpire()); + assertEquals(m_minimum, ar.getMinimum()); + } + + public + void test_10arg_relative_name() { + try { + new SOARecord(m_rn, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_10arg_relative_host() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_rn, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_10arg_relative_admin() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_rn, m_serial, m_refresh, m_retry, m_expire, m_minimum); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + public + void test_10arg_negative_serial() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, -1, m_refresh, m_retry, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_toobig_serial() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, 0x100000000L, m_refresh, m_retry, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_negative_refresh() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, -1, m_retry, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_toobig_refresh() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, 0x100000000L, m_retry, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_negative_retry() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, -1, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_toobig_retry() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, 0x100000000L, m_expire, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_negative_expire() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, -1, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_toobig_expire() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, 0x100000000L, m_minimum); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_negative_minimun() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, -1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + + public + void test_10arg_toobig_minimum() { + try { + new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, 0x100000000L); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException ignored) { + } + } + } + + + public static + class Test_rrFromWire extends TestCase { + private Name m_host, m_admin; + private long m_serial, m_refresh, m_retry, m_expire, m_minimum; + + public + void test() throws IOException { + byte[] raw = new byte[] {1, 'm', 1, 'h', 1, 'n', 0, // host + 1, 'm', 1, 'a', 1, 'n', 0, // admin + (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial + (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh + (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry + (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire + (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum + + DnsInput di = new DnsInput(raw); + SOARecord ar = new SOARecord(); + + ar.rrFromWire(di); + + assertEquals(m_host, ar.getHost()); + assertEquals(m_admin, ar.getAdmin()); + assertEquals(m_serial, ar.getSerial()); + assertEquals(m_refresh, ar.getRefresh()); + assertEquals(m_retry, ar.getRetry()); + assertEquals(m_expire, ar.getExpire()); + assertEquals(m_minimum, ar.getMinimum()); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_host = Name.fromString("M.h.N."); + m_admin = Name.fromString("M.a.n."); + m_serial = 0xABCDEF12L; + m_refresh = 0xCDEF1234L; + m_retry = 0xEF123456L; + m_expire = 0x12345678L; + m_minimum = 0x3456789AL; + } + + + } + + + public static + class Test_rdataFromString extends TestCase { + private Name m_host, m_admin, m_origin; + private long m_serial, m_refresh, m_retry, m_expire, m_minimum; + + public + void test_valid() throws IOException { + Tokenizer t = new Tokenizer("M.h " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + + m_minimum); + SOARecord ar = new SOARecord(); + + ar.rdataFromString(t, m_origin); + + assertEquals(m_host, ar.getHost()); + assertEquals(m_admin, ar.getAdmin()); + assertEquals(m_serial, ar.getSerial()); + assertEquals(m_refresh, ar.getRefresh()); + assertEquals(m_retry, ar.getRetry()); + assertEquals(m_expire, ar.getExpire()); + assertEquals(m_minimum, ar.getMinimum()); + } @Override + protected + void setUp() throws TextParseException, UnknownHostException { + m_origin = Name.fromString("O."); + m_host = Name.fromString("M.h", m_origin); + m_admin = Name.fromString("M.a.n."); + m_serial = 0xABCDEF12L; + m_refresh = 0xCDEF1234L; + m_retry = 0xEF123456L; + m_expire = 0x12345678L; + m_minimum = 0x3456789AL; + } + + public + void test_relative_name() throws IOException { + Tokenizer t = new Tokenizer("M.h " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + + m_minimum); + SOARecord ar = new SOARecord(); + + try { + ar.rdataFromString(t, null); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException ignored) { + } + } + + + } + + + public static + class Test_rrToString extends TestCase { + private Name m_an, m_host, m_admin; + private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; + + public + void test_singleLine() { + SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + String exp = m_host + " " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + m_minimum; + + StringBuilder sb = new StringBuilder(); + ar.rrToString(sb); + String out = sb.toString(); + + assertEquals(exp, out); + } @Override + protected + void setUp() throws TextParseException { + m_an = Name.fromString("My.absolute.name."); + m_ttl = 0x13A8; + m_host = Name.fromString("M.h.N."); + m_admin = Name.fromString("M.a.n."); + m_serial = 0xABCDEF12L; + m_refresh = 0xCDEF1234L; + m_retry = 0xEF123456L; + m_expire = 0x12345678L; + m_minimum = 0x3456789AL; + } + + public + void test_multiLine() { + SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + String re = "^.*\\(\\n" + "\\s*" + m_serial + "\\s*;\\s*serial\\n" + // serial + "\\s*" + m_refresh + "\\s*;\\s*refresh\\n" + // refresh + "\\s*" + m_retry + "\\s*;\\s*retry\\n" + // retry + "\\s*" + m_expire + "\\s*;\\s*expire\\n" + // expire + "\\s*" + m_minimum + "\\s*\\)\\s*;\\s*minimum$"; // minimum + + Options.set("multiline"); + StringBuilder sb = new StringBuilder(); + ar.rrToString(sb); + String out = sb.toString(); + Options.unset("multiline"); + + assertTrue(out.matches(re)); + } + + + } + + + public static + class Test_rrToWire extends TestCase { + private Name m_an, m_host, m_admin; + private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; + + public + void test_canonical() { + byte[] exp = new byte[] {1, 'm', 1, 'h', 1, 'n', 0, // host + 1, 'm', 1, 'a', 1, 'n', 0, // admin + (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial + (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh + (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry + (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire + (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum + + SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + DnsOutput o = new DnsOutput(); + ar.rrToWire(o, null, true); + + assertTrue(Arrays.equals(exp, o.toByteArray())); + } @Override + protected + void setUp() throws TextParseException { + m_an = Name.fromString("My.Abs.Name."); + m_ttl = 0x13A8; + m_host = Name.fromString("M.h.N."); + m_admin = Name.fromString("M.a.n."); + m_serial = 0xABCDEF12L; + m_refresh = 0xCDEF1234L; + m_retry = 0xEF123456L; + m_expire = 0x12345678L; + m_minimum = 0x3456789AL; + } + + public + void test_case_sensitive() { + byte[] exp = new byte[] {1, 'M', 1, 'h', 1, 'N', 0, // host + 1, 'M', 1, 'a', 1, 'n', 0, // admin + (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial + (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh + (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry + (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire + (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum + + SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); + DnsOutput o = new DnsOutput(); + ar.rrToWire(o, null, false); + + assertTrue(Arrays.equals(exp, o.toByteArray())); + } + + + } + + public static + Test suite() { + TestSuite s = new TestSuite(); + s.addTestSuite(Test_init.class); + s.addTestSuite(Test_rrFromWire.class); + s.addTestSuite(Test_rdataFromString.class); + s.addTestSuite(Test_rrToString.class); + s.addTestSuite(Test_rrToWire.class); + return s; + } +} diff --git a/test/dorkbox/network/dns/records/SectionTest.java b/test/dorkbox/network/dns/records/SectionTest.java new file mode 100644 index 00000000..0f7e1566 --- /dev/null +++ b/test/dorkbox/network/dns/records/SectionTest.java @@ -0,0 +1,100 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.constants.DnsSection; +import junit.framework.TestCase; + +public +class SectionTest extends TestCase { + public + void test_string() { + // a regular one + assertEquals("au", DnsSection.string(DnsSection.AUTHORITY)); + + try { + DnsSection.string(-1); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // (max is 3) + try { + DnsSection.string(4); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_value() { + // regular one + assertEquals(DnsSection.ADDITIONAL, DnsSection.value("ad")); + + // something that unknown + assertEquals(-1, DnsSection.value("THIS IS DEFINITELY UNKNOWN")); + + // empty string + assertEquals(-1, DnsSection.value("")); + } + + public + void test_longString() { + assertEquals("ADDITIONAL RECORDS", DnsSection.longString(DnsSection.ADDITIONAL)); + + try { + DnsSection.longString(-1); + } catch (IllegalArgumentException e) { + } + try { + DnsSection.longString(4); + } catch (IllegalArgumentException e) { + } + } + + public + void test_updString() { + assertEquals("ZONE", DnsSection.updString(DnsSection.ZONE)); + + try { + DnsSection.longString(-1); + } catch (IllegalArgumentException e) { + } + try { + DnsSection.longString(4); + } catch (IllegalArgumentException e) { + } + } +} diff --git a/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java b/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java new file mode 100644 index 00000000..6e52814d --- /dev/null +++ b/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java @@ -0,0 +1,118 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; + +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class SingleCompressedNameBaseTest extends TestCase { + private static + class TestClass extends SingleCompressedNameBase { + public + TestClass() {} + + public + TestClass(Name name, int type, int dclass, long ttl, Name singleName, String desc) { + super(name, type, dclass, ttl, singleName, desc); + } + + @Override + public + Name getSingleName() { + return super.getSingleName(); + } + + @Override + public + DnsRecord getObject() { + return null; + } + } + + public + void test_ctor() throws TextParseException { + TestClass tc = new TestClass(); + assertNull(tc.getSingleName()); + + Name n = Name.fromString("my.name."); + Name sn = Name.fromString("my.single.name."); + + tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.A, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(100L, tc.getTTL()); + assertSame(sn, tc.getSingleName()); + } + + public + void test_rrToWire() throws IOException, TextParseException { + Name n = Name.fromString("my.name."); + Name sn = Name.fromString("My.Single.Name."); + + // non-canonical (case sensitive) + TestClass tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + byte[] exp = new byte[] {2, 'M', 'y', 6, 'S', 'i', 'n', 'g', 'l', 'e', 4, 'N', 'a', 'm', 'e', 0}; + + DnsOutput dout = new DnsOutput(); + tc.rrToWire(dout, null, false); + + byte[] out = dout.toByteArray(); + assertEquals(exp, out); + + // canonical (lowercase) + tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + exp = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; + + dout = new DnsOutput(); + tc.rrToWire(dout, null, true); + + out = dout.toByteArray(); + assertEquals(exp, out); + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(java.util.Arrays.equals(exp, act)); + } +} diff --git a/test/dorkbox/network/dns/records/SingleNameBaseTest.java b/test/dorkbox/network/dns/records/SingleNameBaseTest.java new file mode 100644 index 00000000..5e122b00 --- /dev/null +++ b/test/dorkbox/network/dns/records/SingleNameBaseTest.java @@ -0,0 +1,178 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class SingleNameBaseTest extends TestCase { + private static + class TestClass extends SingleNameBase { + public + TestClass() {} + + public + TestClass(Name name, int type, int dclass, long ttl) { + super(name, type, dclass, ttl); + } + + public + TestClass(Name name, int type, int dclass, long ttl, Name singleName, String desc) { + super(name, type, dclass, ttl, singleName, desc); + } + + @Override + public + Name getSingleName() { + return super.getSingleName(); + } + + @Override + public + DnsRecord getObject() { + return null; + } + } + + public + void test_ctor() throws TextParseException { + TestClass tc = new TestClass(); + assertNull(tc.getSingleName()); + + Name n = Name.fromString("my.name."); + Name sn = Name.fromString("my.single.name."); + + tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.A, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(100L, tc.getTTL()); + + tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.A, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(100L, tc.getTTL()); + assertSame(sn, tc.getSingleName()); + } + + public + void test_rrFromWire() throws IOException { + byte[] raw = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; + DnsInput in = new DnsInput(raw); + + TestClass tc = new TestClass(); + tc.rrFromWire(in); + + Name exp = Name.fromString("my.single.name."); + assertEquals(exp, tc.getSingleName()); + } + + public + void test_rdataFromString() throws IOException { + Name exp = Name.fromString("my.single.name."); + + Tokenizer t = new Tokenizer("my.single.name."); + TestClass tc = new TestClass(); + tc.rdataFromString(t, null); + assertEquals(exp, tc.getSingleName()); + + t = new Tokenizer("my.relative.name"); + tc = new TestClass(); + try { + tc.rdataFromString(t, null); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + } + + public + void test_rrToString() throws IOException, TextParseException { + Name exp = Name.fromString("my.single.name."); + + Tokenizer t = new Tokenizer("my.single.name."); + TestClass tc = new TestClass(); + tc.rdataFromString(t, null); + assertEquals(exp, tc.getSingleName()); + + StringBuilder sb = new StringBuilder(); + tc.rrToString(sb); + String out = sb.toString(); + assertEquals(out, exp.toString()); + } + + public + void test_rrToWire() throws IOException, TextParseException { + Name n = Name.fromString("my.name."); + Name sn = Name.fromString("My.Single.Name."); + + // non-canonical (case sensitive) + TestClass tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + byte[] exp = new byte[] {2, 'M', 'y', 6, 'S', 'i', 'n', 'g', 'l', 'e', 4, 'N', 'a', 'm', 'e', 0}; + + DnsOutput dout = new DnsOutput(); + tc.rrToWire(dout, null, false); + + byte[] out = dout.toByteArray(); + assertEquals(exp, out); + + // canonical (lowercase) + tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); + exp = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; + + dout = new DnsOutput(); + tc.rrToWire(dout, null, true); + + out = dout.toByteArray(); + assertEquals(exp, out); + } + + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(java.util.Arrays.equals(exp, act)); + } +} diff --git a/test/dorkbox/network/dns/records/TSIGTest.java b/test/dorkbox/network/dns/records/TSIGTest.java new file mode 100644 index 00000000..0158eefd --- /dev/null +++ b/test/dorkbox/network/dns/records/TSIGTest.java @@ -0,0 +1,90 @@ +package dorkbox.network.dns.records; + +import java.io.IOException; + +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.constants.DnsResponseCode; +import dorkbox.network.dns.constants.DnsSection; +import dorkbox.network.dns.constants.Flags; +import dorkbox.network.dns.exceptions.TextParseException; +import junit.framework.TestCase; + +public +class TSIGTest extends TestCase { + public + void test_TSIG_query() throws TextParseException, IOException { + TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); + + Name qname = Name.fromString("www.example."); + DnsRecord rec = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); + DnsMessage msg = DnsMessage.newQuery(rec); + msg.setTSIG(key, DnsResponseCode.NOERROR, null); + byte[] bytes = msg.toWire(512); + assertEquals(bytes[11], 1); + + DnsMessage parsed = new DnsMessage(bytes); + int result = key.verify(parsed, bytes, null); + assertEquals(result, DnsResponseCode.NOERROR); + assertTrue(parsed.isSigned()); + } + + public + void test_TSIG_response() throws TextParseException, IOException { + TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); + + Name qname = Name.fromString("www.example."); + DnsRecord question = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); + DnsMessage query = DnsMessage.newQuery(question); + query.setTSIG(key, DnsResponseCode.NOERROR, null); + byte[] qbytes = query.toWire(); + DnsMessage qparsed = new DnsMessage(qbytes); + + DnsMessage response = new DnsMessage(query.getHeader() + .getID()); + response.setTSIG(key, DnsResponseCode.NOERROR, qparsed.getTSIG()); + response.getHeader() + .setFlag(Flags.QR); + response.addRecord(question, DnsSection.QUESTION); + DnsRecord answer = DnsRecord.fromString(qname, DnsRecordType.A, DnsClass.IN, 300, "1.2.3.4", null); + response.addRecord(answer, DnsSection.ANSWER); + byte[] bytes = response.toWire(512); + + DnsMessage parsed = new DnsMessage(bytes); + int result = key.verify(parsed, bytes, qparsed.getTSIG()); + assertEquals(result, DnsResponseCode.NOERROR); + assertTrue(parsed.isSigned()); + } + + public + void test_TSIG_truncated() throws TextParseException, IOException { + TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); + + Name qname = Name.fromString("www.example."); + DnsRecord question = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); + DnsMessage query = DnsMessage.newQuery(question); + query.setTSIG(key, DnsResponseCode.NOERROR, null); + byte[] qbytes = query.toWire(); + DnsMessage qparsed = new DnsMessage(qbytes); + + DnsMessage response = new DnsMessage(query.getHeader() + .getID()); + response.setTSIG(key, DnsResponseCode.NOERROR, qparsed.getTSIG()); + response.getHeader() + .setFlag(Flags.QR); + response.addRecord(question, DnsSection.QUESTION); + for (int i = 0; i < 40; i++) { + DnsRecord answer = DnsRecord.fromString(qname, DnsRecordType.TXT, DnsClass.IN, 300, "foo" + i, null); + response.addRecord(answer, DnsSection.ANSWER); + } + byte[] bytes = response.toWire(512); + + DnsMessage parsed = new DnsMessage(bytes); + assertTrue(parsed.getHeader() + .getFlag(Flags.TC)); + int result = key.verify(parsed, bytes, qparsed.getTSIG()); + assertEquals(result, DnsResponseCode.NOERROR); + assertTrue(parsed.isSigned()); + } +} diff --git a/test/dorkbox/network/dns/records/TTLTest.java b/test/dorkbox/network/dns/records/TTLTest.java new file mode 100644 index 00000000..cc5588d5 --- /dev/null +++ b/test/dorkbox/network/dns/records/TTLTest.java @@ -0,0 +1,146 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import dorkbox.network.dns.exceptions.InvalidTTLException; +import junit.framework.TestCase; + +public +class TTLTest extends TestCase { + private final long S = 1; + private final long M = 60 * S; + private final long H = 60 * M; + private final long D = 24 * H; + private final long W = 7 * D; + + public + void test_parseTTL() { + assertEquals(9876, TTL.parseTTL("9876")); + + assertEquals(0, TTL.parseTTL("0S")); + assertEquals(0, TTL.parseTTL("0M")); + assertEquals(0, TTL.parseTTL("0H")); + assertEquals(0, TTL.parseTTL("0D")); + assertEquals(0, TTL.parseTTL("0W")); + + assertEquals(S, TTL.parseTTL("1s")); + assertEquals(M, TTL.parseTTL("1m")); + assertEquals(H, TTL.parseTTL("1h")); + assertEquals(D, TTL.parseTTL("1d")); + assertEquals(W, TTL.parseTTL("1w")); + + assertEquals(98 * S, TTL.parseTTL("98S")); + assertEquals(76 * M, TTL.parseTTL("76M")); + assertEquals(54 * H, TTL.parseTTL("54H")); + assertEquals(32 * D, TTL.parseTTL("32D")); + assertEquals(10 * W, TTL.parseTTL("10W")); + + assertEquals(98 * S + 11 * M + 1234 * H + 2 * D + W, TTL.parseTTL("98S11M1234H2D01W")); + } + + public + void test_parseTTL_invalid() { + try { + TTL.parseTTL(null); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + + try { + TTL.parseTTL(""); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + + try { + TTL.parseTTL("S"); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + + try { + TTL.parseTTL("10S4B"); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + + try { + TTL.parseTTL("1S" + 0xFFFFFFFFL + "S"); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + + try { + TTL.parseTTL("" + 0x100000000L); + fail("NumberFormatException not throw"); + } catch (NumberFormatException ignored) { + } + } + + public + void test_format() { + assertEquals("0S", TTL.format(0)); + assertEquals("1S", TTL.format(1)); + assertEquals("59S", TTL.format(59)); + assertEquals("1M", TTL.format(60)); + assertEquals("59M", TTL.format(59 * M)); + assertEquals("1M33S", TTL.format(M + 33)); + assertEquals("59M59S", TTL.format(59 * M + 59 * S)); + assertEquals("1H", TTL.format(H)); + assertEquals("10H1M21S", TTL.format(10 * H + M + 21)); + assertEquals("23H59M59S", TTL.format(23 * H + 59 * M + 59)); + assertEquals("1D", TTL.format(D)); + assertEquals("4D18H45M30S", TTL.format(4 * D + 18 * H + 45 * M + 30)); + assertEquals("6D23H59M59S", TTL.format(6 * D + 23 * H + 59 * M + 59)); + assertEquals("1W", TTL.format(W)); + assertEquals("10W4D1H21M29S", TTL.format(10 * W + 4 * D + H + 21 * M + 29)); + assertEquals("3550W5D3H14M7S", TTL.format(0x7FFFFFFFL)); + } + + public + void test_format_invalid() { + try { + TTL.format(-1); + fail("InvalidTTLException not thrown"); + } catch (InvalidTTLException ignored) { + } + + try { + TTL.format(0x100000000L); + fail("InvalidTTLException not thrown"); + } catch (InvalidTTLException ignored) { + } + } +} diff --git a/test/dorkbox/network/dns/records/TypeBitmapTest.java b/test/dorkbox/network/dns/records/TypeBitmapTest.java new file mode 100644 index 00000000..f12b505d --- /dev/null +++ b/test/dorkbox/network/dns/records/TypeBitmapTest.java @@ -0,0 +1,57 @@ +// -*- Java -*- +// +// Copyright (c) 2011, org.xbill.DNS +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import junit.framework.TestCase; + +public +class TypeBitmapTest extends TestCase { + public + void test_empty() { + TypeBitmap typeBitmap = new TypeBitmap(new int[] {}); + assertEquals(typeBitmap.toString(), ""); + } + + public + void test_typeA() { + TypeBitmap typeBitmap = new TypeBitmap(new int[] {1}); + assertEquals(typeBitmap.toString(), "A"); + } + + public + void test_typeNSandSOA() { + TypeBitmap typeBitmap = new TypeBitmap(new int[] {2, 6}); + assertEquals(typeBitmap.toString(), "NS SOA"); + } +} diff --git a/test/dorkbox/network/dns/records/U16NameBaseTest.java b/test/dorkbox/network/dns/records/U16NameBaseTest.java new file mode 100644 index 00000000..50652a27 --- /dev/null +++ b/test/dorkbox/network/dns/records/U16NameBaseTest.java @@ -0,0 +1,216 @@ +// -*- Java -*- +// +// Copyright (c) 2005, Matthew J. Rutherford +// Copyright (c) 2005, University of Colorado at Boulder +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the University of Colorado at Boulder nor the +// names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.RelativeNameException; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class U16NameBaseTest extends TestCase { + private + void assertEquals(byte[] exp, byte[] act) { + assertTrue(java.util.Arrays.equals(exp, act)); + } + + private static + class TestClass extends U16NameBase { + public + TestClass() {} + + public + TestClass(Name name, int type, int dclass, long ttl) { + super(name, type, dclass, ttl); + } + + public + TestClass(Name name, int type, int dclass, long ttl, int u16Field, String u16Description, Name nameField, String nameDescription) { + super(name, type, dclass, ttl, u16Field, u16Description, nameField, nameDescription); + } + + @Override + public + int getU16Field() { + return super.getU16Field(); + } + + @Override + public + Name getNameField() { + return super.getNameField(); + } + + @Override + public + DnsRecord getObject() { + return null; + } + } + + public + void test_ctor_0arg() { + TestClass tc = new TestClass(); + assertNull(tc.getName()); + assertEquals(0, tc.getType()); + assertEquals(0, tc.getDClass()); + assertEquals(0, tc.getTTL()); + assertEquals(0, tc.getU16Field()); + assertNull(tc.getNameField()); + } + + public + void test_ctor_4arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + + TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xBCDA); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.MX, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(0xBCDA, tc.getTTL()); + assertEquals(0, tc.getU16Field()); + assertNull(tc.getNameField()); + } + + public + void test_ctor_8arg() throws TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.Other.Name."); + + TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); + + assertSame(n, tc.getName()); + assertEquals(DnsRecordType.MX, tc.getType()); + assertEquals(DnsClass.IN, tc.getDClass()); + assertEquals(0xB12FL, tc.getTTL()); + assertEquals(0x1F2B, tc.getU16Field()); + assertEquals(m, tc.getNameField()); + + // an invalid u16 value + try { + new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x10000, "u16 description", m, "name description"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + + // a relative name + Name rel = Name.fromString("My.relative.Name"); + try { + new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", rel, "name description"); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + + } + + public + void test_rrFromWire() throws IOException { + byte[] raw = new byte[] {(byte) 0xBC, (byte) 0x1F, 2, 'M', 'y', 6, 's', 'i', 'N', 'g', 'l', 'E', 4, 'n', 'A', 'm', 'E', 0}; + DnsInput in = new DnsInput(raw); + + TestClass tc = new TestClass(); + tc.rrFromWire(in); + + Name exp = Name.fromString("My.single.name."); + assertEquals(0xBC1FL, tc.getU16Field()); + assertEquals(exp, tc.getNameField()); + } + + public + void test_rdataFromString() throws IOException { + Name exp = Name.fromString("My.Single.Name."); + + Tokenizer t = new Tokenizer(0x19A2 + " My.Single.Name."); + TestClass tc = new TestClass(); + tc.rdataFromString(t, null); + + assertEquals(0x19A2, tc.getU16Field()); + assertEquals(exp, tc.getNameField()); + + t = new Tokenizer("10 My.Relative.Name"); + tc = new TestClass(); + try { + tc.rdataFromString(t, null); + fail("RelativeNameException not thrown"); + } catch (RelativeNameException e) { + } + } + + public + void test_rrToString() throws IOException, TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("My.Other.Name."); + + TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); + + StringBuilder sb = new StringBuilder(); + tc.rrToString(sb); + String out = sb.toString(); + String exp = 0x1F2B + " My.Other.Name."; + + assertEquals(exp, out); + } + + public + void test_rrToWire() throws IOException, TextParseException { + Name n = Name.fromString("My.Name."); + Name m = Name.fromString("M.O.n."); + + TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); + + // canonical + DnsOutput dout = new DnsOutput(); + tc.rrToWire(dout, null, true); + byte[] out = dout.toByteArray(); + byte[] exp = new byte[] {0x1F, 0x2B, 1, 'm', 1, 'o', 1, 'n', 0}; + assertTrue(Arrays.equals(exp, out)); + + // case sensitive + dout = new DnsOutput(); + tc.rrToWire(dout, null, false); + out = dout.toByteArray(); + exp = new byte[] {0x1F, 0x2B, 1, 'M', 1, 'O', 1, 'n', 0}; + assertTrue(Arrays.equals(exp, out)); + } +} diff --git a/test/dorkbox/network/dns/records/URIRecordTest.java b/test/dorkbox/network/dns/records/URIRecordTest.java new file mode 100644 index 00000000..50bd2c01 --- /dev/null +++ b/test/dorkbox/network/dns/records/URIRecordTest.java @@ -0,0 +1,125 @@ +package dorkbox.network.dns.records; + +import java.io.IOException; +import java.util.Arrays; + +import dorkbox.network.dns.DnsInput; +import dorkbox.network.dns.DnsOutput; +import dorkbox.network.dns.Name; +import dorkbox.network.dns.constants.DnsClass; +import dorkbox.network.dns.constants.DnsRecordType; +import dorkbox.network.dns.exceptions.TextParseException; +import dorkbox.network.dns.utils.Tokenizer; +import junit.framework.TestCase; + +public +class URIRecordTest extends TestCase { + public + void test_ctor_0arg() { + URIRecord r = new URIRecord(); + assertNull(r.getName()); + assertEquals(0, r.getType()); + assertEquals(0, r.getDClass()); + assertEquals(0, r.getTTL()); + assertEquals(0, r.getPriority()); + assertEquals(0, r.getWeight()); + assertTrue("".equals(r.getTarget())); + } + + public + void test_getObject() { + URIRecord dr = new URIRecord(); + DnsRecord r = dr.getObject(); + assertTrue(r instanceof URIRecord); + } + + public + void test_ctor_6arg() throws TextParseException { + Name n = Name.fromString("my.name."); + String target = ("http://foo"); + + URIRecord r = new URIRecord(n, DnsClass.IN, 0xABCDEL, 42, 69, target); + assertEquals(n, r.getName()); + assertEquals(DnsRecordType.URI, r.getType()); + assertEquals(DnsClass.IN, r.getDClass()); + assertEquals(0xABCDEL, r.getTTL()); + assertEquals(42, r.getPriority()); + assertEquals(69, r.getWeight()); + assertEquals(target, r.getTarget()); + } + + public + void test_rdataFromString() throws IOException { + Tokenizer t = new Tokenizer(0xABCD + " " + 0xEF01 + " " + "\"http://foo:1234/bar?baz=bum\""); + + URIRecord r = new URIRecord(); + r.rdataFromString(t, null); + assertEquals(0xABCD, r.getPriority()); + assertEquals(0xEF01, r.getWeight()); + assertEquals("http://foo:1234/bar?baz=bum", r.getTarget()); + } + + public + void test_rdataToWire() throws TextParseException { + Name n = Name.fromString("my.name."); + String target = ("http://foo"); + byte[] exp = new byte[] {(byte) 0xbe, (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70, + (byte) 0x3a, (byte) 0x2f, (byte) 0x2f, (byte) 0x66, (byte) 0x6f, (byte) 0x6f}; + + URIRecord r = new URIRecord(n, DnsClass.IN, 0xABCDEL, 0xbeef, 0xdead, target); + DnsOutput out = new DnsOutput(); + r.rrToWire(out, null, true); + assertTrue(Arrays.equals(exp, out.toByteArray())); + } + + public + void test_rrFromWire() throws IOException { + byte[] raw = new byte[] {(byte) 0xbe, (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70, + (byte) 0x3a, (byte) 0x2f, (byte) 0x2f, (byte) 0x66, (byte) 0x6f, (byte) 0x6f}; + DnsInput in = new DnsInput(raw); + + URIRecord r = new URIRecord(); + r.rrFromWire(in); + assertEquals(0xBEEF, r.getPriority()); + assertEquals(0xDEAD, r.getWeight()); + assertEquals("http://foo", r.getTarget()); + } + + public + void test_toobig_priority() throws TextParseException { + try { + new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 0x10000, 42, "http://foo"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_priority() throws TextParseException { + try { + new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, -1, 42, "http://foo"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toobig_weight() throws TextParseException { + try { + new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 42, 0x10000, "http://foo"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + + public + void test_toosmall_weight() throws TextParseException { + try { + new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 42, -1, "http://foo"); + fail("IllegalArgumentException not thrown"); + } catch (IllegalArgumentException e) { + } + } + +} +