Skip to content
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

common/build-style/python3-pep517.sh: ignore tests in temp destdir #43946

Closed
wants to merge 2 commits into from

Conversation

icp1994
Copy link
Contributor

@icp1994 icp1994 commented May 19, 2023

Testing the changes

  • I tested the changes in this PR: YES

An edge case I came across today. On rare cases, packages include tests in their built wheel. While testing with these wheels extracted in a temporary directory, it conflicts with the tests in the source tree as pytest cannot run testfiless with same name in different directories (ref: pytest-dev/pytest#3151).

See this run as an example. The same package passes checks correctly in this PR.

@classabbyamp classabbyamp added the xbps-src xbps-src related label May 19, 2023
@tornaria
Copy link
Contributor

This PR fixes the first time check is run, but not the second and subsequent runs.

In fact, the wheel will be installed into a different testdir each time (and not removed afterwards) and this only ignores the current one.

Suggestions:

  • use testdir=$(mktemp -d) so the testdir is outside the wrksrc tree.
  • use --ignore=${wrksrc}/tmp so we ignore all installations.

@icp1994 icp1994 force-pushed the build-style/python3-pep517 branch from 94eeba9 to 69ed70b Compare May 25, 2023 14:25
@icp1994
Copy link
Contributor Author

icp1994 commented May 25, 2023

Oh, right.

I'll keep it in wrksrc so that it gets auto-cleaned by xbps-src.

@tornaria
Copy link
Contributor

LGTM now. Just FTR this merge confilcts with #44071 but both PR are necessary.

@icp1994
Copy link
Contributor Author

icp1994 commented May 25, 2023

Yeah I'll rebase once that's merged into master.

@ahesford
Copy link
Member

This seems reasonable. Using mktemp to create directories outside of $wrksrc is undesirable because we might potentially leave artifacts that aren't cleaned up by xbps-src clean. Sure, it will be in /tmp, but it's still better to be sure it gets cleaned up after the build.

@ahesford
Copy link
Member

Hrm, should we just remove the tmpdir after the tests are run?

@icp1994
Copy link
Contributor Author

icp1994 commented May 25, 2023

Where would you put the rm call though? If the pytest call fails, it won't get to that.

@ahesford
Copy link
Member

That's okay, because failing tests will already abort a build and any subsequent attempt probably ought to start from a clean masterdir for proper behavior anyway. Cleaning up at the end of do_check after a successful test should be good enough. Leaving the temporary directory around after a failed test also lets users inspect the installation for defects that might have triggered the error.

@icp1994 icp1994 force-pushed the build-style/python3-pep517 branch from 69ed70b to 6905c03 Compare May 25, 2023 19:13
@icp1994
Copy link
Contributor Author

icp1994 commented May 25, 2023

Oh, okay. I thought the norm was if the build is successful, one should be able to run ./xbps-src check multiple times on failed tests without running ./xbps-src clean

@ahesford
Copy link
Member

Sure, it's reasonable to repeatedly run check to work out test issues, but when it comes time to build and install the final package, I definitely recommend a clean build first.

${make_check_pre} pytest3 --ignore="${wrksrc}/tmp" ${testjobs} \
${make_check_args} ${make_check_target}

rm -r "${wrksrc}/tmp"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking about this some more and believe we should be more targeted in the removal:

Suggested change
rm -r "${wrksrc}/tmp"
rm -r "${testdir}"

Yes, this will leave tmp around if we created it, but I suspect that won't cause any problems, and it might avoid a problem where a package actually ships a tmp directory. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could do:

Suggested change
rm -r "${wrksrc}/tmp"
rm -r "${testdir}"
rmdir tmp >/dev/null 2>&1 || true

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with removing only what was created in this run (i.e. just ${tmpdir}).

Also, in terms of avoiding conflicts, maybe the tmpdir should be something more "unique". Perhaps ${wrksrc}/.xbps-tmpdir/$(data +%s) which also has the advantage that pytest will not recurse hidden directories, so the --ignore .. doesn't seem to be necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about the need to remove the $testdir after a successful run. What's the issue if we keep it there?

And if we are adding /.xbps-tmpdir for uniqueness, I don't see why we also need to include another sub-directory under it. I only added the epoch subdirs for the extremely rare chance if a package actually ships a /tmp dirrctory under $wrksrc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me in principle. Although I'd be wary about what happens when there is an old testdir lying around from a previous check run. I don' t know if python -m installer will do the right thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is irrelevant because the wheel was already built before the tmpdir was created, and the installer should really only be unpacking the wheel. I do prefer @tornaria's suggestion to give the directory a hidden, XBPS-specific name that is extremely unlikely to conflict with package contents. Maybe try changing testdir to .xbps-testdir (which is more meaningful than .xbps-tempdir) and see if that solves your problem without needing to ignore tests, and then skip the removal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some testing, the python installer doesn't override files so moved the deletion logic at top. And removed the now redundant epoch subdir & ignore flag.

@tornaria
Copy link
Contributor

While we are at this, I was going to suggest using a venv instead of --destdir + PYTHONPATH trick. Indeed, I found some packages that fail when PYTHONPATH is messed upon.

The gist of it would be something like:

local testdir="${wrksrc}/.xbps-tmpdir/$(date +%s)"
python3 -m venv --system-site-packages --without-pip ${testdir}
${testdir}/bin/python3 -m installer ${make_install_args} ${make_install_target:-dist/*.whl}

PATH=${testdir}/bin:$PATH ${make_check_pre} python3 -m \
    pytest ${testjobs} ${make_check_args} ${make_check_target}

This is needed to fix check for python3-coverage, see: 4366b1c.

I also needed it to fix check for python3-pytest-cov, however in that case another hack was necessary so I would still need to rewrite do_check(). See: 65eb105.

@ahesford
Copy link
Member

ahesford commented Jun 1, 2023

I'm not convinced we should move to a venv for testing. Half of your two test cases require further adjustment (symlinking a package into the venv) anyway. Adjusting the Python path is a supported mechanism, so the failure of those two packages probably reflects some inappropriate assumptions in those packages.

@icp1994 icp1994 force-pushed the build-style/python3-pep517 branch from 6905c03 to 0712107 Compare June 2, 2023 17:15
@tornaria
Copy link
Contributor

tornaria commented Jun 5, 2023

This LGTM, let's get this in, we can figure out whether switching or not to testing using a venv later (cf #44268 where I needed a venv).

@@ -19,7 +19,9 @@ do_check() {
testjobs="-n $XBPS_MAKEJOBS"
fi

local testdir="${wrksrc}/tmp/$(date +%s)"
local testdir="${wrksrc}/.xbps-testdir"
rm -rf "${testdir}"
Copy link
Member

@ahesford ahesford Jun 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benefit of cleaning up the test directory after we've used it is that we (attempt to) restore the source tree to the state it was in when the function was first called.

The benefit of cleaning up the directory before it would normally exist seems dubious. If we agree there is no need to clean up the test after a successful run, I think changing the directory name as you've done is sufficient.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just ran into the reason for the cleanup: attempting to re-run a check after a failure will cause python3 -m installer to fail unless the test directory is clean. Still, I think the idea of purging a (typically nonexistent) directory just to avoid issues with re-running tests is strange. At this point, I guess I'd rather see

local testdir="${wrksrc}/.xbps-testdir/$(date +s)"

and skip cleanup altogether. This should solve the problem of pytest trying to traverse into tmp without requiring a manual exclude, keeps our tests in a more-likely-unique subdirectory that should not conflict with any package contents, and avoid strange pre-clean steps. As a bonus, if you do run multiple tests to correct a failure, you can always do something like

diff -r .xbps-testdir/<failed> .xbps-testdir/<succeeeded>

after the fact to confirm what, if anything, has changed in the installed wheel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ayyy, feels like I'm running in circles 😆 This should be the Final.Final.Final.patch

@icp1994 icp1994 force-pushed the build-style/python3-pep517 branch 2 times, most recently from a16895d to 01717cb Compare June 5, 2023 19:42
This prevents pytest from collecting tests multiple times when
they are bundled in the wheel itself alongside the source tree.
@icp1994 icp1994 force-pushed the build-style/python3-pep517 branch from 01717cb to 62db149 Compare June 5, 2023 19:46
@ahesford ahesford closed this in 71185be Jun 5, 2023
@icp1994 icp1994 deleted the build-style/python3-pep517 branch June 6, 2023 06:24
sirkhancision pushed a commit to sirkhancision/void-packages that referenced this pull request Jun 10, 2023
This prevents pytest from collecting tests multiple times when
they are bundled in the wheel itself alongside the source tree.

Closes: void-linux#43946 [via git-merge-pr]
sirkhancision pushed a commit to sirkhancision/void-packages that referenced this pull request Jun 12, 2023
This prevents pytest from collecting tests multiple times when
they are bundled in the wheel itself alongside the source tree.

Closes: void-linux#43946 [via git-merge-pr]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
xbps-src xbps-src related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants