package com.constellio.sdk.tests;
import static com.constellio.model.entities.schemas.Schemas.TITLE;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.fromAllSchemasInExceptEvents;
import static com.constellio.sdk.tests.SDKConstellioFactoriesInstanceProvider.DEFAULT_NAME;
import static com.constellio.sdk.tests.SaveStateFeatureAcceptTest.verifySameContentOfUnzippedSaveState;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.ws.rs.client.WebTarget;
import org.apache.chemistry.opencmis.client.api.Session;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.joda.time.Duration;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.carrotsearch.junitbenchmarks.BenchmarkOptionsSystemProperties;
import com.constellio.app.client.services.AdminServicesSession;
import com.constellio.app.entities.modules.InstallableModule;
import com.constellio.app.modules.es.ConstellioESModule;
import com.constellio.app.modules.rm.ConstellioRMModule;
import com.constellio.app.modules.rm.DemoTestRecords;
import com.constellio.app.modules.rm.RMTestRecords;
import com.constellio.app.modules.robots.ConstellioRobotsModule;
import com.constellio.app.modules.tasks.TaskModule;
import com.constellio.app.services.factories.AppLayerFactory;
import com.constellio.app.services.factories.ConstellioFactories;
import com.constellio.app.services.importExport.systemStateExport.SystemStateExportParams;
import com.constellio.app.services.importExport.systemStateExport.SystemStateExporter;
import com.constellio.app.ui.pages.base.SessionContext;
import com.constellio.app.ui.tools.ServerThrowableContext;
import com.constellio.app.ui.tools.vaadin.TestContainerButtonListener;
import com.constellio.app.ui.tools.vaadin.TestEnterViewListener;
import com.constellio.app.ui.tools.vaadin.TestInitUIListener;
import com.constellio.client.cmis.client.CmisSessionBuilder;
import com.constellio.data.conf.HashingEncoding;
import com.constellio.data.conf.PropertiesDataLayerConfiguration.InMemoryDataLayerConfiguration;
import com.constellio.data.dao.services.factories.DataLayerFactory;
import com.constellio.data.dao.services.transactionLog.SecondTransactionLogReplayFilter;
import com.constellio.data.io.IOServicesFactory;
import com.constellio.data.io.services.facades.IOServices;
import com.constellio.data.io.services.zip.ZipService;
import com.constellio.data.io.services.zip.ZipServiceException;
import com.constellio.data.io.streamFactories.StreamFactory;
import com.constellio.data.utils.ConsoleLogger;
import com.constellio.data.utils.TimeProvider;
import com.constellio.data.utils.TimeProvider.DefaultTimeProvider;
import com.constellio.data.utils.dev.Toggle.AvailableToggle;
import com.constellio.model.conf.FoldersLocator;
import com.constellio.model.entities.configs.SystemConfiguration;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.wrappers.Group;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.services.factories.ModelLayerFactory;
import com.constellio.model.services.records.RecordServicesException;
import com.constellio.model.services.records.SchemasRecordsServices;
import com.constellio.model.services.records.reindexing.ReindexationMode;
import com.constellio.model.services.records.reindexing.ReindexingServices;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.users.UserServices;
import com.constellio.sdk.tests.FailureDetectionTestWatcher.FailureDetectionTestWatcherListener;
import com.constellio.sdk.tests.ToggleTestFeature.ToggleCondition;
import com.constellio.sdk.tests.annotations.UiTest;
import com.constellio.sdk.tests.concurrent.ConcurrentJob;
import com.constellio.sdk.tests.concurrent.OngoingConcurrentExecution;
import com.constellio.sdk.tests.schemas.SchemaTestFeatures;
import com.constellio.sdk.tests.selenium.adapters.constellio.ConstellioWebDriver;
import com.constellio.sdk.tests.setups.TestsSpeedStats;
import com.constellio.sdk.tests.setups.Users;
public abstract class AbstractConstellioTest implements FailureDetectionTestWatcherListener {
protected static boolean notAUnitItest = false;
private static TestsSpeedStats stats = new TestsSpeedStats();
public static final String SDK_STREAM = StreamsTestFeatures.SDK_STREAM;
public static SDKPropertiesLoader sdkPropertiesLoader = new SDKPropertiesLoader();
private static Logger LOGGER;
// private static boolean batchProcessControllerStarted = false;
private static String[] notUnitTestSuffix = new String[] { "AcceptanceTest", "IntegrationTest", "RealTest", "LoadTest",
"StressTest", "PerformanceTest", "AcceptTest" };
private static Map<String, Long> previousMemoryUsage = new HashMap<>();
// CHECKSTYLE:OFF
// Junit requires this field to be public
@Rule public SkipTestsRule skipTestRule;
@Rule public FailureDetectionTestWatcher failureDetectionTestWatcher = new FailureDetectionTestWatcher(this);
protected Map<String, String> sdkProperties = new HashMap<>();
protected String zeCollection = "zeCollection";
protected String businessCollection = "LaCollectionDeRida";
protected String admin = "admin";
protected String aliceWonderland = "alice";
protected String alice = "alice";
protected String bob = "bob";
protected String bobGratton = "bob";
protected String chuckNorris = "chuck";
protected String chuck = "chuck";
protected String charlesFrancoisXavier = "charles";
protected String charles = "charles";
protected String dakota = "dakota";
protected String edouard = "edouard";
protected String gandalf = "gandalf";
protected String robin = "robin";
protected String sasquatch = "sasquatch";
protected String heroes = "heroes";
protected String legends = "legends";
protected String sidekicks = "sidekicks";
protected String rumors = "rumors";
private int printIndex = 0;
private long time;
private File state1, state2;
private TemporaryFolder folder;
public AbstractConstellioTest() {
sdkPropertiesLoader.setLocked(isUnitTest());
sdkProperties = sdkPropertiesLoader.getSDKProperties();
skipTestRule = new SkipTestsRule(sdkPropertiesLoader, isUnitTest(getClass().getSimpleName()));
ConsoleLogger.GLOBAL_PREFIX = getClass().getSimpleName();
}
@BeforeClass
public static void beforeClass()
throws Exception {
MetadataSchemasManager.cacheEnabled = true;
LOGGER = null;
System.setProperty(BenchmarkOptionsSystemProperties.BENCHMARK_ROUNDS_PROPERTY, "1");
System.setProperty(BenchmarkOptionsSystemProperties.WARMUP_ROUNDS_PROPERTY, "0");
if (System.getProperty("jub.consumers") == null) {
System.setProperty("jub.consumers", "CONSOLE,H2");
}
if (System.getProperty("jub.db.file") == null) {
System.setProperty("jub.db.file", "benckmarks/.benchmarks");
}
if (System.getProperty(BenchmarkOptionsSystemProperties.CHARTS_DIR_PROPERTY) == null) {
System.setProperty(BenchmarkOptionsSystemProperties.CHARTS_DIR_PROPERTY, "benckmarks/charts");
}
}
protected void givenWaitForBatchProcessAfterTestIsDisabled() {
getCurrentTestSession().getBatchProcessTestFeature().waitForBatchProcessAfterTest = false;
}
protected void givenBackgroundThreadsEnabled() {
getCurrentTestSession().getFactoriesTestFeatures().givenBackgroundThreadsEnabled();
}
protected void givenSystemLanguageIs(String languageCode) {
getCurrentTestSession().getFactoriesTestFeatures().setSystemLanguage(languageCode);
}
@AfterClass
public static void afterClass() {
ConstellioTestSession.closeAfterTestClass();
//stats.printSummaries();
}
protected static LocalDateTime dateTime(int day, int zeroBasedMonth, int year) {
return new LocalDateTime(year, zeroBasedMonth, day, 0, 0);
}
protected static LocalDateTime dateTime(int year, int zeroBasedMonth, int day, int hour, int min, int sec) {
return new LocalDateTime(year, zeroBasedMonth, day, hour, min, sec);
}
protected static LocalDate date(int year, int oneBasedMonth, int day) {
return new LocalDate(year, oneBasedMonth, day);
}
public static boolean isUnitTest(String className) {
for (String suffix : notUnitTestSuffix) {
if (className.endsWith(suffix)) {
return false;
}
}
return true;
}
public static File aFile() {
return TestUtils.aFile();
}
private static void ensureNotUnitTest() {
if (isUnitTestStatic()) {
String message = "Unit tests '" + TestClassFinder.getTestClassName()
+ "' cannot use filesystem, rename this test to AcceptanceTest or IntegrationTest or RealTest";
throw new RuntimeException(message);
}
}
public static boolean isUnitTestStatic() {
return !notAUnitItest && isUnitTest(TestClassFinder.getTestClassName());
}
protected String getTestName() {
return skipTestRule.currentTestName;
}
@org.junit.Before
public void invalidateStaticCaches() {
FoldersLocator.invalidateCaches();
}
@org.junit.Before
public void logTest() {
if (LOGGER == null) {
LOGGER = LoggerFactory.getLogger(getClass());
}
try {
FileUtils.write(new File("constellio.log"), "Test '" + getTestName() + "' has started", true);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void assertThatStatesAreEqual(File state1, File state2)
throws Exception {
File state1TempFolder = newTempFolder();
File state2TempFolder = newTempFolder();
getIOLayerFactory().newZipService().unzip(state1, state1TempFolder);
getIOLayerFactory().newZipService().unzip(state2, state2TempFolder);
verifySameContentOfUnzippedSaveState(state1TempFolder, state2TempFolder);
}
@After
public void printMemoryUsage() {
boolean memoryReport = false;
if (sdkPropertiesLoader.sdkProperties != null) {
memoryReport = "true".equals(sdkPropertiesLoader.sdkProperties.get("memoryReport"));
}
if (memoryReport) {
printDeltaMemoryUsage(getTestName());
System.gc();
System.runFinalization();
previousMemoryUsage = getMemoryUsage();
} else {
try {
FileUtils.write(new File("constellio.log"), "Test '" + getTestName() + "' has ended", true);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
protected boolean checkRollback() {
return skipTestRule.checkRollback;
}
private Map<String, Long> getMemoryUsage() {
Map<String, Long> memoryUsage = new HashMap<>();
for (MemoryPoolMXBean item : ManagementFactory.getMemoryPoolMXBeans()) {
memoryUsage.put(item.getName(), item.getUsage().getUsed());
}
return memoryUsage;
}
private void printDeltaMemoryUsage(String stepName) {
Map<String, Long> currentMemoryUsage = getMemoryUsage();
List<String> keys = new ArrayList<>(currentMemoryUsage.keySet());
Collections.sort(keys);
StringBuilder deltas = new StringBuilder(". Memory deltas : ");
boolean hasOneDelta = false;
for (String key : keys) {
long previous = !previousMemoryUsage.containsKey(key) ? 0 : previousMemoryUsage.get(key);
long current = currentMemoryUsage.get(key);
long delta = current - previous;
if (delta > 10000000) {
long deltaInMo = delta / 1000000;
deltas.append("\n\t\t" + key + ": " + deltaInMo + "Mo");
hasOneDelta = true;
}
}
try {
FileUtils.write(new File("constellio.log"), "Test '" + getTestName() + "' has ended" + (hasOneDelta ? deltas : ""),
true);
} catch (IOException e) {
throw new RuntimeException(e);
}
previousMemoryUsage = currentMemoryUsage;
}
protected byte[] aByteArray() {
return TestUtils.aByteArray();
}
protected LocalDateTime aDateTime() {
return TestUtils.aDateTime();
}
protected LocalDate aDate() {
return TestUtils.aDate();
}
protected File aFile(File parent) {
return TestUtils.aFile(parent);
}
protected long aLong() {
return TestUtils.aLong();
}
protected int anInteger() {
return TestUtils.anInteger();
}
protected String aString() {
return TestUtils.aString();
}
protected String[] aStringArray() {
return TestUtils.aStringArray();
}
protected <T extends Closeable> T closeAfterTest(T closeable) {
return getCurrentTestSession().getStreamsTestFeatures().closeAfterTest(closeable);
}
protected File createTempCopy(File originalFile) {
ensureNotUnitTest();
return getCurrentTestSession().getFileSystemTestFeatures().createTempCopy(originalFile);
}
protected InputStream getTestResourceInputStream(String partialName) {
return getTestResourceInputStream(null, partialName);
}
protected InputStream getTestResourceInputStream(Class<?> clazz, String partialName) {
ensureNotUnitTest();
File testResourceFile = getTestResourceFile(clazz, partialName);
InputStream inputStream;
try {
inputStream = newFileInputStream(testResourceFile);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
closeAfterTest(inputStream);
return inputStream;
}
protected String getTestResourceContent(String partialName) {
try {
return FileUtils.readFileToString(getTestResourceFile(partialName));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static File getResourcesDir() {
File resourcesDir = new File("sdk-resources");
if (!resourcesDir.getAbsolutePath().contains(File.separator + "sdk" + File.separator)) {
resourcesDir = new File("sdk" + File.separator + "sdk-resources");
}
return resourcesDir;
}
protected File getTestResourceFile(String partialName) {
return getTestResourceFile(null, partialName);
}
public static File getTestResourceFileWithoutCheckingIfUnitTest(Class clazz, String partialName) {
String completeName = clazz.getCanonicalName().replace(".", File.separator) + "-" + partialName;
File resourcesDir = getResourcesDir();
File file = new File(resourcesDir, completeName);
if (!file.exists()) {
throw new RuntimeException("No such file '" + file.getAbsolutePath() + "'");
}
return file;
}
protected File getTestResourceFile(Class clazz, String partialName) {
ensureNotUnitTest();
return getTestResourceFileWithoutCheckingIfUnitTest(clazz == null ? getClass() : clazz, partialName);
}
protected StreamFactory<InputStream> getTestResourceInputStreamFactory(final String partialName) {
return getCurrentTestSession().getStreamsTestFeatures()
.ensureAllCreatedCloseableAreClosed(new StreamFactory<InputStream>() {
@Override
public InputStream create(String name)
throws IOException {
return newFileInputStream(getTestResourceFile(partialName));
}
});
}
protected StreamFactory<InputStream> getTestResourceInputStreamFactory(final File file) {
return getCurrentTestSession().getStreamsTestFeatures()
.ensureAllCreatedCloseableAreClosed(new StreamFactory<InputStream>() {
@Override
public InputStream create(String name)
throws IOException {
return newFileInputStream(file);
}
});
}
protected StreamFactory<OutputStream> getTestResourceOutputStreamFactory(final File file) {
return getCurrentTestSession().getStreamsTestFeatures()
.ensureAllCreatedCloseableAreClosed(new StreamFactory<OutputStream>() {
@Override
public OutputStream create(String name)
throws IOException {
return new FileOutputStream(file);
}
});
}
protected StreamFactory<InputStream> getTestResourceInputStreamFactory(final byte[] bytes) {
return getCurrentTestSession().getStreamsTestFeatures()
.ensureAllCreatedCloseableAreClosed(new StreamFactory<InputStream>() {
@Override
public InputStream create(String name)
throws IOException {
return new ByteArrayInputStream(bytes);
}
});
}
protected File getUnzippedResourceFile(Class clazz, String partialName) {
File zipFile = getTestResourceFile(clazz, partialName);
return unzipInTempFolder(zipFile);
}
protected File getUnzippedResourceFile(String partialName) {
File zipFile = getTestResourceFile(partialName);
return unzipInTempFolder(zipFile);
}
protected boolean isUnitTest() {
return isUnitTest(getClass().getSimpleName());
}
@SuppressWarnings("unchecked")
protected <I> List<I> newArrayList(I... items) {
return new ArrayList<>(asList(items));
}
protected void configure(DataLayerConfigurationAlteration dataLayerConfigurationAlteration) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().configure(dataLayerConfigurationAlteration);
}
protected void configure(ModelLayerConfigurationAlteration modelLayerConfigurationAlteration) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().configure(modelLayerConfigurationAlteration);
}
protected void configure(AppLayerConfigurationAlteration appLayerConfigurationAlteration) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().configure(appLayerConfigurationAlteration);
}
protected AppLayerFactory getAppLayerFactory() {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newAppServicesFactory(DEFAULT_NAME);
}
protected AppLayerFactory getAppLayerFactory(String name) {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newAppServicesFactory(name);
}
protected DataLayerFactory getDataLayerFactory() {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newDaosFactory(DEFAULT_NAME);
}
protected DataLayerFactory getDataLayerFactory(String name) {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newDaosFactory(name);
}
protected IOServicesFactory getIOLayerFactory() {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newIOServicesFactory(DEFAULT_NAME);
}
protected ConstellioFactories getConstellioFactories() {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().getConstellioFactories(DEFAULT_NAME);
}
protected ConstellioFactories getConstellioFactories(String name) {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().getConstellioFactories(name);
}
protected ModelLayerFactory getModelLayerFactory() {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newModelServicesFactory(DEFAULT_NAME);
}
protected ModelLayerFactory getModelLayerFactory(String name) {
ensureNotUnitTest();
return getCurrentTestSession().getFactoriesTestFeatures().newModelServicesFactory(name);
}
protected void withSpiedServices(Class<?>... classes) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().withSpiedServices(classes);
}
protected FoldersLocator getFoldersLocator() {
return getCurrentTestSession().getFactoriesTestFeatures().getFoldersLocator(DEFAULT_NAME);
}
protected File givenUnzipedResourceInFolder(String fileName) {
ensureNotUnitTest();
File file = getTestResourceFile(fileName);
return getCurrentTestSession().getFileSystemTestFeatures().givenUnzipedFileInTempFolder(file);
}
protected File givenUnzipedResourceInFolder(Class<? extends AbstractConstellioTest> clazz, String fileName) {
ensureNotUnitTest();
File file = getTestResourceFile(clazz, fileName);
return getCurrentTestSession().getFileSystemTestFeatures().givenUnzipedFileInTempFolder(file);
}
protected File newTempFileWithContent(String fileName, String content) {
ensureNotUnitTest();
return getCurrentTestSession().getFileSystemTestFeatures().newTempFileWithContent(newTempFolder(), fileName, content);
}
protected File newTempFileWithContentInFolder(File tempFolder, String fileName, String content) {
ensureNotUnitTest();
return getCurrentTestSession().getFileSystemTestFeatures().newTempFileWithContent(tempFolder, fileName, content);
}
protected File newTempFolder() {
ensureNotUnitTest();
return getCurrentTestSession().getFileSystemTestFeatures().newTempFolder();
}
protected File newTempFolderInFolder(File tempParentFolder, String tempFolderName) {
File tempFolder = new File(tempParentFolder, tempFolderName);
tempFolder.mkdirs();
assertTrue(tempFolder.exists());
return tempFolder;
}
protected CmisSessionBuilder newCmisSessionBuilder() {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().load();
return getCurrentTestSession().getSeleniumTestFeatures().newCmisSessionBuilder();
}
protected AdminServicesSession newRestClient(String serviceKey, String username, String password) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().load();
return getCurrentTestSession().getSeleniumTestFeatures().newRestClient(serviceKey, username, password);
}
protected WebTarget newWebTarget() {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().load();
return getCurrentTestSession().getSeleniumTestFeatures().newWebTarget();
}
protected WebTarget newWebTarget(String path) {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().load();
return getCurrentTestSession().getSeleniumTestFeatures().newWebTarget(path);
}
protected SolrClient newSearchClient() {
ensureNotUnitTest();
getCurrentTestSession().getFactoriesTestFeatures().load();
return getCurrentTestSession().getSeleniumTestFeatures().newSearchClient();
}
protected String startApplicationWithWebServices() {
getCurrentTestSession().getSeleniumTestFeatures().disableAllServices();
System.setProperty("driverEnabled", "true");
return getCurrentTestSession().getSeleniumTestFeatures().startApplication();
}
protected String startApplication() {
getCurrentTestSession().getSeleniumTestFeatures().disableAllServices();
return getCurrentTestSession().getSeleniumTestFeatures().startApplication();
}
protected String startApplicationWithSSL(boolean keepAlive) {
getCurrentTestSession().getSeleniumTestFeatures().disableAllServices();
return getCurrentTestSession().getSeleniumTestFeatures().startApplicationWithSSL(keepAlive);
}
protected void stopApplication() {
getCurrentTestSession().getSeleniumTestFeatures().stopApplication();
}
protected ConstellioWebDriver newWebDriver() {
return newWebDriver(null, false);
}
protected ConstellioWebDriver newWebDriverSSL() {
return newWebDriver(null, true);
}
protected ConstellioWebDriver newWebDriver(SessionContext sessionContext) {
return newWebDriver(sessionContext, false);
}
protected ConstellioWebDriver newWebDriver(SessionContext sessionContext, boolean useSSL) {
ensureNotUnitTest();
ensureUITest();
if (sessionContext instanceof FakeSessionContext) {
if (((FakeSessionContext) sessionContext).fake) {
throw new RuntimeException("Web driver requires a valid session context. Use 'loggedAsUserInCollection' instead");
}
}
getCurrentTestSession().getFactoriesTestFeatures().load();
AppLayerFactory factory = getAppLayerFactory();
factory.getInitUIListeners().add(new TestInitUIListener(sessionContext));
factory.getEnterViewListeners().add(new TestEnterViewListener());
factory.getContainerButtonListeners().add(new TestContainerButtonListener());
ServerThrowableContext.LAST_THROWABLE.set(null);
return getCurrentTestSession().getSeleniumTestFeatures()
.newWebDriver(skipTestRule.isInDevelopmentTest() || skipTestRule.isMainTest(), useSSL);
}
private void ensureUITest() {
if (getClass().getAnnotation(UiTest.class) == null && !skipTestRule.isInDevelopmentTest()) {
throw new RuntimeException("The test class must have declared @UITest annotation");
}
}
private void ensureInDevelopmentTest() {
if (!skipTestRule.isInDevelopmentTest() && !skipTestRule.isMainTest()) {
throw new RuntimeException("The test class must have declared @InDevelopmentTest annotation");
}
}
protected void waitUntilICloseTheBrowsers() {
ensureNotUnitTest();
ensureInDevelopmentTest();
getCurrentTestSession().getSeleniumTestFeatures().waitUntilICloseTheBrowsers();
}
protected File unzipInTempFolder(File zipFile) {
File tempFolder = newTempFolder();
try {
new ZipService(new IOServices(newTempFolder())).unzip(zipFile, tempFolder);
return tempFolder;
} catch (ZipServiceException e) {
throw new RuntimeException(e);
}
}
protected File createRandomTextFilesInTempFolder(int numberOfFiles, int charactersPerFile) {
return getCurrentTestSession().getFileSystemTestFeatures()
.createRandomTextFilesInTempFolder(numberOfFiles, charactersPerFile);
}
protected void assertInputStreamEquals(InputStream i1, InputStream i2) {
try {
byte[] i1Bytes = IOUtils.toByteArray(i1);
byte[] i2Bytes = IOUtils.toByteArray(i2);
assertThat(i2Bytes).isEqualTo(i1Bytes);
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
protected OngoingConcurrentExecution runConcurrently(ConcurrentJob job) {
return new OngoingConcurrentExecution(job);
}
protected FileSystemTestFeatures modifyFileSystem() {
ensureNotUnitTest();
return getCurrentTestSession().getFileSystemTestFeatures();
}
protected SchemaTestFeatures defineSchemasManager() {
if (isUnitTestStatic()) {
throw new RuntimeException("Must use defineSchemas(mockedMetadataSchemasManager)");
}
return getCurrentTestSession().getSchemaTestFeatures().use();
}
protected SchemaTestFeatures define(MetadataSchemasManager metadataSchemaManager) {
return getCurrentTestSession().getSchemaTestFeatures().useWithMockedSchemaManager(metadataSchemaManager);
}
protected ModulesAndMigrationsTestFeatures givenCollectionInVersion(String collection, List<String> languages,
String version) {
ensureNotUnitTest();
getAppLayerFactory().getCollectionsManager().createCollectionInVersion(collection, languages, version);
return new ModulesAndMigrationsTestFeatures(getCurrentTestSession().getFactoriesTestFeatures(), collection);
}
protected ModulesAndMigrationsTestFeatures givenCollectionWithTitle(String collection, String collectionTitle) {
ModulesAndMigrationsTestFeatures features = givenCollection(collection);
Record collectionRecord = getModelLayerFactory().newRecordServices().getDocumentById(collection);
try {
getModelLayerFactory().newRecordServices().update(collectionRecord.set(Schemas.TITLE, collectionTitle));
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
return features;
}
protected ModulesAndMigrationsTestFeatures givenCollectionWithTitle(String collection, List<String> languages,
String collectionTitle) {
ModulesAndMigrationsTestFeatures features = givenCollection(collection, languages);
Record collectionRecord = getModelLayerFactory().newRecordServices().getDocumentById(collection);
try {
getModelLayerFactory().newRecordServices().update(collectionRecord.set(Schemas.TITLE, collectionTitle));
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
return features;
}
protected ModulesAndMigrationsTestFeatures givenCachedCollection(String collection) {
return givenCollection(collection);
}
protected ModulesAndMigrationsTestFeatures givenSpecialCollection(String collection) {
return givenCollection(collection);
}
protected ModulesAndMigrationsTestFeatures givenCollection(String collection) {
return givenCollection(collection, asList("fr", "en"));
}
protected ModulesAndMigrationsTestFeatures givenSpecialCollection(String collection, List<String> languages) {
return givenCollection(collection, languages);
}
protected ModulesAndMigrationsTestFeatures givenCollection(String collection, List<String> languages) {
ensureNotUnitTest();
getAppLayerFactory().getCollectionsManager().createCollectionInCurrentVersion(collection, languages);
return new ModulesAndMigrationsTestFeatures(getCurrentTestSession().getFactoriesTestFeatures(), collection);
}
protected void givenTimeIs(final LocalDateTime localDateTime) {
final LocalDate localDate = new LocalDate(localDateTime);
TimeProvider.setTimeProvider(new TimeProvider() {
@Override
public LocalDateTime getTimeProviderLocalDateTime() {
return localDateTime;
}
@Override
public LocalDate getTimeProviderLocalDate() {
return localDate;
}
});
}
protected void givenTimeIs(final LocalDate localDate) {
final LocalDateTime localDateTime = localDate.toDateMidnight().toDateTime().toLocalDateTime();
TimeProvider.setTimeProvider(new TimeProvider() {
@Override
public LocalDateTime getTimeProviderLocalDateTime() {
return localDateTime;
}
@Override
public LocalDate getTimeProviderLocalDate() {
return localDate;
}
});
}
protected void givenActualTime() {
TimeProvider.setTimeProvider(new DefaultTimeProvider());
}
protected void waitForBatchProcessAcceptingErrors()
throws InterruptedException {
long batchProcessStart = new Date().getTime();
ensureNotUnitTest();
getCurrentTestSession().getBatchProcessTestFeature().waitForAllBatchProcessesAcceptingErrors(null);
long batchProcessEnd = new Date().getTime();
stats.add(this, getTestName(), "waitForBatchProcess", batchProcessEnd - batchProcessStart);
}
protected void waitForBatchProcess()
throws InterruptedException {
long batchProcessStart = new Date().getTime();
ensureNotUnitTest();
getCurrentTestSession().getBatchProcessTestFeature().waitForAllBatchProcessesAndEnsureNoErrors(null);
long batchProcessEnd = new Date().getTime();
stats.add(this, getTestName(), "waitForBatchProcess", batchProcessEnd - batchProcessStart);
}
protected void waitForBatchProcessAndDoSomethingWhenTheFirstBatchProcessIsStarted(Runnable runtimeAction)
throws InterruptedException {
ensureNotUnitTest();
getCurrentTestSession().getBatchProcessTestFeature().waitForAllBatchProcessesAndEnsureNoErrors(runtimeAction);
}
public void runSubTest(SubTest subTest) {
System.out.println("\n\n=====================- " + subTest.getClass().getSimpleName() + " -===================== \n");
long before = new Date().getTime();
subTest.run();
long after = new Date().getTime();
System.out.println("\nsub test duration : " + (after - before) + "ms");
}
protected void givenConstellioProperties(Map<String, String> configMap) {
getCurrentTestSession().getFactoriesTestFeatures().givenConstellioProperties(configMap);
}
protected void printTimeElapsedSinceLastCall() {
printTimeElapsedSinceLastCall(null);
}
protected void printTimeElapsedSinceLastCall(String comment) {
if (comment == null) {
comment = (printIndex - 1) + "-" + printIndex;
}
System.out.println("= = = = = = = = = = = = = = = = = = = = = = =\n" + "" +
"Segment '" + comment + "' took " + (new Date().getTime() - time) + "ms\n" +
"= = = = = = = = = = = = = = = = = = = = = = =\n");
time = new Date().getTime();
}
protected abstract ConstellioTestSession getCurrentTestSession();
public abstract class SubTest {
public abstract void run();
}
protected InputStream newFileInputStream(File file)
throws FileNotFoundException {
return getModelLayerFactory().getIOServicesFactory().newIOServices().newFileInputStream(file, SDK_STREAM);
}
protected Reader getTestResourceReader(String resourceName)
throws FileNotFoundException {
return getModelLayerFactory().getIOServicesFactory().newIOServices()
.newFileReader(getTestResourceFile(resourceName), SDK_STREAM);
}
protected Reader getTestResourceReader(File file)
throws FileNotFoundException {
return getModelLayerFactory().getIOServicesFactory().newIOServices().newFileReader(file, SDK_STREAM);
}
protected StreamFactory<Reader> getTestResourceReaderFactory(String resourceName)
throws FileNotFoundException {
File file = getTestResourceFile(resourceName);
return getModelLayerFactory().getIOServicesFactory().newIOServices().newFileReaderFactory(file);
}
protected void givenConfig(SystemConfiguration config, Object value) {
ensureNotUnitTest();
if (getModelLayerFactory().getSystemConfigurationsManager().setValue(config, value)) {
getAppLayerFactory().getSystemGlobalConfigsManager().setReindexingRequired(true);
}
}
protected void waitUntilTrue(AtomicBoolean atomicBoolean) {
while (!atomicBoolean.get()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
protected void pokeChuckNorris() {
System.out.println("You poke Chuck Norris...");
System.out.println("Chuck Norris roundhouse kicked you in the face.");
System.exit(0);
}
protected final User wrapUser(Record userRecord) {
ensureNotUnitTest();
getModelLayerFactory().newRecordServices().refresh(userRecord);
if (userRecord == null) {
return null;
} else {
return new SchemasRecordsServices(userRecord.getCollection(), getModelLayerFactory()).wrapUser(userRecord);
}
}
protected final Group wrapGroup(Record userRecord) {
ensureNotUnitTest();
getModelLayerFactory().newRecordServices().refresh(userRecord);
if (userRecord == null) {
return null;
} else {
return new SchemasRecordsServices(userRecord.getCollection(), getModelLayerFactory()).wrapGroup(userRecord);
}
}
protected SessionContext loggedAsUserInCollection(String username, String collection) {
ensureNotUnitTest();
User user = getModelLayerFactory().newUserServices().getUserInCollection(username, collection);
return FakeSessionContext.forRealUserIncollection(user);
}
protected Record record(String id) {
ensureNotUnitTest();
return getModelLayerFactory().newRecordServices().getDocumentById(id);
}
protected Record withId(String id) {
ensureNotUnitTest();
return getModelLayerFactory().newRecordServices().getDocumentById(id);
}
public abstract void afterTest(boolean failed);
protected void safeAfterTest(boolean failed) {
afterTest(failed);
}
public void failed(Throwable e, Description description) {
if (!skipTestRule.wasSkipped()) {
safeAfterTest(true);
}
}
public void finished(Description description) {
if (!skipTestRule.wasSkipped()) {
safeAfterTest(false);
}
}
protected void givenDisabledAfterTestValidations() {
getCurrentTestSession().getAfterTestValidationsTestFeature().disableInCurrentTest();
givenRollbackCheckDisabled();
}
protected String recordIdWithTitleInCollection(String title, String collection) {
Record record = getModelLayerFactory().newSearchServices().searchSingleResult(
fromAllSchemasInExceptEvents(collection).where(TITLE).isEqualTo(title));
return record.getId();
}
protected SaveStateFeature getSaveStateFeature() {
return getCurrentTestSession().getSaveStateFeature();
}
protected void givenTransactionLogIsEnabled() {
givenTransactionLogIsEnabled(null);
}
protected void givenRollbackCheckDisabled() {
getCurrentTestSession().getFactoriesTestFeatures().withoutCheckForRollback();
}
protected void givenTransactionLogIsEnabled(final SecondTransactionLogReplayFilter filter) {
final File logTempFolder = getCurrentTestSession().getFileSystemTestFeatures().newTempFolderWithName("tLog");
configure(new DataLayerConfigurationAlteration() {
@Override
public void alter(InMemoryDataLayerConfiguration configuration) {
configuration.setSecondTransactionLogEnabled(true);
configuration.setSecondTransactionLogBaseFolder(logTempFolder);
if (filter != null) {
configuration.setSecondTransactionLogReplayFilter(filter);
}
}
});
}
private static boolean firstPreparation = true;
public static interface CustomSystemPreparation {
void prepare();
void initializeFromCache();
}
private File getTurboCacheFolder() {
File turboCacheFolder = new File(new FoldersLocator().getSDKProject(), "turboCache");
HyperTurboMode mode = getHyperturboMode();
if (mode == HyperTurboMode.AUTO && turboCacheFolder.exists() && firstPreparation) {
try {
FileUtils.deleteDirectory(turboCacheFolder);
} catch (IOException e) {
throw new RuntimeException(e);
}
firstPreparation = false;
}
turboCacheFolder.mkdirs();
return turboCacheFolder;
}
public void customSystemPreparation(CustomSystemPreparation preparation) {
HyperTurboMode mode = getHyperturboMode();
if (mode.isEnabled()) {
givenTransactionLogIsEnabled();
}
File stateFolder = new File(getTurboCacheFolder(), getClass().getSimpleName());
if (mode.isEnabled() && stateFolder.exists()) {
getCurrentTestSession().getFactoriesTestFeatures().givenSystemInState(stateFolder);
getModelLayerFactory();
preparation.initializeFromCache();
} else {
preparation.prepare();
if (mode.isEnabled()) {
SystemStateExportParams params = new SystemStateExportParams().setExportAllContent();
new SystemStateExporter(getAppLayerFactory()).exportSystemToFolder(stateFolder, params);
}
}
}
private HyperTurboMode getHyperturboMode() {
String mode = sdkProperties.get("hyperTurbo");
if ("manual".equalsIgnoreCase(mode)) {
return HyperTurboMode.MANUAL;
} else if ("off".equalsIgnoreCase(mode)) {
return HyperTurboMode.OFF;
} else {
return HyperTurboMode.AUTO;
}
}
private enum HyperTurboMode {
AUTO, MANUAL, OFF;
boolean isEnabled() {
return this != OFF;
}
}
private static Map<Integer, String> preparationNames = new HashMap<>();
public void prepareSystem(CollectionPreparator... collectionPreparator) {
HyperTurboMode mode = getHyperturboMode();
prepareSystem(mode, collectionPreparator);
}
public void prepareSystemWithoutHyperTurbo(CollectionPreparator... collectionPreparator) {
HyperTurboMode mode = HyperTurboMode.OFF;
prepareSystem(mode, collectionPreparator);
}
private void prepareSystem(HyperTurboMode mode, CollectionPreparator... collectionPreparator) {
List<CollectionPreparator> preparators = new ArrayList<>(asList(collectionPreparator));
Collections.sort(preparators, new Comparator<CollectionPreparator>() {
@Override
public int compare(CollectionPreparator o1, CollectionPreparator o2) {
return o1.collection.compareTo(o2.collection);
}
});
if (mode.isEnabled()) {
givenTransactionLogIsEnabled();
}
File stateFolder = new File(getTurboCacheFolder(), "" + preparators.hashCode());
String taskName;
long start = new Date().getTime();
if (mode.isEnabled() && stateFolder.exists()) {
getCurrentTestSession().getFactoriesTestFeatures().givenSystemInState(stateFolder);
for (CollectionPreparator preparator : preparators) {
if (preparator.rmTestRecords) {
preparator.rmTestRecordsObject.alreadySettedUp(getAppLayerFactory());
}
if (preparator.demoTestRecords) {
preparator.demoTestRecordsObject.alreadySettedUp(getModelLayerFactory());
}
if (preparator.users != null) {
preparator.users.setUp(getModelLayerFactory().newUserServices());
}
}
} else {
stateFolder.mkdirs();
for (CollectionPreparator preparator : preparators) {
ModulesAndMigrationsTestFeatures modulesAndMigrationsTestFeatures = givenCollection(preparator.collection);
modulesAndMigrationsTestFeatures.withMockedAvailableModules(false);
if (preparator.modules.contains(ConstellioRMModule.ID)) {
modulesAndMigrationsTestFeatures = modulesAndMigrationsTestFeatures.withConstellioRMModule();
}
if (preparator.modules.contains(ConstellioESModule.ID)) {
modulesAndMigrationsTestFeatures = modulesAndMigrationsTestFeatures.withConstellioESModule();
}
if (preparator.modules.contains(TaskModule.ID)) {
modulesAndMigrationsTestFeatures = modulesAndMigrationsTestFeatures.withTaskModule();
}
if (preparator.modules.contains(ConstellioRobotsModule.ID)) {
modulesAndMigrationsTestFeatures = modulesAndMigrationsTestFeatures.withRobotsModule();
}
ModelLayerFactory modelLayerFactory = getModelLayerFactory();
if (preparator.allTestUsers) {
modulesAndMigrationsTestFeatures = modulesAndMigrationsTestFeatures.withAllTestUsers();
if (preparator.users != null) {
preparator.users.setUp(modelLayerFactory.newUserServices());
}
}
if (preparator.rmTestRecords) {
try {
RMTestRecords records = preparator.rmTestRecordsObject.setup(getAppLayerFactory());
if (preparator.foldersAndContainersOfEveryStatus) {
records = records.withFoldersAndContainersOfEveryStatus();
}
if (preparator.documentsDecommissioningList) {
records = records.withDocumentDecommissioningLists();
}
if (preparator.documentsHavingContent) {
records = records.withDocumentsHavingContent();
}
if (preparator.events) {
records = records.withEvents();
}
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
if (preparator.demoTestRecords) {
try {
DemoTestRecords records = preparator.demoTestRecordsObject.setup(getAppLayerFactory());
if (preparator.foldersAndContainersOfEveryStatus) {
records = records.withFoldersAndContainersOfEveryStatus();
}
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
}
if (mode.isEnabled()) {
try {
waitForBatchProcess();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//Reindexing doesn't improve test performance, but maybe one day it will
//getModelLayerFactory().newReindexingServices().reindexCollections(ReindexationMode.REWRITE);
SystemStateExportParams params = new SystemStateExportParams().setExportAllContent();
new SystemStateExporter(getAppLayerFactory()).exportSystemToFolder(stateFolder, params);
}
}
long end = new Date().getTime();
taskName = preparationNames.get(preparators.hashCode());
if (taskName == null) {
taskName = "Collections preparation similar to '" + getClass().getSimpleName() + "#" + getTestName() + "'";
preparationNames.put(preparators.hashCode(), taskName);
}
stats.add(this, getTestName(), taskName, end - start);
getCurrentTestSession().getAfterTestValidationsTestFeature().startRollbackNow();
}
public static class CollectionPreparator {
Users users;
RMTestRecords rmTestRecordsObject;
DemoTestRecords demoTestRecordsObject;
boolean rmTestRecords;
boolean demoTestRecords;
boolean foldersAndContainersOfEveryStatus;
boolean documentsDecommissioningList;
boolean events;
boolean documentsHavingContent;
boolean allTestUsers;
String collection;
List<String> modules = new ArrayList<>();
public CollectionPreparator(String collection) {
this.collection = collection;
}
public CollectionPreparator withConstellioRMModule() {
modules.add(ConstellioRMModule.ID);
Collections.sort(modules);
return this;
}
public CollectionPreparator withConstellioESModule() {
modules.add(ConstellioESModule.ID);
Collections.sort(modules);
return this;
}
public CollectionPreparator withTasksModule() {
modules.add(TaskModule.ID);
Collections.sort(modules);
return this;
}
public CollectionPreparator withRobotsModule() {
modules.add(ConstellioRobotsModule.ID);
Collections.sort(modules);
return this;
}
public CollectionPreparator withAllTest(Users users) {
allTestUsers = true;
this.users = users;
return this;
}
public CollectionPreparator withAllTestUsers() {
allTestUsers = true;
return this;
}
public CollectionPreparator withRMTest(RMTestRecords records) {
rmTestRecordsObject = records;
rmTestRecords = true;
return this;
}
public CollectionPreparator withRMTest(DemoTestRecords records) {
demoTestRecordsObject = records;
demoTestRecords = true;
return this;
}
public CollectionPreparator withFoldersAndContainersOfEveryStatus() {
foldersAndContainersOfEveryStatus = true;
return this;
}
public CollectionPreparator withDocumentsDecommissioningList() {
documentsDecommissioningList = true;
return this;
}
public CollectionPreparator withEvents() {
events = true;
return this;
}
public CollectionPreparator withDocumentsHavingContent() {
documentsHavingContent = true;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof CollectionPreparator)) {
return false;
}
CollectionPreparator that = (CollectionPreparator) o;
if (allTestUsers != that.allTestUsers) {
return false;
}
if (demoTestRecords != that.demoTestRecords) {
return false;
}
if (documentsHavingContent != that.documentsHavingContent) {
return false;
}
if (events != that.events) {
return false;
}
if (documentsDecommissioningList != that.documentsDecommissioningList) {
return false;
}
if (foldersAndContainersOfEveryStatus != that.foldersAndContainersOfEveryStatus) {
return false;
}
if (rmTestRecords != that.rmTestRecords) {
return false;
}
if (!collection.equals(that.collection)) {
return false;
}
if (!modules.equals(that.modules)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = (rmTestRecords ? 1 : 0);
result = 31 * result + (demoTestRecords ? 1 : 0);
result = 31 * result + (foldersAndContainersOfEveryStatus ? 1 : 0);
result = 31 * result + (documentsDecommissioningList ? 1 : 0);
result = 31 * result + (events ? 1 : 0);
result = 31 * result + (documentsHavingContent ? 1 : 0);
result = 31 * result + (allTestUsers ? 1 : 0);
result = 31 * result + collection.hashCode();
result = 31 * result + modules.hashCode();
return result;
}
}
public CollectionPreparator withZeCollection() {
return new CollectionPreparator(zeCollection);
}
public CollectionPreparator withCollection(String collection) {
return new CollectionPreparator(collection);
}
public CollectionTestHelper inCollection(String collectionName) {
return new CollectionTestHelper(asList(collectionName), getAppLayerFactory(),
getCurrentTestSession().getFileSystemTestFeatures());
}
protected ModuleEnabler givenInstalledModule(Class<? extends InstallableModule> installableModuleClass) {
ensureNotUnitTest();
return ModuleEnabler.givenInstalledModule(getAppLayerFactory(), installableModuleClass);
}
public ToggleCondition onlyWhen(AvailableToggle toggle) {
getCurrentTestSession().getToggleTestFeature().onlyWhen(toggle);
ToggleCondition toggleCondition = new ToggleCondition();
toggleCondition.toggle = toggle;
return toggleCondition;
}
protected void givenHashingEncodingIs(final HashingEncoding encoding) {
configure(new DataLayerConfigurationAlteration() {
@Override
public void alter(InMemoryDataLayerConfiguration configuration) {
configuration.setHashingEncoding(encoding);
}
});
}
protected void assumeNotSolrCloud() {
Assume.assumeTrue("http".equals(sdkProperties.get("dao.records.type")));
}
protected Session newCMISSessionAsUserInZeCollection(String username) {
ensureNotUnitTest();
return newCMISSessionAsUserInCollection(username, zeCollection);
}
protected void reindexIfRequired() {
ensureNotUnitTest();
if (getAppLayerFactory().getSystemGlobalConfigsManager().isReindexingRequired()) {
ReindexingServices reindexingServices = getModelLayerFactory().newReindexingServices();
reindexingServices.reindexCollections(ReindexationMode.RECALCULATE_AND_REWRITE);
}
}
protected Session newCMISSessionAsUserInCollection(String username, String collection) {
ensureNotUnitTest();
UserServices userServices = getModelLayerFactory().newUserServices();
userServices.addUpdateUserCredential(userServices.getUser(username).withServiceKey(username + "-key"));
String token = userServices.generateToken(username, Duration.standardHours(72));
System.out.println("Logging as " + username + "-key / " + token);
Session session = newCmisSessionBuilder().authenticatedBy(username + "-key", token).onCollection(collection).build();
if (session == null) {
throw new RuntimeException("Failed to initialize cmis session");
}
return session;
}
}