Problem/Motivation
This is a follow-on to #2745123: Simpletest module crashes on cleanup, uninstall which will, we hope, find non-disruptive solutions to the problem of class loading classes under core/tests during runtime. This includes the problem of simpletest_clean_environment() needing to access TestBase.
In this issue we can refactor the simpletest cleanup code to be more maintainable and clear, with inversion of control, in a somewhat more disruptive way for 8.3.x.
simpletest_cleanup_environment() is used by both the Simpletest UI and run-tests.sh. This makes it a good candidate for refactoring to improve the testing system moving forward.
Proposed resolution
Refactor the following functions into a helper class called something like EnvironmentCleaner:
simpletest_clean_environment()simpletest_clean_database()simpletest_clean_temporary_directories()simpletest_clean_results_table()
Mark these functions as deprecated.
Remaining tasks
Turn the EnvironmentCleaner class into a proper service. This would involve turning the TestDatabase class into a service or parameter service as well which might be outside the scope of this issue.
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | interdiff.txt | 464 bytes | mile23 |
| #36 | 2800267_36.patch | 32.1 KB | mile23 |
| #35 | interdiff.txt | 852 bytes | mile23 |
| #35 | 2800267_35.patch | 31.88 KB | mile23 |
| #33 | Screenshot 2019-08-27 at 08.56.28.png | 28.51 KB | lendude |
Comments
Comment #2
mile23First pass at this effort. Discuss. :-)
Comment #3
mile23Might need updating after #2807171: Use the correct testing table prefix in simpletest_clean_database()
Comment #4
joelpittetIt looks to not apply anymore
Comment #5
drugan commentedRe-rolled #2.
I think that this solution for crashes when cleaning environment is good alternative to another one.
The only deficiency is that it is a bit heavier than the one on the link above.
Comment #6
drugan commentedComment #7
drugan commentedComment #9
mile23Rerolled, amended to reflect changes in #2745123: Simpletest module crashes on cleanup, uninstall
Comment #10
mile23Comment #13
dawehnerIt would be nice to not have this below the simpletest namespace but under the generic test bit.
We should throw deprecation notices and have a
@deprecatedtags :(I don't think this is something we have to do. We can do dependency injection without it being a service, aka. be somehow part of a module. What about dropping this todo?
Honestly, test code has different requirements than production code IMHO. One could make up a scope which is minimal aka. just moving code, but sure, let's create a followup for that?
Comment #14
mile23#13.1: Done.
#13.2: Trigger errors should be a follow-up, when we remove usages. Otherwise all tests will always fail. :-)
@deprecationnotices added.#13.3: Agreed. If it was coupled to simpletest module, then maybe it should be a service, but since it's not, it shouldn't be. But it takes a lot of other services as arguments. See next point, too.
#13.4:
Test code has stricter requirements. :-)
Seriously, we should be making a class that performs all these functions without, for instance, asking
\Drupal::config()if it should. Then callers should be responsible for asking config and reporting results. In run-tests.sh we callsimpletest_clean_results_table(), which shouldn't require config, right?But that's not an easy refactor and the main goal here is to get it out of simpletest. Then someone can isolate it from dependencies if it becomes important.
So with that in mind, I injected the messenger service instead of calling
drupal_set_message(). :-)We still use
file_unmanaged_delete_recursive(), which requires an .inc file, but I found this: #2244513: Move the unmanaged file APIs to the file_system service (file.inc)Comment #15
mile23Comment #18
mile23Some planning happening in this meta.
Comment #19
mile23Needed a reroll, but I ended up rearchitecting a little bit.
Adds a service to the simpletest module called
environment_cleaner. Within the context of the simpletest module, this service behaves with BC. It's a service so it can do things like display messages through the messenger service.The service inherits from the real helper class, which is
Drupal\Core\Test\EnvironmentCleaner. This can run in many different contexts. Its only complicated dependency isfile_service.This patch does a poor job of deprecating all the
simpletest_clean*()functions. It only demonstrates the changes and will find deprecated usages in core, but there shouldn't be any.If there is some consensus on this, we can work on the deprecation messages and so forth.
Comment #20
mile23Forgot one important change.
Comment #21
andypostBtw cmi2 also "figured out" environment for config
The
file_servicealso depends on config and stream wrappers which is blocked on relatedComment #22
mile23The only reason we need
file_systemhere is to perform a recursive delete. We don't need any logging or really any other service dependencies. We know where the directory is, and it should never be a stream wrapper type URL.Ideally, we'd use code that has nothing to do with core, because we're testing core, which might break
file_system.In any other project, symfony/filesystem to the rescue. :-)
Comment #23
lendudeNeeded a reroll.
No changes, just a reroll for now.
Comment #24
mile23Added CR: https://www.drupal.org/node/3076634
Updated deprecation messages.
Added a deprecation test, and also some unit testing for
Drupal\Core\Test\EnvironmentCleaner.As always: It's a little tricky to test code that changes test results.
Comment #25
mile23And perhaps I should include a patch.
Comment #26
mile23CS.
Comment #27
lendudeNeeded another reroll, also got rid of an unused
usewhile doing it.Comment #28
lendudeReally just some nits, the rest looks really nice.
This could be a little more descriptive, 'Helper class for cleaning generated test environments.'. I don't know, something like that?
Either leave this out, or explain how/when it's the same or when it's different
Needs a description
Needs a description
Needs a description
Unrelated change?
Extra newlines above and below are not needed.
Comment #30
mile23Thanks.
Addressed #28, fixed test fail.
Comment #31
lendude@Mile23++
Tested this some more. The output on the bot seems fine, but when running 'clean environment' via the Simpletest UI I get the following feedback:
That seems to work better without the patch.
Also I needed a cache rebuild for the clean up to work in the Simpletest UI because of the new service being introduced. So I guess we need a post_update to force a cache rebuild?
Comment #32
mile23Thanks, @Lendude.
Updated with proper formatPlural() format.
Comment #33
lendudeLooks good now.
Feedback has been addressed. So one question remains: do we need an update function to force a cache clear? Seems excessive, but lets see if others agree.
Comment #34
mondrakeWould it make sense to mark these methods @internal since their signatures might change later while working with #3075608: Introduce TestRun objects and refactor TestDatabase to be testable? I think these is not to be considered public API.
Comment #35
mile23Marked the interface as @internal with links to #3075490: Move simpletest module to contrib and #3075608: Introduce TestRun objects and refactor TestDatabase to be testable
Comment #36
mile23Updated for CS. Leaving at RTBC because it's a very minor change.
Comment #37
mile23Updated IS to be more in line with current goals.
Comment #38
mile23Not entirely sure why I added 'needs followup' in #15, presumably because of #2244513: Move the unmanaged file APIs to the file_system service (file.inc) That issue has been fixed and closed, so I don't think we need that tag any more.
Comment #39
mile23This is a child issue of a critical meta: #3057420: [meta] How to deprecate Simpletest with minimal disruption
Comment #40
larowlanComment #41
larowlanCommitted 914d47f and pushed to 8.8.x. Thanks!
Comment #43
mile23Yay! 🎉