diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2b226cb..94265e4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,8 +9,33 @@ set(BUILD_SHARED_LIBS OFF) FetchContent_MakeAvailable(googletest) include(GoogleTest) +function(add_valgrind_wrapper test_name) + set(TEST_NAME "${test_name}") + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/valgrind_test.in + ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_valgrind @ONLY) + + file( + CHMOD + ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_valgrind + PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE) + + install( + PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_valgrind + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT ${PROJECT_NAME}-dev) +endfunction() + add_executable(gdbusproxypp_test gdbusproxypp_test.cpp) target_link_libraries(gdbusproxypp_test PRIVATE GDbusProxy gtest_main) +add_valgrind_wrapper(gdbusproxypp_test) install( TARGETS gdbusproxypp_test @@ -31,6 +56,7 @@ if(BUILD_CONNMAN) TARGETS ${connman_test} EXPORT ${PROJECT_NAME}-config COMPONENT ${PROJECT_NAME}-dev) + add_valgrind_wrapper(${connman_test}) endforeach() endif(BUILD_CONNMAN) diff --git a/tests/gconnman_tech_test.cpp b/tests/gconnman_tech_test.cpp index d09989b..7164e76 100644 --- a/tests/gconnman_tech_test.cpp +++ b/tests/gconnman_tech_test.cpp @@ -17,24 +17,33 @@ TEST(Connman, getTechs) { Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged( - [&called, main_tid = thread_bundle.main_tid, - loop_tid = thread_bundle.loop_tid](const auto& technologies) { - called = true; + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + called = true; + if (check_thread_id) { const auto callback_tid = std::this_thread::get_id(); EXPECT_NE(callback_tid, main_tid); EXPECT_NE(callback_tid, loop_tid); - ASSERT_FALSE(technologies.empty()); - for (const auto& tech : technologies) { - const auto props = tech->properties(); - EXPECT_FALSE(props.getName().empty()); - if (props.isConnected()) { - EXPECT_TRUE(props.isPowered()) - << "Technology is connected but not powered"; - } - std::cout << props; + } + ASSERT_FALSE(technologies.empty()) << "No technologies returned"; + for (const auto& tech : technologies) { + const auto props = tech->properties(); + EXPECT_FALSE(props.getName().empty()); + if (props.isConnected()) { + EXPECT_TRUE(props.isPowered()) + << "Technology is connected but not powered"; } - }); + std::cout << props; + } + }; + + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "TechnologiesChanged callback was never called"; } @@ -47,14 +56,16 @@ TEST(Connman, PowerOnAllTechnologies) { Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged([&called, - main_tid = thread_bundle.main_tid, - loop_tid = thread_bundle.loop_tid]( - const auto& technologies) { - const auto callback_tid = std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - ASSERT_FALSE(technologies.empty()); + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + if (check_thread_id) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + } + ASSERT_FALSE(technologies.empty()) << "No technologies returned"; // Power on all technologies for (const auto& tech : technologies) { tech->onPropertyChanged([main_tid, loop_tid](const auto& prop) { @@ -85,7 +96,12 @@ TEST(Connman, PowerOnAllTechnologies) { }); } } - }); + }; + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "setPowered callback was never called"; } @@ -97,32 +113,42 @@ TEST(Connman, ScanWifiTechnology) { Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged( - [&called, main_tid = thread_bundle.main_tid, - loop_tid = thread_bundle.loop_tid](const auto& technologies) { - ASSERT_FALSE(technologies.empty()) - << "No technologies returned"; + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + if (check_thread_id) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + } + ASSERT_FALSE(technologies.empty()) << "No technologies returned"; - for (const auto& tech : technologies) { - const auto props = tech->properties(); - const auto name = props.getName(); - if (props.getType() == Type::Wifi) { - std::cout << "Scanning technology with name: " << name - << "\n"; - tech->scan( - [&called, name, main_tid, loop_tid](bool success) { - const auto callback_tid = - std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - called = true; - EXPECT_TRUE(success); - std::cout << "Technology " << name - << " scanned successfully.\n"; - }); - } + for (const auto& tech : technologies) { + const auto props = tech->properties(); + const auto name = props.getName(); + if (props.getType() == Type::Wifi) { + std::cout << "Scanning technology with name: " << name + << "\n"; + tech->scan([&called, name, main_tid, + loop_tid](bool success) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + called = true; + EXPECT_TRUE(success); + std::cout << "Technology " << name + << " scanned successfully.\n"; + }); } - }); + } + }; + + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "TechnologiesChanged callback was never called"; } @@ -134,66 +160,75 @@ TEST(Connman, SetTetheringOn) { Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged( - [&called, main_tid = thread_bundle.main_tid, - loop_tid = thread_bundle.loop_tid](const auto& technologies) { - ASSERT_FALSE(technologies.empty()) - << "No technologies returned"; + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + if (check_thread_id) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + } + ASSERT_FALSE(technologies.empty()) << "No technologies returned"; - for (const auto& tech : technologies) { - const auto props = tech->properties(); - const auto name = props.getName(); + for (const auto& tech : technologies) { + const auto props = tech->properties(); + const auto name = props.getName(); - if (props.getType() == Type::Wifi) { // test only wifi - std::cout << "Setting tethering properties for " << name - << "\n"; - tech->setTetheringIdentifier( - "AmarulaTestSSID", - [name, main_tid, loop_tid](bool success) { - const auto callback_tid = - std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - EXPECT_TRUE(success) - << "Failed to set tethering identifier for " - << name; - }); - tech->setTetheringPassphrase( - "AmarulaTestPassphrase", - [name, main_tid, loop_tid](bool success) { - const auto callback_tid = - std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - EXPECT_TRUE(success) - << "Failed to set tethering passphrase for " - << name; - }); + if (props.getType() == Type::Wifi) { // test only wifi + std::cout << "Setting tethering properties for " << name + << "\n"; + tech->setTetheringIdentifier( + "AmarulaTestSSID", + [name, main_tid, loop_tid](bool success) { + const auto callback_tid = + std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + EXPECT_TRUE(success) + << "Failed to set tethering identifier for " + << name; + }); + tech->setTetheringPassphrase( + "AmarulaTestPassphrase", + [name, main_tid, loop_tid](bool success) { + const auto callback_tid = + std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + EXPECT_TRUE(success) + << "Failed to set tethering passphrase for " + << name; + }); - tech->setTetheringFreq( - WIFI_FREQ_2412_MHZ, - [name, main_tid, loop_tid](bool success) { - const auto callback_tid = - std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - EXPECT_TRUE(success) - << "Failed to set tethering frequency for " - << name; - }); - tech->setTethering(true, [&called, name, main_tid, - loop_tid](bool success) { + tech->setTetheringFreq( + WIFI_FREQ_2412_MHZ, + [name, main_tid, loop_tid](bool success) { const auto callback_tid = std::this_thread::get_id(); EXPECT_NE(callback_tid, main_tid); EXPECT_NE(callback_tid, loop_tid); EXPECT_TRUE(success) - << "Failed to set tethering for " << name; - called = true; + << "Failed to set tethering frequency for " + << name; }); - } + tech->setTethering(true, [&called, name, main_tid, + loop_tid](bool success) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + EXPECT_TRUE(success) + << "Failed to set tethering for " << name; + called = true; + }); } - }); + } + }; + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "setTethering callback was never called"; } @@ -205,31 +240,40 @@ TEST(Connman, SetTetheringOff) { Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged( - [&called, main_tid = thread_bundle.main_tid, - loop_tid = thread_bundle.loop_tid](const auto& technologies) { - ASSERT_FALSE(technologies.empty()) - << "No technologies returned"; + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + if (check_thread_id) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + } + ASSERT_FALSE(technologies.empty()) << "No technologies returned"; - for (const auto& tech : technologies) { - const auto props = tech->properties(); - const auto name = props.getName(); + for (const auto& tech : technologies) { + const auto props = tech->properties(); + const auto name = props.getName(); - if (props.getType() == Type::Wifi) { // test only wifi - std::cout << "Disable tethering for " << name << "\n"; - tech->setTethering(false, [&called, name, main_tid, - loop_tid](bool success) { - const auto callback_tid = - std::this_thread::get_id(); - EXPECT_NE(callback_tid, main_tid); - EXPECT_NE(callback_tid, loop_tid); - EXPECT_TRUE(success) - << "Failed to unset tethering for " << name; - called = true; - }); - } + if (props.getType() == Type::Wifi) { // test only wifi + std::cout << "Disable tethering for " << name << "\n"; + tech->setTethering(false, [&called, name, main_tid, + loop_tid](bool success) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + EXPECT_TRUE(success) + << "Failed to unset tethering for " << name; + called = true; + }); } - }); + } + }; + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "setTethering callback was never called"; } @@ -237,12 +281,20 @@ TEST(Connman, SetTetheringOff) { TEST(Connman, PowerOffAllTechnologies) { bool called = false; { + const ThreadBundle thread_bundle; Connman connman; const auto manager = connman.manager(); - manager->onTechnologiesChanged([&](const auto& technologies) { + auto do_on_techs = [&called, main_tid = thread_bundle.main_tid, + loop_tid = thread_bundle.loop_tid]( + const auto& technologies, + const bool check_thread_id = true) { + if (check_thread_id) { + const auto callback_tid = std::this_thread::get_id(); + EXPECT_NE(callback_tid, main_tid); + EXPECT_NE(callback_tid, loop_tid); + } ASSERT_FALSE(technologies.empty()) << "No technologies returned"; - // Power off all technologies for (const auto& tech : technologies) { tech->onPropertyChanged([&](const auto& prop) { @@ -266,7 +318,13 @@ TEST(Connman, PowerOffAllTechnologies) { }); } } - }); + }; + + if (manager->technologies().empty()) { + manager->onTechnologiesChanged(do_on_techs); + } else { + do_on_techs(manager->technologies(), false); + } } ASSERT_TRUE(called) << "setPowered callback was never called"; } diff --git a/tests/valgrind_test.in b/tests/valgrind_test.in new file mode 100644 index 0000000..456e166 --- /dev/null +++ b/tests/valgrind_test.in @@ -0,0 +1,9 @@ +#!/bin/sh + +exec env \ + G_SLICE=always-malloc \ + G_DEBUG=gc-friendly \ + valgrind \ + --leak-check=full \ + --show-leak-kinds=none \ + "$(dirname "$0")/@TEST_NAME@" "$@"