summaryrefslogtreecommitdiffstats
path: root/server/tests
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2013-03-26 01:41:48 +0200
committerVaadin Code Review <review@vaadin.com>2013-04-03 06:25:29 +0000
commit3cc90e37d8abfa53d127691ae0b7641298d64fa2 (patch)
treece9106505ab71dca5560188c9e20b71fa2a09157 /server/tests
parent4c5c1e0cfeff1c7118ab3fffe4d45e0f1966d470 (diff)
downloadvaadin-framework-3cc90e37d8abfa53d127691ae0b7641298d64fa2.tar.gz
vaadin-framework-3cc90e37d8abfa53d127691ae0b7641298d64fa2.zip
Fixed minimal (empty hashmap) memory leak on redeploy (#9993)
Change-Id: I2b3f83220070f1f46730d956abb24ba9edf02f20
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/src/com/vaadin/util/TestCurrentInstance.java145
1 files changed, 145 insertions, 0 deletions
diff --git a/server/tests/src/com/vaadin/util/TestCurrentInstance.java b/server/tests/src/com/vaadin/util/TestCurrentInstance.java
new file mode 100644
index 0000000000..da986abe31
--- /dev/null
+++ b/server/tests/src/com/vaadin/util/TestCurrentInstance.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2013 Vaadin Ltd.
+ *
+ * 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.
+ */
+package com.vaadin.util;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class TestCurrentInstance {
+
+ @Test
+ public void testInitiallyCleared() throws Exception {
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedAfterRemove() throws Exception {
+ CurrentInstance.set(TestCurrentInstance.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ CurrentInstance.set(TestCurrentInstance.class, null);
+
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedAfterRemoveInheritable() throws Exception {
+ CurrentInstance.setInheritable(TestCurrentInstance.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ CurrentInstance.setInheritable(TestCurrentInstance.class, null);
+
+ assertCleared();
+ }
+
+ @Test
+ public void testInheritableThreadLocal() throws Exception {
+ final AtomicBoolean threadFailed = new AtomicBoolean(true);
+
+ CurrentInstance.setInheritable(TestCurrentInstance.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ Assert.assertEquals(TestCurrentInstance.this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ threadFailed.set(false);
+ };
+ };
+ t.start();
+ CurrentInstance.set(TestCurrentInstance.class, null);
+
+ assertCleared();
+ while (t.isAlive()) {
+ Thread.sleep(1000);
+ }
+ Assert.assertFalse("Thread failed", threadFailed.get());
+
+ }
+
+ @Test
+ public void testClearedAfterRemoveInSeparateThread() throws Exception {
+ final AtomicBoolean threadFailed = new AtomicBoolean(true);
+
+ CurrentInstance.setInheritable(TestCurrentInstance.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ Assert.assertEquals(TestCurrentInstance.this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ CurrentInstance.set(TestCurrentInstance.class, null);
+ assertCleared();
+
+ threadFailed.set(false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ };
+ };
+ t.start();
+
+ while (t.isAlive()) {
+ Thread.sleep(1000);
+ }
+ Assert.assertFalse("Thread failed", threadFailed.get());
+
+ // Clearing the threadlocal in the thread should not have cleared it
+ // here
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+
+ // Clearing the only remaining threadlocal should free all memory
+ CurrentInstance.set(TestCurrentInstance.class, null);
+ assertCleared();
+ }
+
+ @Test
+ public void testClearedWithClearAll() throws Exception {
+ CurrentInstance.set(TestCurrentInstance.class, this);
+ Assert.assertEquals(this,
+ CurrentInstance.get(TestCurrentInstance.class));
+ CurrentInstance.clearAll();
+
+ assertCleared();
+ }
+
+ private void assertCleared() throws SecurityException,
+ NoSuchFieldException, IllegalAccessException {
+ Assert.assertNull(getInternalCurrentInstanceVariable().get());
+ }
+
+ private InheritableThreadLocal<Map<Class<?>, CurrentInstance>> getInternalCurrentInstanceVariable()
+ throws SecurityException, NoSuchFieldException,
+ IllegalAccessException {
+ Field f = CurrentInstance.class.getDeclaredField("instances");
+ f.setAccessible(true);
+ return (InheritableThreadLocal<Map<Class<?>, CurrentInstance>>) f
+ .get(null);
+ }
+
+ public void testInheritedClearedAfterRemove() {
+
+ }
+}