3131
3190
rConn2.prepareStatement("SELECT 1").executeQuery();
3194
public void testBug61201() throws Exception {
3195
Properties props = new Properties();
3196
props.setProperty("sessionVariables", "FOREIGN_KEY_CHECKS=0");
3197
props.setProperty("characterEncoding", "latin1");
3198
props.setProperty("profileSQL", "true");
3200
Connection varConn = getConnectionWithProps(props);
3204
public void testChangeUser() throws Exception {
3205
Properties props = getPropertiesFromTestsuiteUrl();
3207
for (int i = 0; i < 500; i++) {
3208
((com.mysql.jdbc.Connection) this.conn).changeUser(props.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY), props.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY));
3212
((com.mysql.jdbc.Connection) this.conn).changeUser("bubba", props.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY));
3213
} catch (SQLException sqlEx) {
3218
this.stmt.executeQuery("SELECT 1");
3222
public void testChangeUserClosedConn() throws Exception {
3223
Properties props = getPropertiesFromTestsuiteUrl();
3224
Connection newConn = getConnectionWithProps((Properties)null);
3228
((com.mysql.jdbc.Connection) newConn).changeUser(props.getProperty(NonRegisteringDriver.USER_PROPERTY_KEY), props.getProperty(NonRegisteringDriver.PASSWORD_PROPERTY_KEY));
3229
fail("Expected SQL Exception");
3230
} catch (MySQLNonTransientException ex) {
3237
public void testBug63284() throws Exception {
3238
Properties props = new Driver().parseURL(BaseTestCase.dbUrl, null);
3239
props.setProperty("autoReconnect", "true");
3240
props.setProperty("socketFactory", "testsuite.UnreliableSocketFactory");
3242
Properties urlProps = new NonRegisteringDriver().parseURL(
3243
BaseTestCase.dbUrl, null);
3245
String host = urlProps.getProperty(Driver.HOST_PROPERTY_KEY);
3246
String port = urlProps.getProperty(Driver.PORT_PROPERTY_KEY);
3248
props.remove(Driver.HOST_PROPERTY_KEY);
3249
props.remove(Driver.NUM_HOSTS_PROPERTY_KEY);
3250
props.remove(Driver.HOST_PROPERTY_KEY + ".1");
3251
props.remove(Driver.PORT_PROPERTY_KEY + ".1");
3253
props.setProperty("queriesBeforeRetryMaster", "50");
3254
props.setProperty("maxReconnects", "1");
3256
UnreliableSocketFactory.mapHost("master", host);
3257
UnreliableSocketFactory.mapHost("slave", host);
3259
Connection failoverConnection1 = null;
3260
Connection failoverConnection2 = null;
3263
failoverConnection1 = getConnectionWithProps("jdbc:mysql://master:"
3264
+ port + ",slave:" + port + "/", props);
3266
failoverConnection2 = getConnectionWithProps("jdbc:mysql://master:"
3267
+ port + ",slave:" + port + "/", props);
3269
assert(((com.mysql.jdbc.Connection)failoverConnection1).isMasterConnection());
3271
// Two different Connection objects should not equal each other:
3272
assert(!failoverConnection1.equals(failoverConnection2));
3274
int hc = failoverConnection1.hashCode();
3276
UnreliableSocketFactory.downHost("master");
3278
for(int i = 0; i < 3; i++ ){
3280
failoverConnection1.createStatement().execute("SELECT 1");
3281
} catch (SQLException e){
3282
// do nothing, expect SQLException when failing over initially
3283
// goal here is to ensure valid connection against a slave
3286
// ensure we're now connected to the slave
3287
assert(!((com.mysql.jdbc.Connection)failoverConnection1).isMasterConnection());
3289
// ensure that hashCode() result is persistent across failover events when proxy state changes
3290
assert(failoverConnection1.hashCode() == hc);
3292
if (failoverConnection1 != null) {
3293
failoverConnection1.close();
3295
if (failoverConnection2 != null) {
3296
failoverConnection2.close();
3301
public void testDefaultPlugin() throws Exception {
3302
if (versionMeetsMinimum(5, 5, 7)) {
3304
Connection testConn = null;
3305
Properties props = new Properties();
3307
props.setProperty("defaultAuthenticationPlugin", "");
3309
testConn = getConnectionWithProps(props);
3310
assertTrue("Exception is expected due to incorrect defaultAuthenticationPlugin value", false);
3311
} catch (SQLException sqlEx) {
3314
if (testConn != null) testConn.close();
3317
props.setProperty("defaultAuthenticationPlugin", "mysql_native_password");
3319
testConn = getConnectionWithProps(props);
3320
assertTrue("Exception is expected due to incorrect defaultAuthenticationPlugin value (mechanism name instead of class name)", false);
3321
} catch (SQLException sqlEx) {
3324
if (testConn != null) testConn.close();
3327
props.setProperty("defaultAuthenticationPlugin", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3329
testConn = getConnectionWithProps(props);
3330
assertTrue("Exception is expected due to defaultAuthenticationPlugin value is not listed", false);
3331
} catch (SQLException sqlEx) {
3334
if (testConn != null) testConn.close();
3337
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3338
props.setProperty("defaultAuthenticationPlugin", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3340
testConn = getConnectionWithProps(props);
3342
} catch (SQLException sqlEx) {
3343
assertTrue("Exception is not expected due to defaultAuthenticationPlugin value is correctly listed", false);
3345
if (testConn != null) testConn.close();
3350
public void testDisabledPlugins() throws Exception {
3351
if (versionMeetsMinimum(5, 5, 7)) {
3353
Connection testConn = null;
3354
Properties props = new Properties();
3356
props.setProperty("disabledAuthenticationPlugins", "mysql_native_password");
3358
testConn = getConnectionWithProps(props);
3359
assertTrue("Exception is expected due to disabled defaultAuthenticationPlugin", false);
3360
} catch (SQLException sqlEx) {
3363
if (testConn != null) testConn.close();
3366
props.setProperty("disabledAuthenticationPlugins", "com.mysql.jdbc.authentication.MysqlNativePasswordPlugin");
3368
testConn = getConnectionWithProps(props);
3369
assertTrue("Exception is expected due to disabled defaultAuthenticationPlugin", false);
3370
} catch (SQLException sqlEx) {
3373
if (testConn != null) testConn.close();
3376
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3377
props.setProperty("defaultAuthenticationPlugin", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3378
props.setProperty("disabledAuthenticationPlugins", "auth_test_plugin");
3380
testConn = getConnectionWithProps(props);
3381
assertTrue("Exception is expected due to disabled defaultAuthenticationPlugin", false);
3382
} catch (SQLException sqlEx) {
3385
if (testConn != null) testConn.close();
3388
props.setProperty("defaultAuthenticationPlugin", "com.mysql.jdbc.authentication.MysqlNativePasswordPlugin");
3389
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3390
props.setProperty("disabledAuthenticationPlugins", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3392
testConn = getConnectionWithProps(props);
3394
} catch (SQLException sqlEx) {
3395
assertTrue("Exception is not expected due to disabled plugin is not default", false);
3397
if (testConn != null) testConn.close();
3402
public void testAuthTestPlugin() throws Exception {
3403
if (versionMeetsMinimum(5, 5, 7)) {
3405
boolean install_plugin_in_runtime = false;
3408
// install plugin if required
3409
this.rs = this.stmt.executeQuery(
3410
"select (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') as `TRUE`" +
3411
" FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='test_plugin_server'");
3413
if (!rs.getBoolean(1)) install_plugin_in_runtime = true;
3415
install_plugin_in_runtime = true;
3418
if (install_plugin_in_runtime) {
3419
String ext = System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") > -1 ? ".dll" : ".so";
3420
this.stmt.executeUpdate("INSTALL PLUGIN test_plugin_server SONAME 'auth_test_plugin"+ext+"'");
3423
String dbname = null;
3424
this.rs = this.stmt.executeQuery("select database() as dbname");
3425
if(this.rs.first()) {
3426
dbname = this.rs.getString("dbname");
3428
if (dbname == null) assertTrue("No database selected", false);
3430
// create proxy users
3431
this.stmt.executeUpdate("grant usage on *.* to 'wl5851user'@'%' identified WITH test_plugin_server AS 'plug_dest'");
3432
this.stmt.executeUpdate("grant usage on *.* to 'plug_dest'@'%' IDENTIFIED BY 'foo'");
3433
this.stmt.executeUpdate("GRANT PROXY ON 'plug_dest'@'%' TO 'wl5851user'@'%'");
3434
this.stmt.executeUpdate("delete from mysql.db where user='plug_dest'");
3435
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'plug_dest', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3436
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'plug_dest', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3437
this.stmt.executeUpdate("flush privileges");
3439
Properties props = new Properties();
3440
props.setProperty("user", "wl5851user");
3441
props.setProperty("password", "plug_dest");
3442
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$AuthTestPlugin");
3444
Connection testConn = null;
3445
Statement testSt = null;
3446
ResultSet testRs = null;
3448
testConn = getConnectionWithProps(props);
3449
testSt = testConn.createStatement();
3450
testRs = testSt.executeQuery("select USER(),CURRENT_USER()");
3452
assertEquals("wl5851user", testRs.getString(1).split("@")[0]);
3453
assertEquals("plug_dest", testRs.getString(2).split("@")[0]);
3456
if (testRs != null) testRs.close();
3457
if (testSt != null) testSt.close();
3458
if (testConn != null) testConn.close();
3462
this.stmt.executeUpdate("drop user 'wl5851user'@'%'");
3463
this.stmt.executeUpdate("drop user 'plug_dest'@'%'");
3464
if (install_plugin_in_runtime) {
3465
this.stmt.executeUpdate("UNINSTALL PLUGIN test_plugin_server");
3471
public void testTwoQuestionsPlugin() throws Exception {
3472
if (versionMeetsMinimum(5, 5, 7)) {
3474
boolean install_plugin_in_runtime = false;
3477
// install plugin if required
3478
this.rs = this.stmt.executeQuery(
3479
"select (PLUGIN_LIBRARY LIKE 'two_questions%') as `TRUE`" +
3480
" FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='two_questions'");
3482
if (!rs.getBoolean(1)) install_plugin_in_runtime = true;
3484
install_plugin_in_runtime = true;
3487
if (install_plugin_in_runtime) {
3488
String ext = System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") > -1 ? ".dll" : ".so";
3489
this.stmt.executeUpdate("INSTALL PLUGIN two_questions SONAME 'auth"+ext+"'");
3492
String dbname = null;
3493
this.rs = this.stmt.executeQuery("select database() as dbname");
3494
if(this.rs.first()) {
3495
dbname = this.rs.getString("dbname");
3497
if (dbname == null) assertTrue("No database selected", false);
3499
this.stmt.executeUpdate("grant usage on *.* to 'wl5851user2'@'%' identified WITH two_questions AS 'two_questions_password'");
3500
this.stmt.executeUpdate("delete from mysql.db where user='wl5851user2'");
3501
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'wl5851user2', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3502
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'wl5851user2', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3503
this.stmt.executeUpdate("flush privileges");
3505
Properties props = new Properties();
3506
props.setProperty("user", "wl5851user2");
3507
props.setProperty("password", "two_questions_password");
3508
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$TwoQuestionsPlugin");
3510
Connection testConn = null;
3511
Statement testSt = null;
3512
ResultSet testRs = null;
3514
testConn = getConnectionWithProps(props);
3515
testSt = testConn.createStatement();
3516
testRs = testSt.executeQuery("select USER(),CURRENT_USER()");
3518
assertEquals("wl5851user2", testRs.getString(1).split("@")[0]);
3521
if (testRs != null) testRs.close();
3522
if (testSt != null) testSt.close();
3523
if (testConn != null) testConn.close();
3527
this.stmt.executeUpdate("drop user 'wl5851user2'@'%'");
3528
if (install_plugin_in_runtime) {
3529
this.stmt.executeUpdate("UNINSTALL PLUGIN two_questions");
3535
public void testThreeAttemptsPlugin() throws Exception {
3536
if (versionMeetsMinimum(5, 5, 7)) {
3538
boolean install_plugin_in_runtime = false;
3541
// install plugin if required
3542
this.rs = this.stmt.executeQuery(
3543
"select (PLUGIN_LIBRARY LIKE 'three_attempts%') as `TRUE`" +
3544
" FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='three_attempts'");
3546
if (!rs.getBoolean(1)) install_plugin_in_runtime = true;
3548
install_plugin_in_runtime = true;
3551
if (install_plugin_in_runtime) {
3552
String ext = System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") > -1 ? ".dll" : ".so";
3553
this.stmt.executeUpdate("INSTALL PLUGIN three_attempts SONAME 'auth"+ext+"'");
3556
String dbname = null;
3557
this.rs = this.stmt.executeQuery("select database() as dbname");
3558
if(this.rs.first()) {
3559
dbname = this.rs.getString("dbname");
3561
if (dbname == null) assertTrue("No database selected", false);
3563
this.stmt.executeUpdate("grant usage on *.* to 'wl5851user3'@'%' identified WITH three_attempts AS 'three_attempts_password'");
3564
this.stmt.executeUpdate("delete from mysql.db where user='wl5851user3'");
3565
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'wl5851user3', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3566
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'wl5851user3', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3567
this.stmt.executeUpdate("flush privileges");
3569
Properties props = new Properties();
3570
props.setProperty("user", "wl5851user3");
3571
props.setProperty("password", "three_attempts_password");
3572
props.setProperty("authenticationPlugins", "testsuite.regression.ConnectionRegressionTest$ThreeAttemptsPlugin");
3574
Connection testConn = null;
3575
Statement testSt = null;
3576
ResultSet testRs = null;
3578
testConn = getConnectionWithProps(props);
3579
testSt = testConn.createStatement();
3580
testRs = testSt.executeQuery("select USER(),CURRENT_USER()");
3582
assertEquals("wl5851user3", testRs.getString(1).split("@")[0]);
3585
if (testRs != null) testRs.close();
3586
if (testSt != null) testSt.close();
3587
if (testConn != null) testConn.close();
3591
this.stmt.executeUpdate("drop user 'wl5851user3'@'%'");
3592
if (install_plugin_in_runtime) {
3593
this.stmt.executeUpdate("UNINSTALL PLUGIN three_attempts");
3599
public static class AuthTestPlugin implements AuthenticationPlugin {
3601
private String password = null;
3603
public void init(com.mysql.jdbc.Connection conn1, Properties props) throws SQLException {
3606
public void destroy() {
3607
this.password = null;
3610
public String getProtocolPluginName() {
3611
return "auth_test_plugin";
3614
public boolean requiresConfidentiality() {
3618
public boolean isReusable() {
3622
public void setAuthenticationParameters(String user, String password) {
3623
this.password = password;
3626
public boolean nextAuthenticationStep(Buffer fromServer, List<Buffer> toServer) throws SQLException {
3628
Buffer bresp = new Buffer(StringUtils.getBytes(this.password));
3629
toServer.add(bresp);
3635
public static class TwoQuestionsPlugin implements AuthenticationPlugin {
3637
private String password = null;
3639
public void init(com.mysql.jdbc.Connection conn1, Properties props) throws SQLException {
3642
public void destroy() {
3643
this.password = null;
3646
public String getProtocolPluginName() {
3650
public boolean requiresConfidentiality() {
3654
public boolean isReusable() {
3658
public void setAuthenticationParameters(String user, String password) {
3659
this.password = password;
3662
public boolean nextAuthenticationStep(Buffer fromServer, List<Buffer> toServer) throws SQLException {
3664
if ((fromServer.getByteBuffer()[0] & 0xff) == 4) {
3665
Buffer bresp = new Buffer(StringUtils.getBytes(this.password));
3666
toServer.add(bresp);
3668
Buffer bresp = new Buffer(StringUtils.getBytes("yes, of course"));
3669
toServer.add(bresp);
3676
public static class ThreeAttemptsPlugin implements AuthenticationPlugin {
3678
private String password = null;
3679
private int counter = 0;
3681
public void init(com.mysql.jdbc.Connection conn1, Properties props) throws SQLException {
3685
public void destroy() {
3686
this.password = null;
3690
public String getProtocolPluginName() {
3694
public boolean requiresConfidentiality() {
3698
public boolean isReusable() {
3702
public void setAuthenticationParameters(String user, String password) {
3703
this.password = password;
3706
public boolean nextAuthenticationStep(Buffer fromServer, List<Buffer> toServer) throws SQLException {
3709
if ((fromServer.getByteBuffer()[0] & 0xff) == 4) {
3710
Buffer bresp = new Buffer(StringUtils.getBytes(counter>2 ? this.password : "wrongpassword"+counter));
3711
toServer.add(bresp);
3713
Buffer bresp = new Buffer(fromServer.getByteBuffer());
3714
toServer.add(bresp);
3721
public void testOldPasswordPlugin() throws Exception {
3723
boolean secure_auth = false;
3724
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'secure_auth'");
3725
while (this.rs.next()) {
3726
secure_auth = "ON".equalsIgnoreCase(this.rs.getString(2));
3729
if (versionMeetsMinimum(5, 5, 7) && !secure_auth) {
3731
String dbname = null;
3732
this.rs = this.stmt.executeQuery("select database() as dbname");
3733
if(this.rs.first()) {
3734
dbname = this.rs.getString("dbname");
3736
if (dbname == null) assertTrue("No database selected", false);
3738
Connection adminConn = null;
3739
Statement adminStmt = null;
3742
testOldPasswordPlugin_createUsers(this.stmt, dbname);
3743
} catch (Exception e) {
3744
adminConn = getAdminConnection();
3745
if (adminConn == null) {
3746
assertTrue("Lack of grant permissions. Change default user or set com.mysql.jdbc.testsuite.admin-url property.", false);
3748
adminStmt = adminConn.createStatement();
3749
testOldPasswordPlugin_createUsers(adminStmt, dbname);
3754
Properties props = new Properties();
3755
props.setProperty("user", "bug64983user1");
3756
props.setProperty("password", "pwd");
3757
props.setProperty("defaultAuthenticationPlugin", "com.mysql.jdbc.authentication.MysqlOldPasswordPlugin");
3759
Connection testConn = null;
3760
Statement testSt = null;
3761
ResultSet testRs = null;
3764
testConn = getConnectionWithProps(props);
3765
testSt = testConn.createStatement();
3766
testRs = testSt.executeQuery("select USER()");
3768
assertEquals("bug64983user1", testRs.getString(1).split("@")[0]);
3770
((MySQLConnection)testConn).changeUser("bug64983user2", "");
3771
testRs = testSt.executeQuery("select USER()");
3773
assertEquals("bug64983user2", testRs.getString(1).split("@")[0]);
3776
if (testRs != null) {
3779
if (testSt != null) {
3782
if (testConn != null) {
3785
if (adminStmt != null) {
3786
adminStmt.executeUpdate("drop user 'bug64983user1'@'%'");
3787
adminStmt.executeUpdate("drop user 'bug64983user2'@'%'");
3790
this.stmt.executeUpdate("drop user 'bug64983user1'@'%'");
3791
this.stmt.executeUpdate("drop user 'bug64983user2'@'%'");
3793
if (adminConn != null) {
3801
public void testOldPasswordPlugin_createUsers(Statement adminStmt, String dbname) throws Exception {
3803
adminStmt.executeUpdate("grant usage on *.* to 'bug64983user1'@'%'");
3804
adminStmt.executeUpdate("set password for 'bug64983user1'@'%' = OLD_PASSWORD('pwd')");
3805
adminStmt.executeUpdate("delete from mysql.db where user='bug64983user1'");
3806
adminStmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'bug64983user1', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3807
adminStmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'bug64983user1', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3809
adminStmt.executeUpdate("grant usage on *.* to 'bug64983user2'@'%'");
3810
adminStmt.executeUpdate("set password for 'bug64983user2'@'%' = OLD_PASSWORD('')");
3811
adminStmt.executeUpdate("delete from mysql.db where user='bug64983user2'");
3812
adminStmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'bug64983user2', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3813
adminStmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'bug64983user2', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3815
adminStmt.executeUpdate("flush privileges");
3818
public void testAuthCleartextPlugin() throws Exception {
3819
if (versionMeetsMinimum(5, 5, 7)) {
3821
boolean install_plugin_in_runtime = false;
3824
// install plugin if required
3825
this.rs = this.stmt.executeQuery(
3826
"select (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') as `TRUE`" +
3827
" FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='cleartext_plugin_server'");
3829
if (!rs.getBoolean(1)) install_plugin_in_runtime = true;
3831
install_plugin_in_runtime = true;
3834
if (install_plugin_in_runtime) {
3835
String ext = System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") > -1 ? ".dll" : ".so";
3836
this.stmt.executeUpdate("INSTALL PLUGIN cleartext_plugin_server SONAME 'auth_test_plugin"+ext+"'");
3839
String dbname = null;
3840
this.rs = this.stmt.executeQuery("select database() as dbname");
3841
if(this.rs.first()) {
3842
dbname = this.rs.getString("dbname");
3844
if (dbname == null) assertTrue("No database selected", false);
3846
// create proxy users
3847
this.stmt.executeUpdate("grant usage on *.* to 'wl5735user'@'%' identified WITH cleartext_plugin_server AS ''");
3848
this.stmt.executeUpdate("delete from mysql.db where user='wl5735user'");
3849
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'wl5735user', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3850
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'wl5735user', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3851
this.stmt.executeUpdate("flush privileges");
3853
Properties props = new Properties();
3854
props.setProperty("user", "wl5735user");
3855
props.setProperty("password", "");
3857
Connection testConn = null;
3858
Statement testSt = null;
3859
ResultSet testRs = null;
3862
testConn = getConnectionWithProps(props);
3863
assertFalse("SQLException expected due to SSL connection is required", true);
3864
} catch (SQLException e) {
3865
String trustStorePath = "src/testsuite/ssl-test-certs/test-cert-store";
3866
System.setProperty("javax.net.ssl.keyStore", trustStorePath);
3867
System.setProperty("javax.net.ssl.keyStorePassword", "password");
3868
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
3869
System.setProperty("javax.net.ssl.trustStorePassword", "password");
3870
props.setProperty("useSSL", "true");
3871
props.setProperty("requireSSL", "true");
3872
testConn = getConnectionWithProps(props);
3875
testSt = testConn.createStatement();
3876
testRs = testSt.executeQuery("select USER(),CURRENT_USER()");
3879
assertEquals("wl5735user", testRs.getString(1).split("@")[0]);
3880
assertEquals("wl5735user", testRs.getString(2).split("@")[0]);
3883
if (testRs != null) testRs.close();
3884
if (testSt != null) testSt.close();
3885
if (testConn != null) testConn.close();
3889
this.stmt.executeUpdate("drop user 'wl5735user'@'%'");
3890
if (install_plugin_in_runtime) {
3891
this.stmt.executeUpdate("UNINSTALL PLUGIN cleartext_plugin_server");
3897
public void testSha256PasswordPlugin() throws Exception {
3898
if (versionMeetsMinimum(5, 6, 5)) {
3900
// check that sha256_password plugin is available
3901
boolean plugin_is_active = false;
3902
this.rs = this.stmt.executeQuery("select (PLUGIN_STATUS='ACTIVE') as `TRUE` from INFORMATION_SCHEMA.PLUGINS where PLUGIN_NAME='sha256_password'");
3904
plugin_is_active = rs.getBoolean(1);
3907
if (plugin_is_active) {
3909
String dbname = null;
3910
this.rs = this.stmt.executeQuery("select database() as dbname");
3911
if(this.rs.first()) {
3912
dbname = this.rs.getString("dbname");
3914
if (dbname == null) assertTrue("No database selected", false);
3916
// create proxy users
3917
this.stmt.executeUpdate("SET @current_old_passwords = @@global.old_passwords");
3919
this.stmt.executeUpdate("grant usage on *.* to 'wl5602user'@'%' identified WITH sha256_password");
3920
this.stmt.executeUpdate("SET GLOBAL old_passwords= 2");
3921
this.stmt.executeUpdate("SET SESSION old_passwords= 2");
3922
this.stmt.executeUpdate("set password for 'wl5602user'@'%' = PASSWORD('pwd')");
3923
this.stmt.executeUpdate("delete from mysql.db where user='wl5602user'");
3924
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', '"+dbname+"', 'wl5602user', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3925
this.stmt.executeUpdate("insert into mysql.db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv,Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Create_tmp_table_priv, Lock_tables_priv, Create_view_priv,Show_view_priv, Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) VALUES ('%', 'information\\_schema', 'wl5602user', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'N', 'N')");
3926
this.stmt.executeUpdate("flush privileges");
3928
Properties props = new Properties();
3929
props.setProperty("user", "wl5602user");
3930
props.setProperty("password", "pwd");
3932
Connection testConn = null;
3933
Statement testSt = null;
3934
ResultSet testRs = null;
3937
testConn = getConnectionWithProps(props);
3938
assertFalse("SQLException expected due to SSL connection is required", true);
3939
} catch (SQLException e) {
3940
String trustStorePath = "src/testsuite/ssl-test-certs/test-cert-store";
3941
System.setProperty("javax.net.ssl.keyStore", trustStorePath);
3942
System.setProperty("javax.net.ssl.keyStorePassword", "password");
3943
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
3944
System.setProperty("javax.net.ssl.trustStorePassword", "password");
3945
props.setProperty("useSSL", "true");
3946
props.setProperty("requireSSL", "true");
3947
testConn = getConnectionWithProps(props);
3950
testSt = testConn.createStatement();
3951
testRs = testSt.executeQuery("select USER(),CURRENT_USER()");
3954
assertEquals("wl5602user", testRs.getString(1).split("@")[0]);
3955
assertEquals("wl5602user", testRs.getString(2).split("@")[0]);
3958
if (testRs != null) testRs.close();
3959
if (testSt != null) testSt.close();
3960
if (testConn != null) testConn.close();
3964
this.stmt.executeUpdate("drop user 'wl5602user'@'%'");
3965
this.stmt.executeUpdate("flush privileges");
3966
this.stmt.executeUpdate("SET GLOBAL old_passwords = @current_old_passwords");
3972
public void testBug36662() throws Exception {
3975
String tz1 = TimeUtil.getCanoncialTimezone("MEST", null);
3977
} catch (Exception e1) {
3978
String mes1 = e1.getMessage();
3979
mes1 = mes1.substring(mes1.lastIndexOf("The timezones that 'MEST' maps to are:")+39);
3981
String tz2 = TimeUtil.getCanoncialTimezone("CEST", null);
3982
assertEquals(mes1, tz2);
3983
} catch (Exception e2) {
3984
String mes2 = e2.getMessage();
3985
mes2 = mes2.substring(mes2.lastIndexOf("The timezones that 'CEST' maps to are:")+39);
3986
assertEquals(mes1, mes2);
3991
public void testBug37931() throws Exception {
3993
Connection _conn = null;
3994
Properties props = new Properties();
3995
props.setProperty("characterSetResults", "ISO8859-1");
3998
_conn = getConnectionWithProps(props);
3999
assertTrue("This point should not be reached.", false);
4000
} catch (Exception e) {
4002
"Can't map ISO8859-1 given for characterSetResults to a supported MySQL encoding.",
4005
if (_conn != null) {
4010
props.setProperty("characterSetResults", "null");
4013
_conn = getConnectionWithProps(props);
4015
Statement _stmt = _conn.createStatement();
4016
ResultSet _rs = _stmt.executeQuery("show variables where variable_name='character_set_results'");
4018
String res = _rs.getString(2);
4019
if (res == null || "NULL".equalsIgnoreCase(res) || res.length() == 0) {
4026
if (_conn != null) {
4032
public void testBug64205() throws Exception {
4033
if (versionMeetsMinimum(5, 5, 0)) {
4034
String dbname = null;
4035
this.rs = this.stmt.executeQuery("select database() as dbname");
4036
if(this.rs.first()) {
4037
dbname = this.rs.getString("dbname");
4039
if (dbname == null) assertTrue("No database selected", false);
4041
Properties props = new Properties();
4042
props.setProperty("characterEncoding", "EUC_JP");
4044
Connection testConn = null;
4045
Statement testSt = null;
4046
ResultSet testRs = null;
4048
testConn = getConnectionWithProps(props);
4049
testSt = testConn.createStatement();
4050
testRs = testSt.executeQuery("SELECT * FROM `"+dbname+"`.`ほげほげ`");
4051
} catch (SQLException e1) {
4052
if (e1 instanceof MySQLSyntaxErrorException) {
4053
assertEquals("Table '"+dbname+".ほげほげ' doesn't exist", e1.getMessage());
4054
} else if (e1.getErrorCode() == MysqlErrorNumbers.ER_FILE_NOT_FOUND) {
4055
// this could happen on Windows with 5.5 and 5.6 servers where BUG#14642248 exists
4056
assertTrue(e1.getMessage().contains("Can't find file"));
4062
props.setProperty("characterSetResults", "SJIS");
4063
testConn = getConnectionWithProps(props);
4064
testSt = testConn.createStatement();
4065
testSt.execute("SET lc_messages = 'ru_RU'");
4066
testRs = testSt.executeQuery("SELECT * FROM `"+dbname+"`.`ほげほげ`");
4067
} catch (SQLException e2) {
4068
if (e2 instanceof MySQLSyntaxErrorException) {
4069
assertEquals("\u0422\u0430\u0431\u043b\u0438\u0446\u0430 '"+dbname+".ほげほげ' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442", e2.getMessage());
4070
} else if (e2.getErrorCode() == MysqlErrorNumbers.ER_FILE_NOT_FOUND) {
4071
// this could happen on Windows with 5.5 and 5.6 servers where BUG#14642248 exists
4072
assertTrue("File not found error message should be russian but is this one: "+e2.getMessage(), e2.getMessage().indexOf("\u0444\u0430\u0439\u043b") > -1);
4079
if (testRs != null) testRs.close();
4080
if (testSt != null) testSt.close();
4081
if (testConn != null) testConn.close();
4086
public void testIsLocal() throws Exception {
4087
boolean normalState = ((ConnectionImpl) conn).isServerLocal();
4090
boolean isNotLocal = ((ConnectionImpl) getConnectionWithProps(StandardSocketFactory.IS_LOCAL_HOSTNAME_REPLACEMENT_PROPERTY_NAME + "=www.oracle.com:3306")).isServerLocal();
4092
assertFalse(isNotLocal == normalState);
4097
* Tests fix for BUG#57662, Incorrect Query Duration When useNanosForElapsedTime Enabled
4100
* if the test fails.
4102
public void testBug57662() throws Exception {
4104
createTable("testBug57662", "(x VARCHAR(10) NOT NULL DEFAULT '')");
4105
Connection conn_is = null;
4107
Properties props = new Properties();
4108
props.setProperty("profileSQL", "true");
4109
props.setProperty("useNanosForElapsedTime", "true");
4110
props.setProperty("logger", "testsuite.simple.TestBug57662Logger");
4111
conn_is = getConnectionWithProps(props);
4112
this.rs = conn_is.getMetaData().getColumns(null, null,
4113
"testBug57662", "%");
4115
assertFalse(((testsuite.simple.TestBug57662Logger)((ConnectionImpl) conn_is).getLog()).hasNegativeDurations);
4118
if (conn_is != null) {
4125
public void testBug14563127() throws Exception {
4126
Properties props = new Properties();
4127
props.setProperty("loadBalanceStrategy",
4128
ForcedLoadBalanceStrategy.class.getName());
4129
props.setProperty("loadBalanceBlacklistTimeout", "5000");
4130
props.setProperty("loadBalancePingTimeout", "100");
4131
props.setProperty("loadBalanceValidateConnectionOnSwapServer", "true");
4133
String portNumber = new NonRegisteringDriver().parseURL(dbUrl, null)
4134
.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);
4136
if (portNumber == null) {
4137
portNumber = "3306";
4140
ForcedLoadBalanceStrategy.forceFutureServer("first:" + portNumber, -1);
4141
Connection conn2 = this.getUnreliableLoadBalancedConnection(
4142
new String[] { "first", "second" }, props);
4143
conn2.setAutoCommit(false);
4144
conn2.createStatement().execute("SELECT 1");
4146
// make sure second is added to active connections cache:
4147
ForcedLoadBalanceStrategy.forceFutureServer("second:" + portNumber, -1);
4150
// switch back to first:
4151
ForcedLoadBalanceStrategy.forceFutureServer("first:" + portNumber, -1);
4154
// kill second while still in cache:
4155
UnreliableSocketFactory.downHost("second");
4157
// force second host to be selected next time:
4158
ForcedLoadBalanceStrategy.forceFutureServer("second:" + portNumber, 1);
4161
conn2.commit(); // will be on second after this
4162
assertTrue("Connection should not be closed", !conn2.isClosed());
4163
} catch (SQLException e) {
4164
fail("Should not error because failure to select another server.");
4172
* Tests fix for BUG#11237 useCompression=true and LOAD DATA LOCAL INFILE SQL Command
4175
* if any errors occur
4177
public void testBug11237() throws Exception {
4178
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'max_allowed_packet'");
4180
if (this.rs.getInt(2) < 4+1024*1024*16-1) {
4181
fail("You need to increase max_allowed_packet to at least "+(4+1024*1024*16-1)+" before running this test!");
4184
int requiredSize = 1024*1024*300;
4185
int fieldLength = 1023;
4186
int loops = requiredSize / 2 / (fieldLength + 1);
4188
File testFile = File.createTempFile("cj-testloaddata", ".dat");
4189
testFile.deleteOnExit();
4190
cleanupTempFiles(testFile, "cj-testloaddata");
4192
BufferedOutputStream bOut = new BufferedOutputStream(new FileOutputStream(testFile));
4194
for (int i = 0; i < loops; i++) {
4195
for (int j = 0; j < fieldLength; j++) {
4196
bOut.write("a".getBytes()[0]);
4198
bOut.write("\t".getBytes()[0]);
4199
for (int j = 0; j < fieldLength; j++) {
4200
bOut.write("b".getBytes()[0]);
4202
bOut.write("\n".getBytes()[0]);
4208
createTable("testBug11237", "(field1 VARCHAR(1024), field2 VARCHAR(1024))");
4210
StringBuffer fileNameBuf = null;
4212
if (File.separatorChar == '\\') {
4213
fileNameBuf = new StringBuffer();
4215
String fileName = testFile.getAbsolutePath();
4216
int fileNameLength = fileName.length();
4218
for (int i = 0; i < fileNameLength; i++) {
4219
char c = fileName.charAt(i);
4222
fileNameBuf.append("/");
4224
fileNameBuf.append(c);
4228
fileNameBuf = new StringBuffer(testFile.getAbsolutePath());
4231
Properties props = new Properties();
4232
props.put("useCompression", "true");
4233
Connection conn1 = getConnectionWithProps(props);
4234
Statement stmt1 = conn1.createStatement();
4236
int updateCount = stmt1
4237
.executeUpdate("LOAD DATA LOCAL INFILE '"
4238
+ fileNameBuf.toString()
4239
+ "' INTO TABLE testBug11237" +
4240
" CHARACTER SET " + CharsetMapping.getMysqlEncodingForJavaEncoding(((MySQLConnection)this.conn).getEncoding(), (com.mysql.jdbc.Connection) conn1));
4242
assertTrue(updateCount == loops);
4246
public void testStackOverflowOnMissingInterceptor() throws Exception {
4248
Properties props = new Properties();
4249
props.setProperty("statementInterceptors", "fooBarBaz");
4251
getConnectionWithProps(props).close();
4252
} catch (Exception e) {
4256
public void testExpiredPassword() throws Exception {
4257
if (versionMeetsMinimum(5, 6, 10)) {
4258
Connection testConn = null;
4259
Statement testSt = null;
4260
ResultSet testRs = null;
4262
Properties urlProps = new NonRegisteringDriver().parseURL(dbUrl, null);
4263
String dbname = urlProps.getProperty(Driver.DBNAME_PROPERTY_KEY);
4267
this.stmt.executeUpdate("grant all on `"+dbname+"`.* to 'must_change1'@'%' IDENTIFIED BY 'aha'");
4268
this.stmt.executeUpdate("grant all on `"+dbname+"`.* to 'must_change2'@'%' IDENTIFIED BY 'aha'");
4269
this.stmt.executeUpdate("ALTER USER 'must_change1'@'%' PASSWORD EXPIRE, 'must_change2'@'%' PASSWORD EXPIRE");
4271
Properties props = new Properties();
4273
// ALTER USER can be prepared as of 5.6.8 (BUG#14646014)
4274
if (versionMeetsMinimum(5, 6, 8)) {
4275
props.setProperty("useServerPrepStmts", "true");
4276
testConn = getConnectionWithProps(props);
4278
this.pstmt = testConn.prepareStatement("ALTER USER 'must_change1'@'%' PASSWORD EXPIRE, 'must_change2'@'%' PASSWORD EXPIRE");
4279
this.pstmt.executeUpdate();
4282
this.pstmt = testConn.prepareStatement("ALTER USER ? PASSWORD EXPIRE, 'must_change2'@'%' PASSWORD EXPIRE");
4283
this.pstmt.setString(1, "must_change1");
4284
this.pstmt.executeUpdate();
4290
props.setProperty("user", "must_change1");
4291
props.setProperty("password", "aha");
4294
testConn = getConnectionWithProps(props);
4295
fail("SQLException expected due to password expired");
4296
} catch (SQLException e1) {
4298
if (e1.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD ||
4299
e1.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD_LOGIN) {
4301
props.setProperty("disconnectOnExpiredPasswords", "false");
4303
testConn = getConnectionWithProps(props);
4304
testSt = testConn.createStatement();
4305
testRs = testSt.executeQuery("SHOW VARIABLES LIKE 'disconnect_on_expired_password'");
4306
fail("SQLException expected due to password expired");
4308
} catch (SQLException e3) {
4309
if (e3.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD_LOGIN) {
4310
testConn = getConnectionWithProps(props);
4311
testSt = testConn.createStatement();
4313
testSt.executeUpdate("SET PASSWORD = PASSWORD('newpwd')");
4316
props.setProperty("user", "must_change1");
4317
props.setProperty("password", "newpwd");
4318
props.setProperty("disconnectOnExpiredPasswords", "true");
4319
testConn = getConnectionWithProps(props);
4320
testSt = testConn.createStatement();
4321
testRs = testSt.executeQuery("SHOW VARIABLES LIKE 'disconnect_on_expired_password'");
4322
assertTrue(testRs.next());
4326
((MySQLConnection) testConn).changeUser("must_change2", "aha");
4327
fail("SQLException expected due to password expired");
4329
} catch (SQLException e4) {
4330
if (e4.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD ||
4331
e4.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD_LOGIN) {
4332
props.setProperty("disconnectOnExpiredPasswords", "false");
4333
testConn = getConnectionWithProps(props);
4336
((MySQLConnection) testConn).changeUser("must_change2", "aha");
4337
testSt = testConn.createStatement();
4338
testRs = testSt.executeQuery("SHOW VARIABLES LIKE 'disconnect_on_expired_password'");
4339
fail("SQLException expected due to password expired");
4341
} catch (SQLException e5) {
4342
if (e5.getErrorCode() == MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD_LOGIN) {
4343
testConn = getConnectionWithProps(props);
4344
testSt = testConn.createStatement();
4346
testSt.executeUpdate("SET PASSWORD = PASSWORD('newpwd')");
4349
props.setProperty("user", "must_change2");
4350
props.setProperty("password", "newpwd");
4351
props.setProperty("disconnectOnExpiredPasswords", "true");
4352
testConn = getConnectionWithProps(props);
4353
testSt = testConn.createStatement();
4354
testRs = testSt.executeQuery("SHOW VARIABLES LIKE 'disconnect_on_expired_password'");
4355
assertTrue(testRs.next());
4374
if (testRs != null) testRs.close();
4375
if (testSt != null) testSt.close();
4376
if (testConn != null) testConn.close();
4377
this.stmt.executeUpdate("drop user 'must_change1'@'%'");
4378
this.stmt.executeUpdate("drop user 'must_change2'@'%'");
4385
public void testBug68011() throws Exception {
4387
Connection c = null;
4389
Properties props = new Properties();
4390
props.setProperty("noDatetimeStringSync", "true");
4391
props.setProperty("useTimezone", "true");
4392
c = getConnectionWithProps(props);
4393
} catch (SQLException e) {
4394
assertTrue(e.getMessage().contains("noDatetimeStringSync"));
4403
* Tests connection attributes
4407
public void testConnectionAttributes() throws Exception {
4408
if(!versionMeetsMinimum(5, 6)){
4411
Properties props = new Properties();
4412
props.setProperty("connectionAttributes", "first:one,again:two");
4413
props.setProperty("user", "root");
4414
Connection attConn = super.getConnectionWithProps(props);
4415
ResultSet rslt = attConn.createStatement().executeQuery(
4416
"SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id = CONNECTION_ID()"
4418
Map<String, Integer> matchedCounts = new HashMap<String, Integer>();
4420
// disabling until standard values are defined and implemented
4421
// matchedCounts.put("_os", 0);
4422
// matchedCounts.put("_platform", 0);
4423
matchedCounts.put("_runtime_version", 0);
4424
matchedCounts.put("_runtime_vendor", 0);
4425
matchedCounts.put("_client_version", 0);
4426
matchedCounts.put("_client_license", 0);
4427
matchedCounts.put("_client_name", 0);
4428
matchedCounts.put("first", 0);
4429
matchedCounts.put("again", 0);
4433
while (rslt.next()){
4434
String key = rslt.getString(2);
4435
String val = rslt.getString(3);
4436
if(!matchedCounts.containsKey(key)) {
4437
fail("Unexpected connection attribute key: " + key);
4439
matchedCounts.put(key, matchedCounts.get(key) + 1);
4440
if (key.equals("_runtime_version")) {
4441
assertEquals(System.getProperty("java.version"), val);
4442
} else if (key.equals("_os")) {
4443
assertEquals(NonRegisteringDriver.OS, val);
4444
} else if (key.equals("_platform")) {
4445
assertEquals(NonRegisteringDriver.PLATFORM, val);
4446
} else if (key.equals("_runtime_vendor")) {
4447
assertEquals(System.getProperty("java.vendor"), val);
4448
} else if (key.equals("_client_version")) {
4449
assertEquals(NonRegisteringDriver.VERSION, val);
4450
} else if (key.equals("_client_license")) {
4451
assertEquals(NonRegisteringDriver.LICENSE, val);
4452
} else if (key.equals("_client_name")) {
4453
assertEquals(NonRegisteringDriver.NAME, val);
4454
} else if (key.equals("first")) {
4455
assertEquals("one", val);
4456
} else if (key.equals("again")) {
4457
assertEquals("two", val);
4464
for (String key : matchedCounts.keySet()) {
4465
if(matchedCounts.get(key) != 1) {
4466
fail("Incorrect number of entries for key \"" + key + "\": " + matchedCounts.get(key));
4470
props.setProperty("connectionAttributes", "none");
4471
attConn = super.getConnectionWithProps(props);
4472
rslt = attConn.createStatement().executeQuery(
4473
"SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id = CONNECTION_ID()"
4476
fail("Expected no connection attributes.");
4484
* Tests fix for BUG#16224249 - Deadlock on concurrently used LoadBalancedMySQLConnection
4488
public void testBug16224249() throws Exception {
4490
Properties props = new NonRegisteringDriver().parseURL(dbUrl, null);
4491
String host = props.getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY, "localhost");
4492
String port = props.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY, "3306");
4493
String hostSpec = host;
4494
if (!NonRegisteringDriver.isHostPropertiesList(host)) {
4495
hostSpec = host + ":" + port;
4498
String database = props.getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
4499
removeHostRelatedProps(props);
4500
props.remove(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
4502
StringBuilder configs = new StringBuilder();
4503
for (@SuppressWarnings("rawtypes")
4504
Map.Entry entry : props.entrySet()) {
4505
configs.append(entry.getKey());
4506
configs.append("=");
4507
configs.append(entry.getValue());
4508
configs.append("&");
4511
String loadbalanceUrl = String.format("jdbc:mysql:loadbalance://%s,%s/%s?%s", hostSpec, hostSpec, database, configs.toString());
4512
String failoverUrl = String.format("jdbc:mysql://%s,%s/%s?%s", hostSpec, "127.0.0.1:"+port, database, configs.toString());
4514
Connection[] loadbalancedconnection = new Connection[] {
4515
new NonRegisteringDriver().connect(loadbalanceUrl, null),
4516
new NonRegisteringDriver().connect(loadbalanceUrl, null),
4517
new NonRegisteringDriver().connect(loadbalanceUrl, null)
4520
Connection[] failoverconnection = new Connection[] {
4521
new NonRegisteringDriver().connect(failoverUrl, null),
4522
new NonRegisteringDriver().connect(failoverUrl, null),
4523
new NonRegisteringDriver().connect(failoverUrl, null)
4526
// WebLogic-style test
4527
Class<?> mysqlCls = null;
4528
Class<?> jcls = failoverconnection[0].getClass(); // the driver-level connection, a Proxy in this case...
4529
ClassLoader jcl = jcls.getClassLoader();
4531
mysqlCls = jcl.loadClass("com.mysql.jdbc.Connection");
4533
mysqlCls = Class.forName("com.mysql.jdbc.Connection", true, null);
4536
if ( (mysqlCls != null) && (mysqlCls.isAssignableFrom(jcls))) {
4537
Method abort = mysqlCls.getMethod("abortInternal", new Class[]{});
4538
boolean hasAbortMethod = abort != null;
4539
assertTrue("abortInternal() method should be found for connection class " + jcls , hasAbortMethod);
4541
fail("com.mysql.jdbc.Connection interface IS NOT ASSIGNABE from connection class " + jcls );
4546
System.out.println("Warming up");
4547
for (int i = 0; i < failoverconnection.length; i++) {
4548
this.stmt = failoverconnection[i].createStatement();
4549
this.pstmt = failoverconnection[i].prepareStatement("SELECT 1 FROM DUAL");
4550
for (int j = 0; j < 10000; j++) {
4551
this.pstmt.executeQuery();
4552
this.stmt.executeQuery("SELECT 1 FROM DUAL");
4556
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(12);
4558
ScheduledFuture<?> f1 = scheduler.schedule(new PollTask(failoverconnection[0], 1), 500, TimeUnit.MILLISECONDS);
4559
ScheduledFuture<?> f2 = scheduler.schedule(new PollTask(failoverconnection[1], 2), 500, TimeUnit.MILLISECONDS);
4560
ScheduledFuture<?> f3 = scheduler.schedule(new PollTask(failoverconnection[2], 3), 500, TimeUnit.MILLISECONDS);
4561
ScheduledFuture<?> f4 = scheduler.schedule(new PollTask(loadbalancedconnection[0], 4), 500, TimeUnit.MILLISECONDS);
4562
ScheduledFuture<?> f5 = scheduler.schedule(new PollTask(loadbalancedconnection[1], 5), 500, TimeUnit.MILLISECONDS);
4563
ScheduledFuture<?> f6 = scheduler.schedule(new PollTask(loadbalancedconnection[2], 6), 500, TimeUnit.MILLISECONDS);
4565
ScheduledFuture<?> f7 = scheduler.schedule(new CancelTask(failoverconnection[0], 7), 600, TimeUnit.MILLISECONDS);
4566
ScheduledFuture<?> f8 = scheduler.schedule(new CancelTask(failoverconnection[1], 8), 600, TimeUnit.MILLISECONDS);
4567
ScheduledFuture<?> f9 = scheduler.schedule(new CancelTask(failoverconnection[2], 9), 600, TimeUnit.MILLISECONDS);
4568
ScheduledFuture<?> f10 = scheduler.schedule(new CancelTask(loadbalancedconnection[0], 10), 600, TimeUnit.MILLISECONDS);
4569
ScheduledFuture<?> f11 = scheduler.schedule(new CancelTask(loadbalancedconnection[1], 11), 600, TimeUnit.MILLISECONDS);
4570
ScheduledFuture<?> f12 = scheduler.schedule(new CancelTask(loadbalancedconnection[2], 12), 600, TimeUnit.MILLISECONDS);
4573
while (f1.get(5, TimeUnit.SECONDS) != null || f2.get(5, TimeUnit.SECONDS) != null ||
4574
f3.get(5, TimeUnit.SECONDS) != null || f4.get(5, TimeUnit.SECONDS) != null ||
4575
f5.get(5, TimeUnit.SECONDS) != null || f6.get(5, TimeUnit.SECONDS) != null ||
4576
f7.get(5, TimeUnit.SECONDS) != null || f8.get(5, TimeUnit.SECONDS) != null ||
4577
f9.get(5, TimeUnit.SECONDS) != null || f10.get(5, TimeUnit.SECONDS) != null ||
4578
f11.get(5, TimeUnit.SECONDS) != null || f12.get(5, TimeUnit.SECONDS) != null
4580
System.out.println("waiting");
4582
} catch (Exception e) {
4583
System.out.println(e.getMessage());
4586
if (this.testServerPrepStmtDeadlockCounter < 12) {
4587
Map<Thread, StackTraceElement[]> tr = Thread.getAllStackTraces();
4588
for (StackTraceElement[] el : tr.values()) {
4589
System.out.println();
4590
for (StackTraceElement stackTraceElement : el) {
4591
System.out.println(stackTraceElement);
4596
for (int i = 0; i < failoverconnection.length; i++) {
4598
rs = failoverconnection[i].createStatement().executeQuery("SELECT 1");
4599
} catch (Exception e1) {
4601
rs = failoverconnection[i].createStatement().executeQuery("SELECT 1");
4602
fail("Connection should be explicitly closed.");
4603
} catch (Exception e2) {
4609
scheduler.shutdown();
4613
* Tests fix for BUG#68763, ReplicationConnection.isMasterConnection() returns false always
4616
* if the test fails.
4618
public void testBug68763() throws Exception {
4620
ReplicationConnection replConn = null;
4622
replConn = (ReplicationConnection) getMasterSlaveReplicationConnection();
4623
replConn.setReadOnly(true);
4624
assertFalse("isMasterConnection() should be false for slave connection", replConn.isMasterConnection());
4625
replConn.setReadOnly(false);
4626
assertTrue("isMasterConnection() should be true for master connection", replConn.isMasterConnection());
4632
* Tests fix for BUG#68733, ReplicationConnection does not ping all underlying
4633
* active physical connections to slaves.
4636
* if the test fails.
4638
public void testBug68733() throws Exception {
4639
Properties props = new Properties();
4640
props.setProperty("loadBalanceStrategy",
4641
ForcedLoadBalanceStrategy.class.getName());
4642
props.setProperty("loadBalancePingTimeout", "100");
4643
props.setProperty("autoReconnect", "true");
4646
String portNumber = new NonRegisteringDriver().parseURL(dbUrl, null)
4647
.getProperty(NonRegisteringDriver.PORT_PROPERTY_KEY);
4649
if (portNumber == null) {
4650
portNumber = "3306";
4653
ForcedLoadBalanceStrategy.forceFutureServer("slave1:" + portNumber, -1);
4654
// throw Exception if slave2 gets ping
4655
UnreliableSocketFactory.downHost("slave2");
4657
Connection conn2 = this.getUnreliableReplicationConnection(
4658
new String[] { "master", "slave1", "slave2" }, props);
4659
((ReplicationConnection) conn2).isMasterConnection();
4660
assertTrue("Is not actually on master!", ((ReplicationConnection) conn2).isMasterConnection());
4663
conn2.setAutoCommit(false);
4667
conn2.setReadOnly(true);
4669
// should succeed, as slave2 has not yet been activated:
4670
conn2.createStatement().execute("/* ping */ SELECT 1");
4671
// allow connections to slave2:
4672
UnreliableSocketFactory.dontDownHost("slave2");
4673
// force next re-balance to slave2:
4674
ForcedLoadBalanceStrategy.forceFutureServer("slave2:" + portNumber, -1);
4677
// down slave1 (active but not selected slave connection):
4678
UnreliableSocketFactory.downHost("slave1");
4679
// should succeed, as slave2 is currently selected:
4680
conn2.createStatement().execute("/* ping */ SELECT 1");
4684
// make all hosts available
4685
UnreliableSocketFactory.flushAllHostLists();
4687
// peg connection to slave2:
4688
ForcedLoadBalanceStrategy.forceFutureServer("slave2:" + portNumber, -1);
4691
rs = conn2.createStatement().executeQuery("SELECT CONNECTION_ID()");
4693
int slave2id = rs.getInt(1);
4695
// peg connection to slave1 now:
4696
ForcedLoadBalanceStrategy.forceFutureServer("slave1:" + portNumber, -1);
4700
// this is a really hacky way to confirm ping was processed
4701
// by an inactive load-balanced connection, but we lack COM_PING
4702
// counters on the server side, and need to create infrastructure
4703
// to capture what's being sent by the driver separately.
4706
conn2.createStatement().execute("/* ping */ SELECT 1");
4707
rs = conn2.createStatement().executeQuery("SELECT time FROM information_schema.processlist WHERE id = " + slave2id);
4709
assertTrue("Processlist should be less than 2 seconds due to ping", rs.getInt(1) < 2);
4711
// peg connection to slave2:
4712
ForcedLoadBalanceStrategy.forceFutureServer("slave2:" + portNumber, -1);
4714
// leaving connection tied to slave2, bring slave2 down and slave1 up:
4715
UnreliableSocketFactory.downHost("slave2");
4718
conn2.createStatement().execute("/* ping */ SELECT 1");
4719
fail("Expected failure because current slave connection is down.");
4720
} catch (SQLException e) { }
4724
ForcedLoadBalanceStrategy.forceFutureServer("slave1:" + portNumber, -1);
4725
UnreliableSocketFactory.flushAllHostLists();
4726
conn2 = this.getUnreliableReplicationConnection(
4727
new String[] { "master", "slave1", "slave2" }, props);
4728
conn2.setAutoCommit(false);
4730
conn2.setReadOnly(true);
4735
ForcedLoadBalanceStrategy.forceFutureServer("slave2:" + portNumber, -1);
4740
UnreliableSocketFactory.downHost("master");
4742
// ping should succeed, because we're still attached to slaves:
4743
conn2.createStatement().execute("/* ping */ SELECT 1");
4745
// bring master back up:
4746
UnreliableSocketFactory.dontDownHost("master");
4748
// get back to master, confirm it's recovered:
4750
conn2.createStatement().execute("/* ping */ SELECT 1");
4752
conn2.setReadOnly(false);
4753
} catch (SQLException e) {}
4757
// take down both slaves:
4758
UnreliableSocketFactory.downHost("slave1");
4759
UnreliableSocketFactory.downHost("slave2");
4762
// should succeed, as we're still on master:
4763
conn2.createStatement().execute("/* ping */ SELECT 1");
4765
UnreliableSocketFactory.dontDownHost("slave1");
4766
UnreliableSocketFactory.dontDownHost("slave2");
4767
UnreliableSocketFactory.downHost("master");
4770
conn2.createStatement().execute("/* ping */ SELECT 1");
4771
fail("should have failed because master is offline");
4772
} catch (SQLException e) {
4776
UnreliableSocketFactory.dontDownHost("master");
4777
conn2.createStatement().execute("/* ping */ SELECT 1");
4778
// continue on slave2:
4779
conn2.setReadOnly(true);
4781
// should succeed, as slave2 is up:
4782
conn2.createStatement().execute("/* ping */ SELECT 1");
4784
UnreliableSocketFactory.downHost("slave2");
4787
conn2.createStatement().execute("/* ping */ SELECT 1");
4788
fail("should have failed because slave2 is offline and the active chosen connection.");
4789
} catch (SQLException e) {}
4795
protected int testServerPrepStmtDeadlockCounter = 0;
4797
class PollTask implements Runnable {
4799
private Connection c;
4800
private int num = 0;
4802
private Statement st1 = null;
4803
private PreparedStatement pst1 = null;
4805
PollTask(Connection cn, int n) throws SQLException {
4809
this.st1 = c.createStatement();
4810
this.pst1 = c.prepareStatement("SELECT 1 FROM DUAL");
4814
System.out.println(this.num + ". Start polling at "+new Date().getTime());
4815
boolean connectionClosed = false;
4817
for (int i = 0; i < 20000; i++) {
4819
this.st1.executeQuery("SELECT 1 FROM DUAL").close();
4820
this.pst1.executeQuery().close();
4821
} catch (Exception ex1) {
4822
if (!connectionClosed) {
4823
System.out.println(this.num + "." + i + " "+ex1.getMessage());
4824
connectionClosed = true;
4831
ConnectionRegressionTest.this.testServerPrepStmtDeadlockCounter++;
4832
System.out.println(this.num + ". Done!");
4837
class CancelTask implements Runnable {
4839
private Connection c;
4840
private int num = 0;
4842
CancelTask(Connection cn, int n) throws SQLException {
4848
System.out.println(this.num + ". Start cancelling at "+new Date().getTime());
4850
if (Proxy.isProxyClass(c.getClass())) {
4852
if (this.num == 7 || this.num == 10) {
4853
Proxy.getInvocationHandler(c).invoke(c, Connection.class.getMethod("close", new Class[]{}), null);
4854
} else if (this.num == 8 || this.num == 11) {
4855
Proxy.getInvocationHandler(c).invoke(c, MySQLConnection.class.getMethod("abortInternal", new Class[]{}), null);
4856
} else if (this.num == 9 || this.num == 12) {
4857
Proxy.getInvocationHandler(c).invoke(c, com.mysql.jdbc.Connection.class.getMethod("abort", new Class[]{Executor.class}), new Object[]{ new ThreadPerTaskExecutor()});
4860
ConnectionRegressionTest.this.testServerPrepStmtDeadlockCounter++;
4861
System.out.println(this.num + ". Done!");
4862
} catch (Throwable e) {
4863
e.printStackTrace();
4870
class ThreadPerTaskExecutor implements Executor {
4871
public void execute(Runnable r) {
4872
new Thread(r).start();
b'\\ No newline at end of file'