Java tutorial
package net.node42.filter; // Copyright 2013 Mark Roderick // // 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 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockServletContext; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import static com.jayway.awaitility.Awaitility.await; import static org.fest.assertions.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.equalTo; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; public class SimpleTimeoutLoadLimitingFilterTest { // STATELESS to run individual @Tests concurrently @Test public void testDefaultSettings() throws Exception { final SimpleTimeoutLoadLimitingFilter target = new SimpleTimeoutLoadLimitingFilter(); final MockFilterConfig filterConfig = new MockFilterConfig(new MockServletContext()); target.init(filterConfig); assertThat(target.maxConcurrentRequests).isNotNull() .isEqualTo(SimpleTimeoutLoadLimitingFilter.REQUEST_COUNT_CONCURRENT_MAX_DEFAULT); assertThat(target.requestCountCheckInterval).isNotNull() .isEqualTo(SimpleTimeoutLoadLimitingFilter.REQUEST_COUNT_CHECK_INTERVAL_DEFAULT); assertThat(target.requestTimeoutMillis).isNotNull() .isEqualTo(SimpleTimeoutLoadLimitingFilter.REQUEST_TIMEOUT_DEFAULT); assertThat(target.timeoutResponseContent).isNotNull() .isEqualTo(SimpleTimeoutLoadLimitingFilter.CONTENT_TIMEOUT_DEFAULT); } @Test public void testSpecifiedSettings() throws Exception { final SimpleTimeoutLoadLimitingFilter target = new SimpleTimeoutLoadLimitingFilter(); final MockFilterConfig filterConfig = new MockFilterConfig(new MockServletContext()); filterConfig.addInitParameter("request_count_concurrent_max", "1"); filterConfig.addInitParameter("request_count_check_interval", "1000"); filterConfig.addInitParameter("request_timeout", "2000"); filterConfig.addInitParameter("response_timeout_file_name", "target/test-classes/ILuvLinux.txt"); target.init(filterConfig); assertThat(target.maxConcurrentRequests).isNotNull().isEqualTo(1); assertThat(target.requestCountCheckInterval).isNotNull().isEqualTo(1000L); assertThat(target.requestTimeoutMillis).isNotNull().isEqualTo(2000L); assertThat(target.timeoutResponseContent).isNotNull() .isEqualTo("It's true.\n\nThis is just a stub file for targeting some unit tests."); } @Test public void testConcurrentCountIncrementation() throws Exception { final SimpleTimeoutLoadLimitingFilter target = new SimpleTimeoutLoadLimitingFilter(); final MockFilterConfig filterConfig = new MockFilterConfig(new MockServletContext()); target.init(filterConfig); final MockHttpServletRequest request = new MockHttpServletRequest(); final MockHttpServletResponse response = new MockHttpServletResponse(); response.setWriterAccessAllowed(true); final FilterChain filterChain = mock(FilterChain.class); doAnswer(new Answer() { @Override public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { Thread.sleep(7000L); return null; } }).when(filterChain).doFilter(any(ServletRequest.class), any(ServletResponse.class)); // Reusing the request/response object for multiple calls. Safe, but they are not viable to inspect for state. await().atMost(2, TimeUnit.SECONDS).untilAtomic(target.ACTIVE_REQUESTS, equalTo(0)); runLoadLimitingFilter(target, request, response, filterChain); await().atMost(2, TimeUnit.SECONDS).untilAtomic(target.ACTIVE_REQUESTS, equalTo(1)); runLoadLimitingFilter(target, request, response, filterChain); await().atMost(2, TimeUnit.SECONDS).untilAtomic(target.ACTIVE_REQUESTS, equalTo(2)); target.destroy(); } @Test public void testTimeoutResponseReturned() throws Exception { final SimpleTimeoutLoadLimitingFilter target = new SimpleTimeoutLoadLimitingFilter(); final MockFilterConfig filterConfig = new MockFilterConfig(new MockServletContext()); // Nothing gets through, and it times out immediately... filterConfig.addInitParameter("request_count_concurrent_max", "0"); filterConfig.addInitParameter("request_timeout", "-1000"); target.init(filterConfig); final MockHttpServletRequest request = new MockHttpServletRequest(); final MockHttpServletResponse response = new MockHttpServletResponse(); response.setWriterAccessAllowed(true); final FilterChain filterChain = mock(FilterChain.class); runLoadLimitingFilter(target, request, response, filterChain); await().atMost(2, TimeUnit.SECONDS).untilAtomic(target.ACTIVE_REQUESTS, equalTo(0)); assertThat(response.getContentAsString()).isNotNull().isNotEmpty() .isEqualTo(SimpleTimeoutLoadLimitingFilter.CONTENT_TIMEOUT_DEFAULT); } @Test public void testDestroy() throws Exception { final SimpleTimeoutLoadLimitingFilter target = new SimpleTimeoutLoadLimitingFilter(); final MockFilterConfig filterConfig = new MockFilterConfig(new MockServletContext()); filterConfig.addInitParameter("request_count_concurrent_max", "0"); filterConfig.addInitParameter("request_count_check_interval", "200"); filterConfig.addInitParameter("request_timeout", "10000"); target.init(filterConfig); assertThat(target.maxConcurrentRequests).isEqualTo(0); assertThat(target.requestCountCheckInterval).isEqualTo(200L); assertThat(target.requestTimeoutMillis).isEqualTo(10000); final MockHttpServletRequest request = new MockHttpServletRequest(); final MockHttpServletResponse response = new MockHttpServletResponse(); response.setWriterAccessAllowed(true); final FilterChain filterChain = mock(FilterChain.class); runLoadLimitingFilter(target, request, response, filterChain); assertThat(response.getContentLength()).isEqualTo(0); // Verify we haven't written a timeout message target.destroy(); assertThat(target.DESTROY.get()).isEqualTo(true); await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return !response.getContentAsString().isEmpty(); } }); assertThat(response.getContentAsString()).isNotEmpty() .isEqualTo(SimpleTimeoutLoadLimitingFilter.CONTENT_TIMEOUT_DEFAULT); } // HELPER METHODS... private void runLoadLimitingFilter(final SimpleTimeoutLoadLimitingFilter target, final MockHttpServletRequest request, final MockHttpServletResponse response, final FilterChain filterChain) { new Thread(new Runnable() { @Override public void run() { try { target.doFilter(request, response, filterChain); } catch (IOException e) { e.printStackTrace(); } catch (ServletException e) { e.printStackTrace(); } } }).start(); } }