[CMCSMACD-6648] Allow for a setup function in SchemaTest#25
Conversation
This allows callers to set up preerquisite data or tables that are needed for the migrations without running afoul of the empty- database check at the beginning of SchemaTest.
leslie-corbalt
left a comment
There was a problem hiding this comment.
cmd/schema-test/README.md, line 3 is stale.
My comments are related to additional clarification and preciseness.
There was a problem hiding this comment.
A more precise message:
Existing relations found. You must run this on an empty database
Maybe omit specifying SchemaTest, since it can also be called by SchemaTestWithSetup?
| @@ -145,6 +132,10 @@ func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) e | |||
There was a problem hiding this comment.
This is not part of this change, but a better function name is verifyNoRelations since \d returns user relations.
There was a problem hiding this comment.
Replace tables with relations
| func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error { | ||
| // Does a SchemaTest but calls the provided setup function after verifying that the | ||
| // database is empty. | ||
| func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error { |
There was a problem hiding this comment.
If setup is required to be non-nil, then the comment should say that.
If setup can be nil, the code must check for it.
There was a problem hiding this comment.
I think the name makes clear that this function only exists to add a setup step to the standard SchemaTest. It would be silly to call it with a nil setup function. I think it's better to keep documentation concise.
| return nil | ||
| } | ||
|
|
||
| // Schema test expects a new *empty* postgres database. |
There was a problem hiding this comment.
Replace this comment with:
// SchemaTest runs SchemaTestWithSetup with no setup step.
| func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error { | ||
| // Does a SchemaTest but calls the provided setup function after verifying that the | ||
| // database is empty. | ||
| func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error { |
There was a problem hiding this comment.
This function should get the long comment. This suggestion adds the points that
- the caller must remove objects that the setup created before running another schema test on the same database
- setup() must be non-nil (based on the current code)
// SchemaTestWithSetup expects a new *empty* postgres database. After confirming
// the database is empty, it calls setup once - e.g. to create schemas or tables
// the migrations depend on - and then:
// 1. Applies all migrations
// 2. Reverses all migrations
// 3. For each migration:
// a. Applies the migration
// b. Reverses the migration
// c. Applies the migration again
//
// Before and after each step, it uses pg_dump to dump the schema, and verifies:
// A. The schema after reversing matches the schema before applying.
// B. (If re-applying) The schema after applying matches the schema after re-applying.
//
// Whatever setup is created is treated as the baseline schema: it is not rolled
// back or dropped, so the caller must remove it before running another schema
// test on the same database. setup must not be nil.
//
// You must have `pg_dump` in your `PATH` to run this.
There was a problem hiding this comment.
I actually think it's better to have the long docstring on the standard function and not this variant.
The caller is not required to remove objects that setup created. They are if they are going to call the function twice, but that is implied by the fact that SchemaTest requires an empty database.
hundt-corbalt
left a comment
There was a problem hiding this comment.
Thanks for the review!
| func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error { | ||
| // Does a SchemaTest but calls the provided setup function after verifying that the | ||
| // database is empty. | ||
| func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error { |
There was a problem hiding this comment.
I think the name makes clear that this function only exists to add a setup step to the standard SchemaTest. It would be silly to call it with a nil setup function. I think it's better to keep documentation concise.
| func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error { | ||
| // Does a SchemaTest but calls the provided setup function after verifying that the | ||
| // database is empty. | ||
| func SchemaTestWithSetup(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration, setup func() error) error { |
There was a problem hiding this comment.
I actually think it's better to have the long docstring on the standard function and not this variant.
The caller is not required to remove objects that setup created. They are if they are going to call the function twice, but that is implied by the fact that SchemaTest requires an empty database.
| @@ -145,6 +132,10 @@ func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) e | |||
| // | ||
| // You must have `pg_dump` in your `PATH` to run this. | ||
| func SchemaTest(emptyDBConfig *PostgresConfig, allMigrations []NamedMigration) error { | ||
| // Does a SchemaTest but calls the provided setup function after verifying that the |
There was a problem hiding this comment.
The capitalization SchemaTest sounds like SchemaTestWithSetup calls SchemaTest but calls the provided setup after verifying that the database is empty.
This comment is confusing.
There was a problem hiding this comment.
How about now?
leslie-corbalt
left a comment
There was a problem hiding this comment.
A comment on your short docstring.
This allows callers to set up prerequisite data or tables that are needed for the migrations without running afoul of the empty- database check at the beginning of SchemaTest.
Testing: pulled this into professor-mac and successfully used it to allow app migrations to depend on teamsapi migrations.
Examples: