1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph.tests;
14 import static junit.framework.Assert.assertEquals;
15 import static junit.framework.Assert.assertSame;
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;
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;
36 * @author Tuukka Lehtonen
38 public class LookupServiceSynchronizationTest {
40 public static final int ITERATIONS = 10;
41 public static final int ITERATION_TIME_MS = 1000;
42 public static final int THREADS = 16;
44 AtomicBoolean endTest;
45 CyclicBarrier startBarrier;
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>();
53 List<Throwable> errors = new ArrayList<Throwable>();
55 public class Lookup implements Runnable {
58 public Lookup(String id, INode node) {
65 System.out.println("started " + Thread.currentThread().getName());
68 while (!endTest.get()) {
70 INode n = NodeUtil.lookup(this.node, this.id);
71 String id = NodeUtil.lookupId(this.node);
73 assertSame(this.node, n);
75 assertSame(this.id, id);
77 } catch (InterruptedException e) {
79 } catch (BrokenBarrierException e) {
82 System.out.println("ending " + Thread.currentThread().getName());
89 public class Mapper implements Runnable {
92 public Mapper(String id, INode node) {
99 System.out.println("started " + Thread.currentThread().getName());
101 startBarrier.await();
102 for (int i = 0; !endTest.get(); ++i) {
104 NodeUtil.map(node, id);
106 NodeUtil.unmap(node);
110 } catch (InterruptedException e) {
112 } catch (BrokenBarrierException e) {
115 System.out.println("ending " + Thread.currentThread().getName());
122 <T extends INode> T addAndMapNode(ParentNode<?> parent, String id, Class<T> clazz) {
123 T node = parent.addNode(id, clazz);
126 NodeUtil.map(node, id);
130 <T extends INode> T addNode(ParentNode<?> parent, String id, Class<T> clazz) {
131 T node = parent.addNode(id, clazz);
137 <T extends INode> T addNode(ParentNode<?> parent, Class<T> clazz) {
138 return addNode(parent, UUID.randomUUID().toString(), clazz);
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);
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"));
155 for (int iter = 1; iter <= ITERATIONS; ++iter) {
156 System.out.println("Starting iteration " + iter);
159 endTest = new AtomicBoolean(false);
160 startBarrier = new CyclicBarrier(THREADS * 2 + 1);
161 ended = new Semaphore(0);
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();
170 startBarrier.await();
171 // Sleep for the testing period
172 synchronized (this) {
173 wait(ITERATION_TIME_MS);
175 // Wait for threads to end
176 System.out.println("Ending iteration " + iter);
179 ended.acquire(2*THREADS);
180 System.out.println("Iteration " + iter + " ended");
183 assertEquals(errors.size(), 0);