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.java 2539 2010-07-02 10:58:13Z alexsnaps $
45 */
46 public class PayloadUtilTest {
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 */
181 private static class PayloadUtilTestCachePeer implements CachePeer {
182
183 public static final String URL_BASE = "//localhost.localdomain:12000/";
184 private final String cacheName;
185
186 public PayloadUtilTestCachePeer(String cacheName) {
187 this.cacheName = cacheName;
188 }
189
190 /***
191 * {@inheritDoc}
192 *
193 * @see net.sf.ehcache.distribution.CachePeer#getUrl()
194 */
195 public String getUrl() throws RemoteException {
196 return URL_BASE + cacheName;
197 }
198
199 /***
200 * {@inheritDoc}
201 *
202 * @see net.sf.ehcache.distribution.CachePeer#getElements(java.util.List)
203 */
204 public List getElements(List keys) throws RemoteException {
205
206 return null;
207 }
208
209 /***
210 * {@inheritDoc}
211 *
212 * @see net.sf.ehcache.distribution.CachePeer#getGuid()
213 */
214 public String getGuid() throws RemoteException {
215
216 return null;
217 }
218
219 /***
220 * {@inheritDoc}
221 *
222 * @see net.sf.ehcache.distribution.CachePeer#getKeys()
223 */
224 public List getKeys() throws RemoteException {
225
226 return null;
227 }
228
229 /***
230 * {@inheritDoc}
231 *
232 * @see net.sf.ehcache.distribution.CachePeer#getName()
233 */
234 public String getName() throws RemoteException {
235
236 return null;
237 }
238
239 /***
240 * {@inheritDoc}
241 *
242 * @see net.sf.ehcache.distribution.CachePeer#getQuiet(java.io.Serializable)
243 */
244 public Element getQuiet(Serializable key) throws RemoteException {
245
246 return null;
247 }
248
249 /***
250 * {@inheritDoc}
251 *
252 * @see net.sf.ehcache.distribution.CachePeer#getUrlBase()
253 */
254 public String getUrlBase() throws RemoteException {
255
256 return null;
257 }
258
259 /***
260 * {@inheritDoc}
261 *
262 * @see net.sf.ehcache.distribution.CachePeer#put(net.sf.ehcache.Element)
263 */
264 public void put(Element element) throws IllegalArgumentException, IllegalStateException, RemoteException {
265
266
267 }
268
269 /***
270 * {@inheritDoc}
271 *
272 * @see net.sf.ehcache.distribution.CachePeer#remove(java.io.Serializable)
273 */
274 public boolean remove(Serializable key) throws IllegalStateException, RemoteException {
275
276 return false;
277 }
278
279 /***
280 * {@inheritDoc}
281 *
282 * @see net.sf.ehcache.distribution.CachePeer#removeAll()
283 */
284 public void removeAll() throws RemoteException, IllegalStateException {
285
286 }
287
288 /***
289 * {@inheritDoc}
290 *
291 * @see net.sf.ehcache.distribution.CachePeer#send(java.util.List)
292 */
293 public void send(List eventMessages) throws RemoteException {
294
295
296 }
297
298 }
299
300 }