You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2018/07/09 08:55:36 UTC

wicket git commit: WICKET-6563 improved test

Repository: wicket
Updated Branches:
  refs/heads/WICKET-6563 7e9c7e516 -> fd7b26bac


WICKET-6563 improved test


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/fd7b26ba
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/fd7b26ba
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/fd7b26ba

Branch: refs/heads/WICKET-6563
Commit: fd7b26bac6f72d5ebc647f490263c41f169faec1
Parents: 7e9c7e5
Author: Sven Meier <sv...@apache.org>
Authored: Mon Jul 9 10:54:57 2018 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Mon Jul 9 10:54:57 2018 +0200

----------------------------------------------------------------------
 .../org/apache/wicket/mock/MockPageStore.java   |   6 +
 .../wicket/pageStore/AsynchronousPageStore.java |  40 +++----
 .../wicket/pageStore/DelegatingPageStore.java   |   2 +-
 .../org/apache/wicket/pageStore/IPageStore.java |   9 +-
 .../pageStore/AsynchronousPageStoreTest.java    | 120 +++++++++++++++++++
 5 files changed, 148 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/fd7b26ba/wicket-core/src/main/java/org/apache/wicket/mock/MockPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/mock/MockPageStore.java b/wicket-core/src/main/java/org/apache/wicket/mock/MockPageStore.java
index cb4eaec..4329140 100644
--- a/wicket-core/src/main/java/org/apache/wicket/mock/MockPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/mock/MockPageStore.java
@@ -53,6 +53,12 @@ public class MockPageStore implements IPageStore
 	}
 
 	@Override
+	public boolean canBeAsynchronous(IPageContext context)
+	{
+		return true;
+	}
+	
+	@Override
 	public void addPage(IPageContext context, IManageablePage page)
 	{
 		pages.put(page.getPageId(), page);

http://git-wip-us.apache.org/repos/asf/wicket/blob/fd7b26ba/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
index 780dafa..0d23925 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/AsynchronousPageStore.java
@@ -111,34 +111,35 @@ public class AsynchronousPageStore extends DelegatingPageStore
 	}
 
 	/**
-	 * A pending asynchronous add in the queue.
+	 * An add of a page that is pending its asynchronous execution.
 	 * <p>
-	 * Used as {@link IPageContext} for the call to the delegate {@link IPageStore#addPage(IPageContext, IManageablePage)}.
+	 * Used as an isolating {@link IPageContext} for the delegation to 
+	 * {@link IPageStore#addPage(IPageContext, IManageablePage)}.
 	 */
 	private static class PendingAdd implements IPageContext
 	{
 		private final IPageContext context;
 		
-		private final String sessionId;
-		
 		private final IManageablePage page;
 
+		private final String sessionId;
+
 		/**
 		 * Is this context passed to an asynchronously called {@link IPageStore#addPage(IPageContext, IManageablePage)}.
 		 */
 		private boolean asynchronous = false;
-		
+
 		/**
 		 * Cache of session attributes which may filled in {@link IPageStore#canBeAsynchronous(IPageContext)},
 		 * so these are available asynchronously later on.
 		 */
-		private Map<String, Serializable> attributeCache = new HashMap<>();
+		private final Map<String, Serializable> attributeCache = new HashMap<>();
 
 		public PendingAdd(final IPageContext context, final IManageablePage page)
 		{
 			this.context = Args.notNull(context, "context");
 			this.page = Args.notNull(page, "page");
-
+			
 			context.bind();
 			this.sessionId = context.getSessionId();
 		}
@@ -156,7 +157,7 @@ public class AsynchronousPageStore extends DelegatingPageStore
 		@Override
 		public String toString()
 		{
-			return "Entry [sessionId=" + sessionId + ", pageId=" + page.getPageId() + "]";
+			return "PendingAdd [sessionId=" + sessionId + ", pageId=" + page.getPageId() + "]";
 		}
 
 		/**
@@ -186,7 +187,7 @@ public class AsynchronousPageStore extends DelegatingPageStore
 		}
 
 		/**
-		 * Prevents access to request when called asynchronously.
+		 * Prevents access to the session when called asynchronously.
 		 * <p>
 		 * All values set from {@link IPageStore#canBeAsynchronous(IPageContext)} are kept
 		 * for later retrieval.
@@ -255,27 +256,15 @@ public class AsynchronousPageStore extends DelegatingPageStore
 		}
 
 		/**
-		 * Prevents access to the session when called asynchronously.
-		 * <p>
-		 * Has no effect when session is already bound. 
+		 * Has no effect if already bound.
 		 */
 		@Override
 		public void bind()
 		{
-			if (sessionId != null) {
-				// already bound
-				return;
-			}
-			
-			if (asynchronous) {
-				throw new WicketRuntimeException("no session available asynchronuously");
-			}
-			
-			context.bind();
 		}
 
 		/**
-		 * Get the identifier of the session, maybe <code>null</code> if not bound.
+		 * Returns id of session.
 		 */
 		@Override
 		public String getSessionId()
@@ -323,6 +312,7 @@ public class AsynchronousPageStore extends DelegatingPageStore
 				if (add != null)
 				{
 					log.debug("Saving asynchronously: {}...", add);
+					add.asynchronous = true;					
 					delegate.addPage(add, add.page);
 					addQueue.remove(add.getKey());
 				}
@@ -386,8 +376,6 @@ public class AsynchronousPageStore extends DelegatingPageStore
 	{
 		PendingAdd add = new PendingAdd(context, page);
 		if (getDelegate().canBeAsynchronous(add)) {
-			add.asynchronous = true;
-			
 			String key = add.getKey();
 			queueMap.put(key, add);
 			try
@@ -408,6 +396,8 @@ public class AsynchronousPageStore extends DelegatingPageStore
 				log.error(e.getMessage(), e);
 				queueMap.remove(key);
 			}
+		} else {
+			log.warn("Delegated page store '{}' can not be asynchronous", getDelegate().getClass().getName());
 		}
 		
 		super.addPage(context, page);

http://git-wip-us.apache.org/repos/asf/wicket/blob/fd7b26ba/wicket-core/src/main/java/org/apache/wicket/pageStore/DelegatingPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/DelegatingPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/DelegatingPageStore.java
index 304988a..126509c 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/DelegatingPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/DelegatingPageStore.java
@@ -24,7 +24,7 @@ import org.apache.wicket.util.lang.Args;
  */
 public abstract class DelegatingPageStore implements IPageStore
 {
-	private IPageStore delegate;
+	private final IPageStore delegate;
 	
 	protected DelegatingPageStore(IPageStore delegate) {
 		this.delegate = Args.notNull(delegate, "delegate");

http://git-wip-us.apache.org/repos/asf/wicket/blob/fd7b26ba/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageStore.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageStore.java b/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageStore.java
index 8860b33..80e1215 100644
--- a/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageStore.java
+++ b/wicket-core/src/main/java/org/apache/wicket/pageStore/IPageStore.java
@@ -24,9 +24,12 @@ import org.apache.wicket.page.IManageablePage;
 public interface IPageStore
 {
 	/**
-	 * This method must be called before any attempt to call
-	 * {@link #addPage(IPageContext, IManageablePage)} asynchronously, as done by
-	 * {@link AsynchronousPageStore}.
+	 * This method is called by {@link AsynchronousPageStore} before any attempt to call
+	 * {@link #addPage(IPageContext, IManageablePage)} asynchronously.
+	 * <p>
+	 * A page store returning <code>true</code> must immediately access all required values from the context, 
+	 * since no additional values can be accessed when {@link #addPage(IPageContext, IManageablePage)} is called
+	 * asynchronously afterwards.
 	 * 
 	 * @return whether {@link #addPage(IPageContext, IManageablePage)} may be called asynchronously,
 	 *         default is <code>false</code>

http://git-wip-us.apache.org/repos/asf/wicket/blob/fd7b26ba/wicket-core/src/test/java/org/apache/wicket/pageStore/AsynchronousPageStoreTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/pageStore/AsynchronousPageStoreTest.java b/wicket-core/src/test/java/org/apache/wicket/pageStore/AsynchronousPageStoreTest.java
index 1d09268..cd3ce08 100644
--- a/wicket-core/src/test/java/org/apache/wicket/pageStore/AsynchronousPageStoreTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/pageStore/AsynchronousPageStoreTest.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -29,6 +30,9 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.commons.lang3.RandomUtils;
+import org.apache.wicket.MetaDataKey;
+import org.apache.wicket.MockPage;
+import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.mock.MockPageStore;
 import org.apache.wicket.page.IManageablePage;
 import org.apache.wicket.serialize.ISerializer;
@@ -164,6 +168,7 @@ public class AsynchronousPageStoreTest
 			{
 				try
 				{
+					// wait until the page was get below
 					semaphore.acquire();
 				}
 				catch (InterruptedException e)
@@ -331,6 +336,121 @@ public class AsynchronousPageStoreTest
 		assertTrue(sync > 0);
 	}
 
+	private MetaDataKey<Serializable> KEY1 = new MetaDataKey<Serializable>()
+	{
+	};
+	
+	private MetaDataKey<Serializable> KEY2 = new MetaDataKey<Serializable>()
+	{
+	};
+	
+	/**
+	 * Store does not allow modifications when pages are added asynchronously.
+	 */
+	@Test
+	public void storeAsynchronousContextClosed() throws InterruptedException
+	{
+		IPageStore store = new MockPageStore() {
+			
+			@Override
+			public boolean canBeAsynchronous(IPageContext context)
+			{
+				// can bind and get session id
+				context.bind();
+				context.getSessionId();
+				
+				// can access request data
+				context.getRequestData(KEY1);
+				context.setRequestData(KEY1, "value1");
+
+				// can access session data
+				context.getSessionData(KEY1);
+				context.setSessionData(KEY1, "value1");
+
+				// can access session
+				context.getSessionAttribute("key1");
+				context.setSessionAttribute("key1", "value1");
+
+				return true;
+			}
+			
+			@Override
+			public synchronized void addPage(IPageContext context, IManageablePage page)
+			{
+				// can bind and get session id
+				context.bind();
+				context.getSessionId();
+				
+				// cannot access request
+				try {
+					context.getRequestData(KEY1);
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				try {
+					context.setRequestData(KEY1, "value1");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				try {
+					context.getRequestData(KEY2);
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				try {
+					context.setRequestData(KEY2, "value2");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+
+				// can read session data 
+				context.getSessionData(KEY1);
+				context.getSessionData(KEY2);
+				// .. but cannot set
+				try {
+					context.setSessionData(KEY1, "value1");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				try {
+					context.setSessionData(KEY2, "value2");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				
+				// can read session already read
+				context.getSessionAttribute("key1");
+				// .. but nothing new
+				try {
+					context.getSessionAttribute("key2");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				// .. but cannot set
+				try {
+					context.setSessionAttribute("key1", "value1");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+				try {
+					context.setSessionAttribute("key2", "value2");
+					fail();
+				} catch (WicketRuntimeException expected) {
+				}
+			}
+		};
+
+		IPageStore asyncPageStore = new AsynchronousPageStore(store, 100);
+
+		MockPage page = new MockPage();
+		
+		IPageContext context = new DummyPageContext();
+		
+		asyncPageStore.addPage(context , page);
+		
+		store.destroy();
+	}
+	
 	// test run
 
 	private class Metrics