1 package org.apache.maven.index;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.concurrent.atomic.AtomicInteger;
25
26 import junit.framework.Assert;
27
28 import org.apache.lucene.search.Query;
29 import org.apache.maven.index.context.DefaultIndexingContext;
30 import org.apache.maven.index.context.IndexingContext;
31 import org.apache.maven.index.expr.UserInputSearchExpression;
32
33 public class ConcurrentUseTest
34 extends AbstractNexusIndexerTest
35 {
36 public static final int THREAD_COUNT = 10;
37
38 protected File repo = new File( getBasedir(), "src/test/repo" );
39
40 @Override
41 protected void prepareNexusIndexer( NexusIndexer nexusIndexer )
42 throws Exception
43 {
44
45 DefaultIndexingContext.BLOCKING_COMMIT = false;
46
47 context =
48 nexusIndexer.addIndexingContext( "test-default", "test", repo, indexDir, null, null, DEFAULT_CREATORS );
49
50 assertNull( context.getTimestamp() );
51
52 nexusIndexer.scan( context );
53
54 assertNotNull( context.getTimestamp() );
55 }
56
57 protected IndexUserThread createThread( final ArtifactInfo ai )
58 {
59
60 return new IndexUserThread( this, nexusIndexer, context, context, ai );
61 }
62
63 public void testConcurrency()
64 throws Exception
65 {
66 IndexUserThread[] threads = new IndexUserThread[THREAD_COUNT];
67
68 ArtifactInfo ai =
69 new ArtifactInfo( "test-default", "org.apache.maven.indexer", "index-concurrent-artifact", "", null );
70
71 for ( int i = 0; i < THREAD_COUNT; i++ )
72 {
73 threads[i] = createThread( ai );
74
75 threads[i].start();
76 }
77
78 Thread.sleep( 5000 );
79
80 boolean thereWereProblems = false;
81
82 int totalAdded = 0;
83
84 for ( int i = 0; i < THREAD_COUNT; i++ )
85 {
86 threads[i].stopThread();
87
88 threads[i].join();
89
90 thereWereProblems = thereWereProblems || threads[i].hadProblem();
91
92 totalAdded += threads[i].getAdded();
93 }
94
95 Assert.assertFalse( "Not all thread did clean job!", thereWereProblems );
96
97 context.commit();
98
99
100
101 Thread.sleep( 2000 );
102
103
104
105 Query q = nexusIndexer.constructQuery( MAVEN.GROUP_ID, new UserInputSearchExpression( ai.groupId ) );
106
107 FlatSearchResponse result = nexusIndexer.searchFlat( new FlatSearchRequest( q, context ) );
108
109 Assert.assertEquals( "All added should be found after final commit!", totalAdded, result.getTotalHitsCount() );
110 }
111
112
113
114 private static final AtomicInteger versionSource = new AtomicInteger( 1 );
115
116 protected void addToIndex( final NexusIndexer nexusIndexer, final IndexingContext indexingContext )
117 throws IOException
118 {
119 final ArtifactInfo artifactInfo =
120 new ArtifactInfo( "test-default", "org.apache.maven.indexer", "index-concurrent-artifact", "1."
121 + String.valueOf( versionSource.getAndIncrement() ), null );
122
123 final ArtifactContext ac = new ArtifactContext( null, null, null, artifactInfo, artifactInfo.calculateGav() );
124
125 nexusIndexer.addArtifactToIndex( ac, indexingContext );
126 }
127
128 protected void deleteFromIndex( final NexusIndexer nexusIndexer, final IndexingContext indexingContext )
129 throws IOException
130 {
131
132
133
134
135
136
137
138
139 }
140
141 protected int readIndex( final NexusIndexer nexusIndexer, final IndexingContext indexingContext )
142 throws IOException
143 {
144 final Query q =
145 nexusIndexer.constructQuery( MAVEN.GROUP_ID, new UserInputSearchExpression( "org.apache.maven.indexer" ) );
146
147 FlatSearchResponse result = nexusIndexer.searchFlat( new FlatSearchRequest( q, indexingContext ) );
148
149 return result.getReturnedHitsCount();
150 }
151
152
153
154 public static class IndexUserThread
155 extends Thread
156 {
157 private final ConcurrentUseTest test;
158
159 private final NexusIndexer nexusIndexer;
160
161 private final IndexingContext searchIndexingContext;
162
163 private final IndexingContext modifyIndexingContext;
164
165 private boolean stopped = false;
166
167 private int added = 0;
168
169 private int deleted = 0;
170
171 private int lastSearchHitCount = 0;
172
173 private Throwable t;
174
175 public IndexUserThread( final ConcurrentUseTest test, final NexusIndexer nexusIndexer,
176 final IndexingContext searchIndexingContext,
177 final IndexingContext modifyIndexingContext, ArtifactInfo artifactInfo )
178 {
179 this.test = test;
180
181 this.nexusIndexer = nexusIndexer;
182
183 this.searchIndexingContext = searchIndexingContext;
184
185 this.modifyIndexingContext = modifyIndexingContext;
186 }
187
188 public int getAdded()
189 {
190 return added;
191 }
192
193 public int getDeleted()
194 {
195 return deleted;
196 }
197
198 public boolean hadProblem()
199 {
200 return t != null;
201 }
202
203 public int getLastSearchHitCount()
204 {
205 return lastSearchHitCount;
206 }
207
208 public void stopThread()
209 throws IOException
210 {
211 this.modifyIndexingContext.commit();
212
213 this.stopped = true;
214 }
215
216 public void run()
217 {
218 while ( !stopped )
219 {
220 if ( System.currentTimeMillis() % 5 == 0 )
221 {
222 try
223 {
224 test.addToIndex( nexusIndexer, modifyIndexingContext );
225
226 added++;
227 }
228 catch ( Throwable e )
229 {
230 t = e;
231
232 e.printStackTrace();
233
234 throw new IllegalStateException( "error", e );
235 }
236 }
237
238 if ( System.currentTimeMillis() % 11 == 0 )
239 {
240 try
241 {
242
243
244 }
245 catch ( Throwable e )
246 {
247 t = e;
248
249 throw new IllegalStateException( "error", e );
250 }
251 }
252
253 try
254 {
255 lastSearchHitCount = test.readIndex( nexusIndexer, searchIndexingContext );
256 }
257 catch ( Throwable e )
258 {
259 t = e;
260
261 throw new IllegalStateException( "error", e );
262 }
263 }
264 }
265 }
266 }