Search in sources :

Example 1 with Edge

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");
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) OrgType(com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType) Edge(com.evolveum.midpoint.repo.sql.helpers.OrgClosureManager.Edge)

Aggregations

Edge (com.evolveum.midpoint.repo.sql.helpers.OrgClosureManager.Edge)1 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 ObjectReferenceType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType)1 OrgType (com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType)1