/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.tests.common.sif.async; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThanOrEqualTo; import java.lang.Thread.State; import java.net.URI; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.xml.ws.Response; import org.ebayopensource.turmeric.runtime.common.impl.internal.utils.IAsyncResponsePoller; import org.ebayopensource.turmeric.runtime.common.impl.internal.utils.ITransportPoller; import org.ebayopensource.turmeric.runtime.sif.impl.internal.service.ServicePoller; import org.ebayopensource.turmeric.runtime.sif.impl.transport.http.HTTPSyncAsyncClientTransportPoller; import org.ebayopensource.turmeric.runtime.spf.impl.transport.local.LocalTransportPoller; import org.ebayopensource.turmeric.runtime.tests.common.jetty.AbstractWithServerTest; import org.junit.Assert; import org.junit.Test; import com.ebay.kernel.service.invocation.client.exception.BaseClientSideException; import com.ebay.kernel.service.invocation.client.http.Request; import com.ebay.kernel.service.invocation.client.http.nio.CompletionQueue; import com.ebay.kernel.service.invocation.client.http.nio.NioAsyncHttpClient; import com.ebay.kernel.service.invocation.client.http.nio.NioAsyncHttpClients; public class ServicePollerTest extends AbstractWithServerTest { static final NioAsyncHttpClient client = NioAsyncHttpClients.newClient( "ServicePollerTest", null, 10000); @Test public void getSetOfTransportPoller() throws Exception { IAsyncResponsePoller poller = getPoller(); Assert.assertTrue(poller.poll(false, false, -1).size() == 0); stimulatePollReq1(poller); Assert.assertTrue(poller.poll(false, false, -1).size() == 1); stimulatePollReq1(poller); ITransportPoller anotherTP = new LocalTransportPoller(); poller.setTransportPoller(anotherTP); Assert.assertNotNull(anotherTP); Assert.assertTrue(anotherTP == poller.getTransportPoller()); Assert.assertTrue(poller.poll(false, false, -1).size() == 0); } @Test public void simplePollBlock() throws Exception { IAsyncResponsePoller poller = getPoller(); stimulatePollReq1(poller); Assert.assertTrue(poller.poll(true, true, -1).size() == 1); } @Test public void simplePollNoBlock() throws Exception { IAsyncResponsePoller poller = getPoller(); stimulatePollReq1(poller); int size = 0; for (int i = 0; i < 100; i++) { size += poller.poll(false, true, -1).size(); if (size == 1) break; Thread.sleep(20); } Assert.assertTrue(size == 1); } @Test public void simplePollNoPartial() throws Exception { IAsyncResponsePoller poller = getPoller(); stimulatePollReq1(poller); stimulatePollReq1(poller); Assert.assertTrue(poller.poll(true, false, -1).size() == 2); stimulatePollReq1(poller); stimulatePollReq1(poller); Assert.assertTrue(poller.poll(false, false, -1).size() == 2); } @Test public void pollBlock() throws Exception { testPollNoTimeout(10, true, true); } @Test public void noPollBlock() throws Exception { testPollNoTimeout(10, false, true); } @Test public void noPartial() throws Exception { testPollNoTimeout(10, false, false); testPollNoTimeout(10, true, false); } @Test public void pollBlockTimout() throws Exception { pollwithShortTimeout(true, true); pollwithLongTimeout(true, true); } @Test public void noPollBlockTimeout() throws Exception { pollwithShortTimeout(false, true); pollwithLongTimeout(false, true); } @Test public void noPartialTimeout() throws Exception { pollwithShortTimeout(false, false); pollwithLongTimeout(false, false); pollwithShortTimeout(true, false); pollwithLongTimeout(true, false); } @Test public void nonBlockWithBlockFlagAndNoRequests() throws Exception { Thread tester = new Thread(new Runnable() { public void run() { try { testPollNoTimeout(0, true, true); } catch (Exception e) { throw new RuntimeException(e); } } }); tester.start(); tester.join(1000); if(!tester.getState().equals(State.TERMINATED)) Assert.fail(String.format("For zero requests polls needs to return immediately, thread state is %s",tester.getState().toString())); } private void testPollTimeout(IAsyncResponsePoller poller) throws Exception { for (int i = 0; i < 25; i++) { stimulatePollReq1(poller); } } private IAsyncResponsePoller getPoller() { IAsyncResponsePoller poller = new ServicePoller(); // Initially transport poller needs to be null Assert.assertNull(poller.getTransportPoller()); poller.setTransportPoller(new HTTPSyncAsyncClientTransportPoller()); Assert.assertNotNull(poller.getTransportPoller()); return poller; } private void testPollNoTimeout(int size, boolean block, boolean partial) throws Exception { IAsyncResponsePoller poller = getPoller(); for (int i = 0; i < size; i++) { stimulatePollReq1(poller); } if (!partial) { int total = poller.poll(block, partial, -1).size(); verifyResults(size, block, partial, poller, total); } else { int total = 0; for (int i = 0; i < 100; i++) { total += poller.poll(block, partial, -1).size(); if (total == size) break; Thread.sleep(20); } verifyResults(size, block, partial, poller, total); } } private void verifyResults(int size, boolean block, boolean partial, IAsyncResponsePoller poller, int total) throws InterruptedException { System.out.printf("\ntestPollNoTimeout(%b,%b): Sent %d and got %d", block, partial, size, total); Assert.assertTrue(total == size); Assert.assertTrue(poller.poll(false, false, 100).size() == 0); System.out.printf("\ntestPollNoTimeout(%b,%b): queue empty verified", block, partial); } private void stimulatePollReq1(IAsyncResponsePoller poller) throws BaseClientSideException { // http://localhost:8080/ws/spf?wsdl&X-TURMERIC-SERVICE-NAME=Test1Service URI uri = serverUri.resolve("?wsdl"); Request r1 = new Request(uri.getHost() + ":" + uri.getPort(), uri.getPath()); r1.addParameter("X-TURMERIC-SERVICE-NAME", "Test1Service"); sendRequest(poller, client, r1); } private void sendRequest(IAsyncResponsePoller poller, NioAsyncHttpClient client, Request req) throws BaseClientSideException { Future<?> future = client.send(req, (CompletionQueue) poller .getTransportPoller()); poller.add(future, new TestResponse(future)); } private void pollwithLongTimeout(boolean block, boolean partial) throws Exception { IAsyncResponsePoller poller = getPoller(); testPollTimeout(poller); int total = (poller.poll(block, partial, 500).size()); System.out.printf("%npollwithLongTimeout(%b,%b): Sent 25 and got %d%n", block, partial, total); Assert.assertThat("poller.poll(block,partial,500).size", total, is(25)); Assert.assertThat("poller.poll(false, false, 100).size()", poller.poll(false, false, 100).size(), is(0)); System.out.printf("%npollwithLongTimeout(%b,%b): queue empty verified%n", block, partial); } @SuppressWarnings("unchecked") private void pollwithShortTimeout(boolean block, boolean partial) throws Exception, InterruptedException { IAsyncResponsePoller poller = getPoller(); testPollTimeout(poller); int size = 0; int total = 0; for (int i = 0; i < 20 && total < 25; i++) { size = poller.poll(block, partial, 10).size(); Assert.assertThat("poller.poll.size", size, lessThanOrEqualTo(25)); total += size; Thread.sleep(10); } System.out.printf("%npollwithShortTimeout(%b,%b): Sent 25 and got %d%n", block, partial, total); Assert.assertThat("Total", total, allOf(greaterThan(1),lessThanOrEqualTo(25))); Assert.assertThat("Poll.size", poller.poll(false, false, 100).size(), is(0)); System.out.printf("%npollwithShortTimeout(%b,%b): queue empty verified%n", block, partial); } @SuppressWarnings("rawtypes") private static class TestResponse implements Response { private final Future<?> m_future; private Object m_response; private boolean m_isDone = false; public TestResponse(Future<?> future) { m_future = future; } public Map getContext() { return null; } public boolean cancel(boolean mayInterruptIfRunning) { return false; } public Object get() throws InterruptedException, ExecutionException { if (m_isDone) return m_response; try { return (m_response = m_future.get()); } finally { m_isDone = true; } } public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return get(); } public boolean isCancelled() { return false; } public boolean isDone() { return m_isDone; } } }