1 package org.simantics.db.tests.regression.bugs;
6 import org.simantics.databoard.Bindings;
7 import org.simantics.db.AsyncReadGraph;
8 import org.simantics.db.ReadGraph;
9 import org.simantics.db.Resource;
10 import org.simantics.db.Session;
11 import org.simantics.db.WriteGraph;
12 import org.simantics.db.WriteOnlyGraph;
13 import org.simantics.db.common.primitiverequest.PossibleObject;
14 import org.simantics.db.common.request.AsyncReadRequest;
15 import org.simantics.db.common.request.WriteOnlyRequest;
16 import org.simantics.db.common.request.WriteRequest;
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.procedure.SyncListener;
19 import org.simantics.db.service.ClusterControl;
20 import org.simantics.db.testing.base.ExistingDatabaseTest;
21 import org.simantics.db.testing.common.TestBase;
22 import org.simantics.layer0.Layer0;
23 import org.simantics.utils.DataContainer;
25 public class SimanticsBug1659Test2 extends ExistingDatabaseTest {
26 static int LOOP_COUNT = 100;
27 static int CLUSTER_COUNT = 2;
28 static int RESOURCE_COUNT = 1000;
29 static boolean DEBUG = false;
30 static boolean DEBUG_LISTENER = false;
31 // Use transient listener.
32 static boolean USE_LISTENER = true;
33 // Use asynchronous listener.
34 static boolean USE_LISTENER2 = true;
35 // Use synchronous listener
36 static boolean USE_LISTENER3 = true;
40 DataContainer<Integer> loopCount = new DataContainer<Integer>();
41 DataContainer<Integer> listenerCount = new DataContainer<Integer>();
44 public void testSimanticsBug1659_2()
45 throws DatabaseException {
46 session = getSession();
47 session.syncRequest(new Init());
51 for (int i=0; i<LOOP_COUNT; ++i) {
54 System.out.println("Create " + i);
55 session.syncRequest(new CreateWriteOnly());
57 System.out.println("Query " + i);
58 session.syncRequest(new Query());
60 System.out.println("Delete loop=" + i + " listeners=" + listenerCount.get());
62 ClusterControl support = getSession().getService(ClusterControl.class);
63 support.collectClusters(Integer.MAX_VALUE);
64 int count = listenerCount.get();
65 if (oldCount != count) {
66 // System.out.println("Listener count is " + count);
69 session.syncRequest(new Delete());
71 System.out.println("Done " + i);
74 class Init extends WriteRequest {
76 public void perform(WriteGraph g) throws DatabaseException {
77 Layer0 l0 = Layer0.getInstance(g);
78 Resource rl = g.getResource(TestBase.ROOT_LIBRARY_URI);
79 testRoot = g.newResource();
80 g.claim(testRoot, l0.InstanceOf, l0.Library);
81 g.claim(rl, l0.ConsistsOf, testRoot);
82 // type = g.newResource();
83 // g.claim(type, l0.Inherits, l0.Entity);
86 class CreateWriteOnly extends WriteOnlyRequest {
88 public void perform(WriteOnlyGraph g) throws DatabaseException {
89 Layer0 b = Layer0.getInstance(g.getService(Session.class));
90 for (int j=0; j<CLUSTER_COUNT; ++j) {
91 Resource root = g.newResource();
92 g.claim(testRoot, b.ConsistsOf, b.PartOf, root);
94 for(int i=0; i<RESOURCE_COUNT; i++) {
95 Resource item = g.newResource();
96 g.claim(item, b.InstanceOf, null, b.String);
97 g.claimValue(item, UUID.randomUUID().toString(), Bindings.STRING);
98 g.claim(root, b.ConsistsOf, b.PartOf, item);
103 class Query extends AsyncReadRequest {
105 public void run(AsyncReadGraph g) {
107 Layer0 l0 = Layer0.getInstance(g);
108 for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
110 System.out.println("Resource " + r);
111 for (Resource rr : g.getObjects(r, l0.ConsistsOf)) {
112 if (!g.isInstanceOf(rr, l0.String))
113 fail("Resource " + rr + " is not instance of String.");
114 if (!g.isInstanceOf(rr, l0.Entity))
115 fail("Resource " + rr + " is not instance of Entity.");
117 g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
120 public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
122 System.out.println("change " + resource);
126 public void exception(ReadGraph graph, Throwable t)
127 throws DatabaseException {
129 fail("Listener got exception: " + t);
133 public boolean isDisposed() {
135 System.out.println("Asked if disposed.");
140 g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount));
143 g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount));
147 } catch (DatabaseException e) {
152 class Listener implements SyncListener<Resource> {
153 final DataContainer<Integer> loopCount;
154 final DataContainer<Integer> listenerCount;
156 boolean disposed = false;
157 Listener(DataContainer<Integer> loopCount, DataContainer<Integer> listenerCount) {
158 this.loopCount = loopCount;
159 this.listenerCount = listenerCount;
160 int value = this.listenerCount.get() + 1;
161 this.listenerCount.set(value);
162 this.me = loopCount.get();
165 public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
167 System.out.println("change " + resource);
171 public void exception(ReadGraph graph, Throwable t)
172 throws DatabaseException {
174 fail("Listener got exception: " + t);
178 public boolean isDisposed() {
180 System.out.println("Asked if disposed.");
183 disposed = loopCount.get() != me;
185 int value = this.listenerCount.get() - 1;
186 this.listenerCount.set(value);
192 class Delete extends WriteRequest {
194 public void perform(WriteGraph g) throws DatabaseException {
195 Layer0 l0 = Layer0.getInstance(g);
196 for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
198 System.out.println("Deny resource " + r);
199 g.deny(testRoot, l0.ConsistsOf, r);