-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Link Event Damping] Add tracker to track the selectable timers used by
link event damper. - Link event damper running on each port will have its own SelectableTimer. This class helps create a mapping of SelectableTimer and object that created the SelectableTimer so that when timer is fired, proper EventHandler object can be invoked. HLD: sonic-net/SONiC#1071
- Loading branch information
Ashish Singh
committed
Nov 28, 2023
1 parent
4ee9c25
commit 0fe378f
Showing
7 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include "SelectablesTracker.h" | ||
|
||
#include "swss/logger.h" | ||
|
||
using namespace syncd; | ||
|
||
bool SelectablesTracker::addSelectableToTracker( | ||
_In_ swss::Selectable *selectable, | ||
_In_ SelectableEventHandler *eventHandler) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (selectable == nullptr) | ||
{ | ||
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL."); | ||
|
||
return false; | ||
} | ||
|
||
int fd = selectable->getFd(); | ||
if (eventHandler == nullptr) | ||
{ | ||
SWSS_LOG_ERROR("Event handler for Selectable with fd: %d is NULL.", fd); | ||
|
||
return false; | ||
} | ||
|
||
if (m_selectableFdToEventHandlerMap.count(fd) != 0) | ||
{ | ||
SWSS_LOG_ERROR("Selectable with fd %d is already in use.", fd); | ||
|
||
return false; | ||
} | ||
|
||
SWSS_LOG_INFO("Adding the Selectable with fd: %d.", fd); | ||
m_selectableFdToEventHandlerMap[fd] = eventHandler; | ||
|
||
return true; | ||
} | ||
|
||
bool SelectablesTracker::removeSelectableFromTracker( | ||
_In_ swss::Selectable *selectable) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (selectable == nullptr) | ||
{ | ||
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL."); | ||
|
||
return false; | ||
} | ||
|
||
int fd = selectable->getFd(); | ||
|
||
SWSS_LOG_INFO("Removing the Selectable with fd: %d.", fd); | ||
if (m_selectableFdToEventHandlerMap.erase(fd) == 0) | ||
{ | ||
SWSS_LOG_ERROR("Selectable with fd %d is not present in the map!", fd); | ||
|
||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool SelectablesTracker::selectableIsTracked( | ||
_In_ swss::Selectable *selectable) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if ((selectable == nullptr) || | ||
(m_selectableFdToEventHandlerMap.count(selectable->getFd()) == 0)) | ||
{ | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
SelectableEventHandler *SelectablesTracker::getEventHandlerForSelectable( | ||
_In_ swss::Selectable *selectable) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
if (selectable == nullptr) | ||
{ | ||
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL."); | ||
|
||
return nullptr; | ||
} | ||
|
||
int fd = selectable->getFd(); | ||
auto it = m_selectableFdToEventHandlerMap.find(fd); | ||
|
||
if (it == m_selectableFdToEventHandlerMap.end()) | ||
{ | ||
SWSS_LOG_ERROR("Selectable with fd %d is not present in the map!", fd); | ||
|
||
return nullptr; | ||
} | ||
|
||
return it->second; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#pragma once | ||
|
||
#include <unordered_map> | ||
|
||
#include "SelectableEventHandler.h" | ||
#include "swss/sal.h" | ||
#include "swss/selectable.h" | ||
#include "swss/selectabletimer.h" | ||
|
||
namespace syncd | ||
{ | ||
// This class keeps track of Selectable being used by an entity and their | ||
// corresponding EventHandler objects. | ||
class SelectablesTracker | ||
{ | ||
private: | ||
|
||
// Not copyable or movable. | ||
SelectablesTracker(const SelectablesTracker &) = delete; | ||
SelectablesTracker(SelectablesTracker &&) = delete; | ||
SelectablesTracker &operator=(const SelectablesTracker &) = delete; | ||
SelectablesTracker &operator=(SelectablesTracker &&) = delete; | ||
|
||
public: | ||
|
||
SelectablesTracker() = default; | ||
|
||
virtual ~SelectablesTracker() = default; | ||
|
||
// Adds the mapping of Selectable and it's corresponding EventHandler object. | ||
virtual bool addSelectableToTracker( | ||
_In_ swss::Selectable *selectable, | ||
_In_ SelectableEventHandler *eventHandler); | ||
|
||
// Removes a Selectable from the map. | ||
virtual bool removeSelectableFromTracker( | ||
_In_ swss::Selectable *selectable); | ||
|
||
// Checks if Selectable is present in the tracker map. | ||
virtual bool selectableIsTracked( | ||
_In_ swss::Selectable *selectable); | ||
|
||
// Gets the EventHandler for a Selectable. | ||
virtual SelectableEventHandler *getEventHandlerForSelectable( | ||
_In_ swss::Selectable *selectable); | ||
|
||
private: | ||
|
||
using SelectableFdToEventHandlerMap = std::unordered_map<int, SelectableEventHandler *>; | ||
|
||
SelectableFdToEventHandlerMap m_selectableFdToEventHandlerMap; | ||
}; | ||
|
||
} // namespace syncd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -149,6 +149,7 @@ config | |
const | ||
CONST | ||
consts | ||
copyable | ||
counterName | ||
countOnly | ||
cout | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#pragma once | ||
|
||
#include "SelectablesTracker.h" | ||
#include "gmock/gmock.h" | ||
|
||
namespace syncd | ||
{ | ||
|
||
class MockSelectablesTracker : public SelectablesTracker | ||
{ | ||
public: | ||
|
||
MockSelectablesTracker() : SelectablesTracker() {} | ||
|
||
~MockSelectablesTracker() override {} | ||
|
||
MOCK_METHOD2(addSelectableToTracker, bool(swss::Selectable *selectable, | ||
SelectableEventHandler *eventHandler) override); | ||
|
||
MOCK_METHOD1(removeSelectableFromTracker, | ||
bool(swss::Selectable *selectable) override); | ||
}; | ||
} // namespace syncd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
#include <gtest/gtest.h> | ||
|
||
#include "SelectablesTracker.h" | ||
|
||
using namespace syncd; | ||
|
||
class SelectableEventHandlerTestHelper : public SelectableEventHandler | ||
{ | ||
public: | ||
|
||
SelectableEventHandlerTestHelper() {} | ||
~SelectableEventHandlerTestHelper() {} | ||
|
||
void handleSelectableEvent() {} | ||
}; | ||
|
||
class SelectablesTrackerTest : public ::testing::Test | ||
{ | ||
public: | ||
|
||
SelectablesTrackerTest() {} | ||
|
||
SelectablesTracker m_selectablesTracker_; | ||
}; | ||
|
||
TEST_F(SelectablesTrackerTest, AddSelectableFailsIfSelectableNull) | ||
{ | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_FALSE(m_selectablesTracker_.addSelectableToTracker( | ||
/*selectable=*/nullptr, (SelectableEventHandler *)&eventHandler)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, AddSelectableFailsIfEventHandlerNull) | ||
{ | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
|
||
EXPECT_FALSE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, /*eventHandler=*/nullptr)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, AddSelectableSucceeds) | ||
{ | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_TRUE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, AddSelectableFailsIfSelectableExists) | ||
{ | ||
// Add a selectable timer to tracker. | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_TRUE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler)); | ||
|
||
// Adding the same selectable timer to tracker should fail. | ||
SelectableEventHandlerTestHelper eventHandler2; | ||
EXPECT_FALSE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler2)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, RemoveSelectableFailsIfSelectableNull) | ||
{ | ||
EXPECT_FALSE( | ||
m_selectablesTracker_.removeSelectableFromTracker(/*selectable=*/nullptr)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, RemoveSelectableFailsIfSelectableNotExist) | ||
{ | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
|
||
EXPECT_FALSE(m_selectablesTracker_.removeSelectableFromTracker( | ||
(swss::Selectable *)&timer)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, RemoveSelectableSucceeds) | ||
{ | ||
// Add a selectable timer. | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_TRUE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler)); | ||
|
||
// Remove the selectable timer just added in tracker. | ||
EXPECT_TRUE(m_selectablesTracker_.removeSelectableFromTracker( | ||
(swss::Selectable *)&timer)); | ||
|
||
// Removing the selectable timer again should fail. | ||
EXPECT_FALSE(m_selectablesTracker_.removeSelectableFromTracker( | ||
(swss::Selectable *)&timer)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, NullptrSelectableIsNotTracked) | ||
{ | ||
EXPECT_FALSE( | ||
m_selectablesTracker_.selectableIsTracked(/*selectable=*/nullptr)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, SelectableIsNotTracked) | ||
{ | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
EXPECT_FALSE( | ||
m_selectablesTracker_.selectableIsTracked((swss::Selectable *)&timer)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, SelectableIsTracked) | ||
{ | ||
// Add the Selectable in the tracker. | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_TRUE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler)); | ||
|
||
// Verify the Selectable in the tracker. | ||
EXPECT_TRUE( | ||
m_selectablesTracker_.selectableIsTracked((swss::Selectable *)&timer)); | ||
|
||
// Remove the Selectable from tracker. | ||
EXPECT_TRUE(m_selectablesTracker_.removeSelectableFromTracker( | ||
(swss::Selectable *)&timer)); | ||
|
||
// Check the Selectable in tracker again, this time it should fail. | ||
EXPECT_FALSE( | ||
m_selectablesTracker_.selectableIsTracked((swss::Selectable *)&timer)); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, GetEventHandlerFailsIfSelectableNull) | ||
{ | ||
EXPECT_EQ( | ||
m_selectablesTracker_.getEventHandlerForSelectable(/*selectable=*/nullptr), | ||
nullptr); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, GetEventHandlerFailsIfSelectableNotExist) | ||
{ | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
EXPECT_EQ(m_selectablesTracker_.getEventHandlerForSelectable( | ||
(swss::Selectable *)&timer), | ||
nullptr); | ||
} | ||
|
||
TEST_F(SelectablesTrackerTest, GetEventHandlerSucceeds) | ||
{ | ||
// Add a selectable timer. | ||
swss::SelectableTimer timer(/*interval=*/{.tv_sec = 10, .tv_nsec = 20}); | ||
SelectableEventHandlerTestHelper eventHandler; | ||
|
||
EXPECT_TRUE(m_selectablesTracker_.addSelectableToTracker( | ||
(swss::Selectable *)&timer, (SelectableEventHandler *)&eventHandler)); | ||
|
||
// Get the event handler for the selectable timer. | ||
EXPECT_EQ(m_selectablesTracker_.getEventHandlerForSelectable( | ||
(swss::Selectable *)&timer), | ||
(SelectableEventHandler *)&eventHandler); | ||
} |