Skip to content

Commit

Permalink
[portsorch] fix PortsOrch::allPortsReady() returns true when it shoul…
Browse files Browse the repository at this point in the history
…d not (sonic-net#1103)

* [portsorch] fix PortsOrch::allPortsReady() returns true when it should not

Warm start flow before the change:
1st iteration:
    - BufferOrch::doTask(): returns since PortInitDone hasn't arived yet
    - PortsOrch::doTask():  processes all PORT_TABLE untill PortInitDone flag
                            m_pendingPortSet is empty yet and m_portInitDone is true
                            so allPortsReady() will return true
    - AnyOrch::doTask():    check g_portsOrch->allPortsRead()

2nd iteration:
    - BufferOrch::doTask(): now buffers are applied

This causes BufferOrch override PfcWdOrch's zero-buffer profile.

The change swaps BufferOrch and PortsOrch in m_orchList, because 1st
BufferOrch iteration will always skip processing and eliminates possibility
of having m_pendingPortSet not filled with ports after m_initDone is set to true.
* remove extra newline
* [pfcwdorch] fix PfcWdSwOrch::doTask() starts WD action when WD wasn't started in warm boot
It appeared that pfc watchdog relied on a buggy behaviour of PortsOrch::allPortsReady().
In fixed PortsOrch::allPortsReady() you'll see that watchdog action is trying to start
before watchdog was started, because allPortsReady() in PfcWdOrch::doTask() returned false.
Before the fix watchdog was started before, because allPortsReady() lied that ports are ready
when they were not.
* [portsorch] populate m_pendingPortSet in PortsOrch::bake()
* [portsorch] optimize to 3 iterations instead of 4
* Revert "[portsorch] optimize to 3 iterations instead of 4"
* revert change of order in m_orchList
* [mock_tests] fix tests build
* [mock_test] create unittest for PortsOrch::allPortsReady cold/warm flows
* [orchdaemon] fix removed sfloworch
* [mock_tests] make mock_tests run on "make check"
  • Loading branch information
stepanblyschak authored and qiluo-msft committed Nov 1, 2019
1 parent 5ab3f6b commit bab7b93
Show file tree
Hide file tree
Showing 14 changed files with 689 additions and 43 deletions.
5 changes: 5 additions & 0 deletions orchagent/pfcwdorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,11 @@ void PfcWdSwOrch<DropHandler, ForwardHandler>::doTask(Consumer& consumer)
{
PfcWdOrch<DropHandler, ForwardHandler>::doTask(consumer);

if (!gPortsOrch->allPortsReady())
{
return;
}

if ((consumer.getDbId() == APPL_DB) && (consumer.getTableName() == APP_PFC_WD_TABLE_NAME))
{
auto it = consumer.m_toSync.begin();
Expand Down
10 changes: 10 additions & 0 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,16 @@ bool PortsOrch::bake()
return false;
}

for (const auto& alias: keys)
{
if (alias == "PortConfigDone" || alias == "PortInitDone")
{
continue;
}

m_pendingPortSet.emplace(alias);
}

addExistingData(m_portTable.get());
addExistingData(APP_LAG_TABLE_NAME);
addExistingData(APP_LAG_MEMBER_TABLE_NAME);
Expand Down
2 changes: 2 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ CFLAGS_SAI = -I /usr/include/sai

TESTS = tests

SUBDIRS = mock_tests

noinst_PROGRAMS = tests

if DEBUG
Expand Down
1 change: 1 addition & 0 deletions tests/mock_tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tests
70 changes: 39 additions & 31 deletions tests/mock_tests/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
CFLAGS_SAI = -I /usr/include/sai

bin_PROGRAMS = tests
TESTS = tests

noinst_PROGRAMS = tests

LDADD_SAI = -lsaimeta -lsaimetadata -lsaivs -lsairedis

Expand All @@ -13,42 +15,48 @@ endif
CFLAGS_GTEST =
LDADD_GTEST = -L/usr/src/gtest

tests_SOURCES = swssnet_ut.cpp request_parser_ut.cpp aclorch_ut.cpp saispy_ut.cpp \
tests_SOURCES = aclorch_ut.cpp \
portsorch_ut.cpp \
saispy_ut.cpp \
ut_saihelper.cpp \
mock_orchagent_main.cpp \
mock_dbconnector.cpp \
mock_consumerstatetable.cpp \
mock_table.cpp \
mock_hiredis.cpp \
mock_redisreply.cpp \
../orchagent/orchdaemon.cpp \
../orchagent/orch.cpp \
../orchagent/notifications.cpp \
../orchagent/routeorch.cpp \
../orchagent/neighorch.cpp \
../orchagent/intfsorch.cpp \
../orchagent/portsorch.cpp \
../orchagent/copporch.cpp \
../orchagent/tunneldecaporch.cpp \
../orchagent/qosorch.cpp \
../orchagent/bufferorch.cpp \
../orchagent/mirrororch.cpp \
../orchagent/fdborch.cpp \
../orchagent/aclorch.cpp \
../orchagent/saihelper.cpp \
../orchagent/switchorch.cpp \
../orchagent/pfcwdorch.cpp \
../orchagent/pfcactionhandler.cpp \
../orchagent/policerorch.cpp \
../orchagent/crmorch.cpp \
../orchagent/request_parser.cpp \
../orchagent/vrforch.cpp \
../orchagent/countercheckorch.cpp \
../orchagent/vxlanorch.cpp \
../orchagent/vnetorch.cpp \
../orchagent/dtelorch.cpp \
../orchagent/flexcounterorch.cpp \
../orchagent/watermarkorch.cpp
$(top_srcdir)/orchagent/orchdaemon.cpp \
$(top_srcdir)/orchagent/orch.cpp \
$(top_srcdir)/orchagent/notifications.cpp \
$(top_srcdir)/orchagent/routeorch.cpp \
$(top_srcdir)/orchagent/neighorch.cpp \
$(top_srcdir)/orchagent/intfsorch.cpp \
$(top_srcdir)/orchagent/portsorch.cpp \
$(top_srcdir)/orchagent/copporch.cpp \
$(top_srcdir)/orchagent/tunneldecaporch.cpp \
$(top_srcdir)/orchagent/qosorch.cpp \
$(top_srcdir)/orchagent/bufferorch.cpp \
$(top_srcdir)/orchagent/mirrororch.cpp \
$(top_srcdir)/orchagent/fdborch.cpp \
$(top_srcdir)/orchagent/aclorch.cpp \
$(top_srcdir)/orchagent/saihelper.cpp \
$(top_srcdir)/orchagent/switchorch.cpp \
$(top_srcdir)/orchagent/pfcwdorch.cpp \
$(top_srcdir)/orchagent/pfcactionhandler.cpp \
$(top_srcdir)/orchagent/policerorch.cpp \
$(top_srcdir)/orchagent/crmorch.cpp \
$(top_srcdir)/orchagent/request_parser.cpp \
$(top_srcdir)/orchagent/vrforch.cpp \
$(top_srcdir)/orchagent/countercheckorch.cpp \
$(top_srcdir)/orchagent/vxlanorch.cpp \
$(top_srcdir)/orchagent/vnetorch.cpp \
$(top_srcdir)/orchagent/dtelorch.cpp \
$(top_srcdir)/orchagent/flexcounterorch.cpp \
$(top_srcdir)/orchagent/watermarkorch.cpp \
$(top_srcdir)/orchagent/chassisorch.cpp \
$(top_srcdir)/orchagent/sfloworch.cpp

tests_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST) $(CFLAGS_SAI)
tests_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST) $(CFLAGS_SAI) -I../orchagent
tests_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST) $(CFLAGS_SAI) -I$(top_srcdir)/orchagent
tests_LDADD = $(LDADD_GTEST) $(LDADD_SAI) -lnl-genl-3 -lhiredis -lhiredis -lpthread \
-lswsscommon -lswsscommon -lgtest -lgtest_main
18 changes: 9 additions & 9 deletions tests/mock_tests/aclorch_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,16 +643,16 @@ namespace aclorch_test
// leakage check
bool validateResourceCountWithLowerLayerDb(const AclOrch *aclOrch)
{
// TODO: Using the need to include "sai_vs_state.h". That will need the include path from `configure`
// Do this later ...
// TODO: Using the need to include "sai_vs_state.h". That will need the include path from `configure`
// Do this later ...
#if WITH_SAI == LIBVS
// {
// auto& aclTableHash = g_switch_state_map.at(gSwitchId)->objectHash.at(SAI_OBJECT_TYPE_ACL_TABLE);
//
// return aclTableHash.size() == Portal::AclOrchInternal::getAclTables(aclOrch).size();
// }
//
// TODO: add rule check
// {
// auto& aclTableHash = g_switch_state_map.at(gSwitchId)->objectHash.at(SAI_OBJECT_TYPE_ACL_TABLE);
//
// return aclTableHash.size() == Portal::AclOrchInternal::getAclTables(aclOrch).size();
// }
//
// TODO: add rule check
#endif

return true;
Expand Down
2 changes: 1 addition & 1 deletion tests/mock_tests/mock_consumerstatetable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ namespace swss
TableName_KeySet(tableName)
{
}
}
}
4 changes: 2 additions & 2 deletions tests/mock_tests/mock_dbconnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ namespace swss

int DBConnector::getDbId() const
{
return 12345;
return m_dbId;
}
}
}
56 changes: 56 additions & 0 deletions tests/mock_tests/mock_orchagent_main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include "orch.h"
#include "switchorch.h"
#include "crmorch.h"
#include "portsorch.h"
#include "routeorch.h"
#include "intfsorch.h"
#include "neighorch.h"
#include "fdborch.h"
#include "mirrororch.h"
#include "bufferorch.h"
#include "vrforch.h"
#include "vnetorch.h"
#include "vxlanorch.h"
#include "policerorch.h"

extern int gBatchSize;
extern bool gSwssRecord;
extern bool gSairedisRecord;
extern bool gLogRotate;
extern ofstream gRecordOfs;
extern string gRecordFile;

extern MacAddress gMacAddress;
extern MacAddress gVxlanMacAddress;

extern sai_object_id_t gSwitchId;
extern sai_object_id_t gVirtualRouterId;
extern sai_object_id_t gUnderlayIfId;

extern SwitchOrch *gSwitchOrch;
extern CrmOrch *gCrmOrch;
extern PortsOrch *gPortsOrch;
extern RouteOrch *gRouteOrch;
extern IntfsOrch *gIntfsOrch;
extern NeighOrch *gNeighOrch;
extern FdbOrch *gFdbOrch;
extern MirrorOrch *gMirrorOrch;
extern BufferOrch *gBufferOrch;
extern VRFOrch *gVrfOrch;

extern sai_acl_api_t *sai_acl_api;
extern sai_switch_api_t *sai_switch_api;
extern sai_virtual_router_api_t *sai_virtual_router_api;
extern sai_port_api_t *sai_port_api;
extern sai_lag_api_t *sai_lag_api;
extern sai_vlan_api_t *sai_vlan_api;
extern sai_bridge_api_t *sai_bridge_api;
extern sai_router_interface_api_t *sai_router_intfs_api;
extern sai_route_api_t *sai_route_api;
extern sai_neighbor_api_t *sai_neighbor_api;
extern sai_tunnel_api_t *sai_tunnel_api;
extern sai_next_hop_api_t *sai_next_hop_api;
extern sai_hostif_api_t *sai_hostif_api;
extern sai_buffer_api_t *sai_buffer_api;
74 changes: 74 additions & 0 deletions tests/mock_tests/mock_table.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "table.h"

using TableDataT = std::map<std::string, std::vector<swss::FieldValueTuple>>;
using TablesT = std::map<std::string, TableDataT>;

namespace testing_db
{

TableDataT gTableData;
TablesT gTables;
std::map<int, TablesT> gDB;

void reset()
{
gDB.clear();
}
}

namespace swss
{

using namespace testing_db;

bool Table::get(const std::string &key, std::vector<FieldValueTuple> &ovalues)
{
auto table = gDB[getDbId()][getTableName()];
if (table.find(key) == table.end())
{
return false;
}

ovalues = table[key];
return true;
}

bool Table::hget(const std::string &key, const std::string &field, std::string &value)
{
auto table = gDB[getDbId()][getTableName()];
if (table.find(key) == table.end())
{
return false;
}

for (const auto &it : table[key])
{
if (it.first == field)
{
value = it.second;
return true;
}
}

return false;
}

void Table::set(const std::string &key,
const std::vector<FieldValueTuple> &values,
const std::string &op,
const std::string &prefix)
{
auto &table = gDB[getDbId()][getTableName()];
table[key] = values;
}

void Table::getKeys(std::vector<std::string> &keys)
{
keys.clear();
auto table = gDB[getDbId()][getTableName()];
for (const auto &it : table)
{
keys.push_back(it.first);
}
}
}
6 changes: 6 additions & 0 deletions tests/mock_tests/mock_table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "table.h"

namespace testing_db
{
void reset();
}
Loading

0 comments on commit bab7b93

Please sign in to comment.