-
-
Notifications
You must be signed in to change notification settings - Fork 439
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
automating the subprocess measurement setup #367
Comments
Is this a solution? https://github.com/dougn/coverage_pth |
Original comment by Tibor (Bitbucket: tibor_arpas, GitHub: Unknown) Nice approach, I guess. I'm still getting ImportError: No module named |
Original comment by Tibor (Bitbucket: tibor_arpas, GitHub: Unknown) The problem I had is only with --editable coveragepy. So yes, it's definitely a solution! Could you include it in coveragepy itself? |
Original comment by Tibor (Bitbucket: tibor_arpas, GitHub: Unknown) There is similar solution here: https://github.com/schlamar/pytest-cov/blob/772f2e210610354a8ffddc0187a23913ae56ca4e/cov-core/setup.py |
Original comment by Buck Evan (Bitbucket: bukzor, GitHub: bukzor) The cov-core solution doesn't uninstall whatsoever. In fact it causes the whole virtualenv to explode (ImportError) if you uninstall it. The coverage-pth solution is better, but doesn't handle The solution found in python-hunter handles all those cases, in addition to supporting easy-install. We've recently adapted this into a package that fills the same problem space as coverage-pth, but is more reliable. IMO this should be a default feature of coveragepy. While it will add one if-statement to all subsequent python startup time, that seems like a near-zero cost to me, and the additional use-cases supported are sizeable. |
I've been using https://pypi.org/project/coverage_enable_subprocess/ recently and it works very nicely. |
The set-up instructions are also somewhat meandering. Should I try my hand at fixing the docs? It's really just 4 steps:
In my humble opinion the way to fix this to be simpler would then be to remove non-parallel mode from coverage entirely, and have it take care of steps 1 (possibly putting coveragerc defaults in a temp dir) 3 ( |
@glyph tell me more about how "removing non-parallel mode entirely" would work? Wouldn't that mean that simple runs would always generate a numbered .coverage.xxx.yyy file? |
That's what I'm suggesting, yes. Is there any particular reason not to do this? |
I don't understand what would happen to "coverage combine". Today, "coverage report" (or html, xml, etc), only report on data in the If we say everything is parallel from now on, does that mean that everyone has to run "coverage combine" before reporting? Or do the reporting commands all implicitly combine first? Running coverage twice in a row would give two distinct data files, then implicit combining would combine them together? That seems wrong. |
It's quite possible that my perspective is badly skewed by the fact that this is already the world I live in. I don't have any projects with only a single test environment, and once you have 2, you want to be able to speed up runs with But let me take it as a given that $ coverage group new --label "lol"
2e843587-a60c-4fab-bfaf-dab910437bb0
$ coverage run --group 2e843587-a60c-4fab-bfaf-dab910437bb0
$ coverage report --group 2e843587-a60c-4fab-bfaf-dab910437bb0
report for 'lol' ... Without You could then have To run a test suite that might run some subprocesses, you could then do, say: $ coverage spawn tox -p auto
| / - \ | etc Like
This reports on the group created by Another advantage of this approach is that you could run multiple tests and report on their combined coverage at the same time in the same project, and you wouldn't need any special locking; |
Further to what @glyph suggests, what if "coverage combine" (and/or just "read all the (I might also be biased, because the only time I don't do |
Any thought about inverting things a bit? This does not address the "how do we get the subprocess to do things" problem, but does address the difficulty introduced by having two models that are leaving different dropped files. thoughts? By the way: there is an issue to remove |
@glyph I think you can achieve your coverage groups by setting What I just did in Klein's Tox config is to set |
This is related (duplicate) to #378. |
Now I think the best approach is to not install a .pth file when coverage.py is installed at all, but instead, to create the .pth file when coverage measurement is started, and remove the file when it ends. My theory is we only want to measure subprocesses when some "main" process (pytest?) is under coverage measurement itself. So when the main process begins coverage, it can configure the mechanism for subprocess measurement. Is there some reason that wouldn't work? |
This is a really obscure and nuanced point about packaging, but in general test suites should not assume that they can write to a sitedir. We have bumped in to this problem a few times with Twisted, where sometimes you're testing an installed / built artifact, and not a virtualenv, but still want to have coverage measurement. For example: let's say you're building a mac app (my favorite weird-build-use-case, everything's always broken here). It's broken in production on users' machines but working in test. You want to ship an instrumented build and collect coverage information. The app bundle will be installed to There are equivalent situations when shipping e.g. a debian package or even a docker container which installs as root but runs tests as a restricted user, but they're a lot harder to describe and there are squirrely workarounds that might partially fix the problem, so this one works as a good example of a place that there's a hard limit on such a thing. |
I hear you, and I understand about the variety of environments. I assume the code will have to handle the case of not being able to find a writable directory in sys.path, and will simply have to issue a warning about that. It's got to be an improvment over what we have now, which is a page explaining how to make your own .pth files, right? |
Note that
Sure, this would definitely be an improvement, but given this disadvantage, I don't quite understand what the benefit of adding the complexity of dynamically writing something at runtime rather than just shipping the Another issue you'll have to grapple with is the fact that overlapping coverage runs (which, previously, would have been able to coexist to some extent with |
I don't know how to express this as a concrete proposal to move forward, but a struggle I've often had with subprocess coverage is that one ends up "having" to implement custom code in the application to facilitate coverage (whether that's a command-line option or environment-variables, etc). The struggle here is that if an application produces subprocesses but doesn't have specialized knowledge of coverage.py, some of those subprocesses won't ever get coverage. So if you're going to put custom "coverage" code into an application, it might as well use That is, applications are going to end up with with a |
@meejah a .pth file contains code that every Python process executes at startup, so the existing solution works fine without requiring applications to do this; I think the discussion here is mostly about how to execute that, rather than about whether to give up on it? |
The conditional in the .pth file (actually in a function it calls) is about an environment variable. There's no guarantee I can set an environment variable and have it carried over into subprocesses. So every choice has a chance of failure, and needs to try to determine if it failed. Which approach has the higher likelihood of succeeding? Is it weird to try a combined approach? Write a .pth at install time, and at run time, update the .pth with specific details (where the rc file is, and whether to measure). |
To @glyph's point as well, the above is still a problem: now I have to arrange for an environment-variable to be passed on to the subprocess, too. If it doesn't work, did I do that wrong? Did the So I think what I'm saying is: the only places I've gotten subprocess-using applications to produce coverage properly is when I've put custom code in them. So just give me reliable "start coverage now" and "end coverage now" APIs, and I'll put those in my applications (and then hopefully I don't have to debug |
Personally, my experience is that environment variables are more likely to succeed. In principle I guessed that this might cause issues, but in practice after using it on many projects over many years, it's mostly been set-it-and-forget-it. Allowlist environment filtering does happen and is unpleasant to debug, but also, allowlist filtering is basically always a bug and it's easy to recommend that tools get rid of it. Like, did you remember to inherit
Given the possibility of multiple possible parallel coverage runs, I don't think there's any value to updating the My estimation is that this is an unnecessary fallback, and maybe not the best one; env vars should work well enough that I don't think this would be required. But as much as I know about weird deployment environments, coverage obviously has a distribution footprint way bigger than anything I've worked on, so I could see that everything has to be triple-redundant and an API like this might be a way to accomplish that. |
These APIs already exist. Are you just saying that the status quo is better (less fragile, etc) than any of these solutions? |
@glyph, yeah I think that is what I'm saying. To be clear, that means the "good advice" for programs wanting subprocess coverage is to include some custom code in them (triggered however you like) that does |
I appreciate all of the advice, and the depth of (scarred) experience that informs these comments. I wish there were something to do though, when I get issues like #1341. |
Respectfully, I disagree. Any one of the solutions described here will still occasionally lead to a bad outcome where you'll need to debug something weird, but like 99.9% of the time they'll work just fine. In the remaining .1% of cases presumably the explicit API will remain. |
Originally reported by Tibor (Bitbucket: tibor_arpas, GitHub: Unknown)
Subprocesses in test suits are a common occurence. coverage.py has an execellent way to measure their coverage but the set-up instructions are quite scary: http://nedbatchelder.com/code/coverage/subprocess.html
Also in the time of tox, continuous integration, virtualizations and containerizations, the manual process is quite beside the point.
What could we do to completely automate the described process?
There is an article by Ned http://nedbatchelder.com/blog/201001/running_code_at_python_startup.html
and a suggestion from @geoffbache
That script fails on my machine (MacOS, Python 2.7) with
But I would hope that it's the best approach.
The text was updated successfully, but these errors were encountered: