From 1ddc43ac753933b8860931b0a31fc0918ae91fa5 Mon Sep 17 00:00:00 2001 From: gururaajar Date: Tue, 17 Feb 2026 10:44:30 -0500 Subject: [PATCH 1/2] RDKEMW-13210: No IP address on 'eth0' when enabling Ethernet after a failed WiFiConnect Reason for Change: Added the unit test case for this test scenario Test Procedure: Run the unit test workflow for libnm Priority: P1 Risks: Medium Signed-off-by: Gururaaja ESR --- tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp b/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp index 278dcbcb..55ecde61 100644 --- a/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp +++ b/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp @@ -2251,6 +2251,147 @@ TEST_F(NetworkManagerWifiTest, RemoveKnownSSIDs_success_ssid_specified_found) g_ptr_array_free(fakeDevices, TRUE); } +TEST_F(NetworkManagerWifiTest, ActivateKnownConnection_WifiConnectionTypeFiltering) +{ + GPtrArray* fakeDevices = g_ptr_array_new(); + NMDevice *deviceDummy = static_cast(g_object_new(NM_TYPE_DEVICE_WIFI, NULL)); + g_ptr_array_add(fakeDevices, deviceDummy); + + // Create multiple connections with different types + GPtrArray* dummyConns = g_ptr_array_new(); + NMConnection *wifiConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *ethConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *vpnConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + g_ptr_array_add(dummyConns, ethConn); // First connection is ethernet + g_ptr_array_add(dummyConns, wifiConn); // Second connection is wifi + g_ptr_array_add(dummyConns, vpnConn); // Third connection is vpn + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_devices(::testing::_)) + .WillRepeatedly(::testing::Return(fakeDevices)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_iface(::testing::_)) + .WillRepeatedly(::testing::Return("wlan0")); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_state(::testing::_)) + .WillRepeatedly(::testing::Return(NM_DEVICE_STATE_DISCONNECTED)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_device_by_iface(::testing::_,::testing::_)) + .WillRepeatedly(::testing::Return(deviceDummy)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_set_autoconnect(::testing::_,::testing::_)) + .WillOnce(::testing::Return()); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_connections(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast(dummyConns))); + + // Setup connection IDs and types + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_id(::testing::_)) + .WillOnce(::testing::Return("Wired connection 1")) // ethConn + .WillOnce(::testing::Return("MyWiFiNetwork")) // wifiConn - match + .WillOnce(::testing::Return("MyWiFiNetwork")) // wifiConn - for activation + .WillOnce(::testing::Return("VPN Connection")); // vpnConn + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_connection_type(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast("802-3-ethernet"))) // ethConn - should be skipped for wlan0 + .WillOnce(::testing::Return(reinterpret_cast("802-11-wireless"))) // wifiConn - should be selected as firstConnection + .WillOnce(::testing::Return(reinterpret_cast("vpn"))); // vpnConn - should be skipped + + EXPECT_CALL(*p_gLibWrapsImplMock, g_main_loop_is_running(::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + NMActiveConnection *dummyActiveConn = static_cast(g_object_new(NM_TYPE_ACTIVE_CONNECTION, NULL)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_finish(::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Return(dummyActiveConn)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_async(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Invoke([](NMClient* client, NMConnection* connection, NMDevice* device, const char* specific_object, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer user_data) { + if (callback) { + GObject* source_object = G_OBJECT(client); + GAsyncResult* result = nullptr; + callback(source_object, result, user_data); + } + })); + + // Test SetInterfaceState for wlan0 which internally calls activateKnownConnection + // It should skip ethernet connection and use wifi connection as firstConnection + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("SetInterfaceState"), + _T("{\"interface\":\"wlan0\",\"enabled\":true}"), response)); + EXPECT_EQ(response, _T("{\"success\":true}")); + + g_object_unref(deviceDummy); + g_object_unref(wifiConn); + g_object_unref(ethConn); + g_object_unref(vpnConn); + g_ptr_array_free(dummyConns, TRUE); + g_ptr_array_free(fakeDevices, TRUE); +} + +TEST_F(NetworkManagerWifiTest, ActivateKnownConnection_EthernetConnectionTypeFiltering) +{ + GPtrArray* fakeDevices = g_ptr_array_new(); + NMDevice *deviceDummy = static_cast(g_object_new(NM_TYPE_DEVICE_ETHERNET, NULL)); + g_ptr_array_add(fakeDevices, deviceDummy); + + // Create multiple connections with different types + GPtrArray* dummyConns = g_ptr_array_new(); + NMConnection *wifiConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *ethConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + g_ptr_array_add(dummyConns, wifiConn); // First connection is wifi + g_ptr_array_add(dummyConns, ethConn); // Second connection is ethernet + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_devices(::testing::_)) + .WillRepeatedly(::testing::Return(fakeDevices)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_iface(::testing::_)) + .WillRepeatedly(::testing::Return("eth0")); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_state(::testing::_)) + .WillRepeatedly(::testing::Return(NM_DEVICE_STATE_DISCONNECTED)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_device_by_iface(::testing::_,::testing::_)) + .WillRepeatedly(::testing::Return(deviceDummy)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_set_autoconnect(::testing::_,::testing::_)) + .WillOnce(::testing::Return()); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_connections(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast(dummyConns))); + + // Setup connection IDs and types + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_id(::testing::_)) + .WillOnce(::testing::Return("MyWiFiNetwork")) // wifiConn + .WillOnce(::testing::Return("Wired connection 1")) // ethConn - match + .WillOnce(::testing::Return("Wired connection 1")); // ethConn - for activation + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_connection_type(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast("802-11-wireless"))) // wifiConn - should be skipped for eth0 + .WillOnce(::testing::Return(reinterpret_cast("802-3-ethernet"))); // ethConn - should be selected as firstConnection + + EXPECT_CALL(*p_gLibWrapsImplMock, g_main_loop_is_running(::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + NMActiveConnection *dummyActiveConn = static_cast(g_object_new(NM_TYPE_ACTIVE_CONNECTION, NULL)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_finish(::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Return(dummyActiveConn)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_async(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Invoke([](NMClient* client, NMConnection* connection, NMDevice* device, const char* specific_object, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer user_data) { + if (callback) { + GObject* source_object = G_OBJECT(client); + GAsyncResult* result = nullptr; + callback(source_object, result, user_data); + } + })); + + // Test SetInterfaceState for ethernet which internally calls activateKnownConnection + // It should skip wifi connection and use ethernet connection as firstConnection + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("SetInterfaceState"), + _T("{\"interface\":\"eth0\",\"enabled\":true}"), response)); + EXPECT_EQ(response, _T("{\"success\":true}")); + + g_object_unref(deviceDummy); + g_object_unref(wifiConn); + g_object_unref(ethConn); + g_ptr_array_free(dummyConns, TRUE); + g_ptr_array_free(fakeDevices, TRUE); +} + TEST_F(NetworkManagerWifiTest, StopWPS) { EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("StopWPS"), From e91e50929c8bc59d5a2008e044d827be3fce6bc1 Mon Sep 17 00:00:00 2001 From: gururaajar Date: Tue, 17 Feb 2026 10:44:30 -0500 Subject: [PATCH 2/2] RDKEMW-13210: No IP address on 'eth0' when enabling Ethernet after a failed WiFiConnect Reason for Change: Added the unit test case for this test scenario Test Procedure: Run the unit test workflow for libnm Priority: P1 Risks: Medium Signed-off-by: Gururaaja ESR --- tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp b/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp index 278dcbcb..22448e0c 100644 --- a/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp +++ b/tests/l2Test/libnm/l2_test_libnmproxyWifi.cpp @@ -2251,6 +2251,146 @@ TEST_F(NetworkManagerWifiTest, RemoveKnownSSIDs_success_ssid_specified_found) g_ptr_array_free(fakeDevices, TRUE); } +TEST_F(NetworkManagerWifiTest, ActivateKnownConnection_WifiConnectionTypeFiltering) +{ + GPtrArray* fakeDevices = g_ptr_array_new(); + NMDevice *deviceDummy = static_cast(g_object_new(NM_TYPE_DEVICE_WIFI, NULL)); + g_ptr_array_add(fakeDevices, deviceDummy); + + // Create multiple connections with different types + GPtrArray* dummyConns = g_ptr_array_new(); + NMConnection *wifiConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *ethConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *vpnConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + g_ptr_array_add(dummyConns, ethConn); // First connection is ethernet + g_ptr_array_add(dummyConns, wifiConn); // Second connection is wifi + g_ptr_array_add(dummyConns, vpnConn); // Third connection is vpn + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_devices(::testing::_)) + .WillRepeatedly(::testing::Return(fakeDevices)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_iface(::testing::_)) + .WillRepeatedly(::testing::Return("wlan0")); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_state(::testing::_)) + .WillRepeatedly(::testing::Return(NM_DEVICE_STATE_DISCONNECTED)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_device_by_iface(::testing::_,::testing::_)) + .WillRepeatedly(::testing::Return(deviceDummy)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_set_autoconnect(::testing::_,::testing::_)) + .WillOnce(::testing::Return()); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_connections(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast(dummyConns))); + + // Setup connection IDs and types + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_id(::testing::_)) + .WillOnce(::testing::Return("Wired connection 1")) // ethConn + .WillOnce(::testing::Return("MyWiFiNetwork")) // wifiConn - match + .WillOnce(::testing::Return("MyWiFiNetwork")) // wifiConn - for activation + .WillOnce(::testing::Return("VPN Connection")); // vpnConn + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_connection_type(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast("802-3-ethernet"))) // ethConn - should be skipped for wlan0 + .WillOnce(::testing::Return(reinterpret_cast("802-11-wireless"))) // wifiConn - should be selected as firstConnection + .WillOnce(::testing::Return(reinterpret_cast("vpn"))); // vpnConn - should be skipped + + EXPECT_CALL(*p_gLibWrapsImplMock, g_main_loop_is_running(::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + NMActiveConnection *dummyActiveConn = static_cast(g_object_new(NM_TYPE_ACTIVE_CONNECTION, NULL)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_finish(::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Return(dummyActiveConn)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_async(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Invoke([](NMClient* client, NMConnection* connection, NMDevice* device, const char* specific_object, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer user_data) { + if (callback) { + GObject* source_object = G_OBJECT(client); + GAsyncResult* result = nullptr; + callback(source_object, result, user_data); + } + })); + + // Test SetInterfaceState for wlan0 which internally calls activateKnownConnection + // It should skip ethernet connection and use wifi connection as firstConnection + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("SetInterfaceState"), + _T("{\"interface\":\"wlan0\",\"enabled\":true}"), response)); + EXPECT_EQ(response, _T("{\"success\":true}")); + + g_object_unref(deviceDummy); + g_object_unref(wifiConn); + g_object_unref(ethConn); + g_object_unref(vpnConn); + g_ptr_array_free(dummyConns, TRUE); + g_ptr_array_free(fakeDevices, TRUE); +} + +TEST_F(NetworkManagerWifiTest, ActivateKnownConnection_EthernetConnectionTypeFiltering) +{ + GPtrArray* fakeDevices = g_ptr_array_new(); + NMDevice *deviceDummy = static_cast(g_object_new(NM_TYPE_DEVICE_ETHERNET, NULL)); + g_ptr_array_add(fakeDevices, deviceDummy); + + // Create multiple connections with different types + GPtrArray* dummyConns = g_ptr_array_new(); + NMConnection *wifiConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + NMConnection *ethConn = reinterpret_cast(g_object_new(NM_TYPE_REMOTE_CONNECTION, NULL)); + g_ptr_array_add(dummyConns, wifiConn); // First connection is wifi + g_ptr_array_add(dummyConns, ethConn); // Second connection is ethernet + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_devices(::testing::_)) + .WillRepeatedly(::testing::Return(fakeDevices)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_iface(::testing::_)) + .WillRepeatedly(::testing::Return("eth0")); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_get_state(::testing::_)) + .WillRepeatedly(::testing::Return(NM_DEVICE_STATE_DISCONNECTED)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_device_by_iface(::testing::_,::testing::_)) + .WillRepeatedly(::testing::Return(deviceDummy)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_device_set_autoconnect(::testing::_,::testing::_)) + .WillOnce(::testing::Return()); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_get_connections(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast(dummyConns))); + + // Setup connection IDs and types + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_id(::testing::_)) + .WillOnce(::testing::Return("Wired connection 1")) // ethConn - match + .WillOnce(::testing::Return("Wired connection 1")); // ethConn - for activation + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_connection_get_connection_type(::testing::_)) + .WillOnce(::testing::Return(reinterpret_cast("802-11-wireless"))) // wifiConn - should be skipped for eth0 + .WillOnce(::testing::Return(reinterpret_cast("802-3-ethernet"))); // ethConn - should be selected as firstConnection + + EXPECT_CALL(*p_gLibWrapsImplMock, g_main_loop_is_running(::testing::_)) + .WillRepeatedly(::testing::Return(true)); + + NMActiveConnection *dummyActiveConn = static_cast(g_object_new(NM_TYPE_ACTIVE_CONNECTION, NULL)); + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_finish(::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Return(dummyActiveConn)); + + EXPECT_CALL(*p_libnmWrapsImplMock, nm_client_activate_connection_async(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .WillOnce(::testing::Invoke([](NMClient* client, NMConnection* connection, NMDevice* device, const char* specific_object, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer user_data) { + if (callback) { + GObject* source_object = G_OBJECT(client); + GAsyncResult* result = nullptr; + callback(source_object, result, user_data); + } + })); + + // Test SetInterfaceState for ethernet which internally calls activateKnownConnection + // It should skip wifi connection and use ethernet connection as firstConnection + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("SetInterfaceState"), + _T("{\"interface\":\"eth0\",\"enabled\":true}"), response)); + EXPECT_EQ(response, _T("{\"success\":true}")); + + g_object_unref(deviceDummy); + g_object_unref(wifiConn); + g_object_unref(ethConn); + g_ptr_array_free(dummyConns, TRUE); + g_ptr_array_free(fakeDevices, TRUE); +} + TEST_F(NetworkManagerWifiTest, StopWPS) { EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("StopWPS"),