1 /***
2 * Copyright 2003-2010 Terracotta, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package net.sf.ehcache.distribution;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.rmi.RemoteException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.Random;
28
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import net.sf.ehcache.AbstractCacheTest;
33 import net.sf.ehcache.CacheManager;
34 import net.sf.ehcache.Element;
35
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Test;
39
40 /***
41 * Note these tests need a live network interface running in multicast mode to work
42 *
43 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
44 * @version $Id: PayloadUtilTest.html 13146 2011-08-01 17:12:39Z oletizi $
45 */
46 public class PayloadUtilTest extends AbstractRMITest {
47
48 private static final Logger LOG = LoggerFactory.getLogger(PayloadUtilTest.class.getName());
49 private static final Random RANDOM = new Random(System.currentTimeMillis());
50 private static final String RANDOM_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
51 private CacheManager manager;
52
53 /***
54 * setup test
55 *
56 * @throws Exception
57 */
58 @Before
59 public void setUp() throws Exception {
60 String fileName = AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-big.xml";
61 manager = new CacheManager(fileName);
62 }
63
64 /***
65 * Shuts down the cachemanager
66 *
67 * @throws Exception
68 */
69 @After
70 public void tearDown() throws Exception {
71 manager.shutdown();
72 }
73
74 /***
75 * The maximum Ethernet MTU is 1500 bytes.
76 * <p/>
77 * We want to be able to work with 100 caches
78 */
79 @Test
80 public void testMaximumDatagram() throws IOException {
81 String payload = createReferenceString();
82
83 final byte[] compressed = PayloadUtil.gzip(payload.getBytes());
84
85 int length = compressed.length;
86 LOG.info("gzipped size: " + length);
87 assertTrue("Heartbeat too big for one Datagram " + length, length <= 1500);
88
89 }
90
91 private String createReferenceString() {
92
93 String[] names = manager.getCacheNames();
94 String urlBase = "//localhost.localdomain:12000/";
95 StringBuilder buffer = new StringBuilder();
96 for (String name : names) {
97 buffer.append(urlBase);
98 buffer.append(name);
99 buffer.append("|");
100 }
101 String payload = buffer.toString();
102 return payload;
103 }
104
105 @Test
106 public void testBigPayload() throws RemoteException {
107 List<CachePeer> bigPayloadList = new ArrayList<CachePeer>();
108
109 int peers = 5000;
110 int minCacheNameSize = 50;
111 int maxCacheNameSize = 500;
112 for (int i = 0; i < peers; i++) {
113 bigPayloadList.add(new PayloadUtilTestCachePeer(getRandomName(minCacheNameSize, maxCacheNameSize)));
114 }
115
116 doTestBigPayLoad(bigPayloadList, 5);
117 doTestBigPayLoad(bigPayloadList, 10);
118 doTestBigPayLoad(bigPayloadList, 50);
119 doTestBigPayLoad(bigPayloadList, 100);
120 doTestBigPayLoad(bigPayloadList, 150);
121 doTestBigPayLoad(bigPayloadList, 300);
122 doTestBigPayLoad(bigPayloadList, 500);
123
124
125
126 doTestBigPayLoad(bigPayloadList, 1000000);
127
128
129 bigPayloadList.clear();
130 bigPayloadList.add(new PayloadUtilTestCachePeer(getRandomName(3000, 3001)));
131 List<byte[]> compressedList = PayloadUtil.createCompressedPayloadList(bigPayloadList, 150);
132 assertEquals(0, compressedList.size());
133
134 }
135
136 private void doTestBigPayLoad(List<CachePeer> bigPayloadList, int maximumPeersPerSend) throws RemoteException {
137 List<byte[]> compressedList = PayloadUtil.createCompressedPayloadList(bigPayloadList, maximumPeersPerSend);
138
139 assertTrue(compressedList.size() > 1);
140 StringBuilder actual = new StringBuilder();
141 for (byte[] bytes : compressedList) {
142 assertTrue("One payload should not be greater than MTU, actual size: " + bytes.length + ", MTU: " + PayloadUtil.MTU,
143 bytes.length <= PayloadUtil.MTU);
144 String urlList = new String(PayloadUtil.ungzip(bytes));
145 String[] urls = urlList.split(PayloadUtil.URL_DELIMITER_REGEXP);
146 assertTrue("Number of URL's in one payload should not exceed maximumPeersPerSend (=" + maximumPeersPerSend + "), actual: "
147 + urls.length, urls.length <= maximumPeersPerSend);
148
149 if (bytes == compressedList.get(compressedList.size() - 1)) {
150 actual.append(urlList);
151 } else {
152 actual.append(urlList + PayloadUtil.URL_DELIMITER);
153 }
154 }
155 StringBuilder expected = new StringBuilder();
156 for (CachePeer peer : bigPayloadList) {
157 if (peer != bigPayloadList.get(bigPayloadList.size() - 1)) {
158 expected.append(peer.getUrl() + PayloadUtil.URL_DELIMITER);
159 } else {
160 expected.append(peer.getUrl());
161 }
162 }
163 assertEquals(expected.toString(), actual.toString());
164 }
165
166 private String getRandomName(final int minLength, final int maxLength) {
167 int length = minLength + RANDOM.nextInt(maxLength - minLength);
168 StringBuilder rv = new StringBuilder();
169 for (int i = 0; i < length; i++) {
170 rv.append(RANDOM_CHARS.charAt(RANDOM.nextInt(RANDOM_CHARS.length())));
171 }
172 return rv.toString();
173 }
174
175 /***
176 * A test class which implements only {@link #getUrl()} to test PayloadUtil.createCompressedPayloadList()
177 *
178 * @author Abhishek Sanoujam
179 */
180 private static class PayloadUtilTestCachePeer implements CachePeer {
181
182 public static final String URL_BASE = "//localhost.localdomain:12000/";
183 private final String cacheName;
184
185 public PayloadUtilTestCachePeer(String cacheName) {
186 this.cacheName = cacheName;
187 }
188
189 /***
190 * {@inheritDoc}
191 *
192 * @see net.sf.ehcache.distribution.CachePeer#getUrl()
193 */
194 public String getUrl() throws RemoteException {
195 return URL_BASE + cacheName;
196 }
197
198 /***
199 * {@inheritDoc}
200 *
201 * @see net.sf.ehcache.distribution.CachePeer#getElements(java.util.List)
202 */
203 public List getElements(List keys) throws RemoteException {
204
205 return null;
206 }
207
208 /***
209 * {@inheritDoc}
210 *
211 * @see net.sf.ehcache.distribution.CachePeer#getGuid()
212 */
213 public String getGuid() throws RemoteException {
214
215 return null;
216 }
217
218 /***
219 * {@inheritDoc}
220 *
221 * @see net.sf.ehcache.distribution.CachePeer#getKeys()
222 */
223 public List getKeys() throws RemoteException {
224
225 return null;
226 }
227
228 /***
229 * {@inheritDoc}
230 *
231 * @see net.sf.ehcache.distribution.CachePeer#getName()
232 */
233 public String getName() throws RemoteException {
234
235 return null;
236 }
237
238 /***
239 * {@inheritDoc}
240 *
241 * @see net.sf.ehcache.distribution.CachePeer#getQuiet(java.io.Serializable)
242 */
243 public Element getQuiet(Serializable key) throws RemoteException {
244
245 return null;
246 }
247
248 /***
249 * {@inheritDoc}
250 *
251 * @see net.sf.ehcache.distribution.CachePeer#getUrlBase()
252 */
253 public String getUrlBase() throws RemoteException {
254
255 return null;
256 }
257
258 /***
259 * {@inheritDoc}
260 *
261 * @see net.sf.ehcache.distribution.CachePeer#put(net.sf.ehcache.Element)
262 */
263 public void put(Element element) throws IllegalArgumentException, IllegalStateException, RemoteException {
264
265
266 }
267
268 /***
269 * {@inheritDoc}
270 *
271 * @see net.sf.ehcache.distribution.CachePeer#remove(java.io.Serializable)
272 */
273 public boolean remove(Serializable key) throws IllegalStateException, RemoteException {
274
275 return false;
276 }
277
278 /***
279 * {@inheritDoc}
280 *
281 * @see net.sf.ehcache.distribution.CachePeer#removeAll()
282 */
283 public void removeAll() throws RemoteException, IllegalStateException {
284
285 }
286
287 /***
288 * {@inheritDoc}
289 *
290 * @see net.sf.ehcache.distribution.CachePeer#send(java.util.List)
291 */
292 public void send(List eventMessages) throws RemoteException {
293
294
295 }
296
297 }
298
299 }