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;
18
19
20 import org.junit.After;
21 import org.junit.Assert;
22
23 import static org.junit.Assert.assertTrue;
24
25 import org.junit.Before;
26
27 import javax.management.MBeanServer;
28 import javax.management.MBeanServerFactory;
29 import javax.management.ObjectName;
30
31 import java.io.File;
32 import java.io.IOException;
33 import java.lang.management.ManagementFactory;
34 import java.lang.reflect.Method;
35 import java.util.ArrayList;
36 import java.util.List;
37 import net.sf.ehcache.distribution.AbstractRMITest;
38 import org.junit.BeforeClass;
39
40 import org.junit.Ignore;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45 /***
46 * Common fields and methods required by most test cases
47 *
48 * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
49 * @version $Id: AbstractCacheTest.html 13146 2011-08-01 17:12:39Z oletizi $
50 */
51 @Ignore
52 public abstract class AbstractCacheTest {
53
54 /***
55 * Where the config is
56 */
57 public static final String SRC_CONFIG_DIR = "src/main/config/";
58
59 /***
60 * Where the test config is
61 */
62 public static final String TEST_CONFIG_DIR = "src/test/resources/";
63 /***
64 * Where the test classes are compiled.
65 */
66 public static final String TEST_CLASSES_DIR = "target/test-classes/";
67
68
69 private static final Logger LOG = LoggerFactory.getLogger(AbstractCacheTest.class.getName());
70
71 /***
72 * name for sample cache 1
73 */
74 protected final String sampleCache1 = "sampleCache1";
75 /***
76 * name for sample cache 2
77 */
78 protected final String sampleCache2 = "sampleCache2";
79 /***
80 * the CacheManager instance
81 */
82 protected CacheManager manager;
83
84 @BeforeClass
85 public static void installRMISocketFactory() {
86 AbstractRMITest.installRMISocketFactory();
87 }
88
89 /***
90 * setup test
91 */
92 @Before
93 public void setUp() throws Exception {
94 manager = CacheManager.create();
95 }
96
97 /***
98 * teardown
99 */
100 @After
101 public void tearDown() throws Exception {
102 if (manager != null) {
103 manager.shutdown();
104 }
105 }
106
107
108 /***
109 * Force the VM to grow to its full size. This stops SoftReferences from being reclaimed in favour of
110 * Heap growth. Only an issue when a VM is cold.
111 */
112 static public void forceVMGrowth() {
113 allocateFiftyMegabytes();
114 System.gc();
115 try {
116 Thread.sleep(200);
117 } catch (InterruptedException e) {
118 Thread.currentThread().interrupt();
119 }
120 System.gc();
121 }
122
123 private static void allocateFiftyMegabytes() {
124 Object[] arrays = new Object[50];
125 for (int i = 0; i < arrays.length; i++) {
126 arrays[i] = new byte[1024 * 1024];
127 }
128 }
129
130 /***
131 * @param name
132 * @throws IOException
133 */
134 protected void deleteFile(String name) throws IOException {
135 String diskPath = System.getProperty("java.io.tmpdir");
136 final File diskDir = new File(diskPath);
137 File dataFile = new File(diskDir, name + ".data");
138 if (dataFile.exists()) {
139 dataFile.delete();
140 }
141 File indexFile = new File(diskDir, name + ".index");
142 if (indexFile.exists()) {
143 indexFile.delete();
144 }
145 }
146
147 /***
148 * Measure memory used by the VM.
149 *
150 * @return
151 * @throws InterruptedException
152 */
153 protected long measureMemoryUse() throws InterruptedException {
154 System.gc();
155 Thread.sleep(1000);
156 System.gc();
157 Thread.sleep(1000);
158 long total;
159 long free;
160 Runtime runtime = Runtime.getRuntime();
161 do {
162 total = runtime.totalMemory();
163 free = runtime.freeMemory();
164 } while (total != runtime.totalMemory());
165
166 return total - free;
167 }
168
169
170 /***
171 * Runs a set of threads, for a fixed amount of time.
172 * <p/>
173 * Throws an exception if there are throwables during the run.
174 */
175 protected void runThreads(final List executables) throws Exception {
176 int failures = runThreadsNoCheck(executables);
177 LOG.info(failures + " failures");
178
179 assertTrue("Failures = " + failures, failures <= 35);
180 }
181
182
183 /***
184 * Runs a set of threads, for a fixed amount of time.
185 * <p/>
186 * Does not fail if throwables are thrown.
187 *
188 * @return the number of Throwables thrown while running
189 */
190 protected int runThreadsNoCheck(final List executables) throws Exception {
191 return runThreadsNoCheck(executables, false);
192 }
193
194 /***
195 * Runs a set of threads, for a fixed amount of time.
196 * <p/>
197 * Does not fail if throwables are thrown.
198 *
199 * @param executables the list of executables to execute
200 * @param explicitLog whether to log detailed AsserttionErrors or not
201 * @return the number of Throwables thrown while running
202 */
203 protected int runThreadsNoCheck(final List executables, final boolean explicitLog) throws Exception {
204
205 final long endTime = System.currentTimeMillis() + 10000;
206 final List<Throwable> errors = new ArrayList<Throwable>();
207
208
209 final Thread[] threads = new Thread[executables.size()];
210 for (int i = 0; i < threads.length; i++) {
211 final Executable executable = (Executable) executables.get(i);
212 threads[i] = new Thread() {
213 @Override
214 public void run() {
215 try {
216
217 while (System.currentTimeMillis() < endTime) {
218 Assert.assertNotNull(executable);
219 executable.execute();
220 }
221 } catch (Throwable t) {
222
223 errors.add(t);
224 if (!explicitLog && t instanceof AssertionError) {
225 LOG.info("Throwable " + t + " " + t.getMessage());
226 } else {
227 LOG.error("Throwable " + t + " " + t.getMessage(), t);
228 }
229 }
230 }
231 };
232 threads[i].start();
233 }
234
235
236 for (Thread thread : threads) {
237 thread.join();
238 }
239
240
241
242
243
244
245 return errors.size();
246 }
247
248 /***
249 * Obtains an MBeanServer, which varies with Java version
250 *
251 * @return
252 */
253 public MBeanServer createMBeanServer() {
254 try {
255 Class managementFactoryClass = Class.forName("java.lang.management.ManagementFactory");
256 Method method = managementFactoryClass.getMethod("getPlatformMBeanServer", (Class[]) null);
257 return (MBeanServer) method.invoke(null, (Object[]) null);
258 } catch (Exception e) {
259 LOG.info("JDK1.5 ManagementFactory not found. Falling back to JMX1.2.1", e);
260 return MBeanServerFactory.createMBeanServer("SimpleAgent");
261 }
262 }
263
264
265 /***
266 * A runnable, that can throw an exception.
267 */
268 protected interface Executable {
269 /***
270 * Executes this object.
271 *
272 * @throws Exception
273 */
274 void execute() throws Exception;
275 }
276
277 protected static final void setHeapDumpOnOutOfMemoryError(boolean value) {
278 try {
279 MBeanServer server = ManagementFactory.getPlatformMBeanServer();
280 ObjectName beanName = ObjectName.getInstance("com.sun.management:type=HotSpotDiagnostic");
281 Object vmOption = server.invoke(beanName, "setVMOption", new Object[] { "HeapDumpOnOutOfMemoryError", Boolean.toString(value) },
282 new String[] { "java.lang.String", "java.lang.String" });
283 LOG.info("Set HeapDumpOnOutOfMemoryError to: " + value);
284 } catch (Throwable t) {
285 LOG.info("Set HeapDumpOnOutOfMemoryError to: " + value + " - failed", t);
286 }
287 }
288 }