source: josm/trunk/test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java@ 11458

Last change on this file since 11458 was 11458, checked in by Don-vip, 7 years ago

sonar - squid:S3578 - Test methods should comply with a naming convention

File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.cache;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertTrue;
6
7import java.io.IOException;
8import java.net.URL;
9import java.util.concurrent.ThreadPoolExecutor;
10import java.util.concurrent.TimeUnit;
11import java.util.concurrent.atomic.AtomicInteger;
12
13import org.apache.commons.jcs.access.behavior.ICacheAccess;
14import org.junit.Rule;
15import org.junit.Test;
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.testutils.JOSMTestRules;
18import org.openstreetmap.josm.tools.Utils;
19
20import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21
22/**
23 * Simple tests for ThreadPoolExecutor / HostLimitQueue veryfing, that this pair works OK
24 * @author Wiktor Niesiobedzki
25 */
26public class HostLimitQueueTest {
27 /**
28 * Setup test.
29 */
30 @Rule
31 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
32 public JOSMTestRules test = new JOSMTestRules().preferences().timeout(20 * 1000);
33
34 private static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers, int queueLimit) {
35 HostLimitQueue workQueue = new HostLimitQueue(queueLimit);
36 ThreadPoolExecutor executor = new ThreadPoolExecutor(
37 0, // 0 so for unused thread pools threads will eventually die, freeing also the threadpool
38 workers, // do not this number of threads
39 300, // keepalive for thread
40 TimeUnit.SECONDS,
41 workQueue,
42 Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
43 );
44 workQueue.setExecutor(executor);
45 return executor;
46 }
47
48 /**
49 * Mock class for tests
50 */
51 static class Task extends JCSCachedTileLoaderJob<String, CacheEntry> {
52 private URL url;
53 private AtomicInteger counter;
54
55 Task(ICacheAccess<String, CacheEntry> cache, URL url, AtomicInteger counter) {
56 super(cache, 1, 1, null);
57 this.url = url;
58 this.counter = counter;
59 }
60
61 @Override
62 public void run() {
63 try {
64 Thread.sleep(1000);
65 } catch (InterruptedException e) {
66 Main.trace(e);
67 } finally {
68 this.counter.incrementAndGet();
69 executionFinished();
70 }
71 }
72
73 @Override
74 public String getCacheKey() {
75 return "";
76 }
77
78 @Override
79 public URL getUrl() throws IOException {
80 return this.url;
81 }
82
83 @Override
84 protected CacheEntry createCacheEntry(byte[] content) {
85 return null;
86 }
87 }
88
89 /**
90 * Check if single threaded execution works properly
91 * @throws Exception in case of error
92 */
93 @Test
94 public void testSingleThreadPerHost() throws Exception {
95 ThreadPoolExecutor tpe = getNewThreadPoolExecutor("test-%d", 3, 1);
96 ICacheAccess<String, CacheEntry> cache = JCSCacheManager.getCache("test", 3, 0, "");
97 AtomicInteger counter = new AtomicInteger(0);
98 long start = System.currentTimeMillis();
99 for (int i = 0; i < 10; i++) {
100 tpe.execute(new Task(cache, new URL("http://localhost/"+i), counter));
101 }
102 tpe.shutdown();
103 tpe.awaitTermination(15, TimeUnit.SECONDS); // at most it should take ~10 seconds, so after 15 it's already failed
104 long duration = System.currentTimeMillis() - start;
105 // check that all tasks were executed
106 assertEquals(10, counter.get());
107 // although there are 3 threads, we can make only 1 parallel call to localhost
108 // so it should take ~10 seconds to finish
109 // if it's shorter, it means that host limit does not work
110 assertTrue("Expected duration between 9 and 11 seconds not met. Actual duration: " + (duration /1000),
111 duration < 11*1000 & duration > 9*1000);
112 }
113
114 /**
115 * Check if two threaded execution work properly
116 * @throws Exception in case of error
117 */
118 @Test
119 public void testMultipleThreadPerHost() throws Exception {
120 ThreadPoolExecutor tpe = getNewThreadPoolExecutor("test-%d", 3, 2);
121 ICacheAccess<String, CacheEntry> cache = JCSCacheManager.getCache("test", 3, 0, "");
122 AtomicInteger counter = new AtomicInteger(0);
123 long start = System.currentTimeMillis();
124 for (int i = 0; i < 10; i++) {
125 tpe.execute(new Task(cache, new URL("http://hostlocal/"+i), counter));
126 }
127 tpe.shutdown();
128 tpe.awaitTermination(15, TimeUnit.SECONDS);
129 long duration = System.currentTimeMillis() - start;
130 // check that all tasks were executed
131 assertEquals(10, counter.get());
132 // although there are 3 threads, we can make only 2 parallel call to localhost
133 // so it should take ~5 seconds to finish
134 // if it's shorter, it means that host limit does not work
135 assertTrue("Expected duration between 4 and 6 seconds not met. Actual duration: " + (duration /1000),
136 duration < 6*1000 & duration > 4*1000);
137 }
138
139 /**
140 * Check two hosts
141 * @throws Exception in case of error
142 */
143 @Test
144 public void testTwoHosts() throws Exception {
145 ThreadPoolExecutor tpe = getNewThreadPoolExecutor("test-%d", 3, 1);
146 ICacheAccess<String, CacheEntry> cache = JCSCacheManager.getCache("test", 3, 0, "");
147 AtomicInteger counter = new AtomicInteger(0);
148 long start = System.currentTimeMillis();
149 for (int i = 0; i < 10; i++) {
150 String url = (i % 2 == 0) ? "http://localhost" : "http://hostlocal";
151 tpe.execute(new Task(cache, new URL(url+i), counter));
152 }
153 tpe.shutdown();
154 tpe.awaitTermination(15, TimeUnit.SECONDS);
155 long duration = System.currentTimeMillis() - start;
156 // check that all tasks were executed
157 assertEquals(10, counter.get());
158 // although there are 3 threads, we can make only 1 parallel per host, and we have 2 hosts
159 // so it should take ~5 seconds to finish
160 // if it's shorter, it means that host limit does not work
161 assertTrue("Expected duration between 4 and 6 seconds not met. Actual duration: " + (duration /1000),
162 duration < 6*1000 & duration > 4*1000);
163 }
164}
Note: See TracBrowser for help on using the repository browser.