-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Use spack.store.use_store consistently in unit tests #21656
Conversation
@tgamblin This is a follow-up on #21442 In that PR I didn't notice we have tests that monkey patch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have one request for comment, and I think @scheibelp should review this.
@@ -1119,7 +1121,6 @@ def relocate_package(spec, allow_root): | |||
prefix_to_prefix_bin = OrderedDict({}) | |||
|
|||
if old_sbang_install_path: | |||
import spack.hooks.sbang as sbang |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was some kind of circular import issue on certain platforms that led to this being nested here. Can you look at the blame for these nested sbang
imports and see if you can figure out whether it's really been resolved? I think @eugeneswalker and @scheibelp should comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The imports are still nested, but they are done at the top of the function. This is because imports act like a local assignment to the spack
variable and using any spack.*
module or function before the nested import will fail with weird errors. Checking git blame
right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only reference found for these imports #20768 (comment)
@@ -1133,7 +1134,6 @@ def relocate_package(spec, allow_root): | |||
# sbang was a bash script, and it lived in the spack prefix. It is | |||
# now a POSIX script that lives in the install prefix. Old packages | |||
# will have the old sbang location in their shebangs. | |||
import spack.hooks.sbang as sbang |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above comment on circular imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a number of small requests and a larger concern about the consistency of store state when running upstream tests in test/install.py
:
This appeared to set store.db and store without addressing the TODO above, so I'm trying to figure out why tests like test_installed_upstream are still passing
I don't have a ready solution for that but we can brainstorm how to deal with it if you'd like.
_install('mpileaks ^mpich2') | ||
_install('mpileaks ^zmpi') | ||
_install('externaltest') | ||
_install('mpileaks ^mpich') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the mock_db.write_transaction
call removed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I reconstructed, this context manager was used since #2502. Initially it was a way to speed-up the fixture by grabbing a write lock early instead of repeatedly take and release the lock for each installation (like Spack would do in its normal operations). This made sense since database
or mutable_database
were installing and uninstalling specs at least once per python file. Since some time though the installations are done just once per session, moved to a cache directory and copied wherever they are needed without the additional burden of installing and uninstalling them again. All this is just to say that we will not lose anything in terms of test performance by removing the context manager.
Instead, the necessity to remove it in this PR comes from the additional serialization I do of attributes related to the store. When we fork a process and we _serialize
we create an equivalent, but different, store object in the forked process. If a write lock for the same DB is held by the parent process that will prevent the child to proceed.
spack#21442 missed a few places in unit tests where the store was monkeypatched within tests. This may cause spurious failures, since monkeypatching was not done consistently over all the global variables in spack.store The spack.store.use_store context manager has been updated to also swap spack.db, spack.layout, spack.root and spack.unpadded_root consistently
- Set store attributes on different lines - Add a comment explaining the call to _store()
Before this commit there were local fixtures replicating the same behavior of creating a temporary local store.
482e0e0
to
cc64c5f
Compare
- Add a comment explaining the call to _store() - Use temporary_store in install_mockery
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this refactor is looking excellent. Especially if we can remove all calls which monkeypatch either the store or db, i.e. all calls like:
monkeypatch.setattr(spack.store, 'db'
monkeypatch.setattr(spack.store, 'store'
I think all such calls have been handled at this point. Calls like
monkeypatch.setattr(spack.store.layout, 'build_packages_path', bpp_path)
should be fine.
I have a couple additional requests related to documentation
lib/spack/spack/test/conftest.py
Outdated
temporary_store_path = tmpdir.join('opt') | ||
with spack.store.use_store(str(temporary_store_path)) as s: | ||
yield s | ||
temporary_store_path.remove() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to remove this? I'd assume the tmpdir
fixture would handle that for you. If it needs to happen, I think it should happen outside of the context manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's one test in bindist.py
that fails without this line, so I moved it outside of the context manager. We can investigate in a later PR why the test is failing. For what is worth I was under the impression that the tmpdir
had to be cleanup immediately after a succesful test, but it seems a few of them are kept around at any time, see e.g. here
- Moved tmpdir path removal outside of context manager - Added docstring for install_upstream
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a final request regarding how the Store
object is serialized. I think this is good to go after that. Do you agree with the following commit message:
Testing: use spack.store.use_store everywhere (#21656)
Keep spack.store.store and spack.store.db consistent in unit tests
* Remove calls to monkeypatch for spack.store.store and spack.store.db:
tests that used these called one or the other, which lead to
inconsistencies (the tests passed regardless but were fragile as a
result)
* Fixtures making use of monkeypatch with mock_store now use the
updated use_store function, which sets store.store and store.db
consistently
* subprocess_context.TestState now transfers the serializes and
restores spack.store.store (without the monkeypatch changes this
would have created inconsistencies)
The commit message is great, I completely agree with that. |
Request for comment has been addressed
Thanks! |
#21442 missed a few places in unit tests where the store was monkeypatched within tests. This may cause spurious failures, since monkeypatching was not done consistently over all the global variables in
spack.store
.Other modifications:
spack.store.use_store
has been updated to also swapspack.store.db
,spack.store.layout
,spack.store.root
andspack.store.unpadded_root
spack.store.store
is serialized insubprocess_context.py
on Python > 3.8 + MacOS