1
1
#include " ut_helper.h"
2
2
#include " mock_orchagent_main.h"
3
3
#include " mock_table.h"
4
+ #include " pfcactionhandler.h"
4
5
5
6
#include < sstream>
6
7
@@ -14,12 +15,15 @@ namespace portsorch_test
14
15
shared_ptr<swss::DBConnector> m_app_db;
15
16
shared_ptr<swss::DBConnector> m_config_db;
16
17
shared_ptr<swss::DBConnector> m_state_db;
18
+ shared_ptr<swss::DBConnector> m_counters_db;
17
19
18
20
PortsOrchTest ()
19
21
{
20
22
// FIXME: move out from constructor
21
23
m_app_db = make_shared<swss::DBConnector>(
22
24
" APPL_DB" , 0 );
25
+ m_counters_db = make_shared<swss::DBConnector>(
26
+ " COUNTERS_DB" , 0 );
23
27
m_config_db = make_shared<swss::DBConnector>(
24
28
" CONFIG_DB" , 0 );
25
29
m_state_db = make_shared<swss::DBConnector>(
@@ -310,4 +314,122 @@ namespace portsorch_test
310
314
gBufferOrch ->dumpPendingTasks (ts);
311
315
ASSERT_TRUE (ts.empty ());
312
316
}
317
+
318
+ TEST_F (PortsOrchTest, PfcZeroBufferHandlerLocksPortPgAndQueue)
319
+ {
320
+ Table portTable = Table (m_app_db.get (), APP_PORT_TABLE_NAME);
321
+ Table pgTable = Table (m_config_db.get (), CFG_BUFFER_PG_TABLE_NAME);
322
+ Table profileTable = Table (m_config_db.get (), CFG_BUFFER_PROFILE_TABLE_NAME);
323
+ Table poolTable = Table (m_config_db.get (), CFG_BUFFER_POOL_TABLE_NAME);
324
+
325
+ // Get SAI default ports to populate DB
326
+ auto ports = ut_helper::getInitialSaiPorts ();
327
+
328
+ // Create dependencies ...
329
+
330
+ const int portsorch_base_pri = 40 ;
331
+
332
+ vector<table_name_with_pri_t > ports_tables = {
333
+ { APP_PORT_TABLE_NAME, portsorch_base_pri + 5 },
334
+ { APP_VLAN_TABLE_NAME, portsorch_base_pri + 2 },
335
+ { APP_VLAN_MEMBER_TABLE_NAME, portsorch_base_pri },
336
+ { APP_LAG_TABLE_NAME, portsorch_base_pri + 4 },
337
+ { APP_LAG_MEMBER_TABLE_NAME, portsorch_base_pri }
338
+ };
339
+
340
+ ASSERT_EQ (gPortsOrch , nullptr );
341
+ gPortsOrch = new PortsOrch (m_app_db.get (), ports_tables);
342
+ vector<string> buffer_tables = { CFG_BUFFER_POOL_TABLE_NAME,
343
+ CFG_BUFFER_PROFILE_TABLE_NAME,
344
+ CFG_BUFFER_QUEUE_TABLE_NAME,
345
+ CFG_BUFFER_PG_TABLE_NAME,
346
+ CFG_BUFFER_PORT_INGRESS_PROFILE_LIST_NAME,
347
+ CFG_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME };
348
+
349
+ ASSERT_EQ (gBufferOrch , nullptr );
350
+ gBufferOrch = new BufferOrch (m_config_db.get (), buffer_tables);
351
+
352
+ // Populate port table with SAI ports
353
+ for (const auto &it : ports)
354
+ {
355
+ portTable.set (it.first , it.second );
356
+ }
357
+
358
+ // Set PortConfigDone, PortInitDone
359
+ portTable.set (" PortConfigDone" , { { " count" , to_string (ports.size ()) } });
360
+ portTable.set (" PortInitDone" , { { " lanes" , " 0" } });
361
+
362
+ // refill consumer
363
+ gPortsOrch ->addExistingData (&portTable);
364
+
365
+ // Apply configuration :
366
+ // create ports
367
+
368
+ static_cast <Orch *>(gPortsOrch )->doTask ();
369
+
370
+ // Apply configuration
371
+ // ports
372
+ static_cast <Orch *>(gPortsOrch )->doTask ();
373
+
374
+ ASSERT_TRUE (gPortsOrch ->allPortsReady ());
375
+
376
+ // No more tasks
377
+ vector<string> ts;
378
+ gPortsOrch ->dumpPendingTasks (ts);
379
+ ASSERT_TRUE (ts.empty ());
380
+ ts.clear ();
381
+
382
+ // Simulate storm drop handler started on Ethernet0 TC 3
383
+ Port port;
384
+ gPortsOrch ->getPort (" Ethernet0" , port);
385
+
386
+ auto countersTable = make_shared<Table>(m_counters_db.get (), COUNTERS_TABLE);
387
+ auto dropHandler = make_unique<PfcWdZeroBufferHandler>(port.m_port_id , port.m_queue_ids [3 ], 3 , countersTable);
388
+
389
+ // Create test buffer pool
390
+ poolTable.set (
391
+ " test_pool" ,
392
+ {
393
+ { " type" , " ingress" },
394
+ { " mode" , " dynamic" },
395
+ { " size" , " 4200000" },
396
+ });
397
+
398
+ // Create test buffer profile
399
+ profileTable.set (" test_profile" , { { " pool" , " [BUFFER_POOL|test_pool]" },
400
+ { " xon" , " 14832" },
401
+ { " xoff" , " 14832" },
402
+ { " size" , " 35000" },
403
+ { " dynamic_th" , " 0" } });
404
+
405
+ // Apply profile on PGs 3-4 all ports
406
+ for (const auto &it : ports)
407
+ {
408
+ std::ostringstream oss;
409
+ oss << it.first << " |3-4" ;
410
+ pgTable.set (oss.str (), { { " profile" , " [BUFFER_PROFILE|test_profile]" } });
411
+ }
412
+ gBufferOrch ->addExistingData (&pgTable);
413
+ gBufferOrch ->addExistingData (&poolTable);
414
+ gBufferOrch ->addExistingData (&profileTable);
415
+
416
+ // process pool, profile and PGs
417
+ static_cast <Orch *>(gBufferOrch )->doTask ();
418
+
419
+ auto pgConsumer = static_cast <Consumer*>(gBufferOrch ->getExecutor (CFG_BUFFER_PG_TABLE_NAME));
420
+ pgConsumer->dumpPendingTasks (ts);
421
+ ASSERT_FALSE (ts.empty ()); // PG is skipped
422
+ ts.clear ();
423
+
424
+ // release zero buffer drop handler
425
+ dropHandler.reset ();
426
+
427
+ // process PGs
428
+ static_cast <Orch *>(gBufferOrch )->doTask ();
429
+
430
+ pgConsumer = static_cast <Consumer*>(gBufferOrch ->getExecutor (CFG_BUFFER_PG_TABLE_NAME));
431
+ pgConsumer->dumpPendingTasks (ts);
432
+ ASSERT_TRUE (ts.empty ()); // PG should be proceesed now
433
+ ts.clear ();
434
+ }
313
435
}
0 commit comments