@Test public void testThreads() throws Exception { final Analyzer analyzer = new MockAnalyzer(random()); RandomIndexWriter iw = new RandomIndexWriter( random(), dir, iwcWithSuggestField(analyzer, "suggest_field_1", "suggest_field_2", "suggest_field_3")); int num = Math.min(1000, atLeast(100)); final String prefix1 = "abc1_"; final String prefix2 = "abc2_"; final String prefix3 = "abc3_"; final Entry[] entries1 = new Entry[num]; final Entry[] entries2 = new Entry[num]; final Entry[] entries3 = new Entry[num]; for (int i = 0; i < num; i++) { int weight = num - (i + 1); entries1[i] = new Entry(prefix1 + weight, weight); entries2[i] = new Entry(prefix2 + weight, weight); entries3[i] = new Entry(prefix3 + weight, weight); } for (int i = 0; i < num; i++) { Document doc = new Document(); doc.add(new SuggestField("suggest_field_1", prefix1 + i, i)); doc.add(new SuggestField("suggest_field_2", prefix2 + i, i)); doc.add(new SuggestField("suggest_field_3", prefix3 + i, i)); iw.addDocument(doc); if (rarely()) { iw.commit(); } } DirectoryReader reader = iw.getReader(); int numThreads = TestUtil.nextInt(random(), 2, 7); Thread threads[] = new Thread[numThreads]; final CyclicBarrier startingGun = new CyclicBarrier(numThreads + 1); final CopyOnWriteArrayList<Throwable> errors = new CopyOnWriteArrayList<>(); final SuggestIndexSearcher indexSearcher = new SuggestIndexSearcher(reader); for (int i = 0; i < threads.length; i++) { threads[i] = new Thread() { @Override public void run() { try { startingGun.await(); PrefixCompletionQuery query = new PrefixCompletionQuery(analyzer, new Term("suggest_field_1", prefix1)); TopSuggestDocs suggest = indexSearcher.suggest(query, num); assertSuggestions(suggest, entries1); query = new PrefixCompletionQuery(analyzer, new Term("suggest_field_2", prefix2)); suggest = indexSearcher.suggest(query, num); assertSuggestions(suggest, entries2); query = new PrefixCompletionQuery(analyzer, new Term("suggest_field_3", prefix3)); suggest = indexSearcher.suggest(query, num); assertSuggestions(suggest, entries3); } catch (Throwable e) { errors.add(e); } } }; threads[i].start(); } startingGun.await(); for (Thread t : threads) { t.join(); } assertTrue(errors.toString(), errors.isEmpty()); reader.close(); iw.close(); }
@Override public String toString() { return copyOnWriteArrayList.toString(); }
@Test public void testPushResourceAreSentNonInterleaved() throws Exception { final CountDownLatch allExpectedPushesReceivedLatch = new CountDownLatch(4); final CountDownLatch allPushDataReceivedLatch = new CountDownLatch(4); final CopyOnWriteArrayList<Integer> dataReceivedOrder = new CopyOnWriteArrayList<>(); InetSocketAddress bigResponseServerAddress = startHTTPServer( version, new AbstractHandler() { @Override public void handle( String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { byte[] bytes = new byte[32768]; new Random().nextBytes(bytes); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(bytes); baseRequest.setHandled(true); } }); Session pushCacheBuildSession = startClient(version, bigResponseServerAddress, null); Fields mainResourceHeaders = createHeadersWithoutReferrer(mainResource); sendRequest(pushCacheBuildSession, mainResourceHeaders, null, null); sendRequest(pushCacheBuildSession, createHeaders("/style.css", mainResource), null, null); sendRequest(pushCacheBuildSession, createHeaders("/javascript.js", mainResource), null, null); sendRequest(pushCacheBuildSession, createHeaders("/image1.jpg", mainResource), null, null); sendRequest(pushCacheBuildSession, createHeaders("/image2.jpg", mainResource), null, null); Session session = startClient(version, bigResponseServerAddress, null); session.syn( new SynInfo(mainResourceHeaders, true), new StreamFrameListener.Adapter() { AtomicInteger currentStreamId = new AtomicInteger(2); @Override public StreamFrameListener onPush(Stream stream, PushInfo pushInfo) { LOG.info("Received push for stream: {} {}", stream.getId(), pushInfo); String uriHeader = pushInfo.getHeaders().get(HTTPSPDYHeader.URI.name(version)).value(); switch ((int) allExpectedPushesReceivedLatch.getCount()) { case 4: assertThat("1st pushed resource is the css", uriHeader.endsWith("css"), is(true)); break; case 3: assertThat("2nd pushed resource is the js", uriHeader.endsWith("js"), is(true)); break; case 2: assertThat( "3rd pushed resource is image1", uriHeader.endsWith("image1.jpg"), is(true)); break; case 1: assertThat( "4th pushed resource is image2", uriHeader.endsWith("image2.jpg"), is(true)); break; } allExpectedPushesReceivedLatch.countDown(); return new Adapter() { @Override public void onData(Stream stream, DataInfo dataInfo) { if (stream.getId() != currentStreamId.get()) throw new IllegalStateException( "Streams interleaved. Expected StreamId: " + currentStreamId + " but was: " + stream.getId()); dataInfo.consume(dataInfo.available()); if (dataInfo.isClose()) { currentStreamId.compareAndSet(currentStreamId.get(), currentStreamId.get() + 2); dataReceivedOrder.add(stream.getId()); allPushDataReceivedLatch.countDown(); } LOG.info(stream.getId() + ":" + dataInfo); } }; } }); assertThat( "All push resources received", allExpectedPushesReceivedLatch.await(5, TimeUnit.SECONDS), is(true)); assertThat( "All pushData received", allPushDataReceivedLatch.await(5, TimeUnit.SECONDS), is(true)); assertThat( "The data for different push streams has not been interleaved", dataReceivedOrder.toString(), equalTo("[2, 4, 6, 8]")); LOG.info(dataReceivedOrder.toString()); }