1/* -*- Mode: Java; tab-width: 4 -*-
2 *
3 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * DNSSDUnitTest is a simple program that exercises parts of the DNSSD API.
18 */
19
20import com.apple.dnssd.*;
21
22import java.net.*;
23import java.util.*;
24
25
26class	DNSSDUnitTest
27{
28	public static final String	TEST_TYPE = "_unittest._udp";
29	public static final String	WIRE_CHAR_SET = "ISO-8859-1";
30
31	public DNSSDUnitTest	fInstance = null;
32
33	public		DNSSDUnitTest() throws Exception
34	{
35		fStage = 0;
36		fInstance = this;
37
38		Enumeration	en = NetworkInterface.getNetworkInterfaces();
39		while ( en.hasMoreElements())
40			System.out.println( ((NetworkInterface) en.nextElement()).getName());
41	}
42
43	public void	testTxtRecord()
44	{
45		byte[]		src = { 6, 'a', 't', '=', 'X', 'Y', 'Z' };
46		TXTRecord	txtRecord = new TXTRecord( src);
47		String		a;
48
49		txtRecord.set( "path", "~/names");
50		txtRecord.set( "rw", (String) null);
51		txtRecord.set( "empty", "");
52		txtRecord.set( "ttl", "4");
53
54		byte[]	rawBytes = txtRecord.getRawBytes();
55		System.out.println( ( new String( rawBytes, 0, rawBytes.length)) + " has count " +
56								String.valueOf( txtRecord.size()));
57
58		System.out.println( txtRecord);
59		boolean		ttlPresent = txtRecord.contains( "ttl");
60		System.out.println( "ttl is present: " + ( ttlPresent ? "true" : "false"));
61		boolean		timeoutPresent = txtRecord.contains( "timeout");
62		System.out.println( "timeout is present: " + ( timeoutPresent ? "true" : "false"));
63
64		txtRecord.set( "path", "~/numbers");
65		System.out.println( txtRecord);
66
67		txtRecord.remove( "ttl");
68		System.out.println( txtRecord);
69
70		txtRecord.remove( "path");
71		System.out.println( txtRecord);
72
73		txtRecord.remove( "at");
74		System.out.println( txtRecord);
75
76		txtRecord.set( "rw", "1");
77		System.out.println( txtRecord);
78	}
79
80	public void	run() throws DNSSDException
81	{
82		System.out.println( "Running DNSSD unit test for " + System.getProperty( "user.name"));
83
84		this.testTxtRecord();
85
86		fRegTest = new RegTest();
87		new BrowseTest();
88		new DomainTest();
89		new RegistrarTest();
90
91		this.waitForEnd();
92	}
93
94	protected int		fStage;
95	protected RegTest	fRegTest;
96
97	public synchronized void bumpStage()
98	{
99		fStage++;
100		this.notifyAll();
101	}
102
103	protected synchronized void waitForEnd()
104	{
105		int stage = fStage;
106		while ( stage == fStage)
107		{
108			try {
109				wait();
110			} catch (InterruptedException e) {}
111		}
112	}
113
114    public static void main(String s[])
115    {
116    	try {
117			new DNSSDUnitTest().run();
118		}
119		catch ( Exception e) { terminateWithException( e); }
120    }
121
122	protected static void	terminateWithException( Exception e)
123	{
124		e.printStackTrace();
125		System.exit( -1);
126	}
127}
128
129class	TermReporter implements BaseListener
130{
131	public void	operationFailed( DNSSDService service, int errorCode)
132	{
133		System.out.println( this.getClass().getName() + " encountered error " + String.valueOf( errorCode));
134	}
135
136	protected void finalize() throws Throwable
137	{
138		System.out.println( "Instance of " + this.getClass().getName() + " has been destroyed");
139	}
140}
141
142class	RegTest extends TermReporter implements RegisterListener
143{
144	public static final int		TEST_PORT = 5678;
145
146	public		RegTest() throws DNSSDException
147	{
148		fReg = DNSSD.register( 0, 0, "Test service", DNSSDUnitTest.TEST_TYPE, "", "", TEST_PORT, null, this);
149	}
150
151	public void	serviceRegistered( DNSSDRegistration registration, int flags, String serviceName,
152								String regType, String domain)
153	{
154		String s = "RegTest result flags:" + String.valueOf( flags) +
155					" serviceName:" + serviceName + " regType:" + regType + " domain:" + domain;
156		System.out.println( s);
157
158		try {
159			new DupRegTest();
160
161			byte[]	kResponsiblePerson = { 'c','o','o','k','i','e',' ','m','o','n','s','t','e','r' };
162			fReg.addRecord( 0, 17 /*ns_t_rp*/, kResponsiblePerson, 3600);
163			new QueryTest( 0, 0, "Test service", 17 /*ns_t_rp*/, 1);
164		} catch( Exception e) { e.printStackTrace(); }
165	}
166
167	protected DNSSDRegistration	fReg;
168}
169
170class	DupRegTest extends TermReporter implements RegisterListener
171{
172	public static final int		TEST_PORT = 5678;
173
174	public		DupRegTest() throws DNSSDException
175	{
176		DNSSD.register( DNSSD.NO_AUTO_RENAME | DNSSD.UNIQUE, 0, "Test service", DNSSDUnitTest.TEST_TYPE, "", "", TEST_PORT + 1, null, this);
177	}
178
179	public void	serviceRegistered( DNSSDRegistration registration, int flags, String serviceName,
180								String regType, String domain)
181	{
182		System.out.println( "Oik - registered a duplicate!");
183		String s = "DupRegTest result flags:" + String.valueOf( flags) +
184					" serviceName:" + serviceName + " regType:" + regType + " domain:" + domain;
185		System.out.println( s);
186	}
187}
188
189class	BrowseTest extends TermReporter implements BrowseListener
190{
191	public		BrowseTest()
192	{
193		try {
194			DNSSD.browse( 0, 0, DNSSDUnitTest.TEST_TYPE, "", this);
195		} catch( Exception e) { e.printStackTrace(); }
196	}
197
198	public void	serviceFound( DNSSDService browser, int flags, int ifIndex,
199							String serviceName, String regType, String domain)
200	{
201		String s = "BrowseTest found flags:" + String.valueOf( flags) +
202					" ifIndex:" + String.valueOf( ifIndex) +
203					" serviceName:" + serviceName + " regType:" + regType + " domain:" + domain;
204		System.out.println( s);
205
206		System.out.println( "Resolving " + serviceName);
207		new ResolveTest( 0, ifIndex, serviceName, regType, domain);
208	}
209
210	public void	serviceLost( DNSSDService browser, int flags, int ifIndex,
211							String serviceName, String regType, String domain)
212	{
213		String s = "BrowseTest lost flags:" + String.valueOf( flags) +
214					" ifIndex:" + String.valueOf( ifIndex) +
215					" serviceName:" + serviceName + " regType:" + regType + " domain:" + domain;
216		System.out.println( s);
217	}
218
219	public void	operationFailed( DNSSDService service, int errorCode)
220	{
221		System.out.println( "Browse failed " + String.valueOf( errorCode));
222	}
223}
224
225class	DomainTest extends TermReporter implements DomainListener
226{
227	public		DomainTest()
228	{
229		try {
230			DNSSD.enumerateDomains( DNSSD.BROWSE_DOMAINS, 0, this);
231		} catch( Exception e) { e.printStackTrace(); }
232	}
233
234	public void	domainFound( DNSSDService enumerator, int flags, int ifIndex, String domain)
235	{
236		String s = "Domain found flags:" + String.valueOf( flags) +
237					" ifIndex:" + String.valueOf( ifIndex) +
238					" domain:" + domain;
239		System.out.println( s);
240	}
241
242	public void	domainLost( DNSSDService enumerator, int flags, int ifIndex, String domain)
243	{
244		String s = "Domain lost flags:" + String.valueOf( flags) +
245					" ifIndex:" + String.valueOf( ifIndex) +
246					" domain:" + domain;
247		System.out.println( s);
248	}
249
250	public void	operationFailed( DNSSDService service, int errorCode)
251	{
252		System.out.println( "Domain enum op failed " + String.valueOf( errorCode));
253	}
254}
255
256class	ResolveTest extends TermReporter implements ResolveListener
257{
258	public		ResolveTest( int flags, int ifIndex, String serviceName, String regType,
259							String domain)
260	{
261		try {
262			DNSSD.resolve( flags, ifIndex, serviceName, regType, domain, this);
263		} catch( Exception e) { e.printStackTrace(); }
264	}
265
266	public void	serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
267								String hostName, int port, TXTRecord txtRecord)
268	{
269		String a;
270		String s = "ResolveTest result flags:" + String.valueOf( flags) +
271					" ifIndex:" + String.valueOf( ifIndex) +
272					" fullName:" + fullName + " hostName:" + hostName + " port:" + String.valueOf( port);
273		for ( int i=0; null != ( a = txtRecord.getKey( i)); i++)
274			s += " attr/val " + String.valueOf( i) + ": " + a + "," + txtRecord.getValueAsString( i);
275
276		System.out.println( s);
277
278		System.out.println( "Querying " + hostName);
279		new QueryTest( 0, ifIndex, hostName, 1 /* ns_t_a */, 1 /* ns_c_in */);
280	}
281}
282
283class	QueryTest extends TermReporter implements QueryListener
284{
285	public		QueryTest( int flags, int ifIndex, String serviceName, int rrtype, int rrclass)
286	{
287		try {
288			DNSSD.queryRecord( flags, ifIndex, serviceName, rrtype, rrclass, this);
289		} catch( Exception e) { e.printStackTrace(); }
290	}
291
292	public void	queryAnswered( DNSSDService query, int flags, int ifIndex, String fullName,
293								int rrtype, int rrclass, byte[] rdata, int ttl)
294	{
295		String s = "QueryTest result flags:" + String.valueOf( flags) +
296					" ifIndex:" + String.valueOf( ifIndex) +
297					" fullName:" + fullName + " rrtype:" + String.valueOf( rrtype) +
298					" rrclass:" + String.valueOf( rrclass) + " ttl:" + String.valueOf( ttl);
299		System.out.println( s);
300
301		try {
302			String	dataTxt = new String( rdata, 0, rdata.length, DNSSDUnitTest.WIRE_CHAR_SET);
303			System.out.println( "Query data is:" + dataTxt);
304		} catch( Exception e) { e.printStackTrace(); }
305	}
306}
307
308class	RegistrarTest extends TermReporter implements RegisterRecordListener
309{
310	public		RegistrarTest()
311	{
312		try {
313			byte[]	kResponsiblePerson = { 'g','r','o','v','e','r' };
314			fRegistrar = DNSSD.createRecordRegistrar( this);
315			fRegistrar.registerRecord( DNSSD.UNIQUE, 0,
316					"test.registrartest.local", 17 /*ns_t_rp*/, 1, kResponsiblePerson, 3600);
317		} catch( Exception e) { e.printStackTrace(); }
318	}
319
320	public void	recordRegistered( DNSRecord record, int flags)
321	{
322		String s = "RegistrarTest result flags:" + String.valueOf( flags);
323		System.out.println( s);
324
325		try {
326			byte[]	kResponsiblePerson = { 'e','l','m','o' };
327			record.update( 0, kResponsiblePerson, 3600);
328			record.remove();
329		} catch( Exception e) { e.printStackTrace(); }
330	}
331
332	protected DNSSDRecordRegistrar	fRegistrar;
333}
334
335