-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
A way to register additional test targets and support .py only tests. #3590
Conversation
@rwgk , as for:
I think I see what you mean, looking at that specific point... the filtering seems to happen in this section above the addition of your new python test file, which happens on line 192. I'll think a bit about how best to solve this in a backwards compatible way. |
Yes, that's it! Thanks for digging it up. Tagging @henryiii for awareness / comment. I was thinking it may be best to change the behavior of
|
That would be backwards compatible I think though? Not too sure where the distinction between cpp and python is needed. Maybe we can just do this and filter it into two lists before anything consumes it? I'll take a closer look this evening. |
Not following too closely yet, but the reason for filtering is to filter out cpp files that don't need to be built, allowing incremental/partial testing. Long term I don't think we should do this at all, but rather have individual test targets for each test, and a "total" test target that runs all of them. That way, you could just build a single test and run a single test, or you could build/run all of them, and it would even reuse the existing builds. I don't think backward compatibility is that important for test running, FWIW. |
503649e
to
4adf27f
Compare
So, I took a look at the 'real' issue. So, for my own understanding I wrote out what actually happens;
So, there's some 'special' handling for the new test file. Less than ideal. I think assuming a test has both a So, I still went the way of supporting both .cpp and .py files in the same list. When there's no extension specified, we assume that both a I did foresee some issues with this and the test filtering, and wanted to preserve backward compatibility for that. To achieve this I made the test filter function ignore file extensions. This is a macro so I ran into the argument issues around that, hence the ugly
So, despite my best efforts this is the one flag that is changed. Since this directly overrides the list, instead of acting as a 'whitelist' it was not easy to fix this. The only way would be intersecting this variable with the I've tested this with
```
cd build/
rm -rf *
cmake ../pybind11/ -DPYBIND11_TEST_FILTER="test_class_sh_module_local.py"
#~ cmake ../pybind11/ -DPYBIND11_TEST_FILTER="test_async" # this also works.
cmake --build . --target check
cd ../
```
and
```
cd build/
rm -rf *
cmake ../pybind11/ -DPYBIND11_TEST_OVERRIDE="test_stl;test_smart_ptr"
cmake --build . --target check
cd ../
```
Both filter and override still seem to behave as expected.
Agreed, the current is a bit odd, but doing that refactor is beyond my understanding of best practices around this unfortunately.
I think preserving the filter functionality is important. There may be build systems out there that ignore tests that take long or are flaky. I know for sure that at my work we do that for some upstream packages. I'd say preserving backwards compatibility is preferred if possible, even when it comes to the build system. @rwgk , could you check if the current version addresses your outstanding bullet point? |
Awesome, thanks a lot! I cannot meaningfully review the cmake details b/o lack of relevant background, but I see test_class_sh_module_local fits in very nicely with your approach. I'm guessing the 50 failures due to a small bug? What do you think about porting your infra-structure changes to the master branch? That would make it easier to maintain the smart_holder branch until it's ready for merging. I could (actually want to) take care of the smart_holder-specific cmake diffs. |
Well... there was supposed to be zero failures of course :D So turned out one of the phases in the CI test ran:
Notice that
Yeah, for sure, I'm indifferent. I can cherrypick these commits to master when the pipeline is green. I'd like to stay on this branch for now to have the test case you introduced in there, as |
Looking great! |
I just spent 10 minutes looking through the changes but TBH I'm having trouble following the code. In general I'm a big fan of merge-and-iterate, but in this situation I'm afraid it could get messy. I've been super conscious about keeping I'm practically certain that there will be tweaks in the review on master; it just always happens. It'll be tricky to handle the conflicts when doing the |
I've just rebased it on |
29a844c
to
47cfb9f
Compare
Awesome, I think that's a great idea, thanks! |
47cfb9f
to
c4f8b54
Compare
Ok, sorry about the double force push, turned out I lost a commit when I switched to I've updated the description to provide an explanation of what happened and how it is all done. @rwgk , I hope this clarifies a bit how this PR makes your new unit tests fit in nicely. (Also, |
Thanks a lot! I'll try this out asap.
It's intentional, that test is very much unlike the others. |
👍 give it a shot, see if it does what you want it to do. Like I said, I mainly saw an ask for help and answered the call. I don't really know how most of the cmake flags are actually used by developers in this repo :) Once you are happy with the proposed changes it should be good for review, pipeline is green again.
Ah, check, yeah, there indeed shouldn't be a strict requirement on a .cpp having a .py file equivalent anymore. |
Minor update: I'm currently mystified
I guess I'll have to dig in. |
Hmm, interesting. I presume this section is related to it... maybe something isn't backwards compatible afterall? @rwgk |
@rwgk , it's a problem in my changes to the Specifically, it's a bug in the extension-remover, it's greedy and in your PR the In short; problem understood, fix in the works. |
Thanks for the hint! I looked at the logs, your guess is definitely true for the CUDA 11 job (below). I'm still trying to understand the difference for PGI. @iwanders
|
This manifests the issue, that clips the list at the |
And the fix is I think changing it to Let me run some tests. |
For easy reference, below are the tests/CMakeLists.txt diffs relative to master
Note importantly: without this PR, the diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b00c043a..7ae2496f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -101,6 +101,20 @@ set(PYBIND11_TEST_FILES
test_callbacks.cpp
test_chrono.cpp
test_class.cpp
+ test_class_sh_basic.cpp
+ test_class_sh_disowning.cpp
+ test_class_sh_disowning_mi.cpp
+ test_class_sh_factory_constructors.cpp
+ test_class_sh_inheritance.cpp
+ test_class_sh_shared_ptr_copy_move.cpp
+ test_class_sh_trampoline_basic.cpp
+ test_class_sh_trampoline_self_life_support.cpp
+ test_class_sh_trampoline_shared_from_this.cpp
+ test_class_sh_trampoline_shared_ptr_cpp_arg.cpp
+ test_class_sh_trampoline_unique_ptr.cpp
+ test_class_sh_unique_ptr_member.cpp
+ test_class_sh_virtual_py_cpp_mix.cpp
+ test_classh_mock.cpp
test_const_name.cpp
test_constants_and_functions.cpp
test_copy_move.cpp
@@ -163,6 +177,8 @@ if(PYBIND11_CUDA_TESTS)
endif()
string(REPLACE ".cpp" ".py" PYBIND11_PYTEST_FILES "${PYBIND11_TEST_FILES}")
+list(APPEND PYBIND11_PYTEST_FILES test_class_sh_module_local.py)
+list(SORT PYBIND11_PYTEST_FILES)
# Contains the set of test files that require pybind11_cross_module_tests to be
# built; if none of these are built (i.e. because TEST_OVERRIDE is used and
@@ -172,6 +188,8 @@ set(PYBIND11_CROSS_MODULE_TESTS test_exceptions.py test_local_bindings.py test_s
set(PYBIND11_CROSS_MODULE_GIL_TESTS test_gil_scoped.py)
+set(PYBIND11_CLASS_SH_MODULE_LOCAL_TESTS test_class_sh_module_local.py)
+
set(PYBIND11_EIGEN_REPO
"https://gitlab.com/libeigen/eigen.git"
CACHE STRING "Eigen repository to use for tests")
@@ -367,6 +385,16 @@ foreach(t ${PYBIND11_CROSS_MODULE_GIL_TESTS})
endif()
endforeach()
+foreach(t ${PYBIND11_CLASS_SH_MODULE_LOCAL_TESTS})
+ list(FIND PYBIND11_PYTEST_FILES ${t} i)
+ if(i GREATER -1)
+ list(APPEND test_targets class_sh_module_local_0)
+ list(APPEND test_targets class_sh_module_local_1)
+ list(APPEND test_targets class_sh_module_local_2)
+ break()
+ endif()
+endforeach()
+
# Support CUDA testing by forcing the target file to compile with NVCC
if(PYBIND11_CUDA_TESTS)
set_property(SOURCE ${PYBIND11_TEST_FILES} PROPERTY LANGUAGE CUDA) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0c146396..0667f0a7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -122,6 +122,21 @@ set(PYBIND11_TEST_FILES
test_callbacks
test_chrono
test_class
+ test_class_sh_basic
+ test_class_sh_disowning
+ test_class_sh_disowning_mi
+ test_class_sh_factory_constructors
+ test_class_sh_inheritance
+ test_class_sh_module_local.py
+ test_class_sh_shared_ptr_copy_move
+ test_class_sh_trampoline_basic
+ test_class_sh_trampoline_self_life_support
+ test_class_sh_trampoline_shared_from_this
+ test_class_sh_trampoline_shared_ptr_cpp_arg
+ test_class_sh_trampoline_unique_ptr
+ test_class_sh_unique_ptr_member
+ test_class_sh_virtual_py_cpp_mix
+ test_classh_mock
test_const_name
test_constants_and_functions
test_copy_move
@@ -221,6 +236,8 @@ tests_extra_targets("test_exceptions.py;test_local_bindings.py;test_stl.py;test_
# And add additional targets for other tests.
tests_extra_targets("test_gil_scoped.py" "cross_module_gil_utils")
+tests_extra_targets("test_class_sh_module_local.py"
+ "class_sh_module_local_0;class_sh_module_local_1;class_sh_module_local_2")
set(PYBIND11_EIGEN_REPO
"https://gitlab.com/libeigen/eigen.git" |
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.
Looking for a 2nd review from @henryiii or @Skylion007.
I'm practically certain that's wasn't the issue: it's a warning, and it also appears in the output of the job that worked. I even compared the compilation commands, they are exactly identical. If you think digging deeper could lead to valuable insights, these are the links to the two logs (not sure how long they will work): Slight less direct links that may work for a longer time:
|
Links expired, but yeah, compile command looked the same. this morning I grabbed that toolchain and the Python3.6m headers and tried to reproduce the failure locally (on 41a549c, which had the failure), but both I would've liked to understand the failure, but I'm clueless as well. Can't reproduce it locally, so I'm ok accepting it as a fluke from this proprietary toolchain. |
Me too (to maximize confidence for this PR). @iwanders I think I found a clue. First a simple sanity check: I triggered the testing again to see if the PGI failure was just a random flake, but it reproduces. (Not surprisingly, it reproduced between CI and CI-SH-DEF already; but now we're sure beyond a reasonable doubt.) Looking at the "established" and "broken" logs from yesterday again, I see this in both (modulo time stamps):
In the "broken" log I see this:
But this does NOT appear in the "established" log. In tests/CMakeLists.txt I see this:
Clearly that didn't work in the "broken" log. As a consequence it ran into an internal compiler error when trying to compile test_smart_ptr.cpp. Does that make sense? |
Of course, it's so easy to make mistakes in cmake, I honestly sometimes feel like there should be a test system for the buildsystem 🙄
Yes, you found a clue indeed! I understand the failure now that you showed it runs with a test filter. So the filter is applied here, and then we go to the filter macro. This then strips the extensions with the regex replace and then discards anything that matches. However, recall that in your branch, the tests looked like this;
In which case, the greedy regex would replace everything from the I've pushed a minimal working example that reproduces the situation. This shows the filter doesn't work in the greedy-regex situation if you have a file with an extension in the middle of the list (bec4e0b). That prints a list that includes the Good to understand that fully 👍 |
Awesome. Thanks for the in-depth explanation! |
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.
Would have been cleaner if we could have used a few features from modern CMake, but we are stuck on older versions for the moment for core stuff and this seems reasonable.
Hah, agreed, |
a36de2c
to
085edf1
Compare
Retesting after |
Thanks a lot Ivor, and thanks Aaron and Henry for the reviews! |
Description
@rwgk asked for help on the CMake bullet point in this comment. I proposed some changes in the comment after that, moving it to a PR for easier discussion.
Changes in this PR are two-fold:
The first commit, solves the first problem. So before, there was special handling for
PYBIND11_CROSS_MODULE_TESTS
,PYBIND11_CROSS_MODULE_GIL_TESTS
andPYBIND11_CLASS_SH_MODULE_LOCAL_TESTS
in the new test @rwgk added in thesmart_holder
branch. I thought that that block, I initially thought the desire was to make that handling uniform. So what I made to handle that using common logic is a lookup where we can register additional targets if a particular test is present. Registering extra targets is done through the newtests_extra_targets
macro. The first argument it takes (needles), are test that will be looked for in the PYTEST lists, if any of the needles is found, the additional targets specified in the second argument (additions) will be added. The registered mappings are stored in an emulated map calledPYBIND11_TEST_EXTRA_TARGETS
.So, registration is done through
tests_extra_targets
, then, after all the filtering is performed on the tests, we iterate through the registeredtest->targets
mapping (PYBIND11_TEST_EXTRA_TARGETS
), check if any of the needles are found in the tests, if so we add the additional targets that are stored as values in the map.The second commit addresses the actual concern @rwgk had with the new test addition not behaving nicely with the override and test filtering. So, the original CMakeLists file assumed that for each cpp file in
PYBIND11_TEST_FILES
, there would be a single .py file with the same name. This didn't play nicely with the new test being added, which has just a single python file, this broke the assumption that the big lists of tests is a list of cpp files for which a .py file exists. So, change made here is to have the big list of files use no extension when both a.py
file AND a.cpp
file is present. If an extension is specified this test is assumed to be stand alone, without a .py or .cpp counterpart of the same name. After filtering, the test list it split with python files going into the already existing PYTEST list and thePYBIND11_TEST_FILES
variable is overwritten with the .cpp files.To preserve backwards compatibility on the test filter, we made the filter function ignore any extensions. After all, the big lists of tests now contains either no extension, or .cpp or .py, but we don't want to break anyone's already existing filters. Then, this still broke the test override, so we fixed (third commit) that by instead of directly overriding
PYBIND11_TEST_FILES
with the override, we now instead match the override list against the test list (ignoring extensions again), and filter out anything that is NOT present in the override. This ensures that overrides specified with a.cpp
file, but in the test list without an extension will still be respected as without an extension. This should make it fully backwards compatible, both for the filter flag and the override flag.It adds a bit of code, but it's fully backwards compatible and should allow for more uniform handling of tests made up of .py, .cpp or both.
Suggested changelog entry: