/******************************************************************************* * Copyright (c) 2013, Perforce Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ package com.perforce.search.test.util; import java.io.InputStream; import java.util.Map; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.testng.Assert; import com.perforce.p4java.extension.command.RequestImpl; import com.perforce.p4java.extension.server.Server; import com.perforce.search.configuration.Configuration; import com.perforce.search.configuration.internal.ConfigurationImpl; import com.perforce.search.controller.QueueController; import com.perforce.search.controller.RootController; import com.perforce.search.controller.SearchController; import com.perforce.search.manager.SearchIndexManager; import com.perforce.search.manager.impl.QueueManagerImpl; import com.perforce.search.manager.impl.SearchIndexManagerImpl; import com.perforce.search.server.ServerConnectionPoolFacade; import com.perforce.search.server.impl.ServerConnectionPoolFacadeImpl; // base class: loads up the various components, provides an initialize function public class IndexTestBase { static final Logger log = Logger.getLogger(IndexTestBase.class); public String configFileLocation = "/default.config"; public Configuration config; public ServerConnectionPoolFacade pool; public SearchIndexManager searchIndexManager; public RootController rootController; public QueueController queueController; public SearchController searchController; // override that is useful for testing, knowing when it's done scanning public QMIWaiter queueManager; public HttpSolrServer solrServer; public boolean scanAndQuit = true; static public int EXPECTED_FILE_COUNT = 46; static public int EXPECTED_FILE_REV_COUNT = (46 * 3); static public int EXPECTED_INDEX_COUNT = 45; static public int EXPECTED_INDEX_REV_COUNT = (45 * 3); static public int EXPECTED_P4ATTR_PROP_COUNT = 3; // all 3 revisions of one // file static public int EXPECTED_P4ATTR_COUNT = 1; // only one head rev of one // file has it public class QMIWaiter extends QueueManagerImpl { public QMIWaiter(Configuration config, SearchIndexManager indexManager, ServerConnectionPoolFacade pool) { super(config, indexManager, pool); } // just for testing public void waitForFileThreadsCompletion() throws InterruptedException { if (this.directoryScanner == null) { log.error("directory scanner not created, returning"); return; } this.directoryScanner.join(); // all directories are scanned, so signal the file threads to quit // when the queue is empty log.debug("directory scanner done, signaling file indexers to quit when empty, files = " + this.getFilesTotal()); // for some tests we leave the file indexers running if (!scanAndQuit) return; setQuitWhenEmpty(true); for (Thread t : this.threads) t.join(); log.debug("file processors done, files = " + this.getFilesTotal()); if (!this.filesScanQueue.isEmpty() || !this.filesTriggerQueue.isEmpty()) throw new InterruptedException("quit when not empty!"); } }; // allow derived classes to customize configuration public void loadConfig() { InputStream properties = this.getClass().getResourceAsStream( configFileLocation); config = new ConfigurationImpl(properties); } public void setUp() throws Exception { log.debug("setUp()"); // load a config file loadConfig(); // create the p4d connection pool pool = new ServerConnectionPoolFacadeImpl(config); // make sure the file count is correct, or else every test is probably // going to fail Server server = null; try { server = pool.acquire(); Map<String, Object>[] files = server.execute(new RequestImpl() { @Override public String getCommand() { return "files"; } @Override public String[] getCommandArgs() { return new String[] { "-a", "//..." }; } }); // 45 files, 3 revisions each (except one dmg) Assert.assertEquals(files.length, EXPECTED_FILE_REV_COUNT); // reset solr, send a delete *:* and commit this.solrServer = new HttpSolrServer(config.getSearchURL()); solrServer.deleteByQuery("*:*"); solrServer.commit(); // reset the change key in the server. if the key is cleared we // don't care @SuppressWarnings("unused") Map<String, Object>[] cmd = server.execute(new RequestImpl() { @Override public String getCommand() { return "counter"; } @Override public String[] getCommandArgs() { return new String[] { "-u", "-d", config.getFileScannerTokenKey() }; } }); // also reset the catchup key or we randomly start catching up and // fail some tests @SuppressWarnings("unused") Map<String, Object>[] cmd2 = server.execute(new RequestImpl() { @Override public String getCommand() { return "counter"; } @Override public String[] getCommandArgs() { return new String[] { "-u", "-d", config.getChangelistCatchupKey() }; } }); // create pool, managers, then controllers, then the QueueManager // (scanner) searchIndexManager = new SearchIndexManagerImpl(config, pool); rootController = new RootController(config); queueController = new QueueController(config); searchController = new SearchController(config, searchIndexManager, pool); queueManager = new QMIWaiter(config, searchIndexManager, pool); // wait for completion queueManager.waitForFileThreadsCompletion(); } finally { pool.release(server); } } }