/* * 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.jdbc.test; import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import javax.sql.PooledConnection; import org.junit.Assert; import org.junit.Test; import org.apache.tomcat.jdbc.test.driver.Connection; import org.apache.tomcat.jdbc.test.driver.Driver; public class AlternateUsernameTest extends DefaultTestCase { private static final int iterations = 500000; //(new Random(System.currentTimeMillis())).nextInt(1000000)+100000; @Test public void testUsernameCompare() throws Exception { testUsername(true); } private void testUsername(boolean allowUsernameChange) throws Exception { long start = System.currentTimeMillis(); int withoutuser =10; int withuser = withoutuser; this.datasource.setMaxActive(withuser+withoutuser); this.datasource.setDriverClassName(Driver.class.getName()); this.datasource.setUrl("jdbc:tomcat:test"); this.datasource.setAlternateUsernameAllowed(allowUsernameChange); this.datasource.getConnection().close(); TestRunner[] runners = new TestRunner[withuser+withoutuser]; for (int i=0; i<withuser; i++) { TestRunner with = new TestRunner("foo","bar",datasource.getPoolProperties().getUsername(),datasource.getPoolProperties().getPassword()); TestRunner without = new TestRunner(null,null,datasource.getPoolProperties().getUsername(),datasource.getPoolProperties().getPassword()); runners[i] = allowUsernameChange?with:without; runners[i+withuser] = without; } ExecutorService svc = Executors.newFixedThreadPool(withuser+withoutuser); List<Future<TestResult>> results = svc.invokeAll(Arrays.asList(runners)); int failures = 0; int total = 0; for (int i=0; i<withuser; i++) { failures += results.get(i).get().failures; total+=results.get(i).get().iterations; failures += results.get(i+withuser).get().failures; total+=results.get(i+withuser).get().iterations; } long stop = System.currentTimeMillis(); Assert.assertEquals("Nr of failures was:"+failures,0, failures); svc.shutdownNow(); this.datasource.close(); System.out.println("Nr of connect() calls:"+Driver.connectCount.get()); System.out.println("Nr of disconnect() calls:"+Driver.disconnectCount.get()); System.out.println("Nr of iterations:"+total+" over "+(stop-start)+ " ms."); } @Test public void testUsernameCompareAgain() throws Exception { testUsernameCompare(); } @Test public void testUsernameCompareNotAllowed() throws Exception { testUsername(false); } public static class TestResult { public int iterations; public int failures; public String lastMessage; } public class TestRunner implements Callable<TestResult> { String username; String password; volatile boolean done = false; TestResult result = null; boolean useuser = true; public TestRunner(String user, String pass, String guser, String gpass) { username = user==null?guser : user; password = pass==null?gpass : pass; useuser = user!=null; } @Override public TestResult call() { TestResult test = new TestResult(); PooledConnection pcon = null; for (int i=0; (!done) && (i<iterations); i++) { test.iterations = i+1; try { pcon = useuser ? (PooledConnection)AlternateUsernameTest.this.datasource.getConnection(username, password) : (PooledConnection)AlternateUsernameTest.this.datasource.getConnection(); Connection con = (Connection)pcon.getConnection(); Assert.assertTrue("Username mismatch: Requested User:"+username+" Actual user:"+con.getUsername(), con.getUsername().equals(username)); Assert.assertTrue("Password mismatch: Requested Password:"+password+" Actual password:"+con.getPassword(), con.getPassword().equals(password)); }catch (SQLException x) { test.failures++; test.lastMessage = x.getMessage(); done = true; x.printStackTrace(); }catch (Exception x) { test.failures++; test.lastMessage = x.getMessage(); x.printStackTrace(); } finally { if (pcon!=null) { try {pcon.close(); }catch (Exception ignore) {} pcon = null; } } } done = true; result = test; return result; } } }