This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new a054f4f  Refactor tests to reduce running time when using multiple 
threads
a054f4f is described below

commit a054f4fe290538fc8015dab79c000404b5371e7c
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Dec 6 11:54:52 2021 +0000

    Refactor tests to reduce running time when using multiple threads
    
    Splits up long running tests into multiple tests to improve concurrency
    towards the end of the test run where a small number of long running
    tests were dominating the test execution time. Generally, the more
    threads the test use, the more pronounced this effect.
---
 .../el/TestImportHandlerStandardPackages.java      |   2 +-
 ...tDoHead.java => HttpServletDoHeadBaseTest.java} |  37 +-
 .../http/TestHttpServletDoHeadValidWrite0.java     |  50 +++
 .../http/TestHttpServletDoHeadValidWrite1.java     |  50 +++
 .../http/TestHttpServletDoHeadValidWrite1023.java  |  50 +++
 .../http/TestHttpServletDoHeadValidWrite1024.java  |  50 +++
 .../http/TestHttpServletDoHeadValidWrite1025.java  |  50 +++
 .../http/TestHttpServletDoHeadValidWrite511.java   |  50 +++
 .../http/TestHttpServletDoHeadValidWrite512.java   |  50 +++
 .../http/TestHttpServletDoHeadValidWrite513.java   |  50 +++
 ...java => TestWebdavServletOptionCollection.java} |  15 +-
 ...ions.java => TestWebdavServletOptionsFile.java} |  15 +-
 ...s.java => TestWebdavServletOptionsUnknown.java} |  15 +-
 .../tomcat/websocket/TestWsWebSocketContainer.java | 372 +--------------------
 ...WsWebSocketContainerSessionExpiryContainer.java |  96 ++++++
 ...stWsWebSocketContainerSessionExpirySession.java | 100 ++++++
 .../TestWsWebSocketContainerTimeoutClient.java     | 123 +++++++
 .../TestWsWebSocketContainerTimeoutServer.java     | 201 +++++++++++
 .../websocket/WsWebSocketContainerBaseTest.java    |  48 +++
 19 files changed, 1002 insertions(+), 422 deletions(-)

diff --git a/test/javax/el/TestImportHandlerStandardPackages.java 
b/test/javax/el/TestImportHandlerStandardPackages.java
index 2f40de8..47332b8 100644
--- a/test/javax/el/TestImportHandlerStandardPackages.java
+++ b/test/javax/el/TestImportHandlerStandardPackages.java
@@ -113,7 +113,7 @@ public class TestImportHandlerStandardPackages {
                         // Skip non-class resources
                         continue;
                     }
-                    if (file.startsWith("Test")) {
+                    if (file.startsWith("Test") || 
file.endsWith("BaseTest.class")) {
                         // Skip test resources
                         continue;
                     }
diff --git a/test/javax/servlet/http/TestHttpServletDoHead.java 
b/test/javax/servlet/http/HttpServletDoHeadBaseTest.java
similarity index 84%
rename from test/javax/servlet/http/TestHttpServletDoHead.java
rename to test/javax/servlet/http/HttpServletDoHeadBaseTest.java
index 74bff5d..b93b749 100644
--- a/test/javax/servlet/http/TestHttpServletDoHead.java
+++ b/test/javax/servlet/http/HttpServletDoHeadBaseTest.java
@@ -20,8 +20,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,8 +28,6 @@ import javax.servlet.ServletException;
 
 import org.junit.Assert;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameter;
 
 import org.apache.catalina.core.StandardContext;
@@ -40,8 +36,11 @@ import org.apache.catalina.startup.TomcatBaseTest;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap;
 
-@RunWith(Parameterized.class)
-public class TestHttpServletDoHead extends TomcatBaseTest {
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+public class HttpServletDoHeadBaseTest extends TomcatBaseTest {
 
     // Tomcat has a minimum output buffer size of 8 * 1024.
     // (8 * 1024) /16 = 512
@@ -49,32 +48,12 @@ public class TestHttpServletDoHead extends TomcatBaseTest {
     private static final String VALID = "** valid data **";
     private static final String INVALID = "* invalid data *";
 
-    private static final Integer BUFFERS[] = new Integer[] { Integer.valueOf 
(16), Integer.valueOf(8 * 1024), Integer.valueOf(16 * 1024) };
+    protected static final Integer BUFFERS[] = new Integer[] { Integer.valueOf 
(16), Integer.valueOf(8 * 1024), Integer.valueOf(16 * 1024) };
 
-    private static final Integer COUNTS[] = new Integer[] { 
Integer.valueOf(0), Integer.valueOf(1),
+    protected static final Integer COUNTS[] = new Integer[] { 
Integer.valueOf(0), Integer.valueOf(1),
             Integer.valueOf(511), Integer.valueOf(512), Integer.valueOf(513),
             Integer.valueOf(1023), Integer.valueOf(1024), 
Integer.valueOf(1025) };
 
-    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
-    public static Collection<Object[]> parameters() {
-
-        List<Object[]> parameterSets = new ArrayList<>();
-        for (Integer buf : BUFFERS) {
-            for (Boolean w : booleans) {
-                for (Integer c1 : COUNTS) {
-                    for (ResetType rt : ResetType.values()) {
-                        for (Integer c2 : COUNTS) {
-                            for (Boolean f : booleans) {
-                                parameterSets.add(new Object[] { buf, w, c1, 
rt, c2, f });
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return parameterSets;
-    }
-
     @Parameter(0)
     public int bufferSize;
     @Parameter(1)
@@ -214,7 +193,7 @@ public class TestHttpServletDoHead extends TomcatBaseTest {
     }
 
 
-    private static enum ResetType {
+    static enum ResetType {
         NONE,
         BUFFER,
         FULL
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite0.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite0.java
new file mode 100644
index 0000000..355b52c
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite0.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite0 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(0), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1.java
new file mode 100644
index 0000000..73ee6c5
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite1 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(1), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1023.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1023.java
new file mode 100644
index 0000000..a261ee2
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1023.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite1023 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(1023), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1024.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1024.java
new file mode 100644
index 0000000..2679c03
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1024.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite1024 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(1024), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1025.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1025.java
new file mode 100644
index 0000000..286cab2
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite1025.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite1025 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(1025), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite511.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite511.java
new file mode 100644
index 0000000..4601291
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite511.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite511 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(511), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite512.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite512.java
new file mode 100644
index 0000000..d314546
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite512.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite512 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(512), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/javax/servlet/http/TestHttpServletDoHeadValidWrite513.java 
b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite513.java
new file mode 100644
index 0000000..c512bb7
--- /dev/null
+++ b/test/javax/servlet/http/TestHttpServletDoHeadValidWrite513.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 javax.servlet.http;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
+@RunWith(Parameterized.class)
+public class TestHttpServletDoHeadValidWrite513 extends 
HttpServletDoHeadBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: {0} {1} {2} {3} {4} {5}")
+    public static Collection<Object[]> parameters() {
+
+        List<Object[]> parameterSets = new ArrayList<>();
+        for (Integer buf : BUFFERS) {
+            for (Boolean w : booleans) {
+                for (Integer c1 : COUNTS) {
+                    for (ResetType rt : ResetType.values()) {
+                        for (Boolean f : booleans) {
+                            parameterSets.add(new Object[] { buf, w, c1, rt, 
Integer.valueOf(513), f });
+                        }
+                    }
+                }
+            }
+        }
+        return parameterSets;
+    }
+}
diff --git a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java 
b/test/org/apache/catalina/servlets/TestWebdavServletOptionCollection.java
similarity index 80%
copy from test/org/apache/catalina/servlets/TestWebdavServletOptions.java
copy to test/org/apache/catalina/servlets/TestWebdavServletOptionCollection.java
index 2ccbbb9..5a8324f 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServletOptionCollection.java
@@ -26,12 +26,15 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
 @RunWith(Parameterized.class)
-public class TestWebdavServletOptions extends ServletOptionsBaseTest {
+public class TestWebdavServletOptionCollection extends ServletOptionsBaseTest {
 
     @Parameters
     public static Collection<Object[]> inputs() {
-        String[] urls = new String[] { COLLECTION_NAME, FILE_NAME, 
UNKNOWN_NAME };
         String[] methods = new String[] { "GET", "POST", "HEAD", "TRACE", 
"PUT", "DELETE",
                 "MKCOL", "LOCK", "UNLOCK", "COPY", "MOVE", "PROPFIND", 
"PROPPATCH" };
 
@@ -40,11 +43,9 @@ public class TestWebdavServletOptions extends 
ServletOptionsBaseTest {
         for (Boolean listingsValue : booleans) {
             for (Boolean readOnlyValue : booleans) {
                 for (Boolean traceValue : booleans) {
-                    for (String url : urls) {
-                        for (String method : methods) {
-                            result.add(new Object[] {
-                                    listingsValue, readOnlyValue, traceValue, 
url, method } );
-                        }
+                    for (String method : methods) {
+                        result.add(new Object[] {
+                                listingsValue, readOnlyValue, traceValue, 
COLLECTION_NAME, method } );
                     }
                 }
             }
diff --git a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java 
b/test/org/apache/catalina/servlets/TestWebdavServletOptionsFile.java
similarity index 80%
copy from test/org/apache/catalina/servlets/TestWebdavServletOptions.java
copy to test/org/apache/catalina/servlets/TestWebdavServletOptionsFile.java
index 2ccbbb9..aedcb16 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServletOptionsFile.java
@@ -26,12 +26,15 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
 @RunWith(Parameterized.class)
-public class TestWebdavServletOptions extends ServletOptionsBaseTest {
+public class TestWebdavServletOptionsFile extends ServletOptionsBaseTest {
 
     @Parameters
     public static Collection<Object[]> inputs() {
-        String[] urls = new String[] { COLLECTION_NAME, FILE_NAME, 
UNKNOWN_NAME };
         String[] methods = new String[] { "GET", "POST", "HEAD", "TRACE", 
"PUT", "DELETE",
                 "MKCOL", "LOCK", "UNLOCK", "COPY", "MOVE", "PROPFIND", 
"PROPPATCH" };
 
@@ -40,11 +43,9 @@ public class TestWebdavServletOptions extends 
ServletOptionsBaseTest {
         for (Boolean listingsValue : booleans) {
             for (Boolean readOnlyValue : booleans) {
                 for (Boolean traceValue : booleans) {
-                    for (String url : urls) {
-                        for (String method : methods) {
-                            result.add(new Object[] {
-                                    listingsValue, readOnlyValue, traceValue, 
url, method } );
-                        }
+                    for (String method : methods) {
+                        result.add(new Object[] {
+                                listingsValue, readOnlyValue, traceValue, 
FILE_NAME, method } );
                     }
                 }
             }
diff --git a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java 
b/test/org/apache/catalina/servlets/TestWebdavServletOptionsUnknown.java
similarity index 80%
rename from test/org/apache/catalina/servlets/TestWebdavServletOptions.java
rename to test/org/apache/catalina/servlets/TestWebdavServletOptionsUnknown.java
index 2ccbbb9..e5457a6 100644
--- a/test/org/apache/catalina/servlets/TestWebdavServletOptions.java
+++ b/test/org/apache/catalina/servlets/TestWebdavServletOptionsUnknown.java
@@ -26,12 +26,15 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
+/*
+ * Split into multiple tests as a single test takes so long it impacts the time
+ * of an entire test run.
+ */
 @RunWith(Parameterized.class)
-public class TestWebdavServletOptions extends ServletOptionsBaseTest {
+public class TestWebdavServletOptionsUnknown extends ServletOptionsBaseTest {
 
     @Parameters
     public static Collection<Object[]> inputs() {
-        String[] urls = new String[] { COLLECTION_NAME, FILE_NAME, 
UNKNOWN_NAME };
         String[] methods = new String[] { "GET", "POST", "HEAD", "TRACE", 
"PUT", "DELETE",
                 "MKCOL", "LOCK", "UNLOCK", "COPY", "MOVE", "PROPFIND", 
"PROPPATCH" };
 
@@ -40,11 +43,9 @@ public class TestWebdavServletOptions extends 
ServletOptionsBaseTest {
         for (Boolean listingsValue : booleans) {
             for (Boolean readOnlyValue : booleans) {
                 for (Boolean traceValue : booleans) {
-                    for (String url : urls) {
-                        for (String method : methods) {
-                            result.add(new Object[] {
-                                    listingsValue, readOnlyValue, traceValue, 
url, method } );
-                        }
+                    for (String method : methods) {
+                        result.add(new Object[] {
+                                listingsValue, readOnlyValue, traceValue, 
UNKNOWN_NAME, method } );
                     }
                 }
             }
diff --git a/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java
index 7fa452a..0a2240d 100644
--- a/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java
+++ b/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java
@@ -20,7 +20,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.SocketTimeoutException;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.security.KeyStore;
@@ -29,8 +28,6 @@ import java.util.List;
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 import javax.net.ssl.SSLContext;
@@ -48,7 +45,6 @@ import javax.websocket.Session;
 import javax.websocket.WebSocketContainer;
 import javax.websocket.server.ServerContainer;
 import javax.websocket.server.ServerEndpoint;
-import javax.websocket.server.ServerEndpointConfig;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -64,15 +60,11 @@ import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterEndpoint;
 import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint;
 import org.apache.tomcat.websocket.server.WsContextListener;
 
-public class TestWsWebSocketContainer extends WebSocketBaseTest {
+public class TestWsWebSocketContainer extends WsWebSocketContainerBaseTest {
 
     private static final String MESSAGE_EMPTY = "";
     private static final String MESSAGE_STRING_1 = "qwerty";
     private static final String MESSAGE_TEXT_4K;
-    private static final byte[] MESSAGE_BINARY_4K = new byte[4096];
-
-    private static final long TIMEOUT_MS = 5 * 1000;
-    private static final long MARGIN = 500;
 
     // 5s should be plenty but Gump can be a lot slower
     private static final long START_STOP_WAIT = 60 * 1000;
@@ -303,159 +295,6 @@ public class TestWsWebSocketContainer extends 
WebSocketBaseTest {
     }
 
 
-    @Test
-    public void testWriteTimeoutClientContainer() throws Exception {
-        doTestWriteTimeoutClient(true);
-    }
-
-
-    @Test
-    public void testWriteTimeoutClientEndpoint() throws Exception {
-        doTestWriteTimeoutClient(false);
-    }
-
-
-    private void doTestWriteTimeoutClient(boolean setTimeoutOnContainer)
-            throws Exception {
-
-        Tomcat tomcat = getTomcatInstance();
-        // No file system docBase required
-        Context ctx = tomcat.addContext("", null);
-        ctx.addApplicationListener(BlockingConfig.class.getName());
-        Tomcat.addServlet(ctx, "default", new DefaultServlet());
-        ctx.addServletMappingDecoded("/", "default");
-
-        WebSocketContainer wsContainer =
-                ContainerProvider.getWebSocketContainer();
-
-        // Set the async timeout
-        if (setTimeoutOnContainer) {
-            wsContainer.setAsyncSendTimeout(TIMEOUT_MS);
-        }
-
-        tomcat.start();
-
-        Session wsSession = wsContainer.connectToServer(
-                TesterProgrammaticEndpoint.class,
-                ClientEndpointConfig.Builder.create().build(),
-                new URI("ws://" + getHostName() + ":" + getPort() + 
BlockingConfig.PATH));
-
-        if (!setTimeoutOnContainer) {
-            wsSession.getAsyncRemote().setSendTimeout(TIMEOUT_MS);
-        }
-
-        long lastSend = 0;
-
-        // Should send quickly until the network buffers fill up and then block
-        // until the timeout kicks in
-        Exception exception = null;
-        try {
-            while (true) {
-                lastSend = System.currentTimeMillis();
-                Future<Void> f = wsSession.getAsyncRemote().sendBinary(
-                        ByteBuffer.wrap(MESSAGE_BINARY_4K));
-                f.get();
-            }
-        } catch (Exception e) {
-            exception = e;
-        }
-
-        long timeout = System.currentTimeMillis() - lastSend;
-
-        // Clear the server side block and prevent further blocks to allow the
-        // server to shutdown cleanly
-        BlockingPojo.clearBlock();
-
-        // Close the client session, primarily to allow the
-        // BackgroundProcessManager to shut down.
-        wsSession.close();
-
-        String msg = "Time out was [" + timeout + "] ms";
-
-        // Check correct time passed
-        Assert.assertTrue(msg, timeout >= TIMEOUT_MS - MARGIN );
-
-        // Check the timeout wasn't too long
-        Assert.assertTrue(msg, timeout < TIMEOUT_MS * 2);
-
-        Assert.assertNotNull(exception);
-    }
-
-
-    @Test
-    public void testWriteTimeoutServerContainer() throws Exception {
-        doTestWriteTimeoutServer(true);
-    }
-
-
-    @Test
-    public void testWriteTimeoutServerEndpoint() throws Exception {
-        doTestWriteTimeoutServer(false);
-    }
-
-
-    private static volatile boolean timeoutOnContainer = false;
-
-    private void doTestWriteTimeoutServer(boolean setTimeoutOnContainer)
-            throws Exception {
-
-        /*
-         * Note: There are all sorts of horrible uses of statics in this test
-         *       because the API uses classes and the tests really need access
-         *       to the instances which simply isn't possible.
-         */
-        timeoutOnContainer = setTimeoutOnContainer;
-
-        Tomcat tomcat = getTomcatInstance();
-
-        // No file system docBase required
-        Context ctx = tomcat.addContext("", null);
-        ctx.addApplicationListener(ConstantTxConfig.class.getName());
-        Tomcat.addServlet(ctx, "default", new DefaultServlet());
-        ctx.addServletMappingDecoded("/", "default");
-
-        WebSocketContainer wsContainer =
-                ContainerProvider.getWebSocketContainer();
-
-        tomcat.start();
-
-        Session wsSession = wsContainer.connectToServer(
-                TesterProgrammaticEndpoint.class,
-                ClientEndpointConfig.Builder.create().build(),
-                new URI("ws://" + getHostName() + ":" + getPort() +
-                        ConstantTxConfig.PATH));
-
-        wsSession.addMessageHandler(new BlockingBinaryHandler());
-
-        int loops = 0;
-        while (loops < 15) {
-            Thread.sleep(1000);
-            if (!ConstantTxEndpoint.getRunning()) {
-                break;
-            }
-            loops++;
-        }
-
-        // Close the client session, primarily to allow the
-        // BackgroundProcessManager to shut down.
-        wsSession.close();
-
-        // Check the right exception was thrown
-        Assert.assertNotNull(ConstantTxEndpoint.getException());
-        Assert.assertEquals(ExecutionException.class,
-                ConstantTxEndpoint.getException().getClass());
-        Assert.assertNotNull(ConstantTxEndpoint.getException().getCause());
-        Assert.assertEquals(SocketTimeoutException.class,
-                ConstantTxEndpoint.getException().getCause().getClass());
-
-        // Check correct time passed
-        Assert.assertTrue(ConstantTxEndpoint.getTimeout() >= TIMEOUT_MS);
-
-        // Check the timeout wasn't too long
-        Assert.assertTrue(ConstantTxEndpoint.getTimeout() < TIMEOUT_MS*2);
-    }
-
-
     public static class BlockingConfig extends WsContextListener {
 
         public static final String PATH = "/block";
@@ -545,81 +384,6 @@ public class TestWsWebSocketContainer extends 
WebSocketBaseTest {
     }
 
 
-    public static class ConstantTxEndpoint extends Endpoint {
-
-        // Have to be static to be able to retrieve results from test case
-        private static volatile long timeout = -1;
-        private static volatile Exception exception = null;
-        private static volatile boolean running = true;
-
-
-        @Override
-        public void onOpen(Session session, EndpointConfig config) {
-
-            // Reset everything
-            timeout = -1;
-            exception = null;
-            running = true;
-
-            if (!TestWsWebSocketContainer.timeoutOnContainer) {
-                session.getAsyncRemote().setSendTimeout(TIMEOUT_MS);
-            }
-
-            long lastSend = 0;
-
-            // Should send quickly until the network buffers fill up and then
-            // block until the timeout kicks in
-            try {
-                while (true) {
-                    lastSend = System.currentTimeMillis();
-                    Future<Void> f = session.getAsyncRemote().sendBinary(
-                            ByteBuffer.wrap(MESSAGE_BINARY_4K));
-                    f.get();
-                }
-            } catch (ExecutionException | InterruptedException e) {
-                exception = e;
-            }
-            timeout = System.currentTimeMillis() - lastSend;
-            running = false;
-        }
-
-        public static long getTimeout() {
-            return timeout;
-        }
-
-        public static Exception getException() {
-            return exception;
-        }
-
-        public static boolean getRunning() {
-            return running;
-        }
-    }
-
-
-    public static class ConstantTxConfig extends WsContextListener {
-
-        private static final String PATH = "/test";
-
-        @Override
-        public void contextInitialized(ServletContextEvent sce) {
-            super.contextInitialized(sce);
-            ServerContainer sc =
-                    (ServerContainer) sce.getServletContext().getAttribute(
-                            
org.apache.tomcat.websocket.server.Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
-            try {
-                sc.addEndpoint(ServerEndpointConfig.Builder.create(
-                        ConstantTxEndpoint.class, PATH).build());
-                if (TestWsWebSocketContainer.timeoutOnContainer) {
-                    sc.setAsyncSendTimeout(TIMEOUT_MS);
-                }
-            } catch (DeploymentException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-    }
-
-
     @Test
     public void testGetOpenSessions() throws Exception {
         Tomcat tomcat = getTomcatInstance();
@@ -677,115 +441,6 @@ public class TestWsWebSocketContainer extends 
WebSocketBaseTest {
 
 
     @Test
-    public void testSessionExpiryContainer() throws Exception {
-
-        Tomcat tomcat = getTomcatInstance();
-        // No file system docBase required
-        Context ctx = tomcat.addContext("", null);
-        ctx.addApplicationListener(TesterEchoServer.Config.class.getName());
-        Tomcat.addServlet(ctx, "default", new DefaultServlet());
-        ctx.addServletMappingDecoded("/", "default");
-
-        tomcat.start();
-
-        // Need access to implementation methods for configuring unit tests
-        WsWebSocketContainer wsContainer = (WsWebSocketContainer)
-                ContainerProvider.getWebSocketContainer();
-
-        // 5 second timeout
-        wsContainer.setDefaultMaxSessionIdleTimeout(5000);
-        wsContainer.setProcessPeriod(1);
-
-        EndpointA endpointA = new EndpointA();
-        connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-        connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-        Session s3a = connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-
-        // Check all three sessions are open
-        Set<Session> setA = s3a.getOpenSessions();
-        Assert.assertEquals(3, setA.size());
-
-        int count = 0;
-        boolean isOpen = true;
-        while (isOpen && count < 8) {
-            count ++;
-            Thread.sleep(1000);
-            isOpen = false;
-            for (Session session : setA) {
-                if (session.isOpen()) {
-                    isOpen = true;
-                    break;
-                }
-            }
-        }
-
-        if (isOpen) {
-            for (Session session : setA) {
-                if (session.isOpen()) {
-                    System.err.println("Session with ID [" + session.getId() +
-                            "] is open");
-                }
-            }
-            Assert.fail("There were open sessions");
-        }
-    }
-
-
-    @Test
-    public void testSessionExpirySession() throws Exception {
-
-        Tomcat tomcat = getTomcatInstance();
-        // No file system docBase required
-        Context ctx = tomcat.addContext("", null);
-        ctx.addApplicationListener(TesterEchoServer.Config.class.getName());
-        Tomcat.addServlet(ctx, "default", new DefaultServlet());
-        ctx.addServletMappingDecoded("/", "default");
-
-        tomcat.start();
-
-        // Need access to implementation methods for configuring unit tests
-        WsWebSocketContainer wsContainer = (WsWebSocketContainer)
-                ContainerProvider.getWebSocketContainer();
-
-        // 5 second timeout
-        wsContainer.setDefaultMaxSessionIdleTimeout(5000);
-        wsContainer.setProcessPeriod(1);
-
-        EndpointA endpointA = new EndpointA();
-        Session s1a = connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-        s1a.setMaxIdleTimeout(3000);
-        Session s2a = connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-        s2a.setMaxIdleTimeout(6000);
-        Session s3a = connectToEchoServer(wsContainer, endpointA,
-                TesterEchoServer.Config.PATH_BASIC);
-        s3a.setMaxIdleTimeout(9000);
-
-        // Check all three sessions are open
-        Set<Session> setA = s3a.getOpenSessions();
-
-        int expected = 3;
-        while (expected > 0) {
-            Assert.assertEquals(expected, getOpenCount(setA));
-
-            int count = 0;
-            while (getOpenCount(setA) == expected && count < 50) {
-                count ++;
-                Thread.sleep(100);
-            }
-
-            expected--;
-        }
-
-        Assert.assertEquals(0, getOpenCount(setA));
-    }
-
-
-    @Test
     public void testSessionExpiryOnUserPropertyReadIdleTimeout() throws 
Exception {
         Tomcat tomcat = getTomcatInstance();
         // No file system docBase required
@@ -865,23 +520,6 @@ public class TestWsWebSocketContainer extends 
WebSocketBaseTest {
     }
 
 
-    private int getOpenCount(Set<Session> sessions) {
-        int result = 0;
-        for (Session session : sessions) {
-            if (session.isOpen()) {
-                result++;
-            }
-        }
-        return result;
-    }
-
-    private Session connectToEchoServer(WebSocketContainer wsContainer,
-            Endpoint endpoint, String path) throws Exception {
-        return wsContainer.connectToServer(endpoint,
-                ClientEndpointConfig.Builder.create().build(),
-                new URI("ws://" + getHostName() + ":" + getPort() + path));
-    }
-
     public static final class EndpointA extends Endpoint {
 
         @Override
@@ -1125,12 +763,4 @@ public class TestWsWebSocketContainer extends 
WebSocketBaseTest {
 
         ((WsWebSocketContainer) wsContainer).destroy();
     }
-
-
-    /*
-     * Make this possible to override so sub-class can more easily test proxy
-     */
-    protected String getHostName() {
-        return "localhost";
-    }
 }
diff --git 
a/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpiryContainer.java
 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpiryContainer.java
new file mode 100644
index 0000000..4359856
--- /dev/null
+++ 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpiryContainer.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tomcat.websocket;
+
+import java.util.Set;
+
+import javax.websocket.ContainerProvider;
+import javax.websocket.Session;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.tomcat.websocket.TestWsWebSocketContainer.EndpointA;
+
+/*
+ * Moved to separate test class to improve test concurrency. These tests are
+ * some of the last tests to start and having them all in a single class
+ * significantly extends the length of a test run when using multiple test
+ * threads.
+ */
+public class TestWsWebSocketContainerSessionExpiryContainer  extends 
WsWebSocketContainerBaseTest {
+
+    @Test
+    public void testSessionExpiryContainer() throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+        // No file system docBase required
+        Context ctx = tomcat.addContext("", null);
+        ctx.addApplicationListener(TesterEchoServer.Config.class.getName());
+        Tomcat.addServlet(ctx, "default", new DefaultServlet());
+        ctx.addServletMappingDecoded("/", "default");
+
+        tomcat.start();
+
+        // Need access to implementation methods for configuring unit tests
+        WsWebSocketContainer wsContainer = (WsWebSocketContainer)
+                ContainerProvider.getWebSocketContainer();
+
+        // 5 second timeout
+        wsContainer.setDefaultMaxSessionIdleTimeout(5000);
+        wsContainer.setProcessPeriod(1);
+
+        EndpointA endpointA = new EndpointA();
+        connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+        connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+        Session s3a = connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+
+        // Check all three sessions are open
+        Set<Session> setA = s3a.getOpenSessions();
+        Assert.assertEquals(3, setA.size());
+
+        int count = 0;
+        boolean isOpen = true;
+        while (isOpen && count < 8) {
+            count ++;
+            Thread.sleep(1000);
+            isOpen = false;
+            for (Session session : setA) {
+                if (session.isOpen()) {
+                    isOpen = true;
+                    break;
+                }
+            }
+        }
+
+        if (isOpen) {
+            for (Session session : setA) {
+                if (session.isOpen()) {
+                    System.err.println("Session with ID [" + session.getId() +
+                            "] is open");
+                }
+            }
+            Assert.fail("There were open sessions");
+        }
+    }
+}
diff --git 
a/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpirySession.java
 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpirySession.java
new file mode 100644
index 0000000..d00e063
--- /dev/null
+++ 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSessionExpirySession.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tomcat.websocket;
+
+import java.util.Set;
+
+import javax.websocket.ContainerProvider;
+import javax.websocket.Session;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.tomcat.websocket.TestWsWebSocketContainer.EndpointA;
+
+/*
+ * Moved to separate test class to improve test concurrency. These tests are
+ * some of the last tests to start and having them all in a single class
+ * significantly extends the length of a test run when using multiple test
+ * threads.
+ */
+public class TestWsWebSocketContainerSessionExpirySession  extends 
WsWebSocketContainerBaseTest {
+
+    @Test
+    public void testSessionExpirySession() throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+        // No file system docBase required
+        Context ctx = tomcat.addContext("", null);
+        ctx.addApplicationListener(TesterEchoServer.Config.class.getName());
+        Tomcat.addServlet(ctx, "default", new DefaultServlet());
+        ctx.addServletMappingDecoded("/", "default");
+
+        tomcat.start();
+
+        // Need access to implementation methods for configuring unit tests
+        WsWebSocketContainer wsContainer = (WsWebSocketContainer)
+                ContainerProvider.getWebSocketContainer();
+
+        // 5 second timeout
+        wsContainer.setDefaultMaxSessionIdleTimeout(5000);
+        wsContainer.setProcessPeriod(1);
+
+        EndpointA endpointA = new EndpointA();
+        Session s1a = connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+        s1a.setMaxIdleTimeout(3000);
+        Session s2a = connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+        s2a.setMaxIdleTimeout(6000);
+        Session s3a = connectToEchoServer(wsContainer, endpointA,
+                TesterEchoServer.Config.PATH_BASIC);
+        s3a.setMaxIdleTimeout(9000);
+
+        // Check all three sessions are open
+        Set<Session> setA = s3a.getOpenSessions();
+
+        int expected = 3;
+        while (expected > 0) {
+            Assert.assertEquals(expected, getOpenCount(setA));
+
+            int count = 0;
+            while (getOpenCount(setA) == expected && count < 50) {
+                count ++;
+                Thread.sleep(100);
+            }
+
+            expected--;
+        }
+
+        Assert.assertEquals(0, getOpenCount(setA));
+    }
+
+
+    private int getOpenCount(Set<Session> sessions) {
+        int result = 0;
+        for (Session session : sessions) {
+            if (session.isOpen()) {
+                result++;
+            }
+        }
+        return result;
+    }
+}
diff --git 
a/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutClient.java 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutClient.java
new file mode 100644
index 0000000..69e449d
--- /dev/null
+++ 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutClient.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tomcat.websocket;
+
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Future;
+
+import javax.websocket.ClientEndpointConfig;
+import javax.websocket.ContainerProvider;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.tomcat.websocket.TestWsWebSocketContainer.BlockingConfig;
+import org.apache.tomcat.websocket.TestWsWebSocketContainer.BlockingPojo;
+import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint;
+
+/*
+ * Moved to separate test class to improve test concurrency. These tests are
+ * some of the last tests to start and having them all in a single class
+ * significantly extends the length of a test run when using multiple test
+ * threads.
+ */
+public class TestWsWebSocketContainerTimeoutClient  extends 
WsWebSocketContainerBaseTest {
+
+    @Test
+    public void testWriteTimeoutClientContainer() throws Exception {
+        doTestWriteTimeoutClient(true);
+    }
+
+
+    @Test
+    public void testWriteTimeoutClientEndpoint() throws Exception {
+        doTestWriteTimeoutClient(false);
+    }
+
+
+    private void doTestWriteTimeoutClient(boolean setTimeoutOnContainer)
+            throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+        // No file system docBase required
+        Context ctx = tomcat.addContext("", null);
+        ctx.addApplicationListener(BlockingConfig.class.getName());
+        Tomcat.addServlet(ctx, "default", new DefaultServlet());
+        ctx.addServletMappingDecoded("/", "default");
+
+        WebSocketContainer wsContainer =
+                ContainerProvider.getWebSocketContainer();
+
+        // Set the async timeout
+        if (setTimeoutOnContainer) {
+            wsContainer.setAsyncSendTimeout(TIMEOUT_MS);
+        }
+
+        tomcat.start();
+
+        Session wsSession = wsContainer.connectToServer(
+                TesterProgrammaticEndpoint.class,
+                ClientEndpointConfig.Builder.create().build(),
+                new URI("ws://" + getHostName() + ":" + getPort() + 
BlockingConfig.PATH));
+
+        if (!setTimeoutOnContainer) {
+            wsSession.getAsyncRemote().setSendTimeout(TIMEOUT_MS);
+        }
+
+        long lastSend = 0;
+
+        // Should send quickly until the network buffers fill up and then block
+        // until the timeout kicks in
+        Exception exception = null;
+        try {
+            while (true) {
+                lastSend = System.currentTimeMillis();
+                Future<Void> f = wsSession.getAsyncRemote().sendBinary(
+                        ByteBuffer.wrap(MESSAGE_BINARY_4K));
+                f.get();
+            }
+        } catch (Exception e) {
+            exception = e;
+        }
+
+        long timeout = System.currentTimeMillis() - lastSend;
+
+        // Clear the server side block and prevent further blocks to allow the
+        // server to shutdown cleanly
+        BlockingPojo.clearBlock();
+
+        // Close the client session, primarily to allow the
+        // BackgroundProcessManager to shut down.
+        wsSession.close();
+
+        String msg = "Time out was [" + timeout + "] ms";
+
+        // Check correct time passed
+        Assert.assertTrue(msg, timeout >= TIMEOUT_MS - MARGIN );
+
+        // Check the timeout wasn't too long
+        Assert.assertTrue(msg, timeout < TIMEOUT_MS * 2);
+
+        Assert.assertNotNull(exception);
+    }
+}
diff --git 
a/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutServer.java 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutServer.java
new file mode 100644
index 0000000..5213099
--- /dev/null
+++ 
b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerTimeoutServer.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tomcat.websocket;
+
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import javax.servlet.ServletContextEvent;
+import javax.websocket.ClientEndpointConfig;
+import javax.websocket.ContainerProvider;
+import javax.websocket.DeploymentException;
+import javax.websocket.Endpoint;
+import javax.websocket.EndpointConfig;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+import javax.websocket.server.ServerContainer;
+import javax.websocket.server.ServerEndpointConfig;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.servlets.DefaultServlet;
+import org.apache.catalina.startup.Tomcat;
+import 
org.apache.tomcat.websocket.TestWsWebSocketContainer.BlockingBinaryHandler;
+import 
org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint;
+import org.apache.tomcat.websocket.server.WsContextListener;
+
+/*
+ * Moved to separate test class to improve test concurrency. These tests are
+ * some of the last tests to start and having them all in a single class
+ * significantly extends the length of a test run when using multiple test
+ * threads.
+ */
+public class TestWsWebSocketContainerTimeoutServer  extends 
WsWebSocketContainerBaseTest {
+
+    @Test
+    public void testWriteTimeoutServerContainer() throws Exception {
+        doTestWriteTimeoutServer(true);
+    }
+
+
+    @Test
+    public void testWriteTimeoutServerEndpoint() throws Exception {
+        doTestWriteTimeoutServer(false);
+    }
+
+
+    private static volatile boolean timeoutOnContainer = false;
+
+    private void doTestWriteTimeoutServer(boolean setTimeoutOnContainer)
+            throws Exception {
+
+        /*
+         * Note: There are all sorts of horrible uses of statics in this test
+         *       because the API uses classes and the tests really need access
+         *       to the instances which simply isn't possible.
+         */
+        timeoutOnContainer = setTimeoutOnContainer;
+
+        Tomcat tomcat = getTomcatInstance();
+
+        // No file system docBase required
+        Context ctx = tomcat.addContext("", null);
+        ctx.addApplicationListener(ConstantTxConfig.class.getName());
+        Tomcat.addServlet(ctx, "default", new DefaultServlet());
+        ctx.addServletMappingDecoded("/", "default");
+
+        WebSocketContainer wsContainer =
+                ContainerProvider.getWebSocketContainer();
+
+        tomcat.start();
+
+        Session wsSession = wsContainer.connectToServer(
+                TesterProgrammaticEndpoint.class,
+                ClientEndpointConfig.Builder.create().build(),
+                new URI("ws://" + getHostName() + ":" + getPort() +
+                        ConstantTxConfig.PATH));
+
+        wsSession.addMessageHandler(new BlockingBinaryHandler());
+
+        int loops = 0;
+        while (loops < 15) {
+            Thread.sleep(1000);
+            if (!ConstantTxEndpoint.getRunning()) {
+                break;
+            }
+            loops++;
+        }
+
+        // Close the client session, primarily to allow the
+        // BackgroundProcessManager to shut down.
+        wsSession.close();
+
+        // Check the right exception was thrown
+        Assert.assertNotNull(ConstantTxEndpoint.getException());
+        Assert.assertEquals(ExecutionException.class,
+                ConstantTxEndpoint.getException().getClass());
+        Assert.assertNotNull(ConstantTxEndpoint.getException().getCause());
+        Assert.assertEquals(SocketTimeoutException.class,
+                ConstantTxEndpoint.getException().getCause().getClass());
+
+        // Check correct time passed
+        Assert.assertTrue(ConstantTxEndpoint.getTimeout() >= TIMEOUT_MS);
+
+        // Check the timeout wasn't too long
+        Assert.assertTrue(ConstantTxEndpoint.getTimeout() < TIMEOUT_MS*2);
+    }
+
+
+    public static class ConstantTxConfig extends WsContextListener {
+
+        private static final String PATH = "/test";
+
+        @Override
+        public void contextInitialized(ServletContextEvent sce) {
+            super.contextInitialized(sce);
+            ServerContainer sc =
+                    (ServerContainer) sce.getServletContext().getAttribute(
+                            
org.apache.tomcat.websocket.server.Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
+            try {
+                sc.addEndpoint(ServerEndpointConfig.Builder.create(
+                        ConstantTxEndpoint.class, PATH).build());
+                if (timeoutOnContainer) {
+                    sc.setAsyncSendTimeout(TIMEOUT_MS);
+                }
+            } catch (DeploymentException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+
+
+    public static class ConstantTxEndpoint extends Endpoint {
+
+        // Have to be static to be able to retrieve results from test case
+        private static volatile long timeout = -1;
+        private static volatile Exception exception = null;
+        private static volatile boolean running = true;
+
+
+        @Override
+        public void onOpen(Session session, EndpointConfig config) {
+
+            // Reset everything
+            timeout = -1;
+            exception = null;
+            running = true;
+
+            if (!timeoutOnContainer) {
+                session.getAsyncRemote().setSendTimeout(TIMEOUT_MS);
+            }
+
+            long lastSend = 0;
+
+            // Should send quickly until the network buffers fill up and then
+            // block until the timeout kicks in
+            try {
+                while (true) {
+                    lastSend = System.currentTimeMillis();
+                    Future<Void> f = session.getAsyncRemote().sendBinary(
+                            ByteBuffer.wrap(MESSAGE_BINARY_4K));
+                    f.get();
+                }
+            } catch (ExecutionException | InterruptedException e) {
+                exception = e;
+            }
+            timeout = System.currentTimeMillis() - lastSend;
+            running = false;
+        }
+
+        public static long getTimeout() {
+            return timeout;
+        }
+
+        public static Exception getException() {
+            return exception;
+        }
+
+        public static boolean getRunning() {
+            return running;
+        }
+    }
+}
diff --git a/test/org/apache/tomcat/websocket/WsWebSocketContainerBaseTest.java 
b/test/org/apache/tomcat/websocket/WsWebSocketContainerBaseTest.java
new file mode 100644
index 0000000..3efb89f
--- /dev/null
+++ b/test/org/apache/tomcat/websocket/WsWebSocketContainerBaseTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.tomcat.websocket;
+
+import java.net.URI;
+
+import javax.websocket.ClientEndpointConfig;
+import javax.websocket.Endpoint;
+import javax.websocket.Session;
+import javax.websocket.WebSocketContainer;
+
+public class WsWebSocketContainerBaseTest extends WebSocketBaseTest {
+
+    protected static final byte[] MESSAGE_BINARY_4K = new byte[4096];
+
+    protected static final long TIMEOUT_MS = 5 * 1000;
+    protected static final long MARGIN = 500;
+
+
+    /*
+     * Make this possible to override so sub-class can more easily test proxy
+     */
+    protected String getHostName() {
+        return "localhost";
+    }
+
+
+    protected Session connectToEchoServer(WebSocketContainer wsContainer,
+            Endpoint endpoint, String path) throws Exception {
+        return wsContainer.connectToServer(endpoint,
+                ClientEndpointConfig.Builder.create().build(),
+                new URI("ws://" + getHostName() + ":" + getPort() + path));
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to