-
Notifications
You must be signed in to change notification settings - Fork 828
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce @DatabaseTestUTC for timezone-sensitive DB tests
- Loading branch information
Showing
6 changed files
with
102 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
server/src/test/java/org/cloudfoundry/identity/uaa/extensions/database/DatabaseTestUTC.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.cloudfoundry.identity.uaa.extensions.database; | ||
|
||
|
||
import org.cloudfoundry.identity.uaa.extensions.timezone.WithTimeZone; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Force the JVM timezone to be UTC for the current test, and reset all | ||
* database connections. This is required because MySQL and Possgres have | ||
* different behavior when it comes to timezone. When passing a time parameter | ||
* value to a JDBC template behaves in the same way, it is converted to the | ||
* JVM timezone. But calling {@code current_timestamp} has different behavior: | ||
* | ||
* <ul> | ||
* <li>In MySQL, it returns UTC-based time.</li> | ||
* <li>In Possgres, it returns timezone-sensitive timestamp. The selected timezone is the JVM timezone <b>whenever the connection was first opened</b>.</li> | ||
* </ul> | ||
* Timezone-sensitive tests are broken in MySQL when ran in a timezone ahead of UTC, | ||
* unless the JVM timezone is forced to be UTC. | ||
* <p> | ||
* Timezone-sensitive tests are broken in Postgres when the timezone is forced to UTC | ||
* right before a test and you are in a timezone behind UTC. | ||
* <p> | ||
* This annotation forces the timezone to be UTC, and then resets all connections, so that | ||
* Possgres connections match the JVM timezone. After a test, timezone is restored and | ||
* connections are reset once more. | ||
* <p> | ||
* It sets the correct order for {@link WithTimeZone} and {@link ResetDatabaseConnectionsExtension}, | ||
* so that the TimeZone is always correct before connections are reset. | ||
* | ||
* @see WithTimeZone | ||
* @see ResetDatabaseConnectionsExtension | ||
*/ | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target(ElementType.METHOD) | ||
@WithTimeZone(WithTimeZone.UTC) | ||
@ExtendWith(ResetDatabaseConnectionsExtension.class) | ||
public @interface DatabaseTestUTC { | ||
} |
47 changes: 47 additions & 0 deletions
47
.../org/cloudfoundry/identity/uaa/extensions/database/ResetDatabaseConnectionsExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package org.cloudfoundry.identity.uaa.extensions.database; | ||
|
||
import org.apache.tomcat.jdbc.pool.DataSource; | ||
import org.junit.jupiter.api.extension.AfterEachCallback; | ||
import org.junit.jupiter.api.extension.BeforeEachCallback; | ||
import org.junit.jupiter.api.extension.ExtensionContext; | ||
import org.springframework.lang.Nullable; | ||
import org.springframework.test.context.junit.jupiter.SpringExtension; | ||
|
||
/** | ||
* Extension to reset database connections before and after a test. | ||
* It closes all existing connections. This is particularly useful when the | ||
* database connection sets session properties when they are opened. | ||
* | ||
* @see DatabaseTestUTC | ||
*/ | ||
class ResetDatabaseConnectionsExtension implements BeforeEachCallback, AfterEachCallback { | ||
|
||
@Override | ||
public void beforeEach(ExtensionContext context) throws Exception { | ||
var dataSource = getDataSourceOrNull(context); | ||
if (dataSource == null) { | ||
return; | ||
} | ||
dataSource.getPool().purge(); | ||
} | ||
|
||
@Override | ||
public void afterEach(ExtensionContext context) throws Exception { | ||
var dataSource = getDataSourceOrNull(context); | ||
if (dataSource == null) { | ||
return; | ||
} | ||
dataSource.getPool().purge(); | ||
} | ||
|
||
|
||
@Nullable | ||
private DataSource getDataSourceOrNull(ExtensionContext context) { | ||
try { | ||
var applicationContext = SpringExtension.getApplicationContext(context); | ||
return applicationContext.getBean(DataSource.class); | ||
} catch (IllegalStateException ignore) { | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters