1 // -*- Java -*-
2 //
3 // Copyright (c) 2005, Matthew J. Rutherford <rutherfo@cs.colorado.edu>
4 // Copyright (c) 2005, University of Colorado at Boulder
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // * Redistributions of source code must retain the above copyright
12 //   notice, this list of conditions and the following disclaimer.
13 //
14 // * Redistributions in binary form must reproduce the above copyright
15 //   notice, this list of conditions and the following disclaimer in the
16 //   documentation and/or other materials provided with the distribution.
17 //
18 // * Neither the name of the University of Colorado at Boulder nor the
19 //   names of its contributors may be used to endorse or promote
20 //   products derived from this software without specific prior written
21 //   permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 package org.xbill.DNS;
36 
37 import	java.net.InetAddress;
38 import	java.net.UnknownHostException;
39 import	java.util.Date;
40 import	java.util.Iterator;
41 import	junit.framework.TestCase;
42 import	org.xbill.DNS.ARecord;
43 import	org.xbill.DNS.CNAMERecord;
44 import	org.xbill.DNS.DClass;
45 import	org.xbill.DNS.Name;
46 import	org.xbill.DNS.RRset;
47 import	org.xbill.DNS.Record;
48 import	org.xbill.DNS.RRSIGRecord;
49 import	org.xbill.DNS.TextParseException;
50 import	org.xbill.DNS.Type;
51 
52 public class RRsetTest extends TestCase
53 {
54     private RRset m_rs;
55     Name m_name, m_name2;
56     long m_ttl;
57     ARecord m_a1, m_a2;
58     RRSIGRecord m_s1, m_s2;
59 
setUp()60     public void setUp() throws TextParseException, UnknownHostException
61     {
62 	m_rs = new RRset();
63 	m_name = Name.fromString("this.is.a.test.");
64 	m_name2 = Name.fromString("this.is.another.test.");
65 	m_ttl = 0xABCDL;
66 	m_a1 = new ARecord(m_name, DClass.IN, m_ttl,
67 			   InetAddress.getByName("192.169.232.11"));
68 	m_a2 = new ARecord(m_name, DClass.IN, m_ttl+1,
69 			   InetAddress.getByName("192.169.232.12"));
70 
71 	m_s1 = new RRSIGRecord(m_name, DClass.IN, m_ttl, Type.A, 0xF, 0xABCDEL,
72 			       new Date(), new Date(), 0xA, m_name,
73 			       new byte[ 0 ]);
74 	m_s2 = new RRSIGRecord(m_name, DClass.IN, m_ttl, Type.A, 0xF, 0xABCDEL,
75 			       new Date(), new Date(), 0xA, m_name2,
76 			       new byte[ 0 ]);
77     }
78 
test_ctor_0arg()79     public void test_ctor_0arg()
80     {
81 	assertEquals(0, m_rs.size());
82 	try {m_rs.getDClass(); fail("IllegalStateException not thrown");}
83 	catch( IllegalStateException e ){}
84 	try {m_rs.getType();fail("IllegalStateException not thrown");}
85 	catch( IllegalStateException e ){}
86 	try {m_rs.getTTL();fail("IllegalStateException not thrown");}
87 	catch( IllegalStateException e ){}
88 	try {m_rs.getName();fail("IllegalStateException not thrown");}
89 	catch( IllegalStateException e ){}
90 	try {m_rs.first();fail("IllegalStateException not thrown");}
91 	catch( IllegalStateException e ){}
92 
93 	assertEquals("{empty}", m_rs.toString());
94 
95 	Iterator itr = m_rs.rrs();
96 	assertNotNull(itr);
97 	assertFalse(itr.hasNext());
98 
99 	itr = m_rs.sigs();
100 	assertNotNull(itr);
101 	assertFalse(itr.hasNext());
102     }
103 
test_basics()104     public void test_basics() throws TextParseException,
105 				     UnknownHostException
106     {
107 	m_rs.addRR(m_a1);
108 
109 	assertEquals(1, m_rs.size());
110 	assertEquals(DClass.IN, m_rs.getDClass());
111 	assertEquals(m_a1, m_rs.first());
112 	assertEquals(m_name, m_rs.getName());
113 	assertEquals(m_ttl, m_rs.getTTL());
114 	assertEquals(Type.A, m_rs.getType());
115 
116 	// add it again, and make sure nothing changed
117 	m_rs.addRR(m_a1);
118 
119 	assertEquals(1, m_rs.size());
120 	assertEquals(DClass.IN, m_rs.getDClass());
121 	assertEquals(m_a1, m_rs.first());
122 	assertEquals(m_name, m_rs.getName());
123 	assertEquals(m_ttl, m_rs.getTTL());
124 	assertEquals(Type.A, m_rs.getType());
125 
126 	m_rs.addRR(m_a2);
127 
128 	assertEquals(2, m_rs.size());
129 	assertEquals(DClass.IN, m_rs.getDClass());
130 	Record r = m_rs.first();
131 	assertEquals(m_a1, r);
132 	assertEquals(m_name, m_rs.getName());
133 	assertEquals(m_ttl, m_rs.getTTL());
134 	assertEquals(Type.A, m_rs.getType());
135 
136 	Iterator itr = m_rs.rrs();
137 	assertEquals(m_a1, itr.next());
138 	assertEquals(m_a2, itr.next());
139 
140 	// make sure that it rotates
141 	itr = m_rs.rrs();
142 	assertEquals(m_a2, itr.next());
143 	assertEquals(m_a1, itr.next());
144 	itr = m_rs.rrs();
145 	assertEquals(m_a1, itr.next());
146 	assertEquals(m_a2, itr.next());
147 
148 	m_rs.deleteRR(m_a1);
149 	assertEquals(1, m_rs.size());
150 	assertEquals(DClass.IN, m_rs.getDClass());
151 	assertEquals(m_a2, m_rs.first());
152 	assertEquals(m_name, m_rs.getName());
153 	assertEquals(m_ttl, m_rs.getTTL());
154 	assertEquals(Type.A, m_rs.getType());
155 
156 	// the signature records
157 	m_rs.addRR(m_s1);
158 	assertEquals(1, m_rs.size());
159 	itr = m_rs.sigs();
160 	assertEquals(m_s1, itr.next());
161 	assertFalse(itr.hasNext());
162 
163 	m_rs.addRR(m_s1);
164 	itr = m_rs.sigs();
165 	assertEquals(m_s1, itr.next());
166 	assertFalse(itr.hasNext());
167 
168 	m_rs.addRR(m_s2);
169 	itr = m_rs.sigs();
170 	assertEquals(m_s1, itr.next());
171 	assertEquals(m_s2, itr.next());
172 	assertFalse(itr.hasNext());
173 
174 	m_rs.deleteRR(m_s1);
175 	itr = m_rs.sigs();
176 	assertEquals(m_s2, itr.next());
177 	assertFalse(itr.hasNext());
178 
179 
180 	// clear it all
181 	m_rs.clear();
182 	assertEquals(0, m_rs.size());
183 	assertFalse(m_rs.rrs().hasNext());
184 	assertFalse(m_rs.sigs().hasNext());
185 
186     }
187 
test_ctor_1arg()188     public void test_ctor_1arg()
189     {
190 	m_rs.addRR(m_a1);
191 	m_rs.addRR(m_a2);
192 	m_rs.addRR(m_s1);
193 	m_rs.addRR(m_s2);
194 
195 	RRset rs2 = new RRset( m_rs );
196 
197 	assertEquals(2, rs2.size());
198 	assertEquals(m_a1, rs2.first());
199 	Iterator itr = rs2.rrs();
200 	assertEquals(m_a1, itr.next());
201 	assertEquals(m_a2, itr.next());
202 	assertFalse(itr.hasNext());
203 
204 	itr = rs2.sigs();
205 	assertTrue(itr.hasNext());
206 	assertEquals(m_s1, itr.next());
207 	assertTrue(itr.hasNext());
208 	assertEquals(m_s2, itr.next());
209 	assertFalse(itr.hasNext());
210     }
211 
test_toString()212     public void test_toString()
213     {
214 	m_rs.addRR(m_a1);
215 	m_rs.addRR(m_a2);
216 	m_rs.addRR(m_s1);
217 	m_rs.addRR(m_s2);
218 
219 	String out = m_rs.toString();
220 
221 	assertTrue(out.indexOf(m_name.toString()) != -1);
222 	assertTrue(out.indexOf(" IN A ") != -1);
223 	assertTrue(out.indexOf("[192.169.232.11]") != -1);
224 	assertTrue(out.indexOf("[192.169.232.12]") != -1);
225     }
226 
test_addRR_invalidType()227     public void test_addRR_invalidType() throws TextParseException
228     {
229 	m_rs.addRR(m_a1);
230 
231 	CNAMERecord c = new CNAMERecord(m_name, DClass.IN, m_ttl, Name.fromString("an.alias."));
232 
233 	try {
234 	    m_rs.addRR(c);
235 	    fail("IllegalArgumentException not thrown");
236 	}
237 	catch( IllegalArgumentException e ){
238 	}
239     }
240 
test_addRR_invalidName()241     public void test_addRR_invalidName() throws TextParseException, UnknownHostException
242     {
243 	m_rs.addRR(m_a1);
244 
245 	m_a2 = new ARecord(m_name2, DClass.IN, m_ttl,
246 			   InetAddress.getByName("192.169.232.11"));
247 
248 	try {
249 	    m_rs.addRR(m_a2);
250 	    fail("IllegalArgumentException not thrown");
251 	}
252 	catch( IllegalArgumentException e ){
253 	}
254     }
255 
test_addRR_invalidDClass()256     public void test_addRR_invalidDClass() throws TextParseException, UnknownHostException
257     {
258 	m_rs.addRR(m_a1);
259 
260 	m_a2 = new ARecord(m_name, DClass.CHAOS, m_ttl,
261 			   InetAddress.getByName("192.169.232.11"));
262 
263 	try {
264 	    m_rs.addRR(m_a2);
265 	    fail("IllegalArgumentException not thrown");
266 	}
267 	catch( IllegalArgumentException e ){
268 	}
269     }
270 
test_TTLcalculation()271     public void test_TTLcalculation()
272     {
273 	m_rs.addRR(m_a2);
274 	assertEquals(m_a2.getTTL(), m_rs.getTTL());
275 	m_rs.addRR(m_a1);
276 	assertEquals(m_a1.getTTL(), m_rs.getTTL());
277 
278 	Iterator itr = m_rs.rrs();
279 	while( itr.hasNext() ){
280 	    Record r = (Record)itr.next();
281 	    assertEquals( m_a1.getTTL(), r.getTTL());
282 	}
283     }
284 
test_Record_placement()285     public void test_Record_placement()
286     {
287 	m_rs.addRR(m_a1);
288 	m_rs.addRR(m_s1);
289 	m_rs.addRR(m_a2);
290 
291 	Iterator itr = m_rs.rrs();
292 	assertTrue(itr.hasNext());
293 	assertEquals(m_a1, itr.next());
294 	assertTrue(itr.hasNext());
295 	assertEquals(m_a2, itr.next());
296 	assertFalse(itr.hasNext());
297 
298 	itr = m_rs.sigs();
299 	assertTrue(itr.hasNext());
300 	assertEquals(m_s1, itr.next());
301 	assertFalse(itr.hasNext());
302     }
303 
test_noncycling_iterator()304     public void test_noncycling_iterator()
305     {
306 	m_rs.addRR(m_a1);
307 	m_rs.addRR(m_a2);
308 
309 	Iterator itr = m_rs.rrs(false);
310 	assertTrue(itr.hasNext());
311 	assertEquals(m_a1, itr.next());
312 	assertTrue(itr.hasNext());
313 	assertEquals(m_a2, itr.next());
314 
315 	itr = m_rs.rrs(false);
316 	assertTrue(itr.hasNext());
317 	assertEquals(m_a1, itr.next());
318 	assertTrue(itr.hasNext());
319 	assertEquals(m_a2, itr.next());
320     }
321 }
322