Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0131A91E5 for ; Fri, 3 Feb 2012 13:25:33 +0000 (UTC) Received: (qmail 96055 invoked by uid 500); 3 Feb 2012 13:25:32 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 95983 invoked by uid 500); 3 Feb 2012 13:25:32 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 95976 invoked by uid 99); 3 Feb 2012 13:25:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 03 Feb 2012 13:25:31 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 03 Feb 2012 13:25:30 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 235D023888FD; Fri, 3 Feb 2012 13:25:10 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1240152 - in /db/derby/code/trunk/java/testing/org/apache/derbyTesting: functionTests/tests/lang/NativeAuthenticationServiceTest.java junit/NetworkServerTestSetup.java Date: Fri, 03 Feb 2012 13:25:10 -0000 To: derby-commits@db.apache.org From: rhillegas@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120203132510.235D023888FD@eris.apache.org> Author: rhillegas Date: Fri Feb 3 13:25:09 2012 New Revision: 1240152 URL: http://svn.apache.org/viewvc?rev=1240152&view=rev Log: DERBY-866: Add test for database restoration using NATIVE authentication. Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/NetworkServerTestSetup.java Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java?rev=1240152&r1=1240151&r2=1240152&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthenticationServiceTest.java Fri Feb 3 13:25:09 2012 @@ -21,16 +21,19 @@ package org.apache.derbyTesting.functionTests.tests.lang; +import java.io.File; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.Properties; +import javax.sql.DataSource; import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.derbyTesting.junit.DatabaseChangeSetup; import org.apache.derbyTesting.junit.JDBC; +import org.apache.derbyTesting.junit.JDBCDataSource; import org.apache.derbyTesting.junit.TestConfiguration; import org.apache.derbyTesting.junit.SystemPropertyTestSetup; @@ -52,6 +55,7 @@ public class NativeAuthenticationService private static final String APPLE_USER = "APPLE"; private static final String PEAR_USER = "PEAR"; private static final String ORANGE_USER = "ORANGE"; + private static final String BANANA_USER = "BANANA"; private static final String WALNUT_USER = "WALNUT"; @@ -60,6 +64,7 @@ public class NativeAuthenticationService private static final String THIRD_DB = "thirdDB"; private static final String FOURTH_DB = "fourthDB"; private static final String FIFTH_DB = "fifthDB"; + private static final String SIXTH_DB = "sixthDB"; private static final String PROVIDER_PROPERTY = "derby.authentication.provider"; @@ -81,8 +86,14 @@ public class NativeAuthenticationService private final boolean _nativeAuthentication; private final boolean _localAuthentication; + private String _credentialsDBPhysicalName; + private DatabaseChangeSetup _fourthDBSetup; private DatabaseChangeSetup _fifthDBSetup; + private DatabaseChangeSetup _sixthDBSetup; + + private String _derbySystemHome; + private String _fullBackupDir; /////////////////////////////////////////////////////////////////////////////////// // @@ -108,6 +119,14 @@ public class NativeAuthenticationService // /////////////////////////////////////////////////////////////////////////////////// + public void setUp() throws Exception + { + super.setUp(); + + _derbySystemHome = getSystemProperty( "derby.system.home" ); + _fullBackupDir = _derbySystemHome + "/backupDir"; + } + /** *

* Return the system properties to be used in a particular test run. @@ -115,12 +134,21 @@ public class NativeAuthenticationService */ private Properties systemProperties( String physicalDatabaseName ) { - if ( !_nativeAuthentication ) { return null; } + Properties result = new Properties(); + String authenticationProvider; - String authenticationProvider = "NATIVE:" + physicalDatabaseName; - if ( _localAuthentication ) { authenticationProvider = authenticationProvider + ":LOCAL"; } + _credentialsDBPhysicalName = physicalDatabaseName; + + if ( !_nativeAuthentication ) + { + authenticationProvider = "NONE"; + } + else + { + authenticationProvider = "NATIVE:" + physicalDatabaseName; + if ( _localAuthentication ) { authenticationProvider = authenticationProvider + ":LOCAL"; } + } - Properties result = new Properties(); result.put( PROVIDER_PROPERTY, authenticationProvider ); return result; @@ -214,20 +242,16 @@ public class NativeAuthenticationService // databases (the credentials db) in order to authenticate engine shutdown. // Properties systemProperties = systemProperties( credentialsDBPhysicalName ); - if ( systemProperties != null ) - { - result = new SystemPropertyTestSetup( result, systemProperties, true ); - } - else - { - // DERBY-5580: We should also shut down the engine before deleting - // the database if we don't set any system properties. - result = new TestSetup(result) { - protected void tearDown() { - TestConfiguration.getCurrent().shutdownEngine(); - } - }; - } + println( "NativeAuthenticationServiceTest.decorate() systemProperties = " + systemProperties ); + result = new SystemPropertyTestSetup( result, systemProperties, true ); + + // DERBY-5580: We should also shut down the engine before deleting + // the database if we don't set any system properties. + //result = new TestSetup(result) { + // protected void tearDown() { + // TestConfiguration.getCurrent().shutdownEngine(); + // } + // }; // // Register temporary databases, where the test will do its work. @@ -240,6 +264,7 @@ public class NativeAuthenticationService result = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, THIRD_DB ); result = _fourthDBSetup = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, FOURTH_DB, true ); result = _fifthDBSetup = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, FIFTH_DB, true ); + result = _sixthDBSetup = TestConfiguration.additionalDatabaseDecoratorNoShutdown( result, SIXTH_DB, true ); result = TestConfiguration.changeUserDecorator( result, DBO, getPassword( DBO ) ); @@ -260,8 +285,11 @@ public class NativeAuthenticationService public void testAll() throws Exception { println( nameOfTest() ); + println( "Credentials DB physical name = " + _credentialsDBPhysicalName ); + println( PROVIDER_PROPERTY + " = " + getSystemProperty( PROVIDER_PROPERTY ) ); vetCoreBehavior(); + vetSystemWideOperations(); if ( !_nativeAuthentication ) { vetProviderChanges(); } @@ -288,6 +316,7 @@ public class NativeAuthenticationService // add another legal user addUser( sysadminConn, APPLE_USER ); + addUser( sysadminConn, BANANA_USER ); // // Creating the credentials db should have stored the following information in it: @@ -295,7 +324,9 @@ public class NativeAuthenticationService // 1) The DBO's credentials should have been stored in SYSUSERS. // 2) The authentication provider should have been set to NATIVE::LOCAL // - String[][] legalUsers = _nativeAuthentication ? new String[][] { { APPLE_USER }, { DBO } } : new String[][] { { APPLE_USER } }; + String[][] legalUsers = _nativeAuthentication ? + new String[][] { { APPLE_USER }, { BANANA_USER } , { DBO } } : + new String[][] { { APPLE_USER }, { BANANA_USER } }; assertResults ( sysadminConn, @@ -388,6 +419,111 @@ public class NativeAuthenticationService /** *

+ * The vetCoreBehavior() method verifies credentials-checking for the + * following system-wide operations: + *

+ * + *
    + *
  • Database creation.
  • + *
  • Engine shutdown.
  • + *
  • Server shutdown. The default credentials are embedded inside the NetworkServerControl + * created by NetworkServerTestSetup.
  • + *
+ * + *

+ * This method verifies credentials-checking for this additional + * system-wide operation: + *

+ * + *
    + *
  • Database restoration.
  • + *
+ */ + private void vetSystemWideOperations() throws Exception + { + // create a database which we will backup and restore + Connection dboConn = openConnection( SIXTH_DB, DBO ); + + // add another user who can perform restores successfully + addUser( dboConn, BANANA_USER ); + + // add a table which we will backup and then drain. this is so that later on we can + // verify that we really restored the database rather than just reconnected to the + // original version. + goodStatement( dboConn, "create table t( a int )" ); + goodStatement( dboConn, "insert into t( a ) values ( 1000 )" ); + if ( _nativeAuthentication) + { + goodStatement( dboConn, "grant select on table t to public" ); + goodStatement( dboConn, "grant insert on table t to public" ); + } + goodStatement( dboConn, "call syscs_util.syscs_backup_database( '" + _fullBackupDir + "' )" ); + goodStatement( dboConn, "delete from t" ); + + // this user is valid both in the system-wide credentials db and in the local db + shutdownAndRestoreDB( true, BANANA_USER, null ); + + // + // If we are doing local authentication, then restoration will fail when we use + // the credentials of a user who is in the system-wide SYSUSERS but not + // in the SYSUSERS of the database being restored. Restoration involves two + // authentication attempts: First we authenticate system-wide in order to + // verify that it's ok to proceed with the restoration. After that, we attempt + // to connect to the restored database. It is the authentication of the second + // attempt which may fail here. + // + shutdownAndRestoreDB( !_localAuthentication, APPLE_USER, INVALID_AUTHENTICATION ); + + // delete the backup directory + assertDirectoryDeleted( new File( _fullBackupDir ) ); + } + private void shutdownAndRestoreDB( boolean shouldSucceed, String user, String expectedSQLState ) throws Exception + { + // shutdown the database. the restore will overwrite it. + _sixthDBSetup.getTestConfiguration().shutdownDatabase(); + + // the physical database name has some parent directories in it. + // we need to strip these off because backup ignores them. + String dbName = _sixthDBSetup.physicalDatabaseName(); + int slashIdx = dbName.lastIndexOf( "/" ); + if ( slashIdx >= 0 ) { dbName = dbName.substring( slashIdx + 1 ); } + + DataSource ds = JDBCDataSource.getDataSourceLogical( SIXTH_DB ); + String fullRestoreDir = _fullBackupDir + "/" + dbName; + JDBCDataSource.setBeanProperty( ds, "connectionAttributes", "restoreFrom=" + fullRestoreDir ); + + Connection conn = null; + + try { + conn = ds.getConnection( user, getPassword( user ) ); + + if ( !shouldSucceed ) { fail( tagError( "Database restoration should have failed." ) ); } + } + catch (SQLException se) + { + if ( shouldSucceed ) { fail( tagError( "Database restoration unexpectedly failed." ) );} + else { assertSQLState( expectedSQLState, se ); } + } + + if ( conn != null ) + { + // verify that this is the version which was backed up, not the original + assertResults + ( + conn, + "select a from " + DBO + ".t", + new String[][] { { "1000" } }, + false + ); + + // add another tuple to distinguish the database from later attempts + // to re-initialize it from the backup + goodStatement( conn, "insert into " + DBO + ".t( a ) values ( 2000 )" ); + } + } + + /** + *

* Try changing the value of the provider property on disk. * These tests are run only if authentication is turned off. *

@@ -580,7 +716,7 @@ public class NativeAuthenticationService { Connection conn = null; - println( user + " attempting to get connection to database " + dbName ); + reportConnectionAttempt( dbName, user ); try { conn = openConnection( dbName, user ); @@ -590,7 +726,7 @@ public class NativeAuthenticationService catch (SQLException se) { if ( shouldFail ) { assertSQLState( expectedSQLState, se ); } - else { fail( tagError( "Connection to " + dbName + " unexpectedly succeeded." ) );} + else { fail( tagError( "Connection to " + dbName + " unexpectedly failed." ) );} } return conn; @@ -602,7 +738,7 @@ public class NativeAuthenticationService { Connection conn = null; - println( user + " attempting to get connection to database " + dbName ); + reportConnectionAttempt( dbName, user ); conn = openConnection( dbName, user ); @@ -621,6 +757,12 @@ public class NativeAuthenticationService return conn; } + private void reportConnectionAttempt( String dbName, String user ) + { + println + ( user + " attempting to get connection to database " + dbName + + " aka " + getTestConfiguration().getPhysicalDatabaseName( dbName ) ); + } private void addUser( Connection conn, String user ) throws Exception { Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/NetworkServerTestSetup.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/NetworkServerTestSetup.java?rev=1240152&r1=1240151&r2=1240152&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/NetworkServerTestSetup.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/NetworkServerTestSetup.java Fri Feb 3 13:25:09 2012 @@ -459,7 +459,7 @@ final public class NetworkServerTestSetu spawnedServer.complete(failedShutdown != null, getWaitTime()); spawnedServer = null; } - + // Throw an error to record the fact that the // shutdown failed. if (failedShutdown != null) @@ -468,8 +468,7 @@ final public class NetworkServerTestSetu { // authentication failure is ok. if ( - !(failedShutdown instanceof SQLException) || - !( "4251I".equals( ((SQLException) failedShutdown).getSQLState() ) ) + !(failedShutdown instanceof SQLException) ) { throw (Exception) failedShutdown;