View Javadoc
1   package org.apache.commons.jcs3.utils.discovery;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.concurrent.Callable;
25  import java.util.concurrent.ExecutionException;
26  import java.util.concurrent.ExecutorService;
27  import java.util.concurrent.Executors;
28  import java.util.concurrent.Future;
29  import java.util.concurrent.TimeUnit;
30  import java.util.concurrent.TimeoutException;
31  
32  import org.apache.commons.jcs3.utils.discovery.UDPDiscoveryMessage.BroadcastType;
33  import org.apache.commons.jcs3.utils.net.HostNameUtil;
34  import org.apache.commons.jcs3.utils.serialization.StandardSerializer;
35  
36  import junit.framework.TestCase;
37  
38  /**
39   * Tests for the sender.
40   */
41  public class UDPDiscoverySenderUnitTest
42      extends TestCase
43  {
44      /** multicast address to send/receive on */
45      private static final String ADDRESS = "228.4.5.9";
46  
47      /** multicast address to send/receive on */
48      private static final int PORT = 5556;
49  
50      /** imaginary host address for sending */
51      private static final String SENDING_HOST = "imaginary host address";
52  
53      /** imaginary port for sending */
54      private static final int SENDING_PORT = 1;
55  
56      /** receiver instance for tests */
57      private UDPDiscoveryReceiver receiver;
58  
59      /** sender instance for tests */
60      private UDPDiscoverySender sender;
61  
62      /**
63       * Set up the receiver. Maybe better to just code sockets here? Set up the sender for sending
64       * the message.
65       * <p>
66       * @throws Exception on error
67       */
68      @Override
69      protected void setUp()
70          throws Exception
71      {
72          super.setUp();
73  
74          receiver = new UDPDiscoveryReceiver( null, null, ADDRESS, PORT );
75          receiver.setSerializer(new StandardSerializer());
76          final Thread t = new Thread( receiver );
77          t.start();
78  
79          sender = new UDPDiscoverySender(null, ADDRESS, PORT, 1, new StandardSerializer());
80      }
81  
82      /**
83       * Kill off the sender and receiver.
84       * <p>
85       * @throws Exception on error
86       */
87      @Override
88      protected void tearDown()
89          throws Exception
90      {
91          receiver.shutdown();
92          sender.close();
93          super.tearDown();
94      }
95  
96      /**
97       * Test sending a live messages.
98       * <p>
99       * @throws Exception on error
100      */
101     public void testPassiveBroadcast()
102         throws Exception
103     {
104         if (HostNameUtil.getMulticastNetworkInterface() == null)
105         {
106             System.out.println("This machine does not support multicast");
107             return;
108         }
109 
110         // SETUP
111         final ArrayList<String> cacheNames = new ArrayList<>();
112 
113         // DO WORK
114         sender.passiveBroadcast( SENDING_HOST, SENDING_PORT, cacheNames, 1L );
115 
116         // VERIFY
117         // grab the sent message
118         final UDPDiscoveryMessage msg = getMessage();
119         assertNotNull("message not received", msg);
120         // disabled test because of JCS-89
121         // assertEquals( "wrong host", SENDING_HOST, msg.getHost() );
122         assertEquals( "wrong port", SENDING_PORT, msg.getPort() );
123         assertEquals( "wrong message type", BroadcastType.PASSIVE, msg.getMessageType() );
124     }
125 
126     /**
127      * Test sending a remove broadcast.
128      * <p>
129      * @throws Exception on error
130      */
131     public void testRemoveBroadcast()
132         throws Exception
133     {
134         if (HostNameUtil.getMulticastNetworkInterface() == null)
135         {
136             System.out.println("This machine does not support multicast");
137             return;
138         }
139 
140         // SETUP
141         final ArrayList<String> cacheNames = new ArrayList<>();
142 
143         // DO WORK
144         sender.removeBroadcast( SENDING_HOST, SENDING_PORT, cacheNames, 1L );
145 
146         // VERIFY
147         // grab the sent message
148         final UDPDiscoveryMessage msg = getMessage();
149         assertNotNull("message not received", msg);
150         // disabled test because of JCS-89
151         // assertEquals( "wrong host", SENDING_HOST, msg.getHost() );
152         assertEquals( "wrong port", SENDING_PORT, msg.getPort() );
153         assertEquals( "wrong message type", BroadcastType.REMOVE, msg.getMessageType() );
154     }
155 
156     /**
157      * Test sending a request broadcast.
158      * <p>
159      * @throws Exception on error
160      */
161     public void testRequestBroadcast()
162         throws Exception
163     {
164         if (HostNameUtil.getMulticastNetworkInterface() == null)
165         {
166             System.out.println("This machine does not support multicast");
167             return;
168         }
169 
170         // DO WORK
171         sender.requestBroadcast();
172 
173         // VERIFY
174         // grab the sent message
175         final UDPDiscoveryMessage msg = getMessage();
176         assertNotNull("message not received", msg);
177         assertEquals( "wrong message type", BroadcastType.REQUEST, msg.getMessageType() );
178     }
179 
180     /**
181      * Wait for multicast message for 3 seconds
182      *
183      * @return the object message or null if nothing received within 3 seconds
184      */
185     private UDPDiscoveryMessage getMessage() {
186         ExecutorService executor = Executors.newCachedThreadPool();
187         Callable<Object> task = new Callable<Object>() {
188            @Override
189         public Object call() throws IOException {
190               return receiver.waitForMessage();
191            }
192         };
193         Future<Object> future = executor.submit(task);
194         try {
195             Object obj = future.get(3, TimeUnit.SECONDS);
196 
197             assertTrue( "unexpected crap received", obj instanceof UDPDiscoveryMessage );
198 
199             return (UDPDiscoveryMessage) obj;
200         } catch (InterruptedException | ExecutionException | TimeoutException ex) {
201             return null;
202         }
203     }
204 }