View Javadoc

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         //CHM does have the occasional very slow time.
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         // Spin up the threads
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                         // Run the thread until the given end time
217                         while (System.currentTimeMillis() < endTime) {
218                             Assert.assertNotNull(executable);
219                             executable.execute();
220                         }
221                     } catch (Throwable t) {
222                         // Hang on to any errors
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         // Wait for the threads to finish
236         for (Thread thread : threads) {
237             thread.join();
238         }
239 
240 //        if (errors.size() > 0) {
241 //            for (Throwable error : errors) {
242 //                LOG.info("Error", error);
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 }