Defect #37686
closedPlugin migrations are skipped or fail due to stale cached versions when a plugin is migrated more than once in the same process
Description
When testing plugin migrations it is necessary to call plugin migrations more than once, e.g.:
# migrate to version A
Redmine::Plugin.migrate('some_plugin', 2)
# ...do some plugin specific database filling...
# try to migrate to version B and see if migration gave proper results
Redmine::Plugin.migrate('some_plugin', 3)
The problem is it does not work as expected. Installed migrations are listed and cached in Redmine::Plugin::Migrator @all_versions variable during first migrate() run. Then it is never updated and subsequent migrate() calls operate on its outdated contents.
Quick workaround is to clear @all_versions variable like this:
Redmine::Plugin.migrate('some_plugin', 2)
Redmine::Plugin::Migrator.instance_variable_get(:@all_versions)&.delete('some_plugin')
Redmine::Plugin.migrate('some_plugin', 3)
Files
Related issues
Updated by Go MAEDA 15 days ago
- Related to Patch #28934: Support migration context for plugins added
Updated by Go MAEDA 15 days ago
- File 0001-Fix-stale-cached-versions-when-a-plugin-is-migrated-.patch 0001-Fix-stale-cached-versions-when-a-plugin-is-migrated-.patch added
- Target version set to Candidate for next minor release
The attached patch fixes this issue.
With this patch, the cached versions of a plugin are discarded right after a migration of that plugin is recorded in schema_migrations, and reloaded from the database when next needed. This is what the workaround in the description does, but automatically.
Only the entry of the migrated plugin is discarded, not the whole cache. A plugin's migrations change only that plugin's own rows, so rake redmine:plugins:migrate still reads schema_migrations only once and the optimization of #28934 is preserved.
As before, the cache is not refreshed when schema_migrations is changed without going through the migrator, for example by a rollback in transactional tests. In such cases, plugin tests can now call the new public method Redmine::Plugin::Migrator.clear_cached_versions without arguments to discard the whole cache.
The patch includes a test that migrates a plugin up and down several times in the same process. It fails without the fix.