/*******************************************************************************
* 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);
}
}
}