use of com.evolveum.midpoint.repo.sql.helpers.OrgClosureManager.Edge in project midpoint by Evolveum.
the class OrgClosureConcurrencyTest method _test200AddRemoveLinksMT.
/**
* We randomly select a set of links to be removed.
* Then we remove them, using a given set of threads.
* After all threads are done, we will check the closure table consistency.
*
* And after that, we will do the reverse, re-adding all the links previously removed.
* In the end, we again check the consistency.
*/
protected void _test200AddRemoveLinksMT(final boolean random) throws Exception {
OperationResult opResult = new OperationResult("===[ test200AddRemoveLinksMT ]===");
info("test200AddRemoveLinks starting with random = " + random);
final Set<Edge> edgesToRemove = Collections.synchronizedSet(new HashSet<Edge>());
final Set<Edge> edgesToAdd = Collections.synchronizedSet(new HashSet<Edge>());
final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
// parentRef link removal + addition
for (int level = 0; level < getConfiguration().getLinkRoundsForLevel().length; level++) {
int rounds = getConfiguration().getLinkRoundsForLevel()[level];
List<String> levelOids = orgsByLevels.get(level);
int retries = 0;
for (int round = 0; round < rounds; round++) {
int index = (int) Math.floor(Math.random() * levelOids.size());
String oid = levelOids.get(index);
OrgType org = repositoryService.getObject(OrgType.class, oid, null, opResult).asObjectable();
// check if it has no parents (shouldn't occur here!)
if (org.getParentOrgRef().isEmpty()) {
throw new IllegalStateException("No parents in " + org);
}
int i = (int) Math.floor(Math.random() * org.getParentOrgRef().size());
ObjectReferenceType parentOrgRef = org.getParentOrgRef().get(i);
Edge edge = new Edge(oid, parentOrgRef.getOid());
if (edgesToRemove.contains(edge)) {
round--;
if (++retries == 1000) {
// primitive attempt to break potential cycles when there is not enough edges to process
throw new IllegalStateException("Too many retries");
} else {
continue;
}
}
edgesToRemove.add(edge);
edgesToAdd.add(edge);
}
}
int numberOfRunners = THREADS;
info("Edges to remove/add (" + edgesToRemove.size() + ": " + edgesToRemove);
info("Number of runners: " + numberOfRunners);
final List<Thread> runners = Collections.synchronizedList(new ArrayList<Thread>());
for (int i = 0; i < numberOfRunners; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
Edge edge = getNext(edgesToRemove, random);
if (edge == null) {
break;
}
LOGGER.info("Removing {}", edge);
removeEdge(edge);
int remaining;
synchronized (OrgClosureConcurrencyTest.this) {
edgesToRemove.remove(edge);
remaining = edgesToRemove.size();
}
info(Thread.currentThread().getName() + " removed " + edge + "; remaining: " + remaining);
}
} catch (Throwable e) {
e.printStackTrace();
exceptions.add(e);
} finally {
runners.remove(Thread.currentThread());
}
}
};
Thread t = new Thread(runnable);
runners.add(t);
t.start();
}
waitForRunnersCompletion(runners);
if (!edgesToRemove.isEmpty()) {
throw new AssertionError("Edges to remove is not empty, see the console or log: " + edgesToRemove);
}
if (!exceptions.isEmpty()) {
throw new AssertionError("Found exceptions: " + exceptions);
}
checkClosure(orgGraph.vertexSet());
info("Consistency after removal OK");
for (int i = 0; i < numberOfRunners; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
while (true) {
Edge edge = getNext(edgesToAdd, random);
if (edge == null) {
break;
}
LOGGER.info("Adding {}", edge);
addEdge(edge);
int remaining;
synchronized (OrgClosureConcurrencyTest.this) {
edgesToAdd.remove(edge);
remaining = edgesToAdd.size();
}
info(Thread.currentThread().getName() + " re-added " + edge + "; remaining: " + remaining);
}
} catch (Throwable e) {
e.printStackTrace();
exceptions.add(e);
} finally {
runners.remove(Thread.currentThread());
}
}
};
Thread t = new Thread(runnable);
runners.add(t);
t.start();
}
waitForRunnersCompletion(runners);
if (!edgesToAdd.isEmpty()) {
throw new AssertionError("Edges to add is not empty, see the console or log: " + edgesToAdd);
}
if (!exceptions.isEmpty()) {
throw new AssertionError("Found exceptions: " + exceptions);
}
checkClosure(orgGraph.vertexSet());
info("Consistency after re-adding OK");
}
Aggregations