package org.simantics.db.tests.regression.bugs; import java.util.UUID; import org.junit.Test; import org.simantics.databoard.Bindings; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.primitiverequest.PossibleObject; import org.simantics.db.common.request.AsyncReadRequest; import org.simantics.db.common.request.WriteOnlyRequest; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.SyncListener; import org.simantics.db.service.ClusterControl; import org.simantics.db.testing.base.ExistingDatabaseTest; import org.simantics.db.testing.common.TestBase; import org.simantics.layer0.Layer0; import org.simantics.utils.DataContainer; public class SimanticsBug1659Test2 extends ExistingDatabaseTest { static int LOOP_COUNT = 100; static int CLUSTER_COUNT = 2; static int RESOURCE_COUNT = 1000; static boolean DEBUG = false; static boolean DEBUG_LISTENER = false; // Use transient listener. static boolean USE_LISTENER = true; // Use asynchronous listener. static boolean USE_LISTENER2 = true; // Use synchronous listener static boolean USE_LISTENER3 = true; Session session; Resource testRoot; Resource type; DataContainer loopCount = new DataContainer(); DataContainer listenerCount = new DataContainer(); @Test public void testSimanticsBug1659_2() throws DatabaseException { session = getSession(); session.syncRequest(new Init()); loopCount.set(-1); listenerCount.set(0); int oldCount = 0; for (int i=0; i() { @Override public void execute(ReadGraph graph, Resource resource) throws DatabaseException { if (DEBUG_LISTENER) System.out.println("change " + resource); } @Override public void exception(ReadGraph graph, Throwable t) throws DatabaseException { t.printStackTrace(); fail("Listener got exception: " + t); } @Override public boolean isDisposed() { if (DEBUG_LISTENER) System.out.println("Asked if disposed."); return true; } }); if (USE_LISTENER2) { g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount)); } if (USE_LISTENER3) { g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount)); } } } } catch (DatabaseException e) { e.printStackTrace(); } } } class Listener implements SyncListener { final DataContainer loopCount; final DataContainer listenerCount; final int me; boolean disposed = false; Listener(DataContainer loopCount, DataContainer listenerCount) { this.loopCount = loopCount; this.listenerCount = listenerCount; int value = this.listenerCount.get() + 1; this.listenerCount.set(value); this.me = loopCount.get(); } @Override public void execute(ReadGraph graph, Resource resource) throws DatabaseException { if (DEBUG_LISTENER) System.out.println("change " + resource); } @Override public void exception(ReadGraph graph, Throwable t) throws DatabaseException { t.printStackTrace(); fail("Listener got exception: " + t); } @Override public boolean isDisposed() { if (DEBUG_LISTENER) System.out.println("Asked if disposed."); if (disposed) return true; disposed = loopCount.get() != me; if (disposed) { int value = this.listenerCount.get() - 1; this.listenerCount.set(value); } return disposed; } } class Delete extends WriteRequest { @Override public void perform(WriteGraph g) throws DatabaseException { Layer0 l0 = Layer0.getInstance(g); for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) { if (DEBUG) System.out.println("Deny resource " + r); g.deny(testRoot, l0.ConsistsOf, r); } } } }