0
$\begingroup$

Rosanswers logo

My team is currently transitioning from Ubuntu 12.04 and ROS Fuerte to Ubuntu 14.04 and ROS Indigo. All of our software is heavily tested using gtest and gmock. The latter is proving particularly difficult during this migration.

In Ubuntu 12.04, the gtest package is source-only, so rosbuild's public.cmake is hard-coded to check for that and compile it as needed. However, gmock's package includes a compiled library, so we just needed to make sure we added it to our linker and we were good to go.

We didn't investigate any further at the time, but it turned out that this only worked out of pure luck. I've since learned that gmock is distributed with a version of gtest included, and must use that version. As luck would have it, the packages in the repos were in sync (i.e. the gtest version was the same as the version of gtest included in gmock).

I learned that because now it's biting us in Ubuntu 14.04. Gmock has changed to also be distributed as source-only, but of course it still includes a version of gtest. However, this time the version of gtest contained within gmock was not in sync with the gtest package, so I spent some time tracking that down (ended up stealing a later version of the gtest package from the next Ubuntu release). Ideally I'd just uninstall the libgtest-dev package, but half the ROS packages depend upon it.

Anyway, in Indigo, Catkin still has the hard-coded logic to look in /usr/src/gtest/src for gtest's source, which is where the libgtest-dev installs it. However, that makes it downright impossible to link in gmock without some serious alterations to gmock. When using gmock, ideally one would simply add it to the CMakeLists.txt and use as well as gtest (since gmock pulls in gtest). However, we can't do that since Catkin automatically pulls in the libgtest-dev's version of gtest, and pulling in gmock just defines the libgtest and libgtest_main targets twice, which obviously doesn't fly.

I feel like my only option is to disable Catkin's testing and stop using Catkin's gtest macros and essentially roll my own version that uses gmock and its bundled gtest instead. Or move to another mocking framework, which would be... painful.

I know other people were using gtest and gmock in 12.04 and rosbuild, but I've seen nothing for gmock and Catkin. What is everyone else doing?


Originally posted by kyrofa on ROS Answers with karma: 347 on 2014-12-17

Post score: 2

$\endgroup$

4 Answers 4

0
$\begingroup$

Rosanswers logo

catkin currently only provides functions to support the user in using gtest.

We have added gmock support in a forked version but there these modifications are not easily deployable to ROS. The reason is that once any package is using gtest a later package within the same workspace can't use gmock since it requires to switch the gtest version being used (when the workspace is build without isolation.

The only viable option would be to remove the dependency on gtest and replacing it with gmock - even if packages only use gtest. Such a change could be considered for the next ROS distro (Jade). I would hesitate to backport such a severe change into a long-ago released ROS release simply for stability reasons.

Anyway, I don't think that your statement that catkin makes it "downright impossible" to use gmock is true. It does not provide any support for it but any package is "free" to use gmock and setup everything necessary for it on its own. The only thing you have to make sure is to "find" gtest (from within gmock) before finding catkin. In that case the whole logic in catkin to find gtest will be skipped (https://github.com/ros/catkin/blob/8033824d340d801eb7a9b2a94504b501173aaff9/cmake/test/gtest.cmake#L62).

This approach will still have the caveat mentioned above when you try to build your package together with other packages without isolation.


Originally posted by Dirk Thomas with karma: 16276 on 2014-12-17

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by kyrofa on 2014-12-18:
According to catkin's gtest.cmake file, if gtest is found is still adds an imported lib called "gtest" and "gtest_main," which means at least with my knowledge of CMake, I can't build another target lib called "gtest" or "gtest_main". So are you suggesting I pre-build gtest and gmock?

Comment by kyrofa on 2014-12-18:
For what it's worth, it would be a pretty simple change for catkin to check to see if /usr/src/gmock/gtest exists before the test for /usr/src/gtest, and would be backward compatible. Wouldn't it?

Comment by Dirk Thomas on 2014-12-18:
That would be a good option. But the path-based lookup is only the second resolve strategy. If the first (find_package(GTest QUIET)) is successful we are not even looking at these hard-coded paths.

I have created https://github.com/ros/catkin/issues/699 for using gmock together with catkin.

Comment by kyrofa on 2014-12-18:
Correct me if I'm wrong, but if I follow the Ubuntu ROS install guide and install ros-indigo-desktop-full, it pulls in libgtest-dev. libgtest-dev is source-only-- find_package(GTest QUIET) will fail! Which means on a default Ubuntu install, you're always using the second resolve strategy.

Comment by kyrofa on 2014-12-18:
So again, the only way to supercede the default behavior is to use find_package(GTest QUIET), which in my understanding requires a pre-built gtest, violating gtest recommendations (https://code.google.com/p/googletest/wiki/FAQ#Why_is_it_not_recommended_to_install_a_pre-compiled_copy_of_Goog).

$\endgroup$
0
$\begingroup$

Rosanswers logo

It seems the only way to continue building GTest and GMock from source (as recommended by Google) is to patch Catkin to check for the presence of GMock before GTest. Such a change is contained within this pull request, and is backward-compatible.


Originally posted by kyrofa with karma: 347 on 2015-01-13

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$
0
$\begingroup$

Rosanswers logo

I build gmock manually and replace GTEST_LIBRARIES after find_package(catkin). This is not clean solution but it works in Ubuntu 14.04 and Indigo.

find_package(catkin REQUIRED)
...
# Build gmock
set(gmock_SOURCE_DIR /usr/src/gmock)
include_directories(${gmock_SOURCE_DIR}/include
                    ${gmock_SOURCE_DIR}
                    ${gmock_SOURCE_DIR}/gtest/include
                    ${gmock_SOURCE_DIR}/gtest)
add_library(gmock
            ${gmock_SOURCE_DIR}/gtest/src/gtest-all.cc
            ${gmock_SOURCE_DIR}/src/gmock-all.cc)
target_link_libraries(gmock pthread)
# Replace catkin variable
set(GTEST_LIBRARIES gmock)
...
catkin_add_gtest(${PROJECT_NAME}-test test/test_sample.cpp)

Originally posted by otamachan with karma: 101 on 2015-11-18

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$
0
$\begingroup$

Rosanswers logo

Based on @otamachan answer, this is my working configuration on Ubuntu 16.04 with ROS Kinetic, gtest (libgtest-dev v1.7.0-4ubuntu1) and gmock (google-mock v1.7.0-18092013-1):

# Tests
if(CATKIN_ENABLE_TESTING)
  find_package(rostest REQUIRED)

  # explicit gmock build (set these paths properly!)
  include_directories(/usr/include/gmock /usr/src/gmock)
  find_library(GMOCK_LIBRARIES libgmock)
  if(NOT GMOCK_LIBRARIES)
    add_library(libgmock /usr/src/gmock/src/gmock-all.cc)
  endif()

  add_rostest_gtest(my_test
    test/my_test.test
    src/test/my_test.cpp
    ...
  )

  target_link_libraries(my_test
    libgmock
    ${catkin_LIBRARIES}
  )
endif()

It seems that the problem has been simplified since gmock does not include gtest anymore.


EDIT: as shown in the launchpad, the google-mock package for Ubuntu Xenial depends on libgtest-dev (>= 1.6.0). Actually it does not includes gtest even since Ubuntu 14.10 (Utopic Unicorn). Unfortunately, Ubuntu 14.04 is shipped with google-mock v1.6.0+svn437-0ubuntu5 (see the package) which includes gtest inside; indeed, it depends on nothing but python.


EDIT2: added a simple check to avoid multiple add_library(libgmock ...) from distinct packages.


Originally posted by alextoind with karma: 217 on 2017-01-17

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by Dirk Thomas on 2017-01-24:
gtest never included gmock. gmock includes / included (?) gtest.

Comment by alextoind on 2017-01-24:
@Dirk Thomas sorry for the typo, it's obviously that way - as shown in the other answer. Edited, thank you!

Comment by roboticom314 on 2017-02-01:
What about running ROS Indigo on Ubuntu 16.04 Xenial? Would this allow for the separation between Google test and Google mock packages to try this fix?

Comment by joq on 2017-02-01:
ROS Indigo is not supported on Ubuntu Xenial. You'd need ROS Kinetic, instead.

Comment by alextoind on 2017-02-01:
@roboticom314 with Xenial you would be fine: it is not a matter of ROS version. However, @joq is right.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.