-
Notifications
You must be signed in to change notification settings - Fork 96
SchemaMigrator/SchemaValidator tests for corner cases #977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Is this for all databases? |
Shouldn't you rebase this on top of this other PR? #970 |
|
||
if ( DatabaseConfiguration.dbType() != DatabaseConfiguration.DBType.POSTGRESQL ) { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do things this way, this test will result in a success even if, in reality, you want to skip it.
That's way I've created the rule. It will also call the before/after methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Some of these tests are not DB specific in their purpose, but DB specific in query implementation. So options are still to find a cleaner (efficient) way to make that happen in one test class, or break them apart into multiple classes. I'm good with either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Break it in separate classes, please. Maybe inner classes extending an abstract super class.
The rule I've created is not that powerful and it only works for classes. if the only difference is the query, having an abstract super class with a mehod getQuery
(and maybe getResult
) will avoid a lot of duplicated work,
I think we could now switch to JUnit 5 and it will make the management of different test sper database easier. But that's a separate issue for when we have time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure.. I'll work toward abstraction and getQuery() & getResult().
@DavideD I added a schema
package since there may be more tests. Any issue with doing that at this time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DavideD I added a
schema
package since there may be more tests. Any issue with doing that at this time?
No, that's fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just keep in mind that we already have several test classes in the project and you should move them in the sme package if you want to create a new one
protected Configuration constructConfiguration(String hbm2DdlOption) { | ||
Configuration configuration = constructConfiguration(); | ||
configuration.setProperty( Settings.HBM2DDL_AUTO, hbm2DdlOption ); | ||
configuration.setProperty( Settings.DEFAULT_CATALOG, "hreact" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is setting the catalog part of the corner case? Because I don't think it's going to work for all databases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point. Will tweak that test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that there was an issue where not setting the catalog will cause a NullPointerException
. If you rebase on top of this pr, that issue should be solved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the dialect's implementation of #getNameQualifierSupport
that determines what may be required.
If NameQualifierSupport#CATALOG
is returned, then Settings.DEFAULT_CATALOG
may need to be defined.
If NameQualifierSupport#SCHEMA
is returned, then Settings.DEFAULT_SCHEMA
may need to be defined.
If NameQualifierSupport#BOTH
is returned, then both Settings.DEFAULT_CATALOG
and Settings.DEFAULT_SCHEMA
may need to be defined.
I think it depends on the particular database whether it is needed and whether GROUPED
strategy is required. I'm not sure what happens if, for example #getNameQualifierSupport
returns NameQualifierSupport#CATALOG
and Settings.DEFAULT_SCHEMA
is provided. ORM may simply ignore the setting.
@dreab8, may be able to shed more light on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly if the db does not support schema and we provide a schema in the mapping of a table we have errors not sure about the Settings, but I may be wrong...We need to test this behaviour.
By the way, the reason I use the |
If you only use the issue number (for example, |
} | ||
|
||
@Test | ||
public void testHaltOnError(TestContext context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, an error found while executing SchemaMigrator
should not terminate the bootstrap process. This is controlled by hibernate.hbm2ddl.halt_on_error
(default is false
)
This test will try to create a table named From
, which is a reserved word for most databases. It should cause warnings to get logged, but the SessionFactory
should still be created. Obviously, there will be problems if an application tries to query or insert data related to the failed DDL.
The test just checks that no exception is thrown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to set hibernate.hbm2ddl.halt_on_error
to false
and see that nothing fails, and then set it to true
and check that we have the failures.
|
||
import io.vertx.ext.unit.TestContext; | ||
|
||
public abstract class SchemaUpdateSchemaNameMySQLTest extends BaseReactiveTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have this class already in the project: https://github.com/hibernate/hibernate-reactive/blob/main/hibernate-reactive-core/src/test/java/org/hibernate/reactive/SchemaUpdateMySqlTestBase.java
Do we need a separate class for this additional tests or we can add them to the existing class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible to add the tests to current HR MySQL test but I may need to bring over the the ORM version of the entities which don't have PK/FK defined. The tests will fails when loading the ASimpleNext metadata during build session factory.
I can do that but I think it muddies the scope of the SchemaUpdateMySqlTestBase.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well OK, it would be nice to have all the common configuration in one place but we can do it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth having this in a separate test because it really is very much a corner case.
Notice that the entities map schema = "test"
.
For MySQL, #getNameQualifierSupport
returns NameQualifierSupport.CATALOG
.
In other words, the mapping really is incorrect; it should map catalog="test"
.
Internally, MySQL DatabaseMetaData
method take the catalog
value and uses it like it is the schema. That's mentioned here
I don't remember, but I think that this weird behavior was introduced at some point, and old mappings got broken.
This is a test that the legacy mapping will still work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@blafond Can you add some javadoc for this class, please?
From what I understand, we are testing:
- Combination of catalog + schema names
- Two different classes with with the same entity name and table name
I also don't see anything specific to MySQL in this test class. I think it will work for MSSQL if we change the name of the catalog to master
during the build and probably for PostgreSQL without additional changes. @blafond could you also check if it works for the other dbs?
In the project we have several test classes for testing schema update/validation for each database (see |
@gbadner @DavideD The ORM test only tests if validation doesn't fail. My HR version actually executes a query to find the specific column and type and verify the DB's expected type. Is this necessary? In HR, I don't think we've been writing tests that don't query the data or schema metadata. |
Ideally, every test should run on every database. The only time we don't do that is when a feature is not supported by all databases or when we need to run native queries. For this particular type of tests, I don't think it's possible because you will probably need to check that the column in the table exists and it's of the expected type. And I think you can only do that with native queries.
Sounds good, but to test that the validation is working we would need the following use case:
An example of how to test for case 1 is in For case 2, I would run a native query that drops the column before running the test. You will need a native query for this case but because it's just a query, Case 3 is what you have done already Let me know if this makes sense |
I've just realized that we should also check that the validation doesn't fail (even if a column is missing) when |
914c128
to
e9f3457
Compare
It's already defined in the Closable interface
Superseeded by #1017 |
Addresses #936
Test cases for corner cases of schema update, migration and validation
This is a draft and I've only checked out some of the tests in #936 and a number of them are targeted specifically to H2.