1 package org.simantics.db.tests.regression.bugs;
6 import org.simantics.databoard.Bindings;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.Session;
10 import org.simantics.db.WriteGraph;
11 import org.simantics.db.WriteOnlyGraph;
12 import org.simantics.db.common.primitiverequest.PossibleObject;
13 import org.simantics.db.common.request.ReadRequest;
14 import org.simantics.db.common.request.WriteOnlyRequest;
15 import org.simantics.db.common.request.WriteRequest;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.procedure.SyncListener;
18 import org.simantics.db.service.ClusterControl;
19 import org.simantics.db.testing.base.ExistingDatabaseTest;
20 import org.simantics.db.testing.common.TestBase;
21 import org.simantics.layer0.Layer0;
22 import org.simantics.utils.DataContainer;
24 public class SimanticsBug1659Test2 extends ExistingDatabaseTest {
25 static int LOOP_COUNT = 100;
26 static int CLUSTER_COUNT = 2;
27 static int RESOURCE_COUNT = 1000;
28 static boolean DEBUG = false;
29 static boolean DEBUG_LISTENER = false;
30 // Use transient listener.
31 static boolean USE_LISTENER = true;
32 // Use asynchronous listener.
33 static boolean USE_LISTENER2 = true;
34 // Use synchronous listener
35 static boolean USE_LISTENER3 = true;
39 DataContainer<Integer> loopCount = new DataContainer<Integer>();
40 DataContainer<Integer> listenerCount = new DataContainer<Integer>();
43 public void testSimanticsBug1659_2()
44 throws DatabaseException {
45 session = getSession();
46 session.syncRequest(new Init());
50 for (int i=0; i<LOOP_COUNT; ++i) {
53 System.out.println("Create " + i);
54 session.syncRequest(new CreateWriteOnly());
56 System.out.println("Query " + i);
57 session.syncRequest(new Query());
59 System.out.println("Delete loop=" + i + " listeners=" + listenerCount.get());
61 ClusterControl support = getSession().getService(ClusterControl.class);
62 support.collectClusters(Integer.MAX_VALUE);
63 int count = listenerCount.get();
64 if (oldCount != count) {
65 // System.out.println("Listener count is " + count);
68 session.syncRequest(new Delete());
70 System.out.println("Done " + i);
73 class Init extends WriteRequest {
75 public void perform(WriteGraph g) throws DatabaseException {
76 Layer0 l0 = Layer0.getInstance(g);
77 Resource rl = g.getResource(TestBase.ROOT_LIBRARY_URI);
78 testRoot = g.newResource();
79 g.claim(testRoot, l0.InstanceOf, l0.Library);
80 g.claim(rl, l0.ConsistsOf, testRoot);
81 // type = g.newResource();
82 // g.claim(type, l0.Inherits, l0.Entity);
85 class CreateWriteOnly extends WriteOnlyRequest {
87 public void perform(WriteOnlyGraph g) throws DatabaseException {
88 Layer0 b = Layer0.getInstance(g.getService(Session.class));
89 for (int j=0; j<CLUSTER_COUNT; ++j) {
90 Resource root = g.newResource();
91 g.claim(testRoot, b.ConsistsOf, b.PartOf, root);
93 for(int i=0; i<RESOURCE_COUNT; i++) {
94 Resource item = g.newResource();
95 g.claim(item, b.InstanceOf, null, b.String);
96 g.claimValue(item, UUID.randomUUID().toString(), Bindings.STRING);
97 g.claim(root, b.ConsistsOf, b.PartOf, item);
102 class Query extends ReadRequest {
104 public void run(ReadGraph g) throws DatabaseException {
105 Layer0 l0 = Layer0.getInstance(g);
106 for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
108 System.out.println("Resource " + r);
109 for (Resource rr : g.getObjects(r, l0.ConsistsOf)) {
110 if (!g.isInstanceOf(rr, l0.String))
111 fail("Resource " + rr + " is not instance of String.");
112 if (!g.isInstanceOf(rr, l0.Entity))
113 fail("Resource " + rr + " is not instance of Entity.");
115 g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
118 public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
120 System.out.println("change " + resource);
124 public void exception(ReadGraph graph, Throwable t)
125 throws DatabaseException {
127 fail("Listener got exception: " + t);
131 public boolean isDisposed() {
133 System.out.println("Asked if disposed.");
138 g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount));
141 g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount));
147 class Listener implements SyncListener<Resource> {
148 final DataContainer<Integer> loopCount;
149 final DataContainer<Integer> listenerCount;
151 boolean disposed = false;
152 Listener(DataContainer<Integer> loopCount, DataContainer<Integer> listenerCount) {
153 this.loopCount = loopCount;
154 this.listenerCount = listenerCount;
155 int value = this.listenerCount.get() + 1;
156 this.listenerCount.set(value);
157 this.me = loopCount.get();
160 public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
162 System.out.println("change " + resource);
166 public void exception(ReadGraph graph, Throwable t)
167 throws DatabaseException {
169 fail("Listener got exception: " + t);
173 public boolean isDisposed() {
175 System.out.println("Asked if disposed.");
178 disposed = loopCount.get() != me;
180 int value = this.listenerCount.get() - 1;
181 this.listenerCount.set(value);
187 class Delete extends WriteRequest {
189 public void perform(WriteGraph g) throws DatabaseException {
190 Layer0 l0 = Layer0.getInstance(g);
191 for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
193 System.out.println("Deny resource " + r);
194 g.deny(testRoot, l0.ConsistsOf, r);