]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/testcases/org/simantics/scenegraph/tests/LookupServiceSynchronizationTest.java
Spreadsheet changes
[simantics/platform.git] / bundles / org.simantics.scenegraph / testcases / org / simantics / scenegraph / tests / LookupServiceSynchronizationTest.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.scenegraph.tests;
13
14 import static junit.framework.Assert.assertEquals;
15 import static junit.framework.Assert.assertSame;
16
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.UUID;
20 import java.util.concurrent.BrokenBarrierException;
21 import java.util.concurrent.CyclicBarrier;
22 import java.util.concurrent.Semaphore;
23 import java.util.concurrent.atomic.AtomicBoolean;
24
25 import org.junit.Test;
26 import org.simantics.scenegraph.INode;
27 import org.simantics.scenegraph.ParentNode;
28 import org.simantics.scenegraph.g2d.G2DParentNode;
29 import org.simantics.scenegraph.g2d.G2DSceneGraph;
30 import org.simantics.scenegraph.g2d.nodes.DataNode;
31 import org.simantics.scenegraph.g2d.nodes.NavigationNode;
32 import org.simantics.scenegraph.utils.NodeUtil;
33
34
35 /**
36  * @author Tuukka Lehtonen
37  */
38 public class LookupServiceSynchronizationTest {
39
40     public static final int ITERATIONS        = 10;
41     public static final int ITERATION_TIME_MS = 1000;
42     public static final int THREADS           = 16;
43
44     AtomicBoolean           endTest;
45     CyclicBarrier           startBarrier;
46     Semaphore               ended;
47
48     G2DSceneGraph           root              = new G2DSceneGraph();
49     List<INode>             nodes             = new ArrayList<INode>();
50     List<String>            nodeIds           = new ArrayList<String>();
51     List<String>            mappedIds         = new ArrayList<String>();
52
53     List<Throwable>         errors            = new ArrayList<Throwable>();
54
55     public class Lookup implements Runnable {
56         String id;
57         INode node;
58         public Lookup(String id, INode node) {
59             this.id = id;
60             this.node = node;
61         }
62         @Override
63         public void run() {
64             try {
65                 System.out.println("started " + Thread.currentThread().getName());
66                 System.out.flush();
67                 startBarrier.await();
68                 while (!endTest.get()) {
69                     Thread.yield();
70                     INode n = NodeUtil.lookup(this.node, this.id);
71                     String id = NodeUtil.lookupId(this.node);
72                     if (n != null)
73                         assertSame(this.node, n);
74                     if (id != null)
75                         assertSame(this.id, id);
76                 }
77             } catch (InterruptedException e) {
78                 errors.add(e);
79             } catch (BrokenBarrierException e) {
80                 errors.add(e);
81             } finally {
82                 System.out.println("ending " + Thread.currentThread().getName());
83                 System.out.flush();
84                 ended.release();
85             }
86         }
87     }
88
89     public class Mapper implements Runnable {
90         String id;
91         INode node;
92         public Mapper(String id, INode node) {
93             this.id = id;
94             this.node = node;
95         }
96         @Override
97         public void run() {
98             try {
99                 System.out.println("started " + Thread.currentThread().getName());
100                 System.out.flush();
101                 startBarrier.await();
102                 for (int i = 0; !endTest.get(); ++i) {
103                     Thread.yield();
104                     NodeUtil.map(node, id);
105                     if ((i & 1) == 0)
106                         NodeUtil.unmap(node);
107                     else
108                         root.unmap(id);
109                 }
110             } catch (InterruptedException e) {
111                 errors.add(e);
112             } catch (BrokenBarrierException e) {
113                 errors.add(e);
114             } finally {
115                 System.out.println("ending " + Thread.currentThread().getName());
116                 System.out.flush();
117                 ended.release();
118             }
119         }
120     }
121
122     <T extends INode> T addAndMapNode(ParentNode<?> parent, String id, Class<T> clazz) {
123         T node = parent.addNode(id, clazz);
124         nodes.add( node );
125         nodeIds.add( id );
126         NodeUtil.map(node, id);
127         return node;
128     }
129
130     <T extends INode> T addNode(ParentNode<?> parent, String id, Class<T> clazz) {
131         T node = parent.addNode(id, clazz);
132         nodes.add( node );
133         nodeIds.add( id );
134         return node;
135     }
136
137     <T extends INode> T addNode(ParentNode<?> parent, Class<T> clazz) {
138         return addNode(parent, UUID.randomUUID().toString(), clazz);
139     }
140
141     @Test
142     public void testLookup() throws Exception {
143         NavigationNode nav = addAndMapNode(root, "navigation", NavigationNode.class);
144         DataNode data = addAndMapNode(root, "data", DataNode.class);
145         G2DParentNode elements = addNode(nav, "elements", G2DParentNode.class);
146         @SuppressWarnings("unused")
147         G2DParentNode ghosts = addNode(nav, "ghosts", G2DParentNode.class);
148
149         // Basic checks
150         assertSame(nav, root.lookupNode("navigation"));
151         assertSame(data, root.lookupNode("data"));
152         assertSame(nav, NodeUtil.lookup(nav, "navigation"));
153         assertSame(data, NodeUtil.lookup(data, "data"));
154
155         for (int iter = 1; iter <= ITERATIONS; ++iter) {
156             System.out.println("Starting iteration " + iter);
157             System.out.flush();
158             // Start iteration
159             endTest = new AtomicBoolean(false);
160             startBarrier = new CyclicBarrier(THREADS * 2 + 1);
161             ended = new Semaphore(0);
162
163             for (int i = 0; i < THREADS; ++i) {
164                 String id = UUID.randomUUID().toString();
165                 INode node = addNode(elements, id, G2DParentNode.class);
166                 new Thread(new Mapper(id, node), "Mapper-" + i).start();
167                 new Thread(new Lookup(id, node), "Lookup-" + i).start();
168             }
169
170             startBarrier.await();
171             // Sleep for the testing period
172             synchronized (this) {
173                 wait(ITERATION_TIME_MS);
174             }
175             // Wait for threads to end
176             System.out.println("Ending iteration " + iter);
177             System.out.flush();
178             endTest.set(true);
179             ended.acquire(2*THREADS);
180             System.out.println("Iteration " + iter + " ended");
181         }
182
183         assertEquals(errors.size(), 0);
184     }
185
186 }