001: package org.apache.lucene.search;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import junit.framework.TestCase;
021: import org.apache.lucene.util.LuceneTestCase;
022: import org.apache.lucene.store.Directory;
023: import org.apache.lucene.store.RAMDirectory;
024: import org.apache.lucene.index.IndexReader;
025: import org.apache.lucene.index.IndexWriter;
026: import org.apache.lucene.analysis.WhitespaceAnalyzer;
027: import org.apache.lucene.document.*;
028:
029: import java.util.Random;
030: import java.util.List;
031: import java.io.IOException;
032:
033: /**
034: *
035: * @version $Id: TestThreadSafe.java 598296 2007-11-26 14:52:01Z mikemccand $
036: */
037: public class TestThreadSafe extends LuceneTestCase {
038: Random r = new Random();
039: Directory dir1;
040: Directory dir2;
041:
042: IndexReader ir1;
043: IndexReader ir2;
044:
045: String failure = null;
046:
047: class Thr extends Thread {
048: final int iter;
049: final Random rand;
050:
051: // pass in random in case we want to make things reproducable
052: public Thr(int iter, Random rand, int level) {
053: this .iter = iter;
054: this .rand = rand;
055: }
056:
057: public void run() {
058: try {
059: for (int i = 0; i < iter; i++) {
060: /*** future
061: // pick a random index reader... a shared one, or create your own
062: IndexReader ir;
063: ***/
064:
065: switch (rand.nextInt(1)) {
066: case 0:
067: loadDoc(ir1);
068: break;
069: }
070:
071: }
072: } catch (Throwable th) {
073: failure = th.toString();
074: TestCase.fail(failure);
075: }
076: }
077:
078: void loadDoc(IndexReader ir) throws IOException {
079: // beware of deleted docs in the future
080: Document doc = ir.document(rand.nextInt(ir.maxDoc()),
081: new FieldSelector() {
082: public FieldSelectorResult accept(
083: String fieldName) {
084: switch (rand.nextInt(2)) {
085: case 0:
086: return FieldSelectorResult.LAZY_LOAD;
087: case 1:
088: return FieldSelectorResult.LOAD;
089: // TODO: add other options
090: default:
091: return FieldSelectorResult.LOAD;
092: }
093: }
094: });
095:
096: List fields = doc.getFields();
097: for (int i = 0; i < fields.size(); i++) {
098: Fieldable f = (Fieldable) fields.get(i);
099: validateField(f);
100: }
101:
102: }
103:
104: }
105:
106: void validateField(Fieldable f) {
107: String val = f.stringValue();
108: if (!val.startsWith("^") || !val.endsWith("$")) {
109: throw new RuntimeException("Invalid field:" + f.toString()
110: + " val=" + val);
111: }
112: }
113:
114: String[] words = "now is the time for all good men to come to the aid of their country"
115: .split(" ");
116:
117: void buildDir(Directory dir, int nDocs, int maxFields,
118: int maxFieldLen) throws IOException {
119: IndexWriter iw = new IndexWriter(dir, new WhitespaceAnalyzer(),
120: true);
121: iw.setMaxBufferedDocs(10);
122: for (int j = 0; j < nDocs; j++) {
123: Document d = new Document();
124: int nFields = r.nextInt(maxFields);
125: for (int i = 0; i < nFields; i++) {
126: int flen = r.nextInt(maxFieldLen);
127: StringBuffer sb = new StringBuffer("^ ");
128: while (sb.length() < flen)
129: sb.append(' ').append(
130: words[r.nextInt(words.length)]);
131: sb.append(" $");
132: Field.Store store = Field.Store.YES; // make random later
133: Field.Index index = Field.Index.TOKENIZED; // make random later
134: d.add(new Field("f" + i, sb.toString(), store, index));
135: }
136: iw.addDocument(d);
137: }
138: iw.close();
139: }
140:
141: void doTest(int iter, int nThreads) throws Exception {
142: Thr[] tarr = new Thr[nThreads];
143: for (int i = 0; i < nThreads; i++) {
144: tarr[i] = new Thr(iter, new Random(), 1);
145: tarr[i].start();
146: }
147: for (int i = 0; i < nThreads; i++) {
148: tarr[i].join();
149: }
150: if (failure != null) {
151: TestCase.fail(failure);
152: }
153: }
154:
155: public void testLazyLoadThreadSafety() throws Exception {
156: dir1 = new RAMDirectory();
157: // test w/ field sizes bigger than the buffer of an index input
158: buildDir(dir1, 15, 5, 2000);
159:
160: // do many small tests so the thread locals go away inbetween
161: for (int i = 0; i < 100; i++) {
162: ir1 = IndexReader.open(dir1);
163: doTest(10, 100);
164: }
165: }
166:
167: }
|