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