Derby
  1. Derby
  2. DERBY-6094

Derby ignores DriverManager.setLoginTimeout()

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.10.1.1
    • Fix Version/s: 10.10.1.1
    • Component/s: JDBC
    • Labels:
      None
    • Urgency:
      Normal
    • Issue & fix info:
      Repro attached
    • Bug behavior facts:
      Deviation from standard

      Description

      If you set a login timeout using the DriverManager, Derby ignores the setting. I will attach a test case which shows this.

      1. derby-6094-01-ac-enforceDriverManagerLoginTimeout.diff
        33 kB
        Rick Hillegas
      2. derby-6094-01-ad-enforceDriverManagerLoginTimeout.diff
        44 kB
        Rick Hillegas
      3. derby-6094-01-ae-enforceDriverManagerLoginTimeout.diff
        44 kB
        Rick Hillegas
      4. derby-6094-02-aa-createDBFirst.diff
        7 kB
        Rick Hillegas
      5. derby-6094-03-aa-retryOnInterrupt.diff
        5 kB
        Rick Hillegas
      6. derby-6094-04-aa-testCleanup.diff
        3 kB
        Rick Hillegas
      7. Driver20.java
        13 kB
        Dag H. Wanvik
      8. LoginTimeoutTest.java
        9 kB
        Rick Hillegas
      9. LoginTimeoutTest.java
        6 kB
        Rick Hillegas
      10. LoginTimeoutTest.java
        2 kB
        Rick Hillegas
      11. LoginTimeoutTest.java
        2 kB
        Rick Hillegas

        Issue Links

          Activity

          Hide
          Rick Hillegas added a comment -

          Attaching LoginTimeoutTest, a program which shows this problem. The test installs a user authenticator which takes 5 seconds to do its job. If you set the login timeout to 1 second and try to connect to Derby, you will get a Derby connection after 5 seconds.

          Show
          Rick Hillegas added a comment - Attaching LoginTimeoutTest, a program which shows this problem. The test installs a user authenticator which takes 5 seconds to do its job. If you set the login timeout to 1 second and try to connect to Derby, you will get a Derby connection after 5 seconds.
          Hide
          Rick Hillegas added a comment -

          Linking to DERBY-6000 because this issue was discovered while buddy-testing the JDBC 4.2 support: http://wiki.apache.org/db-derby/TenTenOneBuddyTesting. Also linking to DERBY-2026 because Dag posed a question there about whether we even test DriverManager.setLoginTimeout(). Apparently we don't.

          Show
          Rick Hillegas added a comment - Linking to DERBY-6000 because this issue was discovered while buddy-testing the JDBC 4.2 support: http://wiki.apache.org/db-derby/TenTenOneBuddyTesting . Also linking to DERBY-2026 because Dag posed a question there about whether we even test DriverManager.setLoginTimeout(). Apparently we don't.
          Hide
          Rick Hillegas added a comment -

          In private email, JDBC spec lead Lance Andersen confirms that the Driver implementation (not the DriverManager itself) is responsible for enforcing login timeouts.

          Show
          Rick Hillegas added a comment - In private email, JDBC spec lead Lance Andersen confirms that the Driver implementation (not the DriverManager itself) is responsible for enforcing login timeouts.
          Hide
          Rick Hillegas added a comment -

          Attaching a new version of LoginTimeoutTest, correcting a bug which caused it to always set the login timeout to 1 second.

          Show
          Rick Hillegas added a comment - Attaching a new version of LoginTimeoutTest, correcting a bug which caused it to always set the login timeout to 1 second.
          Hide
          Rick Hillegas added a comment -

          Attaching a new version of LoginTimeoutTest. This version shows what Derby does in the following situations:

          1) An embedded app tries to connect after calling DriverManager.setLoginTimeout() on the embedded VM.

          2) A client app tries to connect after someone called DriverManager.setLoginTimeout() on the server VM.

          3) A client app tries to connect after calling DriverManager.setLoginTimeout() on the client VM.

          I believe that in all 3 situations, sluggish logins should result in java.sql.SQLTimeoutException. The behavior right now is:

          (1) and (2): no exception

          (3): a java.sql.SQLNonTransientConnectionException

          I have coded a candidate solution, but I want to run a battery of tests before submitting it for community review.

          Show
          Rick Hillegas added a comment - Attaching a new version of LoginTimeoutTest. This version shows what Derby does in the following situations: 1) An embedded app tries to connect after calling DriverManager.setLoginTimeout() on the embedded VM. 2) A client app tries to connect after someone called DriverManager.setLoginTimeout() on the server VM. 3) A client app tries to connect after calling DriverManager.setLoginTimeout() on the client VM. I believe that in all 3 situations, sluggish logins should result in java.sql.SQLTimeoutException. The behavior right now is: (1) and (2): no exception (3): a java.sql.SQLNonTransientConnectionException I have coded a candidate solution, but I want to run a battery of tests before submitting it for community review.
          Hide
          Rick Hillegas added a comment -

          Attaching a new version of LoginTimeoutTest. This version shows the login timeout behavior of Derby's DataSources also.

          Show
          Rick Hillegas added a comment - Attaching a new version of LoginTimeoutTest. This version shows the login timeout behavior of Derby's DataSources also.
          Hide
          Dag H. Wanvik added a comment - - edited

          Good tests. Minor: comment say 5 seconds sleep, code says 2.

          I don't quite understand this result:

          Stopping server...
          Starting server with timeout 10
          :
          Setting timeout 10 on local connector
          Testing derby6094.Derby6094$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 )
          java.sql.SQLNonTransientConnectionException: SQLState = 08001. Message = java.net.ConnectException : \
          Error connecting to server localhost on port 8246 with message Connection refused: connect.
          Experiment took 1030 milliseconds.

          If both the client and the server side timeout is 10 seconds (I presume only the client side one sets any actual timeout: on the socket) and the authenticator sleeps only 2 (or 5) seconds, why the failure?

          Another question: You fork a server, but the test has unused code for starting the server via the API in the same VM. Have you seen a difference in behavior there?

          Show
          Dag H. Wanvik added a comment - - edited Good tests. Minor: comment say 5 seconds sleep, code says 2. I don't quite understand this result: Stopping server... Starting server with timeout 10 : Setting timeout 10 on local connector Testing derby6094.Derby6094$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 ) java.sql.SQLNonTransientConnectionException: SQLState = 08001. Message = java.net.ConnectException : \ Error connecting to server localhost on port 8246 with message Connection refused: connect. Experiment took 1030 milliseconds. If both the client and the server side timeout is 10 seconds (I presume only the client side one sets any actual timeout: on the socket) and the authenticator sleeps only 2 (or 5) seconds, why the failure? Another question: You fork a server, but the test has unused code for starting the server via the API in the same VM. Have you seen a difference in behavior there?
          Hide
          Rick Hillegas added a comment -

          Hi Dag,

          Thanks for taking a look at the LoginTimeoutTest repro. Attaching a new version of the repro which fixes that typo you found.

          I agree that the result you are seeing is odd. I don't see that result myself. This is a warning to me: when I turn this code into a regression test, it may be plagued by heisenbugs like our other timing-sensitive network tests. This is the result I see:

          Stopping server...
          Starting server with timeout 10

          Setting timeout 1 on local connector
          Testing LoginTimeoutTest$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 )
          java.sql.SQLNonTransientConnectionException: SQLState = 08006. Message = A communications error has been detected: Read timed out.
          Experiment took 1040 milliseconds.
          Setting timeout 10 on local connector
          Testing LoginTimeoutTest$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 )
          Ha! Got a org.apache.derby.client.net.NetConnection40
          Experiment took 4010 milliseconds.

          Note that when I ran the experiment, the odd test case succeeded (as expected), but it took 4 seconds rather than the authentication sleep time of 2 seconds. That is because Derby does double authentication when you create a database. I don't understand why you are seeing a "connection refused" error after 1 second when you run that experiment. A socket timeout ought to be reported as such, as you can see from the immediately preceding experiment on my machine. So it seems that you are seeing some other communications failure. Are your results reproducible?

          It's true that an earlier rev of the test ran the server in the same VM as the client. I thought that would make the test run faster because I wouldn't have to keep bouncing the server. But I abandoned that approach early on because it didn't test the case where the client and server set different timeouts.

          Thanks,
          -Rick

          Show
          Rick Hillegas added a comment - Hi Dag, Thanks for taking a look at the LoginTimeoutTest repro. Attaching a new version of the repro which fixes that typo you found. I agree that the result you are seeing is odd. I don't see that result myself. This is a warning to me: when I turn this code into a regression test, it may be plagued by heisenbugs like our other timing-sensitive network tests. This is the result I see: Stopping server... Starting server with timeout 10 Setting timeout 1 on local connector Testing LoginTimeoutTest$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 ) java.sql.SQLNonTransientConnectionException: SQLState = 08006. Message = A communications error has been detected: Read timed out. Experiment took 1040 milliseconds. Setting timeout 10 on local connector Testing LoginTimeoutTest$DriverManagerConnector( jdbc:derby://localhost:8246/memory:db1 ) Ha! Got a org.apache.derby.client.net.NetConnection40 Experiment took 4010 milliseconds. Note that when I ran the experiment, the odd test case succeeded (as expected), but it took 4 seconds rather than the authentication sleep time of 2 seconds. That is because Derby does double authentication when you create a database. I don't understand why you are seeing a "connection refused" error after 1 second when you run that experiment. A socket timeout ought to be reported as such, as you can see from the immediately preceding experiment on my machine. So it seems that you are seeing some other communications failure. Are your results reproducible? It's true that an earlier rev of the test ran the server in the same VM as the client. I thought that would make the test run faster because I wouldn't have to keep bouncing the server. But I abandoned that approach early on because it didn't test the case where the client and server set different timeouts. Thanks, -Rick
          Hide
          Rick Hillegas added a comment -

          Attaching derby-6094-01-ac-enforceDriverManagerLoginTimeout.diff. This is the first rev of a patch to fix this issue. The new regression test is vacuous and needs to be beefed up with the actual test cases from the repro. I am attaching this patch because I would like to get advice and early feedback from the community.

          At a high level, the patch does the following:

          1) Enforces login timeouts on the embedded driver and data sources.

          2) Makes client-side login timeouts conform to the JDBC 4.2 spec. That is, makes them raise SQLTimeoutException rather than the less refined SQLTransientException.

          3) Adds a debug flag so that JUnit tests can be run with login timeouts set.

          I would like the community's feedback on the following issues:

          A) Login timeouts are NOT implemented for CDC/FP 1.1. This is because I used java.util.concurrent classes to implement login timeouts and those classes are not available on CDC/FP 1.1. I think that it should be possible to implement login timeouts using the Thread support in FP 1.1, but I think that the java.util.concurrent approach is going to be easier to understand and maintain and likely to be more robust. If someone cares about login timeouts on CDC/FP 1.1, please speak up. We can log another JIRA for adding that feature. Note that I'm not volunteering to do that work: it's not an important platform to me.

          B) I am not sure what to do about Thread interrupts incurred during a timed login attempt. I would like advice from the experts on Derby interrupt handling. The attached patch simply wraps the interrupt exception in a SQLException. But maybe the right thing to do is to retry the login attempt until the timer expires. Or something else. I tripped across this problem while running InterruptResilienceTest with login timeouts. When I run that test like this...

          java -Dderby.tests.login.timeout=10 junit.textui.TestRunner org.apache.derbyTesting.functionTests.tests.store.InterruptResilienceTest

          ...I get errors in testRAFReadWriteMultipleThreads. It looks to me like the following is happening: A WorkerThread catches an interrupted lock exception, which it expects will happen from time to time. The WorkerThread then goes on to create a new connection but gets another interrupt before the login timeout expires.

          Touches the following files:

          ------------------

          M java/build/org/apache/derbyBuild/splitmessages.java
          M java/engine/org/apache/derby/impl/jdbc/SQLExceptionFactory40.java
          M java/engine/org/apache/derby/loc/messages.xml
          M java/shared/org/apache/derby/shared/common/reference/SQLState.java
          M java/client/org/apache/derby/client/am/SQLExceptionFactory40.java
          M java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java

          New SQLState for login timeouts. This is wrapped in a SQLTimeoutException on Java 6 and higher.

          ------------------

          M java/engine/org/apache/derby/jdbc/InternalDriver.java
          M java/engine/org/apache/derby/jdbc/Driver169.java
          M java/engine/org/apache/derby/jdbc/Driver20.java

          The guts of (1). This is where the java.util.concurrent classes are used to enforce login timeouts for the embedded driver.

          ------------------

          M java/engine/org/apache/derby/impl/jdbc/LOBStoredProcedure.java
          M java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java
          M java/engine/org/apache/derby/impl/db/SlaveDatabase.java
          M java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java
          M java/engine/org/apache/derby/jdbc/EmbeddedSimpleDataSource.java
          M java/engine/org/apache/derby/catalog/SystemProcedures.java
          M java/testing/org/apache/derbyTesting/functionTests/tests/tools/RollBackWrappingWhenFailOnImportTest.java

          The changes to the embedded driver resulted in an api change which percolated through the classes above.

          ------------------

          M java/client/org/apache/derby/client/net/NetConnection.java

          This is the enforcement of (2), the raising of SQLTimeoutException on the client when the login timeout expires.

          ------------------

          M java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
          M java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java
          M java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
          M java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java
          M java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
          M java/testing/org/apache/derbyTesting/junit/ConnectionPoolDataSourceConnector.java
          M java/testing/org/apache/derbyTesting/junit/Connector.java

          The changes for (3). Adds a new debug flag: derby.tests.login.timeout. You can set this to an integer, the length in seconds of the login timeout which you want to apply to all connection attempts. I have run the full JUnit suite with this flag set to 10. The tests run cleanly except for the following problems:

          i) The errors in InterruptResilienceTest described above.

          ii) I had to comment out NativeAuthenticationServiceTest. By itself, this test runs fine with derby.tests.login.timeout=10. However, when running the full JUnit suite with derby.tests.login.timeout=10, NativeAuthenticationServiceTest fails and its failure then chokes the rest of the suite. I need to investigate what's going on here.

          ------------------

          M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
          A java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java

          This is the shell of a new test which will contain the cases from the repro.

          Show
          Rick Hillegas added a comment - Attaching derby-6094-01-ac-enforceDriverManagerLoginTimeout.diff. This is the first rev of a patch to fix this issue. The new regression test is vacuous and needs to be beefed up with the actual test cases from the repro. I am attaching this patch because I would like to get advice and early feedback from the community. At a high level, the patch does the following: 1) Enforces login timeouts on the embedded driver and data sources. 2) Makes client-side login timeouts conform to the JDBC 4.2 spec. That is, makes them raise SQLTimeoutException rather than the less refined SQLTransientException. 3) Adds a debug flag so that JUnit tests can be run with login timeouts set. I would like the community's feedback on the following issues: A) Login timeouts are NOT implemented for CDC/FP 1.1. This is because I used java.util.concurrent classes to implement login timeouts and those classes are not available on CDC/FP 1.1. I think that it should be possible to implement login timeouts using the Thread support in FP 1.1, but I think that the java.util.concurrent approach is going to be easier to understand and maintain and likely to be more robust. If someone cares about login timeouts on CDC/FP 1.1, please speak up. We can log another JIRA for adding that feature. Note that I'm not volunteering to do that work: it's not an important platform to me. B) I am not sure what to do about Thread interrupts incurred during a timed login attempt. I would like advice from the experts on Derby interrupt handling. The attached patch simply wraps the interrupt exception in a SQLException. But maybe the right thing to do is to retry the login attempt until the timer expires. Or something else. I tripped across this problem while running InterruptResilienceTest with login timeouts. When I run that test like this... java -Dderby.tests.login.timeout=10 junit.textui.TestRunner org.apache.derbyTesting.functionTests.tests.store.InterruptResilienceTest ...I get errors in testRAFReadWriteMultipleThreads. It looks to me like the following is happening: A WorkerThread catches an interrupted lock exception, which it expects will happen from time to time. The WorkerThread then goes on to create a new connection but gets another interrupt before the login timeout expires. Touches the following files: ------------------ M java/build/org/apache/derbyBuild/splitmessages.java M java/engine/org/apache/derby/impl/jdbc/SQLExceptionFactory40.java M java/engine/org/apache/derby/loc/messages.xml M java/shared/org/apache/derby/shared/common/reference/SQLState.java M java/client/org/apache/derby/client/am/SQLExceptionFactory40.java M java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java New SQLState for login timeouts. This is wrapped in a SQLTimeoutException on Java 6 and higher. ------------------ M java/engine/org/apache/derby/jdbc/InternalDriver.java M java/engine/org/apache/derby/jdbc/Driver169.java M java/engine/org/apache/derby/jdbc/Driver20.java The guts of (1). This is where the java.util.concurrent classes are used to enforce login timeouts for the embedded driver. ------------------ M java/engine/org/apache/derby/impl/jdbc/LOBStoredProcedure.java M java/engine/org/apache/derby/impl/jdbc/authentication/NativeAuthenticationServiceImpl.java M java/engine/org/apache/derby/impl/db/SlaveDatabase.java M java/engine/org/apache/derby/jdbc/EmbeddedBaseDataSource.java M java/engine/org/apache/derby/jdbc/EmbeddedSimpleDataSource.java M java/engine/org/apache/derby/catalog/SystemProcedures.java M java/testing/org/apache/derbyTesting/functionTests/tests/tools/RollBackWrappingWhenFailOnImportTest.java The changes to the embedded driver resulted in an api change which percolated through the classes above. ------------------ M java/client/org/apache/derby/client/net/NetConnection.java This is the enforcement of (2), the raising of SQLTimeoutException on the client when the login timeout expires. ------------------ M java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java M java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java M java/testing/org/apache/derbyTesting/junit/TestConfiguration.java M java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java M java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java M java/testing/org/apache/derbyTesting/junit/ConnectionPoolDataSourceConnector.java M java/testing/org/apache/derbyTesting/junit/Connector.java The changes for (3). Adds a new debug flag: derby.tests.login.timeout. You can set this to an integer, the length in seconds of the login timeout which you want to apply to all connection attempts. I have run the full JUnit suite with this flag set to 10. The tests run cleanly except for the following problems: i) The errors in InterruptResilienceTest described above. ii) I had to comment out NativeAuthenticationServiceTest. By itself, this test runs fine with derby.tests.login.timeout=10. However, when running the full JUnit suite with derby.tests.login.timeout=10, NativeAuthenticationServiceTest fails and its failure then chokes the rest of the suite. I need to investigate what's going on here. ------------------ M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java A java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java This is the shell of a new test which will contain the cases from the repro.
          Hide
          Rick Hillegas added a comment - - edited

          Attaching derby-6094-01-ad-enforceDriverManagerLoginTimeout.diff. This version of the patch beefs up LoginTimeoutTest with test cases from the repro. I'm running tests now. If the tests pass, I plan to commit this version.

          I'm still interested in the community's advice about how thread interrupts should interact with login timeouts.

          I've also looked into the failures in NativeAuthenticationServiceTest which appear when you put it in a suite with another test and set derby.tests.login.timeout=10. I'm fairly certain that this is a test design defect but I haven't gotten to the bottom of it yet.

          Touches the following additional file:

          M java/testing/org/apache/derbyTesting/junit/JDBCClient.java

          Made the DERBYNETCLIENT constant public so that LoginTimeoutTest can use it.

          Show
          Rick Hillegas added a comment - - edited Attaching derby-6094-01-ad-enforceDriverManagerLoginTimeout.diff. This version of the patch beefs up LoginTimeoutTest with test cases from the repro. I'm running tests now. If the tests pass, I plan to commit this version. I'm still interested in the community's advice about how thread interrupts should interact with login timeouts. I've also looked into the failures in NativeAuthenticationServiceTest which appear when you put it in a suite with another test and set derby.tests.login.timeout=10. I'm fairly certain that this is a test design defect but I haven't gotten to the bottom of it yet. Touches the following additional file: M java/testing/org/apache/derbyTesting/junit/JDBCClient.java Made the DERBYNETCLIENT constant public so that LoginTimeoutTest can use it.
          Hide
          Rick Hillegas added a comment -

          Attaching derby-6094-01-ae-enforceDriverManagerLoginTimeout.diff. This third rev of the patch changes LoginTimeoutTest to use the singleUseDatabaseDecorator rather than CleanDatabaseTestSetup. For some reason, CleanDatabaseTestSetup results in errors when LoginTimeoutTest is run in a suite alongside other JUnit tests. Re-running the JUnit tests...

          Show
          Rick Hillegas added a comment - Attaching derby-6094-01-ae-enforceDriverManagerLoginTimeout.diff. This third rev of the patch changes LoginTimeoutTest to use the singleUseDatabaseDecorator rather than CleanDatabaseTestSetup. For some reason, CleanDatabaseTestSetup results in errors when LoginTimeoutTest is run in a suite alongside other JUnit tests. Re-running the JUnit tests...
          Hide
          Rick Hillegas added a comment -

          JUnit tests passed cleanly for me on derby-6094-01-ae-enforceDriverManagerLoginTimeout.diff. Committed at subversion revision 1454600.

          Show
          Rick Hillegas added a comment - JUnit tests passed cleanly for me on derby-6094-01-ae-enforceDriverManagerLoginTimeout.diff. Committed at subversion revision 1454600.
          Hide
          Dag H. Wanvik added a comment - - edited

          Thanks, Rick. For the record, the odd results I saw was due to pilot error (NetBeans doesn't pass the active class path to the server subprocess, to it never got started). I'll have a look at the interrupts issue.

          Show
          Dag H. Wanvik added a comment - - edited Thanks, Rick. For the record, the odd results I saw was due to pilot error (NetBeans doesn't pass the active class path to the server subprocess, to it never got started). I'll have a look at the interrupts issue.
          Hide
          Dag H. Wanvik added a comment -

          Currently, when Derby sees an interrupt, it does one of two things: a) if it is at a reasonable point to stop execution, e.g. waiting for a lock, or between statements in a batch, it will return control to the user with an exception b) if it is not in such a point of execution, it will make a note, but proceed, but possibly throw later, cf. point a). In both cases the interrupt flag remains set when the user regains control (i.e the JDBC call returns).

          I think in a login situation, we would only want to stop execution of the login if it is safe (as in in we wouldn't lose resources or cause internal inconsistencies). I see you use the Future class to carry out the login using an upper time bound corresponding to the login timeout. I don't know how the execution of the asynchronous task would be stopped in such a case. Would it be safe (necessarily)?

          If the Future#get method throws an interrupt exception, we could retry but with a shorter timeout, I guess (after noting and clearing the flag as per our common approach). Since we already have a mechanism for stopping if login takes too long I don't see the need for having interrupts as a mechanism to stop it.

          Show
          Dag H. Wanvik added a comment - Currently, when Derby sees an interrupt, it does one of two things: a) if it is at a reasonable point to stop execution, e.g. waiting for a lock, or between statements in a batch, it will return control to the user with an exception b) if it is not in such a point of execution, it will make a note, but proceed, but possibly throw later, cf. point a). In both cases the interrupt flag remains set when the user regains control (i.e the JDBC call returns). I think in a login situation, we would only want to stop execution of the login if it is safe (as in in we wouldn't lose resources or cause internal inconsistencies). I see you use the Future class to carry out the login using an upper time bound corresponding to the login timeout. I don't know how the execution of the asynchronous task would be stopped in such a case. Would it be safe (necessarily)? If the Future#get method throws an interrupt exception, we could retry but with a shorter timeout, I guess (after noting and clearing the flag as per our common approach). Since we already have a mechanism for stopping if login takes too long I don't see the need for having interrupts as a mechanism to stop it.
          Hide
          Knut Anders Hatlen added a comment -

          The new test failed in the latest nightly test cycle:

          http://download.java.net/javadesktop/derby/javadb-5573775-report/javadb-5573775-3606706-details.html

          junit.framework.AssertionFailedError: Should have been able to connect!
          at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.tryTimeout(LoginTimeoutTest.java:290)
          at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.tryTimeout(LoginTimeoutTest.java:277)
          at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.vetConnector(LoginTimeoutTest.java:266)
          at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.testBasic(LoginTimeoutTest.java:255)
          at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
          (...)

          Show
          Knut Anders Hatlen added a comment - The new test failed in the latest nightly test cycle: http://download.java.net/javadesktop/derby/javadb-5573775-report/javadb-5573775-3606706-details.html junit.framework.AssertionFailedError: Should have been able to connect! at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.tryTimeout(LoginTimeoutTest.java:290) at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.tryTimeout(LoginTimeoutTest.java:277) at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.vetConnector(LoginTimeoutTest.java:266) at org.apache.derbyTesting.functionTests.tests.jdbc4.LoginTimeoutTest.testBasic(LoginTimeoutTest.java:255) at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117) (...)
          Hide
          Dag H. Wanvik added a comment -

          Uploading a modified Driver20.java suggesting how we could handle interrupts seen in the util.concurrent calls. Basically, the code retries the connect until the timeout has happened or success, reestablish the interrupt flag on exit. This also makes InterruptResilienceTest work in my environment.

          Show
          Dag H. Wanvik added a comment - Uploading a modified Driver20.java suggesting how we could handle interrupts seen in the util.concurrent calls. Basically, the code retries the connect until the timeout has happened or success, reestablish the interrupt flag on exit. This also makes InterruptResilienceTest work in my environment.
          Hide
          Rick Hillegas added a comment -

          Thanks, Dag. The change to Driver20 looks good to me. I suppose that in an interrupt-intensive application, this change could result in login timeouts lasting up to twice the time which the application specifies. In such an environment, timing is likely to be throw off a lot. I don't think this needs to be sanded down further. Thanks.

          Show
          Rick Hillegas added a comment - Thanks, Dag. The change to Driver20 looks good to me. I suppose that in an interrupt-intensive application, this change could result in login timeouts lasting up to twice the time which the application specifies. In such an environment, timing is likely to be throw off a lot. I don't think this needs to be sanded down further. Thanks.
          Hide
          Rick Hillegas added a comment -

          Attaching derby-6094-02-aa-createDBFirst.diff. Hopefully, this will fix the failure in LoginTimeoutTest seen on Linux. Committed at subversion revision 1455156.

          I ran the LoginTimeoutTest on Java 7 on Linux running inside VirtualBox on Mac OSX. The test failed for me there. For some reason, database creation takes a long time in that environment. This caused an initial connection attempt to fail on a login timeout when the test expected the connection attempt to succeed. I have changed the test in order to remove this source of heisenbugs. Now the test creates the database before trying to test timeouts.

          While I was in there, I also added some more defensive logic to make the test cleanup after itself when an unexpected error occurs.

          Touches the following files:

          M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java
          M java/testing/org/apache/derbyTesting/junit/BaseTestCase.java

          Show
          Rick Hillegas added a comment - Attaching derby-6094-02-aa-createDBFirst.diff. Hopefully, this will fix the failure in LoginTimeoutTest seen on Linux. Committed at subversion revision 1455156. I ran the LoginTimeoutTest on Java 7 on Linux running inside VirtualBox on Mac OSX. The test failed for me there. For some reason, database creation takes a long time in that environment. This caused an initial connection attempt to fail on a login timeout when the test expected the connection attempt to succeed. I have changed the test in order to remove this source of heisenbugs. Now the test creates the database before trying to test timeouts. While I was in there, I also added some more defensive logic to make the test cleanup after itself when an unexpected error occurs. Touches the following files: M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java M java/testing/org/apache/derbyTesting/junit/BaseTestCase.java
          Hide
          Rick Hillegas added a comment -

          Attaching derby-6094-03-aa-retryOnInterrupt.diff. This patch applies Dag's suggested changes. I am running tests now.

          I also added a login timeout to the InterruptResilienceTest. That forces the new logic to be excercised.

          With the new logic, I have successfully run InterruptResilienceTest and LoginTimeoutTest on Mac OSX and on Linux on top of VirtualBox on top of Mac OSX.

          Touches the following files:

          M java/engine/org/apache/derby/jdbc/Driver20.java
          M java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java

          Show
          Rick Hillegas added a comment - Attaching derby-6094-03-aa-retryOnInterrupt.diff. This patch applies Dag's suggested changes. I am running tests now. I also added a login timeout to the InterruptResilienceTest. That forces the new logic to be excercised. With the new logic, I have successfully run InterruptResilienceTest and LoginTimeoutTest on Mac OSX and on Linux on top of VirtualBox on top of Mac OSX. Touches the following files: M java/engine/org/apache/derby/jdbc/Driver20.java M java/testing/org/apache/derbyTesting/functionTests/tests/store/InterruptResilienceTest.java
          Hide
          Knut Anders Hatlen added a comment -

          Thanks for fixing the test instability, Rick.

          Two small nits:

          • The new connection that's used to ensure the database is created, should probably be closed after use (connections created with openDefaultConnection() aren't automatically closed by the framework).
          • The new minion failWithTrace() duplicates the functionality in BaseTestCase.fail(String msg, Throwable t), except the latter will make the original stack trace available to the JUnit machinery, not just print it to the console.
          Show
          Knut Anders Hatlen added a comment - Thanks for fixing the test instability, Rick. Two small nits: The new connection that's used to ensure the database is created, should probably be closed after use (connections created with openDefaultConnection() aren't automatically closed by the framework). The new minion failWithTrace() duplicates the functionality in BaseTestCase.fail(String msg, Throwable t), except the latter will make the original stack trace available to the JUnit machinery, not just print it to the console.
          Hide
          Rick Hillegas added a comment -

          Tests passed cleanly for me on derby-6094-03-aa-retryOnInterrupt.diff. Committed at subversion revision 1455230.

          Show
          Rick Hillegas added a comment - Tests passed cleanly for me on derby-6094-03-aa-retryOnInterrupt.diff. Committed at subversion revision 1455230.
          Hide
          Rick Hillegas added a comment -

          Thanks for the quick review, Knut. Attaching derby-6094-04-aa-testCleanup.diff. This patch makes the changes Knut suggested. The patched test runs cleanly for me on Mac OSX and on Linux on VirtualBox on Mac OSX. Committed at subversion revision 1455238.

          Touches the following file:

          M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java

          Show
          Rick Hillegas added a comment - Thanks for the quick review, Knut. Attaching derby-6094-04-aa-testCleanup.diff. This patch makes the changes Knut suggested. The patched test runs cleanly for me on Mac OSX and on Linux on VirtualBox on Mac OSX. Committed at subversion revision 1455238. Touches the following file: M java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/LoginTimeoutTest.java
          Hide
          Rick Hillegas added a comment -

          I believe the work on this issue is done. I have logged a follow-on issue, DERBY-6107, to investigate why setting a login timeout causes NativeAuthenticationServiceTest to fail when run inside a larger suite.

          Show
          Rick Hillegas added a comment - I believe the work on this issue is done. I have logged a follow-on issue, DERBY-6107 , to investigate why setting a login timeout causes NativeAuthenticationServiceTest to fail when run inside a larger suite.

            People

            • Assignee:
              Unassigned
              Reporter:
              Rick Hillegas
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development