]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java
Added missing org.simantics.db.{tests,testing} plug-ins.
[simantics/platform.git] / tests / org.simantics.db.tests / src / org / simantics / db / tests / regression / bugs / SimanticsBug1659Test1.java
diff --git a/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java b/tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test1.java
new file mode 100644 (file)
index 0000000..768ebf7
--- /dev/null
@@ -0,0 +1,204 @@
+package org.simantics.db.tests.regression.bugs;
+
+import org.junit.Test;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.primitiverequest.PossibleObject;
+import org.simantics.db.common.request.ReadRequest;
+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.db.tests.common.Configuration;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.DataContainer;
+
+public class SimanticsBug1659Test1 extends ExistingDatabaseTest {
+    static int LOOP_COUNT = Configuration.get().i1659LoopCount;
+    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<Integer> loopCount = new DataContainer<Integer>();
+    DataContainer<Integer> listenerCount = new DataContainer<Integer>();
+    
+    @Test
+    public void testSimanticsBug16591()
+    throws DatabaseException {
+        session = getSession();
+        session.syncRequest(new Init());
+        loopCount.set(-1);
+        listenerCount.set(0);
+        int oldCount = 0;
+        for (int i=0; i<LOOP_COUNT; ++i) {
+            loopCount.set(i);
+            if (DEBUG)
+                System.out.println("Create " + i);
+            session.syncRequest(new Create());
+            if (DEBUG)
+                System.out.println("Query " + i);
+            session.syncRequest(new Query());
+            if (DEBUG)
+                System.out.println("Delete loop=" + i + " listeners=" + listenerCount.get());
+            loopCount.set(-1);
+            ClusterControl support = getSession().getService(ClusterControl.class);
+            support.collectClusters(Integer.MAX_VALUE);
+            int count = listenerCount.get();
+            if (oldCount != count) {
+//                System.out.println("Listener count is " + count);
+                oldCount = count;
+            }
+            session.syncRequest(new Delete());
+            if (DEBUG)
+                System.out.println("Done " + i);
+//            if (DEBUG)
+//                System.out.println("collect " + i);
+//            try {
+//                Thread.sleep(100);
+//            } catch (InterruptedException e) {
+//                e.printStackTrace();
+//            }
+        }
+    }
+    class Init extends WriteRequest {
+        @Override
+        public void perform(WriteGraph g) throws DatabaseException {
+            Layer0 l0 = Layer0.getInstance(g);
+            Resource rl = g.getResource(TestBase.ROOT_LIBRARY_URI);
+            testRoot = g.newResource();
+            g.claim(testRoot, l0.InstanceOf, l0.Library);          
+            g.claim(rl, l0.ConsistsOf, testRoot);
+            type = g.newResource();
+            g.claim(type, l0.Inherits, l0.Entity);          
+        }
+    }
+    class Create extends WriteRequest {
+        @Override
+        public void perform(WriteGraph g) throws DatabaseException {
+            Resource root = g.newResource();
+            Layer0 l0 = Layer0.getInstance(g);
+            g.claim(root, l0.InstanceOf, l0.Library);          
+            g.claim(testRoot, l0.ConsistsOf, root);
+            for (int i=0; i<RESOURCE_COUNT; ++i) {
+                if (i % 10000 == 0) {
+                    if (DEBUG)
+                        System.out.println("flush");
+                    g.flushCluster();
+                }
+                Resource r = g.newResource();
+                g.claim(r, l0.InstanceOf, type);
+                g.claim(root, l0.ConsistsOf, r);
+            }
+        }
+    }
+    class Query extends ReadRequest {
+        @Override
+        public void run(ReadGraph g) throws DatabaseException {
+            Layer0 l0 = Layer0.getInstance(g);
+            for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
+                if (DEBUG)
+                    System.out.println("Resource " + r);
+                for (Resource rr : g.getObjects(r, l0.ConsistsOf)) {
+//                    if (DEBUG)
+//                        System.out.println("Resource " + rr);
+                       if (!g.isInstanceOf(rr, type))
+                               fail("Resource " + rr + " is not instance of type.");
+                       if (!g.isInstanceOf(rr, l0.Entity))
+                               fail("Resource " + rr + " is not instance of Entity.");
+                       if (USE_LISTENER)
+                           g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
+       
+                               @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));
+                    }
+                }
+            }
+        }
+    }
+    class Listener implements SyncListener<Resource> {
+        final DataContainer<Integer> loopCount;
+        final DataContainer<Integer> listenerCount;
+        final int me;
+        boolean disposed = false;
+        Listener(DataContainer<Integer> loopCount, DataContainer<Integer> 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);
+            }
+        }
+    }
+}