From 705efc5bdf7971cde7a1de1b05b437cea557eee9 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 4 Mar 2014 21:38:42 -0500 Subject: [PATCH] Fix timing issue with obtaining async result Issue: SPR-11516 --- .../test/web/servlet/DefaultMvcResult.java | 27 ++++++++++--------- .../samples/standalone/AsyncTests.java | 24 ++++++++++++++++- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java b/spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java index e9951189be7..0cb7119bee6 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/DefaultMvcResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,9 @@ import org.springframework.web.servlet.support.RequestContextUtils; */ class DefaultMvcResult implements MvcResult { + private static final Object RESULT_NONE = new Object(); + + private final MockHttpServletRequest mockRequest; private final MockHttpServletResponse mockResponse; @@ -48,7 +51,7 @@ class DefaultMvcResult implements MvcResult { private Exception resolvedException; - private Object asyncResult; + private Object asyncResult = RESULT_NONE; private CountDownLatch asyncResultLatch; @@ -123,18 +126,18 @@ class DefaultMvcResult implements MvcResult { @Override public Object getAsyncResult(long timeout) { - // MockHttpServletRequest type doesn't have async methods - HttpServletRequest request = this.mockRequest; - if ((timeout != 0) && request.isAsyncStarted()) { - if (timeout == -1) { - timeout = request.getAsyncContext().getTimeout(); - } - if (!awaitAsyncResult(timeout)) { - throw new IllegalStateException( - "Gave up waiting on async result from handler [" + this.handler + "] to complete"); + if (this.asyncResult == RESULT_NONE) { + if ((timeout != 0) && this.mockRequest.isAsyncStarted()) { + if (timeout == -1) { + timeout = this.mockRequest.getAsyncContext().getTimeout(); + } + if (!awaitAsyncResult(timeout) && this.asyncResult == RESULT_NONE) { + throw new IllegalStateException( + "Gave up waiting on async result from handler [" + this.handler + "] to complete"); + } } } - return this.asyncResult; + return (this.asyncResult == RESULT_NONE ? null : this.asyncResult); } private boolean awaitAsyncResult(long timeout) { diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java index a3640dd6fad..2c8f1f9fc41 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,20 @@ public class AsyncTests { .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); } + @Test + @Ignore + public void testDeferredResultWithSetValue() throws Exception { + MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithSetValue", "true")) + .andExpect(request().asyncStarted()) + .andExpect(request().asyncResult(new Person("Joe"))) + .andReturn(); + + this.mockMvc.perform(asyncDispatch(mvcResult)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); + } + @Controller private static class AsyncController { @@ -115,6 +129,14 @@ public class AsyncTests { return deferredResult; } + @RequestMapping(value="/{id}", params="deferredResultWithSetValue", produces="application/json") + @ResponseBody + public DeferredResult getDeferredResultWithSetValue() { + DeferredResult deferredResult = new DeferredResult(); + deferredResult.setResult(new Person("Joe")); + return deferredResult; + } + public void onMessage(String name) { for (DeferredResult deferredResult : this.deferredResults) { deferredResult.setResult(new Person(name));