Skip to content
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

Implement functional migration tests #19353

Merged
merged 1 commit into from
Jan 23, 2020
Merged

Implement functional migration tests #19353

merged 1 commit into from
Jan 23, 2020

Conversation

roji
Copy link
Member

@roji roji commented Dec 18, 2019

This adds functional migration tests which perform DDL operations on the database.

The total running time of the SQL Server suite is roughly the same as before, thanks to test parallelism and async I/O. ❤️

  • The new tests have been added as MigrationTestBase, MigrationsSqlServerTest, MigrationsSqliteTest; they are ports of almost all existing MigrationsSqlGeneratorTests.
  • The previous MigrationsTestBase has been renamed to MigrationsInfrastructureTestBase, and the First/Second test has been removed from it. We can probably refactor it a bit (e.g. move SQL-only tests out to MigratorTests or something).
  • Moved MigrationsSqlGeneratorTests from EFCore.Relational.Specifications.Tests to EFCore.Relational.Tests. For now I've kept all tests, although I think we can remove any already covered in the new MigrationTestBase (which is most of them).
  • Similar question for MigrationsModelDifferTest: the new functional tests implicitly exercise the model differ, so I'm not sure if many of the differ-specific are still valuable.
  • Naming-wise, since MigrationTestBase tests have been ported from MigrationSqlGeneratorTests, I've conserved the names. But these are basically migration operations - but that doesn't really seem appropriate, as the operations are internal implementation details. We should consider renaming to something more functional (e.g. instead of AddUniqueConstraintOperation, we could all it AlternateKey_add).
  • For data/seeding tests, ideally we'd query the database for data, but that's a bit difficult to set up. SQL assertions are probably good enough for now.
  • Database creation tests have not been ported over and remain in SqlServerMigrationSqlGeneratorTest, as in the real world they seem pretty flaky, at least for SQL Server and Sqlite. We can look at it later if we want to.
  • Originally I had the test infrastructure apply the reverse migration, and even compare reverse-engineered models before and after for equality. However, I ran into issues on Sqlite where symmetrical operations aren't always supported (e.g. you can add columns but you can't drop them). So for now we can just explicitly test the reverse migrations, which we want to do anyway.

Closes #19039
Replaces #19258

@roji roji requested a review from bricelam December 18, 2019 15:01
Copy link
Member Author

@roji roji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some specific comments

b.Property<string>("NormalizedName")
.HasMaxLength(256);
[ConditionalFact(Skip = "Column 'FullName' in table 'People' is of a type that is invalid for use as a key column in an index.")]
public override async Task AlterColumnOperation_change_computed_with_index()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails with Column 'FullName' in table 'People' is of a type that is invalid for use as a key column in an index., is that expected?


[ConditionalFact]
public virtual void Can_get_active_provider()
public virtual async Task CreateTableOperation_all_settings()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is somewhat useless since a database must support everything in order to run it (e.g. Sqlite disables it). Better to just remove and leave the feature-by-feature tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What doesn't SQLite support here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schema, check constraints...

Am going to leave as-is (ignored for Sqlite) and we can re-discuss in cleanup if this test is valuable or not...


b.HasKey("LoginProvider", "ProviderKey");
[ConditionalFact(Skip = "Doesn't work")]
public virtual async Task AlterColumnOperation_remove_identity()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like AlterColumnOperation_make_identity, this fails with: To change the IDENTITY property of a column, the column needs to be dropped and recreated., is this expected?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, thanks.

}

public override void Can_generate_one_up_script()
// In Sqlite, comments are only generated when creating a table
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only see comments generated for CreateTableOperation... I'm guessing this is intentional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It's not possible to add these with ALTER TABLE..ADD statements.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will leave these overrides to assert the actual behavior.

{
// Build the source and target models. Add current/latest product version if one wasn't set.
var sourceModelBuilder = Fixture.TestHelp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For higher fidelity the source builder shouldn't have conventions, that's how the snapshot is built and we have had several bugs that were hidden by conventions. However it will require more configuration to actually set up the tests.

Copy link
Contributor

@bricelam bricelam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Regarding MigrationsModelDifferTest, I agree we can probably remove it.


[ConditionalFact]
public virtual void Can_get_active_provider()
public virtual async Task CreateTableOperation_all_settings()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What doesn't SQLite support here?


b.HasKey("LoginProvider", "ProviderKey");
[ConditionalFact(Skip = "Doesn't work")]
public virtual async Task AlterColumnOperation_remove_identity()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected.


b.ToTable("AspNetUserLogins");
});
// AlterColumnOperation_remove_identity_legacy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is important to make sure that old model snapshots are handled correctly. Do we still have coverage for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave this test (and others like it) in MigrationSqlGeneratorTestBase and we can rediscuss later (will note in cleanup issue).

}

public override void Can_generate_one_up_script()
// In Sqlite, comments are only generated when creating a table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It's not possible to add these with ALTER TABLE..ADD statements.

@roji roji force-pushed the MigrationTests branch 2 times, most recently from 552280c to 9b8292d Compare January 22, 2020 16:12
Copy link
Member Author

@roji roji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bricelam @AndriySvyryd did a final big cleanup pass and addressed all comments. Another quick sign-off would be great.

  • The tests now use a conventionless model builder.
  • I've removed everything in the MigrationSqlGeneratorTest (unit) test suites that is covered by the newer MigrationsTest (functional) test suite. Some things still remain, we should ideally take another look at some point (Remaining clean up for migration tests #19668). I haven't touched the ModelDifferTests because this PR is already big enough (again, Remaining clean up for migration tests #19668).
  • I've renamed the migration tests and grouped them by type (table, column, index...) and then by operation (create, alter, drop...).


[ConditionalFact]
public virtual void Can_get_active_provider()
public virtual async Task CreateTableOperation_all_settings()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schema, check constraints...

Am going to leave as-is (ignored for Sqlite) and we can re-discuss in cleanup if this test is valuable or not...


b.HasKey("LoginProvider", "ProviderKey");
[ConditionalFact(Skip = "Doesn't work")]
public virtual async Task AlterColumnOperation_remove_identity()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, thanks.


b.ToTable("AspNetUserLogins");
});
// AlterColumnOperation_remove_identity_legacy
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave this test (and others like it) in MigrationSqlGeneratorTestBase and we can rediscuss later (will note in cleanup issue).

}

public override void Can_generate_one_up_script()
// In Sqlite, comments are only generated when creating a table
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will leave these overrides to assert the actual behavior.


b.HasKey("Id");
[C
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to create a test condition for online indexes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Added an enum value to SqlServerCondition and configured config.json to false for LocalDB, but am not sure how to set up true in CI. Will merge now and we can fix as part of #19668.

@roji roji force-pushed the MigrationTests branch 2 times, most recently from 28eeadb to 1a03e66 Compare January 23, 2020 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change migrations tests to work against the database
3 participants