/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.lucene.profiling; import java.io.File; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.RAMDirectory; import org.infinispan.Cache; import org.infinispan.lucene.CacheTestSupport; import org.infinispan.lucene.DirectoryIntegrityCheck; import org.infinispan.lucene.InfinispanDirectory; import org.infinispan.manager.CacheContainer; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; /** * PerformanceCompareStressTest is useful to get an idea on relative performance between Infinispan * in local or clustered mode against a RAMDirectory or FSDirectory. To be reliable set a long * DURATION_MS and a number of threads similar to the use case you're interested in: results might * vary on the number of threads because of the lock differences. This is not meant as a benchmark * but used to detect regressions. * * This requires Lucene > 2.9.1 or Lucene > 3.0.0 because of * https://issues.apache.org/jira/browse/LUCENE-2095 * * @author Sanne Grinovero * @since 4.0 */ @SuppressWarnings("unchecked") @Test(groups = "profiling", testName = "lucene.profiling.PerformanceCompareStressTest", sequential = true) public class PerformanceCompareStressTest { /** * The number of terms in the dictionary used as source of terms by the IndexWriter to produce * new documents */ private static final int DICTIONARY_SIZE = 800 * 1000; /** Concurrent Threads in tests */ private static final int READER_THREADS = 5; private static final int WRITER_THREADS = 1; private static final int CHUNK_SIZE = 512 * 1024; private static final String indexName = "tempIndexName"; private static final long DURATION_MS = 2 * 60 * 1000; private Cache cache; private EmbeddedCacheManager cacheFactory; @Test public void profileTestRAMDirectory() throws InterruptedException, IOException { RAMDirectory dir = new RAMDirectory(); stressTestDirectory(dir, "RAMDirectory"); } @Test public void profileTestFSDirectory() throws InterruptedException, IOException { File indexDir = new File(new File("."), indexName); boolean directoriesCreated = indexDir.mkdirs(); assert directoriesCreated : "couldn't create directory for FSDirectory test"; FSDirectory dir = FSDirectory.open(indexDir); stressTestDirectory(dir, "FSDirectory"); } @Test public void profileTestInfinispanDirectoryWithNetworkDelayZero() throws Exception { // TestingUtil.setDelayForCache(cache, 0, 0); InfinispanDirectory dir = new InfinispanDirectory(cache, cache, cache, indexName, CHUNK_SIZE); stressTestDirectory(dir, "InfinispanClustered-delayedIO:0"); verifyDirectoryState(); } @Test public void profileTestInfinispanDirectoryWithNetworkDelay4() throws Exception { TestingUtil.setDelayForCache(cache, 4, 4); InfinispanDirectory dir = new InfinispanDirectory(cache, cache, cache, indexName, CHUNK_SIZE); stressTestDirectory(dir, "InfinispanClustered-delayedIO:4"); verifyDirectoryState(); } @Test public void profileTestInfinispanDirectoryWithHighNetworkDelay40() throws Exception { TestingUtil.setDelayForCache(cache, 40, 40); InfinispanDirectory dir = new InfinispanDirectory(cache, cache, cache, indexName, CHUNK_SIZE); stressTestDirectory(dir, "InfinispanClustered-delayedIO:40"); verifyDirectoryState(); } @Test public void profileInfinispanLocalDirectory() throws InterruptedException, IOException { CacheContainer cacheContainer = CacheTestSupport.createLocalCacheManager(); try { cache = cacheContainer.getCache(); InfinispanDirectory dir = new InfinispanDirectory(cache, cache, cache, indexName, CHUNK_SIZE); stressTestDirectory(dir, "InfinispanLocal"); verifyDirectoryState(); } finally { cacheContainer.stop(); } } @Test(enabled=false)//to prevent invocations from some versions of TestNG public static void stressTestDirectory(Directory dir, String testLabel) throws InterruptedException, IOException { SharedState state = new SharedState(DICTIONARY_SIZE); CacheTestSupport.initializeDirectory(dir); ExecutorService e = Executors.newFixedThreadPool(READER_THREADS + WRITER_THREADS); for (int i = 0; i < READER_THREADS; i++) { e.execute(new LuceneReaderThread(dir, state)); } for (int i = 0; i < WRITER_THREADS; i++) { e.execute(new LuceneWriterThread(dir, state)); } e.shutdown(); state.startWaitingThreads(); Thread.sleep(DURATION_MS); long searchesCount = state.incrementIndexSearchesCount(0); long writerTaskCount = state.incrementIndexWriterTaskCount(0); state.quit(); boolean terminatedCorrectly = e.awaitTermination(20, TimeUnit.SECONDS); Assert.assertTrue(terminatedCorrectly); System.out.println("Test " + testLabel + " run in " + DURATION_MS + "ms:\n\tSearches: " + searchesCount + "\n\t" + "Writes: " + writerTaskCount); } @BeforeMethod public void beforeTest() { cacheFactory = TestCacheManagerFactory.createClusteredCacheManager(CacheTestSupport.createTestConfiguration()); cacheFactory.start(); cache = cacheFactory.getCache(); cache.clear(); } @AfterMethod public void afterTest() { TestingUtil.killCaches(cache); TestingUtil.killCacheManagers(cacheFactory); TestingUtil.recursiveFileRemove(indexName); } private void verifyDirectoryState() { DirectoryIntegrityCheck.verifyDirectoryStructure(cache, indexName, true); } }