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