@@ -191,6 +191,57 @@ class test_ucp_net_devices_config : public ucp_test {
191191 const std::string &dev_name) {
192192 return devices.find (dev_name) != devices.end ();
193193 }
194+
195+ /* Test that a device config triggers duplicate device warning */
196+ void test_duplicate_device_warning (const std::string &devices_config,
197+ const std::string &duplicate_dev_name)
198+ {
199+ entity *e = create_entity ();
200+
201+ std::set<std::string> mlx5_devices = get_mlx5_device_names (*e);
202+ if (mlx5_devices.empty ()) {
203+ UCS_TEST_SKIP_R (" No mlx5 network device available" );
204+ }
205+
206+ if (!has_device (mlx5_devices, duplicate_dev_name)) {
207+ UCS_TEST_SKIP_R (duplicate_dev_name + " device not available" );
208+ }
209+
210+ m_entities.clear ();
211+
212+ modify_config (" NET_DEVICES" , devices_config.c_str ());
213+
214+ size_t warn_count;
215+ {
216+ scoped_log_handler slh (hide_warns_logger);
217+ warn_count = m_warnings.size ();
218+ create_entity ();
219+ }
220+
221+ EXPECT_EQ (m_warnings.size () - warn_count, 1 )
222+ << " Expected exactly one warning" ;
223+
224+ // print all warnings
225+ for (const std::string &warn : m_warnings) {
226+ std::cout << warn << std::endl;
227+ }
228+
229+ /* Check that a warning about duplicate device was printed */
230+ std::string expected_warn = " device '" + duplicate_dev_name +
231+ " ' was selected multiple times" ;
232+ bool found_warning = false ;
233+ for (size_t i = warn_count; i < m_warnings.size (); ++i) {
234+ if (m_warnings[i].find (expected_warn) != std::string::npos) {
235+ found_warning = true ;
236+ break ;
237+ }
238+ }
239+
240+ EXPECT_TRUE (found_warning)
241+ << " Expected warning about duplicate device '"
242+ << duplicate_dev_name << " ' with config '" << devices_config
243+ << " '" ;
244+ }
194245};
195246
196247/*
@@ -291,56 +342,6 @@ UCS_TEST_P(test_ucp_net_devices_config, range_with_base_names)
291342 << " mlx5 devices to be selected with range" ;
292343}
293344
294- /*
295- * Test that specifying a device multiple times (e.g., via range and explicit)
296- * produces a warning about duplicate device specification.
297- */
298- UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning)
299- {
300- entity *e = create_entity ();
301-
302- std::set<std::string> mlx5_devices = get_mlx5_device_names (*e);
303- if (mlx5_devices.empty ()) {
304- UCS_TEST_SKIP_R (" No mlx5 network device available" );
305- }
306-
307- std::set<std::string> base_names = get_mlx5_base_names (mlx5_devices);
308- if (base_names.empty ()) {
309- UCS_TEST_SKIP_R (" No mlx5 devices with port suffix found" );
310- }
311-
312- /* Pick the first base name for testing */
313- std::string test_base_name = *base_names.begin ();
314-
315- m_entities.clear ();
316-
317- /* Set NET_DEVICES to include both a range and an explicit device that
318- * overlaps with the range, e.g., "mlx5_[0-99],mlx5_0" */
319- std::string devices_config = " mlx5_[0-99]," + test_base_name;
320- modify_config (" NET_DEVICES" , devices_config.c_str ());
321-
322- size_t warn_count;
323- {
324- scoped_log_handler slh (hide_warns_logger);
325- warn_count = m_warnings.size ();
326- create_entity ();
327- }
328-
329- /* Check that a warning about duplicate device was printed */
330- std::string expected_warn = " device '" + test_base_name +
331- " ' is specified multiple times" ;
332- bool found_warning = false ;
333- for (size_t i = warn_count; i < m_warnings.size (); ++i) {
334- if (m_warnings[i].find (expected_warn) != std::string::npos) {
335- found_warning = true ;
336- break ;
337- }
338- }
339-
340- EXPECT_TRUE (found_warning) << " Expected warning about duplicate device '"
341- << test_base_name << " '" ;
342- }
343-
344345/*
345346 * Test that a range not covering all devices only selects matching devices.
346347 * E.g., "mlx5_[1-2]" should match mlx5_1 and mlx5_2, but not mlx5_0.
@@ -377,4 +378,33 @@ UCS_TEST_P(test_ucp_net_devices_config, partial_range_selection)
377378 EXPECT_EQ (selected_base_names, expected_base_names);
378379}
379380
380- UCP_INSTANTIATE_TEST_CASE_TLS (test_ucp_net_devices_config, all, " all" )
381+ /*
382+ * Test that specifying a device multiple times produces a warning
383+ */
384+ UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning_simple)
385+ {
386+ test_duplicate_device_warning (" mlx5_0:1,mlx5_0:1" , " mlx5_0:1" );
387+ }
388+
389+ UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning_base_name)
390+ {
391+ test_duplicate_device_warning (" mlx5_0:1,mlx5_0" , " mlx5_0:1" );
392+ }
393+
394+ UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning_two_base_name)
395+ {
396+ test_duplicate_device_warning (" mlx5_0,mlx5_0" , " mlx5_0:1" );
397+ }
398+
399+ UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning_range)
400+ {
401+ test_duplicate_device_warning (" mlx5_[0-99],mlx5_0" , " mlx5_0:1" );
402+ }
403+
404+ UCS_TEST_P (test_ucp_net_devices_config, duplicate_device_warning_two_ranges)
405+ {
406+ test_duplicate_device_warning (" mlx5_[0-1],mlx5_[1-2]" , " mlx5_1:1" );
407+ }
408+
409+
410+ UCP_INSTANTIATE_TEST_CASE_TLS (test_ucp_net_devices_config, ib, " ib" )
0 commit comments