]> gerrit.simantics Code Review - simantics/platform.git/blob - tests/org.simantics.db.tests/src/org/simantics/db/tests/api/request/misc/RequestQueuingTest.java
c17e35797c71cc3f7aa3190c0fff0923e14de5ef
[simantics/platform.git] / tests / org.simantics.db.tests / src / org / simantics / db / tests / api / request / misc / RequestQueuingTest.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.tests.api.request.misc;
13
14 import java.util.concurrent.atomic.AtomicInteger;
15
16 import org.junit.Test;
17 import org.simantics.db.AsyncReadGraph;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Session;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.procedure.AsyncListener;
22 import org.simantics.db.procedure.AsyncProcedure;
23 import org.simantics.db.request.AsyncRead;
24 import org.simantics.db.request.Read;
25 import org.simantics.db.service.QueryControl;
26 import org.simantics.db.service.QueryControl.ControlProcedure;
27 import org.simantics.db.testing.base.ExistingDatabaseTest;
28
29 public class RequestQueuingTest extends ExistingDatabaseTest {
30         
31         final private static int LOOPS = 10;
32         
33     private Object RESULT = new Object();
34     private DatabaseException EXCEPTION = new DatabaseException();
35     
36     private AtomicInteger results = new AtomicInteger(0);
37     private AtomicInteger exceptions = new AtomicInteger(0);
38         
39     class A implements AsyncRead<Object> {
40         
41         private void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure, final int todo) {
42
43                 if(todo == 0) {
44                         
45                                 procedure.execute(graph, RESULT);
46                                 
47                 } else {
48
49                         final QueryControl control = graph.getService(QueryControl.class);
50                         final int current = control.getGraphThread(graph);
51                         final int next = (current + 1) % control.getAmountOfQueryThreads(); 
52                         control.schedule(graph, next, new ControlProcedure() {
53
54                                 public void execute(AsyncReadGraph graph) {
55                                         perform(graph, procedure, todo-1);
56                                 }
57
58                         });
59                         
60                 }
61                 
62                 
63         }
64
65                 @Override
66                 public void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure) {
67                         perform(graph, procedure, 5);
68                 }
69
70         @Override
71             public int threadHash() {
72                 return hashCode();
73             }
74
75                 @Override
76                 public int getFlags() {
77                         return 0;
78                 }
79         
80     }
81
82     class B implements Read<Object> {
83
84                 @Override
85                 public Object perform(ReadGraph graph) throws DatabaseException {
86                         
87                         return graph.syncRequest(new A());
88                         
89                 }
90         
91     }
92     
93     class A2 implements AsyncRead<Object> {
94
95         private void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure, final int todo) {
96
97                 if(todo == 0) {
98                         
99                                 procedure.exception(graph, EXCEPTION);
100                                 
101                 } else {
102
103                         final QueryControl control = graph.getService(QueryControl.class);
104                         final int current = control.getGraphThread(graph);
105                         final int next = (current + 1) % control.getAmountOfQueryThreads(); 
106                         control.schedule(graph, next, new ControlProcedure() {
107
108                                 public void execute(AsyncReadGraph graph) {
109                                         perform(graph, procedure, todo-1);
110                                 }
111
112                         });
113                         
114                 }
115                 
116                 
117         }
118
119                 @Override
120                 public void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure) {
121                         perform(graph, procedure, 5);
122                 }
123
124         @Override
125             public int threadHash() {
126                 return hashCode();
127             }
128
129                 @Override
130                 public int getFlags() {
131                         return 0;
132                 }
133         
134     }
135
136     class B2 implements Read<Object> {
137
138                 @Override
139                 public Object perform(ReadGraph graph) throws DatabaseException {
140                         
141                         return graph.syncRequest(new A2());
142                         
143                 }
144         
145     }
146
147     class C implements AsyncListener<Object> {
148
149                 @Override
150                 public void execute(AsyncReadGraph graph, Object result) {
151                         if(RESULT == result) results.incrementAndGet();
152                 }
153
154                 @Override
155                 public void exception(AsyncReadGraph graph, Throwable throwable) {
156                         if(EXCEPTION == throwable) exceptions.incrementAndGet();
157                 }
158
159                 @Override
160                 public boolean isDisposed() {
161                         return false;
162                 }
163         
164     }
165     
166         @Test
167         public void test() throws Exception {
168                 
169                 Session session = getSession();
170                 
171                 session.syncRequest(new Read<Object>() {
172
173                         @Override
174                         public Object perform(ReadGraph graph) throws DatabaseException {
175
176                                 A a = new A();
177                                 B b = new B();
178                                 A2 a2 = new A2();
179                                 B2 b2 = new B2();
180                                 for(int i=0;i<LOOPS;i++) graph.asyncRequest(a, new C());
181                                 for(int i=0;i<LOOPS;i++) graph.asyncRequest(a2, new C());
182                                 for(int i=0;i<LOOPS;i++) graph.asyncRequest(b, new C());
183                                 for(int i=0;i<LOOPS;i++) graph.asyncRequest(b2, new C());
184
185                                 return null;
186
187                         }
188
189                 });
190                 
191                 if(results.get() != 2*LOOPS) fail("Incorrect amount of reported results (expected " + 2*LOOPS + ", got " + results.get() + ")");
192                 if(exceptions.get() != 2*LOOPS) fail("Incorrect amount of reported exceptions (expected " + 2*LOOPS + ", got " + exceptions.get() + ")");
193                 
194         }
195
196 }