Skip to content

Commit

Permalink
Increased test speed by hundreds or thousands of percentages.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Eichar committed Nov 5, 2014
1 parent 05c2d89 commit 32129cb
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 241 deletions.
6 changes: 6 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
<artifactId>jetty-servlet</artifactId>
</dependency>

<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
Expand Down
30 changes: 22 additions & 8 deletions core/src/main/java/org/fao/geonet/kernel/SchemaManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

package org.fao.geonet.kernel;

import com.google.common.annotations.VisibleForTesting;
import jeeves.server.context.ServiceContext;
import jeeves.server.dispatchers.guiservices.XmlFile;
import jeeves.server.overrides.ConfigurationOverrides;
Expand Down Expand Up @@ -133,12 +134,25 @@ public static Path registerXmlCatalogFiles(Path webappDir, Path schemapluginUriC
return webInf;
}

//--------------------------------------------------------------------------
//---
//--- Constructor
//---
//--------------------------------------------------------------------------
@VisibleForTesting
public void configureFrom(SchemaManager schemaManager, Path basePath, GeonetworkDataDirectory dataDir) {
this.basePath = basePath;
this.resourcePath = dataDir.getResourcesDir();
this.schemaPluginsDir = dataDir.getSchemaPluginsDir();
this.schemaPluginsCat = schemaPluginsDir.resolve("schemaplugin-uri-catalog.xml");
this.defaultLang = schemaManager.defaultLang;
this.defaultSchema = schemaManager.defaultSchema;
this.createOrUpdateSchemaCatalog = schemaManager.createOrUpdateSchemaCatalog;

this.hmSchemas.clear();
this.hmSchemas.putAll(schemaManager.hmSchemas);


fnames = new String[schemaManager.fnames.length];
System.arraycopy(schemaManager.fnames, 0, fnames, 0, fnames.length);
numberOfCoreSchemasAdded = schemaManager.numberOfCoreSchemasAdded;

}
/**
* initialize and configure schema manager. should only be on startup.
*
Expand All @@ -156,10 +170,10 @@ public void configure(ApplicationContext applicationContext, Path basePath, Path
this.basePath = basePath;
this.resourcePath = resourcePath;
this.schemaPluginsDir = sPDir;
this.defaultLang = defaultLang;
this.defaultSchema = defaultSchema;
this.schemaPluginsCat = schemaPluginsCat;
this.createOrUpdateSchemaCatalog = createOrUpdateSchemaCatalog;
this.defaultLang = defaultLang;
this.defaultSchema = defaultSchema;
this.createOrUpdateSchemaCatalog = createOrUpdateSchemaCatalog;

Element schemaPluginCatRoot = getSchemaPluginCatalogTemplate();

Expand Down
233 changes: 5 additions & 228 deletions core/src/test/java/org/fao/geonet/AbstractCoreIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package org.fao.geonet;

import com.google.common.collect.Lists;
import com.vividsolutions.jts.geom.MultiPolygon;
import jeeves.constants.ConfigFile;
import jeeves.server.ServiceConfig;
import jeeves.server.UserSession;
import jeeves.server.context.ServiceContext;
import jeeves.server.sources.ServiceRequest;
Expand All @@ -15,38 +13,17 @@
import org.fao.geonet.domain.Source;
import org.fao.geonet.domain.User;
import org.fao.geonet.kernel.DataManager;
import org.fao.geonet.kernel.GeonetworkDataDirectory;
import org.fao.geonet.kernel.SchemaManager;
import org.fao.geonet.kernel.mef.Importer;
import org.fao.geonet.kernel.search.LuceneConfig;
import org.fao.geonet.kernel.search.SearchManager;
import org.fao.geonet.kernel.search.index.DirectoryFactory;
import org.fao.geonet.kernel.search.spatial.SpatialIndexWriter;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.languages.LanguageDetector;
import org.fao.geonet.repository.AbstractSpringDataTest;
import org.fao.geonet.repository.SourceRepository;
import org.fao.geonet.repository.UserRepository;
import org.fao.geonet.util.ThreadUtils;
import org.fao.geonet.utils.IO;
import org.fao.geonet.utils.Log;
import org.fao.geonet.utils.TransformerFactoryFactory;
import org.fao.geonet.utils.Xml;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureStore;
import org.geotools.feature.AttributeTypeBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
Expand All @@ -56,19 +33,13 @@
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.sql.DataSource;

import static org.junit.Assert.assertTrue;

/**
* A helper class for testing services. This super-class loads in the spring beans for Spring-data repositories and mocks for
Expand All @@ -80,217 +51,23 @@
*/
@ContextConfiguration(inheritLocations = true, locations = "classpath:core-repository-test-context.xml")
public abstract class AbstractCoreIntegrationTest extends AbstractSpringDataTest {
private static final String DATA_DIR_LOCK_NAME = "lock";
@Autowired
protected ConfigurableApplicationContext _applicationContext;
@PersistenceContext
protected EntityManager _entityManager;
@Autowired
protected DataStore _datastore;
@Autowired
protected UserRepository _userRepo;
@Autowired
protected DirectoryFactory _directoryFactory;

/**
* Contain all datadirectories for all nodes.
*/
protected static Path _dataDirContainer;
private static Path _dataDirLockFile;

/**
* Default node data directory
*/
protected static Path _dataDirectory;

@AfterClass
public static void tearDown() throws Exception {
if (_dataDirLockFile != null) {
Files.deleteIfExists(_dataDirLockFile);
}
}
protected GeonetTestFixture testFixture;

@Before
public void configureAppContext() throws Exception {

synchronized (AbstractCoreIntegrationTest.class) {
setUpDataDirectory();

if (!Files.exists(_dataDirLockFile)) {
IO.touch(_dataDirLockFile);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run()
{
try {
Files.deleteIfExists(_dataDirLockFile);
} catch (IOException e) {
throw new Error(e);
}
}
});
}
}

System.setProperty(LuceneConfig.USE_NRT_MANAGER_REOPEN_THREAD, Boolean.toString(true));
// clear out datastore
for (Name name : _datastore.getNames()) {
((FeatureStore<?, ?>) _datastore.getFeatureSource(name)).removeFeatures(Filter.INCLUDE);
}
final String initializedString = "initialized";
final Path webappDir = getWebappDir(getClass());
LanguageDetector.init(webappDir.resolve(_applicationContext.getBean(Geonet.Config.LANGUAGE_PROFILES_DIR, String.class)));

final GeonetworkDataDirectory geonetworkDataDirectory = _applicationContext.getBean(GeonetworkDataDirectory.class);

Files.createDirectories(_dataDirContainer);
IO.copyDirectoryOrFile(webappDir.resolve("WEB-INF/data"), _dataDirectory);
final ArrayList<Element> params = getServiceConfigParameterElements();

final ServiceConfig serviceConfig = new ServiceConfig(params);

try {
_applicationContext.getBean(initializedString);
} catch (NoSuchBeanDefinitionException e) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
AttributeDescriptor geomDescriptor = new AttributeTypeBuilder().crs(DefaultGeographicCRS.WGS84).binding(MultiPolygon.class)
.buildDescriptor("the_geom");
builder.setName("spatialIndex");
builder.add(geomDescriptor);
builder.add(SpatialIndexWriter._IDS_ATTRIBUTE_NAME, String.class);
_datastore.createSchema(builder.buildFeatureType());

_applicationContext.getBeanFactory().registerSingleton("serviceConfig", serviceConfig);
_applicationContext.getBeanFactory().registerSingleton(initializedString, initializedString);
}

NodeInfo nodeInfo = _applicationContext.getBean(NodeInfo.class);
nodeInfo.setId(getGeonetworkNodeId());
nodeInfo.setDefaultNode(isDefaultNode());

TransformerFactoryFactory.init("net.sf.saxon.TransformerFactoryImpl");

geonetworkDataDirectory.init("geonetwork", webappDir, _dataDirectory, serviceConfig, null);

_directoryFactory.resetIndex();

final Path schemaPluginsDir = geonetworkDataDirectory.getSchemaPluginsDir();

final Path resourcePath = geonetworkDataDirectory.getResourcesDir();

final SchemaManager schemaManager = _applicationContext.getBean(SchemaManager.class);
Files.deleteIfExists(_dataDirectory.resolve("config/schemaplugin-uri-catalog.xml"));
Path schemaPluginsCatalogFile = schemaPluginsDir.resolve("schemaplugin-uri-catalog.xml");
deploySchema(webappDir, schemaPluginsDir);

_applicationContext.getBean(LuceneConfig.class).configure("WEB-INF/config-lucene.xml");
SchemaManager.registerXmlCatalogFiles(webappDir, schemaPluginsCatalogFile);

schemaManager.configure(_applicationContext, webappDir, resourcePath,
schemaPluginsCatalogFile, schemaPluginsDir, "eng", "iso19139", true);

assertTrue(schemaManager.existsSchema("iso19139"));
assertTrue(schemaManager.existsSchema("iso19115"));
assertTrue(schemaManager.existsSchema("dublin-core"));

_applicationContext.getBean(SearchManager.class).init(false, false, "", 100);
_applicationContext.getBean(DataManager.class).init(createServiceContext(), false);

String siteUuid = _dataDirectory.getFileName().toString();
_applicationContext.getBean(SettingManager.class).setSiteUuid(siteUuid);
final SourceRepository sourceRepository = _applicationContext.getBean(SourceRepository.class);
List<Source> sources = sourceRepository.findAll();
if (sources.isEmpty()) {
sources = new ArrayList<Source>(1);
sources.add(sourceRepository.save(new Source().setLocal(true).setName("Name").setUuid(siteUuid)));
}
final DataSource dataSource = _applicationContext.getBean(DataSource.class);
Connection conn = null;
try {
conn = dataSource.getConnection();
ThreadUtils.init(conn.getMetaData().getURL(), _applicationContext.getBean(SettingManager.class));
} finally {
if (conn != null) {
conn.close();
}
}

}

private void setUpDataDirectory() throws IOException {
if (_dataDirLockFile != null && Files.exists(_dataDirLockFile) &&
Files.getLastModifiedTime(_dataDirLockFile).toMillis() < twoHoursAgo()) {
Files.delete(_dataDirLockFile);
}
if (_dataDirectory == null || _dataDirLockFile == null || !Files.exists(_dataDirLockFile)) {
Path dir = getClassFile(getClass()).getParentFile().toPath();
final String pathToTargetDir = "core/target";
while(!Files.exists(dir.resolve(pathToTargetDir))) {
dir = dir.getParent();
}
dir = dir.resolve(pathToTargetDir).resolve("integration-test-datadirs");

int i = 0;
while (Files.exists(dir.resolve(String.valueOf(i)).resolve(DATA_DIR_LOCK_NAME))) {
i++;
}

while (i < 1000) {
try {
Files.createDirectories(dir.resolve(String.valueOf(i)));
break;
} catch (IOException e) {
i++;
}
}


_dataDirContainer = dir.resolve(String.valueOf(i));

_dataDirectory = _dataDirContainer.resolve("defaultDataDir");
_dataDirLockFile = _dataDirContainer.resolve(DATA_DIR_LOCK_NAME);
}
}

private long twoHoursAgo() {
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.HOUR_OF_DAY, -2);
return calendar.getTimeInMillis();
}

private void deploySchema(Path srcDataDir, Path schemaPluginPath) throws IOException {
// Copy schema plugin
final String schemaModulePath = "schemas";
Path schemaModuleDir = srcDataDir.resolve("../../../../").resolve(schemaModulePath).normalize();
if (Files.exists(schemaModuleDir)) {
try (DirectoryStream<Path> paths = Files.newDirectoryStream(schemaModuleDir)) {
for (Path path : paths) {
final Path srcSchemaPluginDir = path.resolve("src/main/plugin").resolve(path.getFileName());
if (Files.exists(srcSchemaPluginDir)) {
Path destPath = schemaPluginPath.resolve(path.getFileName());
IO.copyDirectoryOrFile(srcSchemaPluginDir, destPath);
}
}
}
} else {
throw new AssertionError("Schemas module not found. this must be a programming error");
}
public void setup() throws Exception {
testFixture.setup(this);
}

@After
public void deleteNonDefaultNodeDataDirectories() throws IOException {
synchronized (AbstractCoreIntegrationTest.class) {
int i = 0;
while(i < 30) {
try {
IO.deleteFileOrDirectory(_dataDirContainer);
i = 100;
} catch (Exception e) {
i ++;
}
}
Files.deleteIfExists(_dataDirLockFile);
}

public void tearDown() throws Exception {
testFixture.tearDown();
}

protected boolean isDefaultNode() {
Expand Down
Loading

0 comments on commit 32129cb

Please sign in to comment.