1 /* 2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License, version 2.0, 6 * as published by the Free Software Foundation. 7 * 8 * This program is also distributed with certain software (including 9 * but not limited to OpenSSL) that is licensed under separate terms, 10 * as designated in a particular file or component or in included license 11 * documentation. The authors of MySQL hereby grant you an additional 12 * permission to link the program and your derivative works with the 13 * separately licensed software that they have included with MySQL. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License, version 2.0, for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 package testsuite.clusterj; 26 27 import java.util.Arrays; 28 import java.util.List; 29 import java.util.Properties; 30 31 import testsuite.clusterj.model.Employee; 32 33 import com.mysql.clusterj.ClusterJFatalUserException; 34 import com.mysql.clusterj.ClusterJHelper; 35 import com.mysql.clusterj.Constants; 36 import com.mysql.clusterj.Session; 37 import com.mysql.clusterj.SessionFactory; 38 39 @org.junit.Ignore("test requires specific connection pooling setup") 40 public class ConnectionPoolTest extends AbstractClusterJTest { 41 42 @Override getDebug()43 public boolean getDebug() { 44 return false; 45 } 46 runSpecificNodeIdTests()47 protected boolean runSpecificNodeIdTests() { 48 return false; 49 } 50 51 @Override localSetUp()52 public void localSetUp() { 53 loadProperties(); 54 // close the existing session factory because it uses one of the cluster connection (api) nodes 55 if (sessionFactory != null) { 56 sessionFactory.close(); 57 sessionFactory = null; 58 } 59 } 60 testNoPooling()61 public void testNoPooling() { 62 Properties modifiedProperties = new Properties(); 63 modifiedProperties.putAll(props); 64 SessionFactory sessionFactory1 = null; 65 SessionFactory sessionFactory2 = null; 66 67 // with connection.pool.size set to 1 each session factory should be the same 68 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 1); 69 sessionFactory1 = ClusterJHelper.getSessionFactory(modifiedProperties); 70 sessionFactory2 = ClusterJHelper.getSessionFactory(modifiedProperties); 71 sessionFactory1.close(); 72 sessionFactory2.close(); 73 errorIfNotEqual("With connection pooling, SessionFactory1 should be the same object as SessionFactory2", 74 true, sessionFactory1 == sessionFactory2); 75 76 // with connection.pool.size set to 0 each session factory should be unique 77 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 0); 78 sessionFactory1 = ClusterJHelper.getSessionFactory(modifiedProperties); 79 sessionFactory2 = ClusterJHelper.getSessionFactory(modifiedProperties); 80 try { 81 SessionFactory sessionFactory3 = ClusterJHelper.getSessionFactory(modifiedProperties); 82 sessionFactory3.close(); 83 } catch (ClusterJFatalUserException ex) { 84 // good catch 85 } 86 sessionFactory1.close(); 87 sessionFactory2.close(); 88 errorIfNotEqual("With no connection pooling, SessionFactory1 should not be the same object as SessionFactory2", 89 false, sessionFactory1 == sessionFactory2); 90 91 failOnError(); 92 } 93 testConnectionPoolSize()94 public void testConnectionPoolSize() { 95 Properties modifiedProperties = new Properties(); 96 modifiedProperties.putAll(props); 97 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 2); 98 checkConnectionPoolSize2("testConnectionPoolSize", modifiedProperties); 99 failOnError(); 100 } 101 testConnectionPoolSizeAndNodeIds()102 public void testConnectionPoolSizeAndNodeIds() { 103 if (!runSpecificNodeIdTests()) { 104 return; 105 } 106 Properties modifiedProperties = new Properties(); 107 modifiedProperties.putAll(props); 108 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 2); 109 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "4;5"); 110 checkConnectionPoolSize2("testConnectionPoolSizeAndNodeIds", modifiedProperties); 111 failOnError(); 112 } 113 testConnectionNodeIds()114 public void testConnectionNodeIds() { 115 if (!runSpecificNodeIdTests()) { 116 return; 117 } 118 Properties modifiedProperties = new Properties(); 119 modifiedProperties.putAll(props); 120 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "4,5"); 121 checkConnectionPoolSize2("testConnectionNodeIds", modifiedProperties); 122 failOnError(); 123 } 124 testConnectionSingleNodeIdAndConnectionPoolSize()125 public void testConnectionSingleNodeIdAndConnectionPoolSize() { 126 if (!runSpecificNodeIdTests()) { 127 return; 128 } 129 Properties modifiedProperties = new Properties(); 130 modifiedProperties.putAll(props); 131 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 2); 132 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "4"); 133 checkConnectionPoolSize2("testConnectionSingleNodeIdAndConnectionPoolSize", modifiedProperties); 134 failOnError(); 135 } 136 checkConnectionPoolSize2(String where, Properties modifiedProperties)137 private void checkConnectionPoolSize2(String where, Properties modifiedProperties) { 138 SessionFactory sessionFactory1 = null; 139 SessionFactory sessionFactory2 = null; 140 SessionFactory sessionFactory3 = null; 141 sessionFactory1 = ClusterJHelper.getSessionFactory(modifiedProperties); 142 sessionFactory2 = ClusterJHelper.getSessionFactory(modifiedProperties); 143 sessionFactory3 = ClusterJHelper.getSessionFactory(modifiedProperties); 144 errorIfNotEqual(where + " SessionFactory1 should be the same object as SessionFactory2", true, 145 sessionFactory1 == sessionFactory2); 146 errorIfNotEqual(where + " SessionFactory1 should be the same object as SessionFactory3", true, 147 sessionFactory1 == sessionFactory3); 148 Session session1 = sessionFactory1.getSession(); 149 Employee e1 = session1.find(Employee.class, 0); 150 checkSessions(where + " after get session1", sessionFactory1, new Integer[] {1, 0}); 151 Session session2 = sessionFactory1.getSession(); 152 Employee e2 = session2.find(Employee.class, 0); 153 checkSessions(where + " after get session2", sessionFactory1, new Integer[] {1, 1}); 154 Session session3 = sessionFactory1.getSession(); 155 checkSessions(where + " after get session3", sessionFactory1, new Integer[] {2, 1}); 156 Session session4 = sessionFactory1.getSession(); 157 checkSessions(where + " after get session4", sessionFactory1, new Integer[] {2, 2}); 158 Session session5 = sessionFactory1.getSession(); 159 checkSessions(where + " after get session5", sessionFactory1, new Integer[] {3, 2}); 160 Session session6 = sessionFactory1.getSession(); 161 checkSessions(where + " after get session6", sessionFactory1, new Integer[] {3, 3}); 162 163 session1.close(); 164 checkSessions(where + " after close session1", sessionFactory1, new Integer[] {2, 3}); 165 session4.close(); 166 checkSessions(where + " after close session4", sessionFactory1, new Integer[] {2, 2}); 167 session5.close(); 168 checkSessions(where + " after close session5", sessionFactory1, new Integer[] {1, 2}); 169 Session session7 = sessionFactory1.getSession(); 170 checkSessions(where + " after get session7", sessionFactory1, new Integer[] {2, 2}); 171 172 session2.close(); 173 session3.close(); 174 session6.close(); 175 session7.close(); 176 sessionFactory1.close(); 177 } 178 testNegativeMismatchConnectionPoolSizeAndConnectionPoolNodeids()179 public void testNegativeMismatchConnectionPoolSizeAndConnectionPoolNodeids() { 180 Properties modifiedProperties = new Properties(); 181 modifiedProperties.putAll(props); 182 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 3); 183 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "4\t5"); 184 try { 185 ClusterJHelper.getSessionFactory(modifiedProperties); 186 } catch (ClusterJFatalUserException ex) { 187 if (getDebug()) ex.printStackTrace(); 188 // good catch 189 String expected = "4\t5"; 190 if (!ex.getMessage().contains(expected)) { 191 error("Mismatch error message should contain " + expected); 192 } 193 } 194 failOnError(); 195 } 196 testNegativeConnectionPoolNodeidsFormatError()197 public void testNegativeConnectionPoolNodeidsFormatError() { 198 Properties modifiedProperties = new Properties(); 199 modifiedProperties.putAll(props); 200 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_SIZE, 2); 201 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "7 t"); 202 try { 203 ClusterJHelper.getSessionFactory(modifiedProperties); 204 } catch (ClusterJFatalUserException ex) { 205 if (getDebug()) ex.printStackTrace(); 206 // good catch 207 String expected = "NumberFormatException"; 208 if (!ex.getMessage().contains(expected)) { 209 error("Mismatch error message '" + ex.getMessage() + "' should contain '" + expected + '"'); 210 } 211 } 212 failOnError(); 213 } 214 215 @org.junit.Ignore("testNegativeConnectionPoolIllegalNodeids takes too long") testNegativeConnectionPoolIllegalNodeids()216 public void testNegativeConnectionPoolIllegalNodeids() { 217 Properties modifiedProperties = new Properties(); 218 modifiedProperties.putAll(props); 219 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "256"); 220 try { 221 ClusterJHelper.getSessionFactory(modifiedProperties); 222 } catch (ClusterJFatalUserException ex) { 223 if (getDebug()) ex.printStackTrace(); 224 // good catch 225 String expected = "illegal"; 226 if (!ex.getMessage().contains(expected)) { 227 error("Mismatch error message '" + ex.getMessage() + "' should contain '" + expected + '"'); 228 } 229 } 230 failOnError(); 231 } 232 testNegativeConnectionPoolNoNodeId()233 public void testNegativeConnectionPoolNoNodeId() { 234 if (!runSpecificNodeIdTests()) { 235 return; 236 } 237 Properties modifiedProperties = new Properties(); 238 modifiedProperties.putAll(props); 239 modifiedProperties.put(Constants.PROPERTY_CONNECTION_POOL_NODEIDS, "48"); 240 try { 241 ClusterJHelper.getSessionFactory(modifiedProperties); 242 } catch (ClusterJFatalUserException ex) { 243 if (getDebug()) ex.printStackTrace(); 244 // good catch 245 String expected = "No node defined"; 246 if (!ex.getMessage().contains(expected)) { 247 error("Mismatch error message '" + ex.getMessage() + "' should contain '" + expected + '"'); 248 } 249 } 250 failOnError(); 251 } 252 checkSessions(String where, SessionFactory sessionFactory, Integer[] expected)253 private void checkSessions(String where, SessionFactory sessionFactory, Integer[] expected) { 254 List<Integer> connectionCounts = sessionFactory.getConnectionPoolSessionCounts(); 255 if (getDebug()) System.out.println("connection counts: " + connectionCounts.toString()); 256 if (expected.length != connectionCounts.size()) { 257 error(where + " wrong number of connections in pool\n" 258 + "Expected: " + Arrays.toString(expected) 259 + " Actual: " + connectionCounts); 260 return; 261 } 262 int i = 0; 263 for (Integer connectionCount: connectionCounts) { 264 if (getDebug()) System.out.println("Connection " + i + " has " + connectionCount + " sessions."); 265 if (i >= expected.length) break; 266 errorIfNotEqual(where + " wrong count on connection " + i, expected[i], connectionCount); 267 i++; 268 } 269 if (getDebug()) System.out.println(); 270 } 271 } 272