001: // -*- Java -*-
002: //
003: // Copyright (c) 2005, Matthew J. Rutherford <rutherfo@cs.colorado.edu>
004: // Copyright (c) 2005, University of Colorado at Boulder
005: // All rights reserved.
006: //
007: // Redistribution and use in source and binary forms, with or without
008: // modification, are permitted provided that the following conditions are
009: // met:
010: //
011: // * Redistributions of source code must retain the above copyright
012: // notice, this list of conditions and the following disclaimer.
013: //
014: // * Redistributions in binary form must reproduce the above copyright
015: // notice, this list of conditions and the following disclaimer in the
016: // documentation and/or other materials provided with the distribution.
017: //
018: // * Neither the name of the University of Colorado at Boulder nor the
019: // names of its contributors may be used to endorse or promote
020: // products derived from this software without specific prior written
021: // permission.
022: //
023: // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
024: // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
025: // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
026: // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
027: // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
028: // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
029: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
030: // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
031: // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
032: // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
033: // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
034: //
035: package org.xbill.DNS;
036:
037: import java.io.IOException;
038: import java.net.UnknownHostException;
039: import java.util.Arrays;
040: import java.util.Random;
041: import junit.framework.Test;
042: import junit.framework.TestCase;
043: import junit.framework.TestSuite;
044:
045: public class SOARecordTest {
046: private final static Random m_random = new Random();
047:
048: private static long randomU16() {
049: return m_random.nextLong() >>> 48;
050: }
051:
052: private static long randomU32() {
053: return m_random.nextLong() >>> 32;
054: }
055:
056: public static class Test_init extends TestCase {
057: private Name m_an, m_rn, m_host, m_admin;
058: private long m_ttl, m_serial, m_refresh, m_retry, m_expire,
059: m_minimum;
060:
061: protected void setUp() throws TextParseException,
062: UnknownHostException {
063: m_an = Name.fromString("My.Absolute.Name.");
064: m_rn = Name.fromString("My.Relative.Name");
065: m_host = Name.fromString("My.Host.Name.");
066: m_admin = Name.fromString("My.Administrative.Name.");
067: m_ttl = randomU16();
068: m_serial = randomU32();
069: m_refresh = randomU32();
070: m_retry = randomU32();
071: m_expire = randomU32();
072: m_minimum = randomU32();
073: }
074:
075: public void test_0arg() throws UnknownHostException {
076: SOARecord ar = new SOARecord();
077: assertNull(ar.getName());
078: assertEquals(0, ar.getType());
079: assertEquals(0, ar.getDClass());
080: assertEquals(0, ar.getTTL());
081: assertNull(ar.getHost());
082: assertNull(ar.getAdmin());
083: assertEquals(0, ar.getSerial());
084: assertEquals(0, ar.getRefresh());
085: assertEquals(0, ar.getRetry());
086: assertEquals(0, ar.getExpire());
087: assertEquals(0, ar.getMinimum());
088: }
089:
090: public void test_getObject() {
091: SOARecord ar = new SOARecord();
092: Record r = ar.getObject();
093: assertTrue(r instanceof SOARecord);
094: }
095:
096: public void test_10arg() {
097: SOARecord ar = new SOARecord(m_an, DClass.IN, m_ttl,
098: m_host, m_admin, m_serial, m_refresh, m_retry,
099: m_expire, m_minimum);
100: assertEquals(m_an, ar.getName());
101: assertEquals(Type.SOA, ar.getType());
102: assertEquals(DClass.IN, ar.getDClass());
103: assertEquals(m_ttl, ar.getTTL());
104: assertEquals(m_host, ar.getHost());
105: assertEquals(m_admin, ar.getAdmin());
106: assertEquals(m_serial, ar.getSerial());
107: assertEquals(m_refresh, ar.getRefresh());
108: assertEquals(m_retry, ar.getRetry());
109: assertEquals(m_expire, ar.getExpire());
110: assertEquals(m_minimum, ar.getMinimum());
111: }
112:
113: public void test_10arg_relative_name() {
114: try {
115: new SOARecord(m_rn, DClass.IN, m_ttl, m_host, m_admin,
116: m_serial, m_refresh, m_retry, m_expire,
117: m_minimum);
118: fail("RelativeNameException not thrown");
119: } catch (RelativeNameException e) {
120: }
121: }
122:
123: public void test_10arg_relative_host() {
124: try {
125: new SOARecord(m_an, DClass.IN, m_ttl, m_rn, m_admin,
126: m_serial, m_refresh, m_retry, m_expire,
127: m_minimum);
128: fail("RelativeNameException not thrown");
129: } catch (RelativeNameException e) {
130: }
131: }
132:
133: public void test_10arg_relative_admin() {
134: try {
135: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_rn,
136: m_serial, m_refresh, m_retry, m_expire,
137: m_minimum);
138: fail("RelativeNameException not thrown");
139: } catch (RelativeNameException e) {
140: }
141: }
142:
143: public void test_10arg_negative_serial() {
144: try {
145: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
146: -1, m_refresh, m_retry, m_expire, m_minimum);
147: fail("IllegalArgumentException not thrown");
148: } catch (IllegalArgumentException e) {
149: }
150: }
151:
152: public void test_10arg_toobig_serial() {
153: try {
154: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
155: 0x100000000L, m_refresh, m_retry, m_expire,
156: m_minimum);
157: fail("IllegalArgumentException not thrown");
158: } catch (IllegalArgumentException e) {
159: }
160: }
161:
162: public void test_10arg_negative_refresh() {
163: try {
164: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
165: m_serial, -1, m_retry, m_expire, m_minimum);
166: fail("IllegalArgumentException not thrown");
167: } catch (IllegalArgumentException e) {
168: }
169: }
170:
171: public void test_10arg_toobig_refresh() {
172: try {
173: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
174: m_serial, 0x100000000L, m_retry, m_expire,
175: m_minimum);
176: fail("IllegalArgumentException not thrown");
177: } catch (IllegalArgumentException e) {
178: }
179: }
180:
181: public void test_10arg_negative_retry() {
182: try {
183: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
184: m_serial, m_refresh, -1, m_expire, m_minimum);
185: fail("IllegalArgumentException not thrown");
186: } catch (IllegalArgumentException e) {
187: }
188: }
189:
190: public void test_10arg_toobig_retry() {
191: try {
192: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
193: m_serial, m_refresh, 0x100000000L, m_expire,
194: m_minimum);
195: fail("IllegalArgumentException not thrown");
196: } catch (IllegalArgumentException e) {
197: }
198: }
199:
200: public void test_10arg_negative_expire() {
201: try {
202: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
203: m_serial, m_refresh, m_retry, -1, m_minimum);
204: fail("IllegalArgumentException not thrown");
205: } catch (IllegalArgumentException e) {
206: }
207: }
208:
209: public void test_10arg_toobig_expire() {
210: try {
211: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
212: m_serial, m_refresh, m_retry, 0x100000000L,
213: m_minimum);
214: fail("IllegalArgumentException not thrown");
215: } catch (IllegalArgumentException e) {
216: }
217: }
218:
219: public void test_10arg_negative_minimun() {
220: try {
221: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
222: m_serial, m_refresh, m_retry, m_expire, -1);
223: fail("IllegalArgumentException not thrown");
224: } catch (IllegalArgumentException e) {
225: }
226: }
227:
228: public void test_10arg_toobig_minimum() {
229: try {
230: new SOARecord(m_an, DClass.IN, m_ttl, m_host, m_admin,
231: m_serial, m_refresh, m_retry, m_expire,
232: 0x100000000L);
233: fail("IllegalArgumentException not thrown");
234: } catch (IllegalArgumentException e) {
235: }
236: }
237: }
238:
239: public static class Test_rrFromWire extends TestCase {
240: private Name m_host, m_admin;
241: private long m_serial, m_refresh, m_retry, m_expire, m_minimum;
242:
243: protected void setUp() throws TextParseException,
244: UnknownHostException {
245: m_host = Name.fromString("M.h.N.");
246: m_admin = Name.fromString("M.a.n.");
247: m_serial = 0xABCDEF12L;
248: m_refresh = 0xCDEF1234L;
249: m_retry = 0xEF123456L;
250: m_expire = 0x12345678L;
251: m_minimum = 0x3456789AL;
252: }
253:
254: public void test() throws IOException {
255: byte[] raw = new byte[] { 1, 'm', 1, 'h', 1, 'n', 0, // host
256: 1, 'm', 1, 'a', 1, 'n', 0, // admin
257: (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial
258: (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh
259: (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry
260: (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire
261: (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A }; // minimum
262:
263: DNSInput di = new DNSInput(raw);
264: SOARecord ar = new SOARecord();
265:
266: ar.rrFromWire(di);
267:
268: assertEquals(m_host, ar.getHost());
269: assertEquals(m_admin, ar.getAdmin());
270: assertEquals(m_serial, ar.getSerial());
271: assertEquals(m_refresh, ar.getRefresh());
272: assertEquals(m_retry, ar.getRetry());
273: assertEquals(m_expire, ar.getExpire());
274: assertEquals(m_minimum, ar.getMinimum());
275: }
276: }
277:
278: public static class Test_rdataFromString extends TestCase {
279: private Name m_host, m_admin, m_origin;
280: private long m_serial, m_refresh, m_retry, m_expire, m_minimum;
281:
282: protected void setUp() throws TextParseException,
283: UnknownHostException {
284: m_origin = Name.fromString("O.");
285: m_host = Name.fromString("M.h", m_origin);
286: m_admin = Name.fromString("M.a.n.");
287: m_serial = 0xABCDEF12L;
288: m_refresh = 0xCDEF1234L;
289: m_retry = 0xEF123456L;
290: m_expire = 0x12345678L;
291: m_minimum = 0x3456789AL;
292: }
293:
294: public void test_valid() throws IOException {
295: Tokenizer t = new Tokenizer("M.h " + m_admin + " "
296: + m_serial + " " + m_refresh + " " + m_retry + " "
297: + m_expire + " " + m_minimum);
298: SOARecord ar = new SOARecord();
299:
300: ar.rdataFromString(t, m_origin);
301:
302: assertEquals(m_host, ar.getHost());
303: assertEquals(m_admin, ar.getAdmin());
304: assertEquals(m_serial, ar.getSerial());
305: assertEquals(m_refresh, ar.getRefresh());
306: assertEquals(m_retry, ar.getRetry());
307: assertEquals(m_expire, ar.getExpire());
308: assertEquals(m_minimum, ar.getMinimum());
309: }
310:
311: public void test_relative_name() throws IOException {
312: Tokenizer t = new Tokenizer("M.h " + m_admin + " "
313: + m_serial + " " + m_refresh + " " + m_retry + " "
314: + m_expire + " " + m_minimum);
315: SOARecord ar = new SOARecord();
316:
317: try {
318: ar.rdataFromString(t, null);
319: fail("RelativeNameException not thrown");
320: } catch (RelativeNameException e) {
321: }
322: }
323: }
324:
325: public static class Test_rrToString extends TestCase {
326: private Name m_an, m_host, m_admin;
327: private long m_ttl, m_serial, m_refresh, m_retry, m_expire,
328: m_minimum;
329:
330: protected void setUp() throws TextParseException {
331: m_an = Name.fromString("My.absolute.name.");
332: m_ttl = 0x13A8;
333: m_host = Name.fromString("M.h.N.");
334: m_admin = Name.fromString("M.a.n.");
335: m_serial = 0xABCDEF12L;
336: m_refresh = 0xCDEF1234L;
337: m_retry = 0xEF123456L;
338: m_expire = 0x12345678L;
339: m_minimum = 0x3456789AL;
340: }
341:
342: public void test_singleLine() {
343: SOARecord ar = new SOARecord(m_an, DClass.IN, m_ttl,
344: m_host, m_admin, m_serial, m_refresh, m_retry,
345: m_expire, m_minimum);
346: String exp = m_host + " " + m_admin + " " + m_serial + " "
347: + m_refresh + " " + m_retry + " " + m_expire + " "
348: + m_minimum;
349:
350: String out = ar.rrToString();
351:
352: assertEquals(exp, out);
353: }
354:
355: public void test_multiLine() {
356: SOARecord ar = new SOARecord(m_an, DClass.IN, m_ttl,
357: m_host, m_admin, m_serial, m_refresh, m_retry,
358: m_expire, m_minimum);
359: String re = "^.*\\(\\n" + "\\s*" + m_serial
360: + "\\s*;\\s*serial\\n" + // serial
361: "\\s*" + m_refresh + "\\s*;\\s*refresh\\n" + // refresh
362: "\\s*" + m_retry + "\\s*;\\s*retry\\n" + // retry
363: "\\s*" + m_expire + "\\s*;\\s*expire\\n" + // expire
364: "\\s*" + m_minimum + "\\s*\\)\\s*;\\s*minimum$"; // minimum
365:
366: Options.set("multiline");
367: String out = ar.rrToString();
368: Options.unset("multiline");
369:
370: assertTrue(out.matches(re));
371: }
372: }
373:
374: public static class Test_rrToWire extends TestCase {
375: private Name m_an, m_host, m_admin;
376: private long m_ttl, m_serial, m_refresh, m_retry, m_expire,
377: m_minimum;
378:
379: protected void setUp() throws TextParseException {
380: m_an = Name.fromString("My.Abs.Name.");
381: m_ttl = 0x13A8;
382: m_host = Name.fromString("M.h.N.");
383: m_admin = Name.fromString("M.a.n.");
384: m_serial = 0xABCDEF12L;
385: m_refresh = 0xCDEF1234L;
386: m_retry = 0xEF123456L;
387: m_expire = 0x12345678L;
388: m_minimum = 0x3456789AL;
389: }
390:
391: public void test_canonical() {
392: byte[] exp = new byte[] { 1, 'm', 1, 'h', 1, 'n', 0, // host
393: 1, 'm', 1, 'a', 1, 'n', 0, // admin
394: (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial
395: (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh
396: (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry
397: (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire
398: (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A }; // minimum
399:
400: SOARecord ar = new SOARecord(m_an, DClass.IN, m_ttl,
401: m_host, m_admin, m_serial, m_refresh, m_retry,
402: m_expire, m_minimum);
403: DNSOutput o = new DNSOutput();
404: ar.rrToWire(o, null, true);
405:
406: assertTrue(Arrays.equals(exp, o.toByteArray()));
407: }
408:
409: public void test_case_sensitive() {
410: byte[] exp = new byte[] { 1, 'M', 1, 'h', 1, 'N', 0, // host
411: 1, 'M', 1, 'a', 1, 'n', 0, // admin
412: (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial
413: (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh
414: (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry
415: (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire
416: (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A }; // minimum
417:
418: SOARecord ar = new SOARecord(m_an, DClass.IN, m_ttl,
419: m_host, m_admin, m_serial, m_refresh, m_retry,
420: m_expire, m_minimum);
421: DNSOutput o = new DNSOutput();
422: ar.rrToWire(o, null, false);
423:
424: assertTrue(Arrays.equals(exp, o.toByteArray()));
425: }
426: }
427:
428: public static Test suite() {
429: TestSuite s = new TestSuite();
430: s.addTestSuite(Test_init.class);
431: s.addTestSuite(Test_rrFromWire.class);
432: s.addTestSuite(Test_rdataFromString.class);
433: s.addTestSuite(Test_rrToString.class);
434: s.addTestSuite(Test_rrToWire.class);
435: return s;
436: }
437: }
|