Skip to content

Cached properties in playground scenarios interact badly with rollbacks

Today I tried to convert WorkflowTemplateViewTests to use scenario = scenarios.DefaultContext() and to get its user token from there. This failed with a confusing pile of test isolation errors depending on which tests I ran. I eventually worked out that what's happening appears to be as follows:

  • DefaultScopeUser.user_token creates a Token and caches it
  • A test causes a transaction rollback (which can happen for all sorts of normal reasons)
  • DefaultScopeUser.user_token is called again, but this time the uncommitted token from a previously-rolled-back transaction is cached
  • The token's key no longer matches anything in the database, so everything fails with authentication errors

For now I'll just avoid using the playground scenario mechanism here, but I think we should try to fix this somehow. I'm not sure exactly how. Django transactions don't have rollback hooks. I don't think we can sensibly use savepoints to retain scenario-induced changes while discarding the rest of what a test has done, because the scenario's properties might be evaluated at any point during a test. Maybe we can have something that runs on test teardown that checks whether a transaction was rolled back and if so clears the cached properties in scenarios? Or something else?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information