From c20a4d6ad15980d5121610bc9a3ffc9bba4d631d Mon Sep 17 00:00:00 2001 From: Gregory Becker Date: Tue, 4 Apr 2023 16:35:41 -0700 Subject: [PATCH] fix bug in recreating new exchange view; test --- lib/spack/spack/test/cmd/env.py | 19 +++++++++++++++++-- lib/spack/spack/util/atomic_update.py | 6 ++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 23bf33aacc5..483d60df48c 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -3367,16 +3367,31 @@ def test_view_update_unnecessary(update_method, tmpdir, install_mockery, mock_fe libdwarf = spack.spec.Spec("libdwarf").concretized() install("libdwarf") - # Ensure multiple previous views around + # Create a "previous" view view.regenerate([libelf]) - view.regenerate([libelf, libdwarf]) # monkeypatch so that any attempt to actually regenerate the view fails def raises(*args, **kwargs): raise AssertionError + old_view = view.view monkeypatch.setattr(view, "view", raises) + # regenerating the view is a no-op, so doesn't raise + # will raise if the view isn't identical + view.regenerate([libelf]) + with pytest.raises(AssertionError): + view.regenerate([libelf, libdwarf]) + + # Create another view so there are multiple old views around + monkeypatch.setattr(view, "view", old_view) + view.regenerate([libelf, libdwarf]) + + # Redo the monkeypatch + monkeypatch.setattr(view, "view", raises) + + # no raise for no-op regeneration + # raise when it's not a no-op view.regenerate([libelf, libdwarf]) with pytest.raises(AssertionError): view.regenerate([libelf]) diff --git a/lib/spack/spack/util/atomic_update.py b/lib/spack/spack/util/atomic_update.py index abc3ed67131..a79f96b5bb0 100644 --- a/lib/spack/spack/util/atomic_update.py +++ b/lib/spack/spack/util/atomic_update.py @@ -49,14 +49,12 @@ def atomic_update_renameat2(src, dest): dest_exists = os.path.lexists(dest) if not dest_exists: - fs.touch(dest) + fs.mkdirp(dest) try: rc = renameat2()(AT_FDCWD, src.encode(), AT_FDCWD, dest.encode(), RENAME_EXCHANGE) if rc: raise OSError(f"renameat2 failed to exchange {src} and {dest}") - if not dest_exists: - os.unlink(src) - except (OSError, IOError): + except OSError: if not dest_exists: os.unlink(dest) raise