--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/43a48c26-ce65-4cc0-9e87-fd99c16b726f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Any pointers here? Is this even the right place to ask?I'm happy to do much of the legwork to make python coverage support happen, but it will go much quicker if somebody with more familiarity than myself can give me a brief overview of what needs to be done.-Hyrum
On Tue, Nov 7, 2017 at 1:20 AM, Matthieu Poncin <matt...@yousician.com> wrote:
I would be very interested in this too
On Monday, October 30, 2017 at 4:42:58 PM UTC, Hyrum Wright wrote:I'm interesting in having Bazel support code coverage for Python tests.From https://github.com/bazelbuild/bazel/issues/1118, it seems like the basic infrastructure is there.https://docs.google.com/document/d/1WRQTXQBV-m1_HDkAPvRSfGIrDW4pkI7ATPWtNdC8k9E/edit describes the ideal world of how coverage should work. The doc looks to be a bit dated, and since Java coverage is already implemented it would seem that the basic infrastructure exists for running coverage.Python already has tooling for running coverage outside of Bazel: https://coverage.readthedocs.io/en/coverage-4.4.1/ It would be nice to be able to integrate that tooling into Bazel for use on Python tests.Any thoughts, updates, or pointers here? Is supporting python coverage in Bazel a fool's errand, or actually feasible?-Hyrum
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/43a48c26-ce65-4cc0-9e87-fd99c16b726f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CALmYJEVkJUCQm_TPf5YGkcfDRVgxbxPYRg_0MbSF-P-ZLmg6gg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
+Ulf Adams (but he's currently out sick, get well soon Ulf!) for the high level vision.+Yilei Yang for python insight+Dmitry Lomov for vision :)Last thing I heard was that we don't want to invest much into language specific coverage support. Ideally we would have a cross language coverage framework, but afaik nobody is working on this currently.
On Tue, Nov 14, 2017 at 7:57 AM Hyrum Wright <hwr...@duolingo.com> wrote:
Any pointers here? Is this even the right place to ask?I'm happy to do much of the legwork to make python coverage support happen, but it will go much quicker if somebody with more familiarity than myself can give me a brief overview of what needs to be done.-Hyrum
On Tue, Nov 7, 2017 at 1:20 AM, Matthieu Poncin <matt...@yousician.com> wrote:
I would be very interested in this too
On Monday, October 30, 2017 at 4:42:58 PM UTC, Hyrum Wright wrote:I'm interesting in having Bazel support code coverage for Python tests.From https://github.com/bazelbuild/bazel/issues/1118, it seems like the basic infrastructure is there.https://docs.google.com/document/d/1WRQTXQBV-m1_HDkAPvRSfGIrDW4pkI7ATPWtNdC8k9E/edit describes the ideal world of how coverage should work. The doc looks to be a bit dated, and since Java coverage is already implemented it would seem that the basic infrastructure exists for running coverage.Python already has tooling for running coverage outside of Bazel: https://coverage.readthedocs.io/en/coverage-4.4.1/ It would be nice to be able to integrate that tooling into Bazel for use on Python tests.Any thoughts, updates, or pointers here? Is supporting python coverage in Bazel a fool's errand, or actually feasible?-Hyrum
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/43a48c26-ce65-4cc0-9e87-fd99c16b726f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CALmYJEVkJUCQm_TPf5YGkcfDRVgxbxPYRg_0MbSF-P-ZLmg6gg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
For my current purposes, I'm more interested in just getting the coverage tooling running. After it is generating output, we can worry about proper formatting and merging.To get the tooling running, it would be helpful to know the answers to these questions:
- Where is the location of the vendored copy of coverage, so that it can be added to the python path here: https://github.com/bazelbuild/bazel/compare/master...hwright:py-coverage#diff-34d8cb4d69c74a59002d79684518a778R151 (Note that this isn't for the test itself, but inside of the python stub.)
- Where are the resulting files written? In which part of the the bazel symlink hierarchy should I look for the output written by the test runner? Is that location considered temporary?
On Mon, Nov 27, 2017 at 2:15 PM, Hyrum Wright <hwr...@duolingo.com> wrote:For my current purposes, I'm more interested in just getting the coverage tooling running. After it is generating output, we can worry about proper formatting and merging.To get the tooling running, it would be helpful to know the answers to these questions:
- Where is the location of the vendored copy of coverage, so that it can be added to the python path here: https://github.com/bazelbuild/bazel/compare/master...hwright:py-coverage#diff-34d8cb4d69c74a59002d79684518a778R151 (Note that this isn't for the test itself, but inside of the python stub.)
I don't see a vendored copy of coverage.py - why do you think we are vendoring one?
- Where are the resulting files written? In which part of the the bazel symlink hierarchy should I look for the output written by the test runner? Is that location considered temporary?
The result files need to be written to a temporary directory COVERAGE_DIR. The test runner should take steps to ensure unique file names. If you run locally without sandboxing, the coverage directory won't be deleted, so you should be able to see the results after a test run.
On Tue, Nov 28, 2017 at 3:43 AM, Ulf Adams <ulf...@google.com> wrote:On Mon, Nov 27, 2017 at 2:15 PM, Hyrum Wright <hwr...@duolingo.com> wrote:For my current purposes, I'm more interested in just getting the coverage tooling running. After it is generating output, we can worry about proper formatting and merging.To get the tooling running, it would be helpful to know the answers to these questions:
- Where is the location of the vendored copy of coverage, so that it can be added to the python path here: https://github.com/bazelbuild/bazel/compare/master...hwright:py-coverage#diff-34d8cb4d69c74a59002d79684518a778R151 (Note that this isn't for the test itself, but inside of the python stub.)
I don't see a vendored copy of coverage.py - why do you think we are vendoring one?I've added the vendored copy on my branch:With that branch, I can explicitly add "@bazel_tools//third_party/py/coverage" to the dependencies of a py_test, and the test stub will find the coverage module. I'd like for the test stub to be able to find that module without having to explicitly include it in the test dependencies, since it is only required for running coverage, and it is always required when running coverage.
- Where are the resulting files written? In which part of the the bazel symlink hierarchy should I look for the output written by the test runner? Is that location considered temporary?
The result files need to be written to a temporary directory COVERAGE_DIR. The test runner should take steps to ensure unique file names. If you run locally without sandboxing, the coverage directory won't be deleted, so you should be able to see the results after a test run.Can you point me at the documentation for COVERAGE_DIR? Is this something which bazel creates when running in coverage mode? I assume it's an environment variable; in which environments is it set?
On Tue, Nov 28, 2017 at 2:57 PM, Hyrum Wright <hwr...@duolingo.com> wrote:On Tue, Nov 28, 2017 at 3:43 AM, Ulf Adams <ulf...@google.com> wrote:On Mon, Nov 27, 2017 at 2:15 PM, Hyrum Wright <hwr...@duolingo.com> wrote:For my current purposes, I'm more interested in just getting the coverage tooling running. After it is generating output, we can worry about proper formatting and merging.To get the tooling running, it would be helpful to know the answers to these questions:
- Where is the location of the vendored copy of coverage, so that it can be added to the python path here: https://github.com/bazelbuild/bazel/compare/master...hwright:py-coverage#diff-34d8cb4d69c74a59002d79684518a778R151 (Note that this isn't for the test itself, but inside of the python stub.)
I don't see a vendored copy of coverage.py - why do you think we are vendoring one?I've added the vendored copy on my branch:With that branch, I can explicitly add "@bazel_tools//third_party/py/coverage" to the dependencies of a py_test, and the test stub will find the coverage module. I'd like for the test stub to be able to find that module without having to explicitly include it in the test dependencies, since it is only required for running coverage, and it is always required when running coverage.Ah, I see. You'd have to change the definition of py_test in Bazel to get the dependency.
On Tue, Nov 28, 2017 at 9:11 AM, Ulf Adams <ulf...@google.com> wrote:On Tue, Nov 28, 2017 at 2:57 PM, Hyrum Wright <hwr...@duolingo.com> wrote:On Tue, Nov 28, 2017 at 3:43 AM, Ulf Adams <ulf...@google.com> wrote:On Mon, Nov 27, 2017 at 2:15 PM, Hyrum Wright <hwr...@duolingo.com> wrote:For my current purposes, I'm more interested in just getting the coverage tooling running. After it is generating output, we can worry about proper formatting and merging.To get the tooling running, it would be helpful to know the answers to these questions:
- Where is the location of the vendored copy of coverage, so that it can be added to the python path here: https://github.com/bazelbuild/bazel/compare/master...hwright:py-coverage#diff-34d8cb4d69c74a59002d79684518a778R151 (Note that this isn't for the test itself, but inside of the python stub.)
I don't see a vendored copy of coverage.py - why do you think we are vendoring one?I've added the vendored copy on my branch:With that branch, I can explicitly add "@bazel_tools//third_party/py/coverage" to the dependencies of a py_test, and the test stub will find the coverage module. I'd like for the test stub to be able to find that module without having to explicitly include it in the test dependencies, since it is only required for running coverage, and it is always required when running coverage.Ah, I see. You'd have to change the definition of py_test in Bazel to get the dependency.I spent some time last week digging around in the python rules and trying to figure out where the extra dependency would get injected. I came up empty, but had some promising leads. Specifically, it looks like there are multiple implementations of the py_test rule in Bazel:
Update:I've now got a Bazel which can run python coverage. Anybody that's interested can see the relevant patch here:The method for making the vendored coverage module available to the test stub seems like quite the hack: plumbing a path from the install path back through the BazelPythonConfiguration. If there's a better way to do this (or one that would make merging this branch more palatable) please let me know.
The next step seems to be to update tools/test/collect_coverage.sh to combine the output generated by bazel coverage .... In looking at collect_coverage.sh, I can't really tell if it's trying to be Java-specific or C++ specific or something else. It looks to have a dependency on the system-installed /usr/bin/lcov binary, which doesn't seem ideal from a hermeticity perspective.
I plan to use coverage.py's own faculties for merging its output. Is collect_coverage.sh the right place to do so? If so, how can I get the path to the vendored coverage installation in the Bazel install base from within that script? Is there a way to differentiate the different coverage tools producing output that script consumes?
On Tue, Nov 28, 2017 at 9:30 PM, Hyrum Wright <hwr...@duolingo.com> wrote:Update:I've now got a Bazel which can run python coverage. Anybody that's interested can see the relevant patch here:The method for making the vendored coverage module available to the test stub seems like quite the hack: plumbing a path from the install path back through the BazelPythonConfiguration. If there's a better way to do this (or one that would make merging this branch more palatable) please let me know.It needs to be a dependency on a rule or target, for hermeticity.
The next step seems to be to update tools/test/collect_coverage.sh to combine the output generated by bazel coverage .... In looking at collect_coverage.sh, I can't really tell if it's trying to be Java-specific or C++ specific or something else. It looks to have a dependency on the system-installed /usr/bin/lcov binary, which doesn't seem ideal from a hermeticity perspective.It's trying to be language-agnostic. The idea is that all test runners generate the same format into a common directory, and then we can use a simple tool to merge all the results. Having language-specific sections in collect_coverage.sh is a problem - if we can't do it in a language-agnostic way then we need to find a way to inject language-specific parts into the processing without having them hard-coded in the script. (Although I could be convinced to defer such work.)
Note that Bazel only declares a single coverage output file per test at this time, so if we want that to work for multi-lingual integration tests (which would be nice), they all have to be in the same format. There have been calls for allowing multiple output files / formats, but it's going to be a strictly worse user experience, as we then can't really post-process the results, e.g., to generate an html report. As a temporary workaround, I hear that some people are generating coverage data into the undeclared outputs directory.I plan to use coverage.py's own faculties for merging its output. Is collect_coverage.sh the right place to do so? If so, how can I get the path to the vendored coverage installation in the Bazel install base from within that script? Is there a way to differentiate the different coverage tools producing output that script consumes?As I said, we don't currently have a way of injecting language-specific information into the script. The way we do it at Google is that we have hard-coded support for specific languages, i.e., we haven't solved this problem yet. I'd prefer not to repeat that, but I'm also sympathetic to a desire to have it work without rewriting the entire infrastructure.The InstrumentedFilesProvider currently has a way of injecting environment variables from the rule implementations to the test. You might be able to make that do what you need, but it's probably insufficient to handle the general case.
On Wed, Nov 29, 2017 at 3:03 AM, Ulf Adams <ulf...@google.com> wrote:On Tue, Nov 28, 2017 at 9:30 PM, Hyrum Wright <hwr...@duolingo.com> wrote:Update:I've now got a Bazel which can run python coverage. Anybody that's interested can see the relevant patch here:The method for making the vendored coverage module available to the test stub seems like quite the hack: plumbing a path from the install path back through the BazelPythonConfiguration. If there's a better way to do this (or one that would make merging this branch more palatable) please let me know.It needs to be a dependency on a rule or target, for hermeticity.Right.My initial attempts to add "@bazel_tools//third_party/py/coverage" to the dependencies from within the PyTest implementation were a bit muddled. My naive approach was to clone the existing RuleContext and replace it with one which has that target as an additional dependency here: https://github.com/bazelbuild/bazel/blob/91fb38e92ace6cf14ce5da6527d71320b4e3f3d2/src/main/java/com/google/devtools/build/lib/rules/python/PyTest.java#L40
On Wed, Nov 29, 2017 at 2:55 PM, Hyrum Wright <hwr...@duolingo.com> wrote:On Wed, Nov 29, 2017 at 3:03 AM, Ulf Adams <ulf...@google.com> wrote:On Tue, Nov 28, 2017 at 9:30 PM, Hyrum Wright <hwr...@duolingo.com> wrote:Update:I've now got a Bazel which can run python coverage. Anybody that's interested can see the relevant patch here:The method for making the vendored coverage module available to the test stub seems like quite the hack: plumbing a path from the install path back through the BazelPythonConfiguration. If there's a better way to do this (or one that would make merging this branch more palatable) please let me know.It needs to be a dependency on a rule or target, for hermeticity.Right.My initial attempts to add "@bazel_tools//third_party/py/coverage" to the dependencies from within the PyTest implementation were a bit muddled. My naive approach was to clone the existing RuleContext and replace it with one which has that target as an additional dependency here: https://github.com/bazelbuild/bazel/blob/91fb38e92ace6cf14ce5da6527d71320b4e3f3d2/src/main/java/com/google/devtools/build/lib/rules/python/PyTest.java#L40The dependency needs to be statically declared in PyTestRule. When the rule is being evaluated it is too late - Bazel loads and analyzes all dependencies before evaluating the rule, and there's no mechanism to retry or to analyze on demand.
On Thu, Nov 30, 2017 at 3:42 AM, Ulf Adams <ulf...@google.com> wrote:On Wed, Nov 29, 2017 at 2:55 PM, Hyrum Wright <hwr...@duolingo.com> wrote:On Wed, Nov 29, 2017 at 3:03 AM, Ulf Adams <ulf...@google.com> wrote:On Tue, Nov 28, 2017 at 9:30 PM, Hyrum Wright <hwr...@duolingo.com> wrote:Update:I've now got a Bazel which can run python coverage. Anybody that's interested can see the relevant patch here:The method for making the vendored coverage module available to the test stub seems like quite the hack: plumbing a path from the install path back through the BazelPythonConfiguration. If there's a better way to do this (or one that would make merging this branch more palatable) please let me know.It needs to be a dependency on a rule or target, for hermeticity.Right.My initial attempts to add "@bazel_tools//third_party/py/coverage" to the dependencies from within the PyTest implementation were a bit muddled. My naive approach was to clone the existing RuleContext and replace it with one which has that target as an additional dependency here: https://github.com/bazelbuild/bazel/blob/91fb38e92ace6cf14ce5da6527d71320b4e3f3d2/src/main/java/com/google/devtools/build/lib/rules/python/PyTest.java#L40The dependency needs to be statically declared in PyTestRule. When the rule is being evaluated it is too late - Bazel loads and analyzes all dependencies before evaluating the rule, and there's no mechanism to retry or to analyze on demand.There is no class named PyTestRule. I'm assuming you meant BazelPyTestRule: https://github.com/bazelbuild/bazel/blob/e222ba362c4c8c0cc0c76b308ee899e75098746a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyTestRule.javaThat seems like a fine place to inject the new dependency, but again the mechanics of doing so are a bit daunting to somebody unfamiliar with the Bazel codebase (and unable to find documentation about it). For example, it looks like we need to override the existing "deps" attribute as part of the RuleContext.Builder, but we don't have a way to get the existing value before overwriting it. We need that value so we can append to the list, rather than just substituting it. I can't find any other instance in the Bazel codebase where an attribute with a label list is extended, so I'm not even sure that facility exists.Again, any pointers would here would be useful.
-Hyrum
--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/82532b8f-2696-4525-838b-a670bec072f0%40googlegroups.com.