Skip to content

Commit

Permalink
repo-sql-impl-test experiment with DB cleanup instead of dirty context
Browse files Browse the repository at this point in the history
This speeds up the tests significantly, but currently there are couple
of problems with it:
- H2 server is sometimes started repeatedly (port binding fails).
- Seems that some objects are missing for some tests.
This may be caused by:
- Various Spring contexts are used, this is definitely a problem,
it should be unified on BaseSQLRepoTest level to avoid context refresh.
- Some data are probably initialized during Spring setup and missing
after they are deleted. We either have to add WHERE to DELETE if these
objects are always to be preserved, or (more systemic?) to initialize
these objects after the DB cleanup.
  • Loading branch information
virgo47 committed Mar 18, 2020
1 parent 6b82757 commit 15280e4
Show file tree
Hide file tree
Showing 48 changed files with 608 additions and 584 deletions.
Expand Up @@ -145,15 +145,6 @@ public static void assertElement(List<Object> elements, QName elementQName, Stri
AssertJUnit.fail("No element with name " + elementQName);
}

public static void assertExceptionSanity(ObjectAlreadyExistsException e) {
LOGGER.debug("Exception (expected) {}", e, e);
System.out.println("Exception (expected)");
System.out.println(ExceptionUtils.getFullStackTrace(e));
assert !e.getMessage().isEmpty() : "Empty exception message";
assert e.getMessage().length() < MAX_EXCEPTION_MESSAGE_LENGTH : "Exception message too long ("
+ e.getMessage().length() + " characters): " + e.getMessage();
}

public static void displayCleanup(String testName) {
System.out.println(TEST_OUT_SECTION_PREFIX + " CLEANUP " + testName + TEST_OUT_SECTION_SUFFIX);
LOGGER.info(TEST_LOG_SECTION_PREFIX + " CLEANUP " + testName + TEST_LOG_SECTION_SUFFIX);
Expand Down
4 changes: 4 additions & 0 deletions repo/repo-sql-impl-test/pom.xml
Expand Up @@ -109,6 +109,10 @@
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
Expand Down
@@ -0,0 +1,154 @@
package com.evolveum.midpoint.repo.sql.testing;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.repo.sql.SqlRepositoryConfiguration;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;

/**
* Class for DB cleanup before the test class is run.
* Partially duplicates {@link TestSqlRepositoryBeanPostProcessor} - if this is successful
* we should somehow consolidate/merge these.
*/
@Component
public class DbDeleter {

private static final Trace LOGGER = TraceManager.getTrace(DbDeleter.class);

private static final String TRUNCATE_FUNCTION = "cleanupTestDatabase";
private static final String TRUNCATE_PROCEDURE = "cleanupTestDatabaseProc";

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

@Autowired
private TestSqlRepositoryFactory testSqlRepositoryFactory;

public void cleanupTestDatabase() {
SqlRepositoryConfiguration config = testSqlRepositoryFactory.getSqlConfiguration();
if (!config.isDropIfExists()) {
LOGGER.info("We're not deleting objects from DB if drop-if-exists=false.");
return;
}

System.out.println("\n!!! DELETING objects from database.");
LOGGER.info("Deleting objects from database.");

long startMs = System.currentTimeMillis();
EntityManager entityManager = entityManagerFactory.createEntityManager();
try {
entityManager.getTransaction().begin();

Query query;
if (config.isUsingH2()) {
LOGGER.info("Using bunch of deletes for H2.");
deleteAllTables(entityManager);
} else if (config.isUsingOracle() || config.isUsingSQLServer()) {
LOGGER.info("Using truncate procedure.");
query = entityManager.createNativeQuery("{ call " + TRUNCATE_PROCEDURE + "() }");
query.executeUpdate();
} else {
LOGGER.info("Using truncate function.");
query = entityManager.createNativeQuery("select " + TRUNCATE_FUNCTION + "();");
query.getSingleResult();
}

entityManager.getTransaction().commit();
} catch (Exception ex) {
LOGGER.error("Couldn't cleanup database, reason:", ex);
entityManager.getTransaction().rollback();
throw ex;
} finally {
entityManager.close();
}
LOGGER.info("DB cleaned up in {} ms", System.currentTimeMillis() - startMs);
}

private void deleteAllTables(EntityManager entityManager) {
deleteTable(entityManager, "m_object_text_info");
deleteTable(entityManager, "m_operation_execution");
deleteTable(entityManager, "m_sequence");
deleteTable(entityManager, "m_acc_cert_wi_reference");
deleteTable(entityManager, "m_acc_cert_wi");
deleteTable(entityManager, "m_acc_cert_case");
deleteTable(entityManager, "m_acc_cert_campaign");
deleteTable(entityManager, "m_acc_cert_definition");
deleteTable(entityManager, "m_audit_resource");
deleteTable(entityManager, "m_audit_ref_value");
deleteTable(entityManager, "m_audit_prop_value");
deleteTable(entityManager, "m_audit_delta");
deleteTable(entityManager, "m_audit_item");
deleteTable(entityManager, "m_audit_event");
deleteTable(entityManager, "m_object_ext_date");
deleteTable(entityManager, "m_object_ext_long");
deleteTable(entityManager, "m_object_ext_string");
deleteTable(entityManager, "m_object_ext_poly");
deleteTable(entityManager, "m_object_ext_reference");
deleteTable(entityManager, "m_object_ext_boolean");
deleteTable(entityManager, "m_reference");
deleteTable(entityManager, "m_assignment_ext_date");
deleteTable(entityManager, "m_assignment_ext_long");
deleteTable(entityManager, "m_assignment_ext_poly");
deleteTable(entityManager, "m_assignment_ext_reference");
deleteTable(entityManager, "m_assignment_ext_string");
deleteTable(entityManager, "m_assignment_ext_boolean");
deleteTable(entityManager, "m_assignment_extension");
deleteTable(entityManager, "m_assignment_reference");
deleteTable(entityManager, "m_assignment_policy_situation");
deleteTable(entityManager, "m_assignment");
deleteTable(entityManager, "m_connector_target_system");
deleteTable(entityManager, "m_connector");
deleteTable(entityManager, "m_connector_host");
deleteTable(entityManager, "m_lookup_table_row");
deleteTable(entityManager, "m_lookup_table");
deleteTable(entityManager, "m_node");
deleteTable(entityManager, "m_shadow");
deleteTable(entityManager, "m_task_dependent");
deleteTable(entityManager, "m_task");
deleteTable(entityManager, "m_object_template");
deleteTable(entityManager, "m_value_policy");
deleteTable(entityManager, "m_resource");
deleteTable(entityManager, "m_user_employee_type");
deleteTable(entityManager, "m_user_organization");
deleteTable(entityManager, "m_user_organizational_unit");
deleteTable(entityManager, "m_focus_photo");
deleteTable(entityManager, "m_focus_policy_situation");
deleteTable(entityManager, "m_user");
deleteTable(entityManager, "m_report");
deleteTable(entityManager, "m_report_output");
deleteTable(entityManager, "m_org_org_type");
deleteTable(entityManager, "m_org_closure");
deleteTable(entityManager, "m_org");
deleteTable(entityManager, "m_role");
deleteTable(entityManager, "m_service_type");
deleteTable(entityManager, "m_service");
deleteTable(entityManager, "m_archetype");
deleteTable(entityManager, "m_abstract_role");
deleteTable(entityManager, "m_system_configuration");
deleteTable(entityManager, "m_generic_object");
deleteTable(entityManager, "m_trigger");
deleteTable(entityManager, "m_focus");
deleteTable(entityManager, "m_security_policy");
deleteTable(entityManager, "m_form");
deleteTable(entityManager, "m_case_wi_reference");
deleteTable(entityManager, "m_case_wi");
deleteTable(entityManager, "m_case");
deleteTable(entityManager, "m_function_library");
deleteTable(entityManager, "m_ext_item");
deleteTable(entityManager, "m_object_subtype");
deleteTable(entityManager, "m_object_collection");
deleteTable(entityManager, "m_dashboard");
deleteTable(entityManager, "m_object");
}

private void deleteTable(EntityManager entityManager, String tableName) {
entityManager.createNativeQuery("DELETE FROM " + tableName).executeUpdate();
}
}
Expand Up @@ -7,28 +7,27 @@

package com.evolveum.midpoint.repo.sql;

import static org.testng.AssertJUnit.*;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.RetrieveOption;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import org.testng.annotations.BeforeClass;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;

import static org.testng.AssertJUnit.*;

/**
*
*/
public abstract class AbstractPhotoTest<T extends FocusType> extends BaseSQLRepoTest {

static final File TEST_DIR = new File("src/test/resources/photo");
Expand Down
Expand Up @@ -7,6 +7,21 @@

package com.evolveum.midpoint.repo.sql;

import static org.testng.AssertJUnit.*;

import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext;

import java.io.File;
import java.util.*;
import javax.xml.namespace.QName;

import org.hibernate.Session;
import org.hibernate.query.Query;
import org.hibernate.stat.Statistics;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;

import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.ItemDelta;
Expand All @@ -20,7 +35,8 @@
import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus;
import com.evolveum.midpoint.repo.sql.type.XMLGregorianCalendarType;
import com.evolveum.midpoint.repo.sql.util.RUtil;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.GetOperationOptionsBuilder;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand All @@ -30,26 +46,8 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.stat.Statistics;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;

import javax.xml.namespace.QName;
import java.io.File;
import java.util.*;

import static com.evolveum.midpoint.prism.util.PrismTestUtil.getPrismContext;
import static org.testng.AssertJUnit.*;

/**
* @author lazyman
*/
@ContextConfiguration(locations = {"../../../../../ctx-test.xml"})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@ContextConfiguration(locations = { "../../../../../ctx-test.xml" })
public class AddGetObjectTest extends BaseSQLRepoTest {

@Test(enabled = false)
Expand All @@ -64,16 +62,16 @@ public <T extends ObjectType> void perfTest() throws Exception {
long time = System.currentTimeMillis();
for (int i = 0; i < elements.size(); i++) {
if (i % 500 == 0) {
logger.info("Previous cycle time {}. Next cycle: {}", new Object[]{
(System.currentTimeMillis() - time - previousCycle), i});
logger.info("Previous cycle time {}. Next cycle: {}", new Object[] {
(System.currentTimeMillis() - time - previousCycle), i });
previousCycle = System.currentTimeMillis() - time;
}

PrismObject<T> object = (PrismObject<T>) elements.get(i);
repositoryService.addObject(object, null, new OperationResult("add performance test"));
}
logger.info("Time to add objects ({}): {}",
new Object[]{elements.size(), (System.currentTimeMillis() - time)});
new Object[] { elements.size(), (System.currentTimeMillis() - time) });

stats.logSummary();
}
Expand All @@ -88,7 +86,7 @@ public void addSameName() throws Exception {

assert false : "Unexpected success";
} catch (ObjectAlreadyExistsException e) {
TestUtil.assertExceptionSanity(e);
displayExpectedException(e);
}
}

Expand All @@ -97,7 +95,7 @@ public void addGetDSEESyncDoubleTest() throws Exception {
final File OBJECTS_FILE = new File("./../../samples/dsee/odsee-localhost-advanced-sync.xml");
if (!OBJECTS_FILE.exists()) {
logger.warn("skipping addGetDSEESyncDoubleTest, file {} not found.",
new Object[]{OBJECTS_FILE.getPath()});
new Object[] { OBJECTS_FILE.getPath() });
return;
}
addGetCompare(OBJECTS_FILE);
Expand All @@ -107,7 +105,7 @@ public void addGetDSEESyncDoubleTest() throws Exception {

assert false : "Unexpected success";
} catch (ObjectAlreadyExistsException e) {
TestUtil.assertExceptionSanity(e);
displayExpectedException(e);
}
}

Expand Down Expand Up @@ -192,7 +190,7 @@ private List<PrismObject<?>> addGetCompare(File file) throws Exception {
}
} catch (Throwable ex) {
logger.error("Exception occurred for {}", object, ex);
throw new RuntimeException("Exception during processing of "+object+": "+ex.getMessage(), ex);
throw new RuntimeException("Exception during processing of " + object + ": " + ex.getMessage(), ex);
}
}
AssertJUnit.assertEquals("Found changes during add/get test " + count, 0, count);
Expand All @@ -209,7 +207,7 @@ private Integer size(PrismContainerValue value) {

private void checkContainerValuesSize(QName parentName, PrismContainerValue<?> newValue, PrismContainerValue<?> oldValue) {
logger.info("Checking: " + parentName);
AssertJUnit.assertEquals("Count doesn't match for '" + parentName + "' id="+newValue.getId(), size(oldValue), size(newValue));
AssertJUnit.assertEquals("Count doesn't match for '" + parentName + "' id=" + newValue.getId(), size(oldValue), size(newValue));

List<QName> checked = new ArrayList<>();

Expand Down Expand Up @@ -309,7 +307,7 @@ public void addGetFullAccount() throws Exception {

ObjectDelta<ShadowType> delta = fileAccount.diff(repoAccount);
AssertJUnit.assertNotNull(delta);
logger.info("delta\n{}", new Object[]{delta.debugDump(3)});
logger.info("delta\n{}", new Object[] { delta.debugDump(3) });
if (!delta.isEmpty()) {
fail("delta is not empty: " + delta.debugDump());
}
Expand Down Expand Up @@ -385,7 +383,7 @@ public void testAddGetSyncDescription() throws Exception {
}

@Test
public void addGetRoleWithResourceRefFilter() throws Exception{
public void addGetRoleWithResourceRefFilter() throws Exception {
PrismObject<RoleType> role = prismContext.parseObject(new File("src/test/resources/basic/role-resource-filter.xml"));

System.out.println("role: " + role.debugDump());
Expand Down Expand Up @@ -482,7 +480,6 @@ private String testIterationToken(String token) throws Exception {
// System.out.println(">>> " + time);
// }


@Test
public void test() throws Exception {
OperationResult result = new OperationResult("asdf");
Expand Down Expand Up @@ -563,7 +560,7 @@ public void test100AddUserWithoutAssignmentIds() throws Exception {
}
Collections.sort(dbShorts);

logger.info("assigments ids: expected {} db {}", Arrays.toString(xmlShorts.toArray()),
logger.info("assignments ids: expected {} db {}", Arrays.toString(xmlShorts.toArray()),
Arrays.toString(dbShorts.toArray()));
AssertJUnit.assertArrayEquals(xmlShorts.toArray(), dbShorts.toArray());
} finally {
Expand Down Expand Up @@ -737,10 +734,10 @@ public void test300ContainerIds() throws Exception {
UserType user = new UserType(prismContext)
.name("t300")
.beginAssignment()
.description("a1")
.description("a1")
.<UserType>end()
.beginAssignment()
.description("a2")
.description("a2")
.end();

// WHEN
Expand Down

0 comments on commit 15280e4

Please sign in to comment.