View Javadoc

1   /**
2    *
3    */
4   package javax.jmdns.test;
5   
6   import static junit.framework.Assert.assertEquals;
7   import static junit.framework.Assert.assertNull;
8   import static junit.framework.Assert.assertNotNull;
9   import static junit.framework.Assert.assertTrue;
10  
11  import java.io.IOException;
12  import java.util.ArrayList;
13  import java.util.Collections;
14  import java.util.Enumeration;
15  import java.util.HashMap;
16  import java.util.List;
17  import java.util.Map;
18  import java.util.logging.ConsoleHandler;
19  import java.util.logging.Level;
20  import java.util.logging.LogManager;
21  import java.util.logging.Logger;
22  
23  import javax.jmdns.JmDNS;
24  import javax.jmdns.ServiceEvent;
25  import javax.jmdns.ServiceInfo;
26  import javax.jmdns.ServiceListener;
27  import javax.jmdns.impl.constants.DNSConstants;
28  import javax.jmdns.impl.tasks.state.DNSStateTask;
29  
30  import org.junit.Before;
31  import org.junit.Test;
32  
33  /**
34   *
35   */
36  public class TextUpdateTest {
37  
38      private ServiceInfo         service;
39      private ServiceInfo         printer;
40      private MockListener        serviceListenerMock;
41  
42      private final static String serviceKey = "srvname"; // Max 9 chars
43  
44      public static class MockListener implements ServiceListener {
45  
46          private final List<ServiceEvent> _serviceAdded    = Collections.synchronizedList(new ArrayList<ServiceEvent>(2));
47          private final List<ServiceEvent> _serviceRemoved  = Collections.synchronizedList(new ArrayList<ServiceEvent>(2));
48          private final List<ServiceEvent> _serviceResolved = Collections.synchronizedList(new ArrayList<ServiceEvent>(2));
49  
50          /*
51           * (non-Javadoc)
52           * @see javax.jmdns.ServiceListener#serviceAdded(javax.jmdns.ServiceEvent)
53           */
54          @Override
55          public void serviceAdded(ServiceEvent event) {
56              _serviceAdded.add(event.clone());
57          }
58  
59          /*
60           * (non-Javadoc)
61           * @see javax.jmdns.ServiceListener#serviceRemoved(javax.jmdns.ServiceEvent)
62           */
63          @Override
64          public void serviceRemoved(ServiceEvent event) {
65              _serviceRemoved.add(event.clone());
66          }
67  
68          /*
69           * (non-Javadoc)
70           * @see javax.jmdns.ServiceListener#serviceResolved(javax.jmdns.ServiceEvent)
71           */
72          @Override
73          public void serviceResolved(ServiceEvent event) {
74              _serviceResolved.add(event.clone());
75          }
76  
77          public List<ServiceEvent> servicesAdded() {
78              return _serviceAdded;
79          }
80  
81          public List<ServiceEvent> servicesRemoved() {
82              return _serviceRemoved;
83          }
84  
85          public List<ServiceEvent> servicesResolved() {
86              return _serviceResolved;
87          }
88  
89          public synchronized void reset() {
90              _serviceAdded.clear();
91              _serviceRemoved.clear();
92              _serviceResolved.clear();
93          }
94  
95          @Override
96          public String toString() {
97              StringBuilder aLog = new StringBuilder();
98              aLog.append("Services Added: " + _serviceAdded.size());
99              for (ServiceEvent event : _serviceAdded) {
100                 aLog.append("\n\tevent name: '");
101                 aLog.append(event.getName());
102                 aLog.append("' type: '");
103                 aLog.append(event.getType());
104                 aLog.append("' info: '");
105                 aLog.append(event.getInfo());
106             }
107             aLog.append("\nServices Removed: " + _serviceRemoved.size());
108             for (ServiceEvent event : _serviceRemoved) {
109                 aLog.append("\n\tevent name: '");
110                 aLog.append(event.getName());
111                 aLog.append("' type: '");
112                 aLog.append(event.getType());
113                 aLog.append("' info: '");
114                 aLog.append(event.getInfo());
115             }
116             aLog.append("\nServices Resolved: " + _serviceResolved.size());
117             for (ServiceEvent event : _serviceResolved) {
118                 aLog.append("\n\tevent name: '");
119                 aLog.append(event.getName());
120                 aLog.append("' type: '");
121                 aLog.append(event.getType());
122                 aLog.append("' info: '");
123                 aLog.append(event.getInfo());
124             }
125             return aLog.toString();
126         }
127 
128     }
129 
130     @Before
131     public void setup() {
132         boolean log = false;
133         if (log) {
134             ConsoleHandler handler = new ConsoleHandler();
135             handler.setLevel(Level.FINEST);
136             for (Enumeration<String> enumerator = LogManager.getLogManager().getLoggerNames(); enumerator.hasMoreElements();) {
137                 String loggerName = enumerator.nextElement();
138                 Logger logger = Logger.getLogger(loggerName);
139                 logger.addHandler(handler);
140                 logger.setLevel(Level.FINEST);
141             }
142         }
143 
144         String text = "Test hypothetical web server";
145         Map<String, byte[]> properties = new HashMap<String, byte[]>();
146         properties.put(serviceKey, text.getBytes());
147         service = ServiceInfo.create("_html._tcp.local.", "apache-someuniqueid", 80, 0, 0, true, properties);
148         text = "Test hypothetical print server";
149         properties.clear();
150         properties.put(serviceKey, text.getBytes());
151         printer = ServiceInfo.create("_html._tcp.local.", "printer-someuniqueid", "_printer", 80, 0, 0, true, properties);
152         serviceListenerMock = new MockListener();
153     }
154 
155     @Test
156     public void testListenForTextUpdateOnOtherRegistry() throws IOException, InterruptedException {
157         System.out.println("Unit Test: testListenForTextUpdateOnOtherRegistry()");
158         JmDNS registry = null;
159         JmDNS newServiceRegistry = null;
160         try {
161             registry = JmDNS.create("Listener");
162             registry.addServiceListener(service.getType(), serviceListenerMock);
163             //
164             newServiceRegistry = JmDNS.create("Registry");
165             newServiceRegistry.registerService(service);
166 
167             // We get the service added event when we register the service. However the service has not been resolved at this point.
168             // The info associated with the event only has the minimum information i.e. name and type.
169             List<ServiceEvent> servicesAdded = serviceListenerMock.servicesAdded();
170             assertEquals("We did not get the service added event.", 1, servicesAdded.size());
171             ServiceInfo info = servicesAdded.get(servicesAdded.size() - 1).getInfo();
172             assertEquals("We did not get the right name for the resolved service:", service.getName(), info.getName());
173             assertEquals("We did not get the right type for the resolved service:", service.getType(), info.getType());
174             // We get the service added event when we register the service. However the service has not been resolved at this point.
175             // The info associated with the event only has the minimum information i.e. name and type.
176             List<ServiceEvent> servicesResolved = serviceListenerMock.servicesResolved();
177             assertEquals("We did not get the service resolved event.", 1, servicesResolved.size());
178             ServiceInfo result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
179             assertNotNull("Did not get the expected service info: ", result);
180             assertEquals("Did not get the expected service info: ", service, result);
181             assertEquals("Did not get the expected service info text: ", service.getPropertyString(serviceKey), result.getPropertyString(serviceKey));
182 
183             serviceListenerMock.reset();
184             String text = "Test improbable web server";
185             Map<String, byte[]> properties = new HashMap<String, byte[]>();
186             properties.put(serviceKey, text.getBytes());
187             service.setText(properties);
188             Thread.sleep(3000);
189             servicesResolved = serviceListenerMock.servicesResolved();
190             assertEquals("We did not get the service text updated event.", 1, servicesResolved.size());
191             result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
192             assertEquals("Did not get the expected service info text: ", text, result.getPropertyString(serviceKey));
193 
194             serviceListenerMock.reset();
195             text = "Test more improbable web server";
196             properties = new HashMap<String, byte[]>();
197             properties.put(serviceKey, text.getBytes());
198             service.setText(properties);
199             Thread.sleep(3000);
200             servicesResolved = serviceListenerMock.servicesResolved();
201             assertEquals("We did not get the service text updated event.", 1, servicesResolved.size());
202             result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
203             assertEquals("Did not get the expected service info text: ", text, result.getPropertyString(serviceKey));
204 
205             serviceListenerMock.reset();
206             text = "Test even more improbable web server";
207             properties = new HashMap<String, byte[]>();
208             properties.put(serviceKey, text.getBytes());
209             service.setText(properties);
210             Thread.sleep(3000);
211             servicesResolved = serviceListenerMock.servicesResolved();
212             assertEquals("We did not get the service text updated event.", 1, servicesResolved.size());
213             result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
214             assertEquals("Did not get the expected service info text: ", text, result.getPropertyString(serviceKey));
215 
216         } finally {
217             if (registry != null) registry.close();
218             if (newServiceRegistry != null) newServiceRegistry.close();
219         }
220     }
221 
222     @Test
223     public void testRegisterEmptyTXTField() throws IOException, InterruptedException {
224         System.out.println("Unit Test: testRegisterEmptyTXTField()");
225         JmDNS registry = null;
226         JmDNS newServiceRegistry = null;
227         try {
228             registry = JmDNS.create("Listener");
229             registry.addServiceListener(service.getType(), serviceListenerMock);
230             //
231             newServiceRegistry = JmDNS.create("Registry");
232             newServiceRegistry.registerService(service);
233 
234             // We get the service added event when we register the service. However the service has not been resolved at this point.
235             // The info associated with the event only has the minimum information i.e. name and type.
236             List<ServiceEvent> servicesAdded = serviceListenerMock.servicesAdded();
237             assertEquals("We did not get the service added event.", 1, servicesAdded.size());
238             ServiceInfo info = servicesAdded.get(servicesAdded.size() - 1).getInfo();
239             assertEquals("We did not get the right name for the resolved service:", service.getName(), info.getName());
240             assertEquals("We did not get the right type for the resolved service:", service.getType(), info.getType());
241             // We get the service added event when we register the service. However the service has not been resolved at this point.
242             // The info associated with the event only has the minimum information i.e. name and type.
243             List<ServiceEvent> servicesResolved = serviceListenerMock.servicesResolved();
244             assertEquals("We did not get the service resolved event.", 1, servicesResolved.size());
245             ServiceInfo result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
246             assertNotNull("Did not get the expected service info: ", result);
247             assertEquals("Did not get the expected service info: ", service, result);
248             assertEquals("Did not get the expected service info text: ", service.getPropertyString(serviceKey), result.getPropertyString(serviceKey));
249 
250             serviceListenerMock.reset();
251             Map<String, byte[]> properties = new HashMap<String, byte[]>();
252             service.setText(properties);
253             Thread.sleep(3000);
254             servicesResolved = serviceListenerMock.servicesResolved();
255             assertEquals("We did not get the service text updated event.", 1, servicesResolved.size());
256             result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
257             assertNull("Did not get the expected service info text: ", result.getPropertyString(serviceKey));
258         } finally {
259             if (registry != null) registry.close();
260             if (newServiceRegistry != null) newServiceRegistry.close();
261         }
262     }
263 
264     @Test
265     public void testRegisterCaseSensitiveField() throws IOException {
266         System.out.println("Unit Test: testRegisterCaseSensitiveField()");
267         JmDNS registry = null;
268         JmDNS newServiceRegistry = null;
269         try {
270             String text = "Test hypothetical Web Server";
271             Map<String, byte[]> properties = new HashMap<String, byte[]>();
272             properties.put(serviceKey, text.getBytes());
273             service = ServiceInfo.create("_Html._Tcp.local.", "Apache-SomeUniqueId", 80, 0, 0, true, properties);
274 
275             registry = JmDNS.create("Listener");
276             registry.addServiceListener(service.getType(), serviceListenerMock);
277             //
278             newServiceRegistry = JmDNS.create("Registry");
279             newServiceRegistry.registerService(service);
280 
281             // We get the service added event when we register the service. However the service has not been resolved at this point.
282             // The info associated with the event only has the minimum information i.e. name and type.
283             List<ServiceEvent> servicesAdded = serviceListenerMock.servicesAdded();
284             assertEquals("We did not get the service added event.", 1, servicesAdded.size());
285             ServiceInfo info = servicesAdded.get(servicesAdded.size() - 1).getInfo();
286             assertEquals("We did not get the right name for the resolved service:", service.getName(), info.getName());
287             assertEquals("We did not get the right type for the resolved service:", service.getType(), info.getType());
288             // We get the service added event when we register the service. However the service has not been resolved at this point.
289             // The info associated with the event only has the minimum information i.e. name and type.
290             List<ServiceEvent> servicesResolved = serviceListenerMock.servicesResolved();
291             assertEquals("We did not get the service resolved event.", 1, servicesResolved.size());
292             ServiceInfo result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
293             assertNotNull("Did not get the expected service info: ", result);
294             assertEquals("Did not get the expected service info: ", service, result);
295             assertEquals("Did not get the expected service info text: ", service.getPropertyString(serviceKey), result.getPropertyString(serviceKey));
296 
297             ServiceInfo[] infos = registry.list(service.getType());
298             assertEquals("We did not get the right list of service info.", 1, infos.length);
299             assertEquals("Did not get the expected service info: ", service, infos[0]);
300             assertEquals("Did not get the expected service info text: ", service.getPropertyString(serviceKey), infos[0].getPropertyString(serviceKey));
301 
302             infos = registry.list(service.getType().toLowerCase());
303             assertEquals("We did not get the right list of service info.", 1, infos.length);
304             assertEquals("Did not get the expected service info: ", service, infos[0]);
305             assertEquals("Did not get the expected service info text: ", service.getPropertyString(serviceKey), infos[0].getPropertyString(serviceKey));
306 
307         } finally {
308             if (registry != null) registry.close();
309             if (newServiceRegistry != null) newServiceRegistry.close();
310         }
311     }
312 
313     @Test
314     public void testRenewExpiringRequests() throws IOException, InterruptedException {
315         System.out.println("Unit Test: testRenewExpiringRequests()");
316         JmDNS registry = null;
317         JmDNS newServiceRegistry = null;
318         try {
319 
320             // To test for expiring TTL
321             DNSStateTask.setDefaultTTL(1 * 60);
322 
323             registry = JmDNS.create("Listener");
324             registry.addServiceListener(service.getType(), serviceListenerMock);
325             //
326             newServiceRegistry = JmDNS.create("Registry");
327             newServiceRegistry.registerService(service);
328 
329             List<ServiceEvent> servicesAdded = serviceListenerMock.servicesAdded();
330             assertTrue("We did not get the service added event.", servicesAdded.size() == 1);
331 
332             ServiceInfo[] services = registry.list(service.getType());
333             assertEquals("We should see the service we just registered: ", 1, services.length);
334             assertEquals(service, services[0]);
335 
336             // wait for the TTL
337             Thread.sleep(2 * 60 * 1000);
338 
339             services = registry.list(service.getType());
340             assertEquals("We should see the service after the renewal: ", 1, services.length);
341             assertEquals(service, services[0]);
342 
343         } finally {
344             if (registry != null) registry.close();
345             if (newServiceRegistry != null) newServiceRegistry.close();
346             DNSStateTask.setDefaultTTL(DNSConstants.DNS_TTL);
347         }
348     }
349 
350     @Test
351     public void testSubtype() throws IOException {
352         System.out.println("Unit Test: testSubtype()");
353         JmDNS registry = null;
354         JmDNS newServiceRegistry = null;
355         try {
356             registry = JmDNS.create("Listener");
357             registry.addServiceListener(service.getType(), serviceListenerMock);
358             //
359             newServiceRegistry = JmDNS.create("Registry");
360             newServiceRegistry.registerService(printer);
361 
362             // We get the service added event when we register the service. However the service has not been resolved at this point.
363             // The info associated with the event only has the minimum information i.e. name and type.
364             List<ServiceEvent> servicesAdded = serviceListenerMock.servicesAdded();
365             assertEquals("We did not get the service added event.", 1, servicesAdded.size());
366             ServiceInfo info = servicesAdded.get(servicesAdded.size() - 1).getInfo();
367             assertEquals("We did not get the right name for the resolved service:", printer.getName(), info.getName());
368             assertEquals("We did not get the right type for the resolved service:", printer.getType(), info.getType());
369             // We get the service added event when we register the service. However the service has not been resolved at this point.
370             // The info associated with the event only has the minimum information i.e. name and type.
371             List<ServiceEvent> servicesResolved = serviceListenerMock.servicesResolved();
372             assertEquals("We did not get the service resolved event.", 1, servicesResolved.size());
373             ServiceInfo result = servicesResolved.get(servicesResolved.size() - 1).getInfo();
374             assertNotNull("Did not get the expected service info: ", result);
375             assertEquals("Did not get the expected service info: ", printer, result);
376             assertEquals("Did not get the expected service info subtype: ", printer.getSubtype(), result.getSubtype());
377             assertEquals("Did not get the expected service info text: ", printer.getPropertyString(serviceKey), result.getPropertyString(serviceKey));
378             serviceListenerMock.reset();
379         } finally {
380             if (registry != null) registry.close();
381             if (newServiceRegistry != null) newServiceRegistry.close();
382         }
383 
384     }
385 
386 }