]> gerrit.simantics Code Review - simantics/platform.git/blob - tests/org.simantics.db.tests/src/org/simantics/db/tests/regression/bugs/SimanticsBug1659Test2.java
Multiple reader thread support for db client
[simantics/platform.git] / tests / org.simantics.db.tests / src / org / simantics / db / tests / regression / bugs / SimanticsBug1659Test2.java
1 package org.simantics.db.tests.regression.bugs;
2
3 import java.util.UUID;
4
5 import org.junit.Test;
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;
24
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;
37     Session session;
38     Resource testRoot;
39     Resource type;
40     DataContainer<Integer> loopCount = new DataContainer<Integer>();
41     DataContainer<Integer> listenerCount = new DataContainer<Integer>();
42     
43     @Test
44     public void testSimanticsBug1659_2()
45     throws DatabaseException {
46         session = getSession();
47         session.syncRequest(new Init());
48         loopCount.set(-1);
49         listenerCount.set(0);
50         int oldCount = 0;
51         for (int i=0; i<LOOP_COUNT; ++i) {
52             loopCount.set(i);
53             if (DEBUG)
54                 System.out.println("Create " + i);
55             session.syncRequest(new CreateWriteOnly());
56             if (DEBUG)
57                 System.out.println("Query " + i);
58             session.syncRequest(new Query());
59             if (DEBUG)
60                 System.out.println("Delete loop=" + i + " listeners=" + listenerCount.get());
61             loopCount.set(-1);
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);
67                 oldCount = count;
68             }
69             session.syncRequest(new Delete());
70             if (DEBUG)
71                 System.out.println("Done " + i);
72         }
73     }
74     class Init extends WriteRequest {
75         @Override
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);          
84         }
85     }
86     class CreateWriteOnly extends WriteOnlyRequest {
87         @Override
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);
93                 g.flushCluster();
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);
99                 }
100             }
101         }
102     }
103     class Query extends AsyncReadRequest {
104         @Override
105         public void run(AsyncReadGraph g) {
106                 try {
107             Layer0 l0 = Layer0.getInstance(g);
108             for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
109                 if (DEBUG)
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.");
116                         if (USE_LISTENER)
117                             g.forPossibleObject(rr, l0.InstanceOf, new SyncListener<Resource>() {
118         
119                                 @Override
120                                 public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
121                                         if (DEBUG_LISTENER)
122                                                 System.out.println("change " + resource);
123                                 }
124         
125                                                 @Override
126                                                 public void exception(ReadGraph graph, Throwable t)
127                                                                 throws DatabaseException {
128                                                         t.printStackTrace();
129                                         fail("Listener got exception: " + t);
130                                                 }
131         
132                                                 @Override
133                                                 public boolean isDisposed() {
134                                                         if (DEBUG_LISTENER)
135                                                                 System.out.println("Asked if disposed.");
136                                                         return true;
137                                                 }
138                             });
139                     if (USE_LISTENER2) {
140                         g.forPossibleObject(rr, l0.InstanceOf, new Listener(loopCount, listenerCount));
141                     }
142                     if (USE_LISTENER3) {
143                        g.syncRequest(new PossibleObject(rr, l0.InstanceOf), new Listener(loopCount, listenerCount));
144                     }
145                 }
146             }
147                 } catch (DatabaseException e) {
148                         e.printStackTrace();
149                 }
150         }
151     }
152     class Listener implements SyncListener<Resource> {
153         final DataContainer<Integer> loopCount;
154         final DataContainer<Integer> listenerCount;
155         final int me;
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();
163         }
164         @Override
165         public void execute(ReadGraph graph, Resource resource) throws DatabaseException {
166             if (DEBUG_LISTENER)
167                 System.out.println("change " + resource);
168         }
169
170         @Override
171         public void exception(ReadGraph graph, Throwable t)
172                 throws DatabaseException {
173             t.printStackTrace();
174             fail("Listener got exception: " + t);
175         }
176
177         @Override
178         public boolean isDisposed() {
179             if (DEBUG_LISTENER)
180                 System.out.println("Asked if disposed.");
181             if (disposed)
182                 return true;
183             disposed = loopCount.get() != me;
184             if (disposed) {
185                 int value = this.listenerCount.get() - 1;
186                 this.listenerCount.set(value);
187             }
188             return disposed;
189         }
190         
191     }
192     class Delete extends WriteRequest {
193         @Override
194         public void perform(WriteGraph g) throws DatabaseException {
195             Layer0 l0 = Layer0.getInstance(g);
196             for (Resource r : g.getObjects(testRoot, l0.ConsistsOf)) {
197                 if (DEBUG)
198                     System.out.println("Deny resource " + r);
199                 g.deny(testRoot, l0.ConsistsOf, r);
200             }
201         }
202     }
203 }