Skip to content

Commit

Permalink
[Mux] Add support for mux metrics to State DB (#1757)
Browse files Browse the repository at this point in the history
* Update Mux metric table for orchagent switchover
* Add VS test to check metric fields
  • Loading branch information
prsunny authored and qiluo-msft committed Jun 11, 2021
1 parent 386de71 commit 849bdf9
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 6 deletions.
35 changes: 32 additions & 3 deletions orchagent/muxorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include <unordered_set>
#include <stdexcept>
#include <inttypes.h>
#include <math.h>
#include <chrono>
#include <time.h>

#include "sai.h"
#include "ipaddress.h"
Expand Down Expand Up @@ -405,6 +408,8 @@ void MuxCable::setState(string new_state)
return;
}

mux_cb_orch_->updateMuxMetricState(mux_name_, new_state, true);

MuxState state = state_;
state_ = ns;

Expand All @@ -419,6 +424,8 @@ void MuxCable::setState(string new_state)
throw std::runtime_error("Failed to handle state transition");
}

mux_cb_orch_->updateMuxMetricState(mux_name_, new_state, false);

st_chg_in_progress_ = false;
st_chg_failed_ = false;
SWSS_LOG_INFO("Changed state to %s", new_state.c_str());
Expand Down Expand Up @@ -1261,9 +1268,10 @@ bool MuxOrch::delOperation(const Request& request)
return true;
}

MuxCableOrch::MuxCableOrch(DBConnector *db, const std::string& tableName):
MuxCableOrch::MuxCableOrch(DBConnector *db, DBConnector *sdb, const std::string& tableName):
Orch2(db, tableName, request_),
app_tunnel_route_table_(db, APP_TUNNEL_ROUTE_TABLE_NAME)
app_tunnel_route_table_(db, APP_TUNNEL_ROUTE_TABLE_NAME),
mux_metric_table_(sdb, STATE_MUX_METRICS_TABLE_NAME)
{
mux_table_ = unique_ptr<Table>(new Table(db, APP_HW_MUX_CABLE_TABLE_NAME));
}
Expand All @@ -1276,6 +1284,27 @@ void MuxCableOrch::updateMuxState(string portName, string muxState)
mux_table_->set(portName, tuples);
}

void MuxCableOrch::updateMuxMetricState(string portName, string muxState, bool start)
{
string msg = "orch_switch_" + muxState;
msg += start? "_start": "_end";

auto now = std::chrono::system_clock::now();
auto now_t = std::chrono::system_clock::to_time_t(now);
auto dur = now - std::chrono::system_clock::from_time_t(now_t);
auto micros = std::chrono::duration_cast<std::chrono::microseconds>(dur).count();

std::tm now_tm;
gmtime_r(&now_t, &now_tm);

char buf[256];
std::strftime(buf, 256, "%Y-%b-%d %H:%M:%S.", &now_tm);

string time = string(buf) + to_string(micros);

mux_metric_table_.hset(portName, msg, time);
}

void MuxCableOrch::addTunnelRoute(const NextHopKey &nhKey)
{
vector<FieldValueTuple> data;
Expand Down Expand Up @@ -1349,7 +1378,7 @@ MuxStateOrch::MuxStateOrch(DBConnector *db, const std::string& tableName) :
Orch2(db, tableName, request_),
mux_state_table_(db, STATE_MUX_CABLE_TABLE_NAME)
{
SWSS_LOG_ENTER();
SWSS_LOG_ENTER();
}

void MuxStateOrch::updateMuxState(string portName, string muxState)
Expand Down
4 changes: 3 additions & 1 deletion orchagent/muxorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,10 @@ class MuxCableRequest : public Request
class MuxCableOrch : public Orch2
{
public:
MuxCableOrch(DBConnector *db, const std::string& tableName);
MuxCableOrch(DBConnector *db, DBConnector *sdb, const std::string& tableName);

void updateMuxState(string portName, string muxState);
void updateMuxMetricState(string portName, string muxState, bool start);
void addTunnelRoute(const NextHopKey &nhKey);
void removeTunnelRoute(const NextHopKey &nhKey);

Expand All @@ -240,6 +241,7 @@ class MuxCableOrch : public Orch2

unique_ptr<Table> mux_table_;
MuxCableRequest request_;
swss::Table mux_metric_table_;
ProducerStateTable app_tunnel_route_table_;
};

Expand Down
2 changes: 1 addition & 1 deletion orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ bool OrchDaemon::init()
MuxOrch *mux_orch = new MuxOrch(m_configDb, mux_tables, tunnel_decap_orch, gNeighOrch, gFdbOrch);
gDirectory.set(mux_orch);

MuxCableOrch *mux_cb_orch = new MuxCableOrch(m_applDb, APP_MUX_CABLE_TABLE_NAME);
MuxCableOrch *mux_cb_orch = new MuxCableOrch(m_applDb, m_stateDb, APP_MUX_CABLE_TABLE_NAME);
gDirectory.set(mux_cb_orch);

MuxStateOrch *mux_st_orch = new MuxStateOrch(m_stateDb, STATE_HW_MUX_CABLE_TABLE_NAME);
Expand Down
55 changes: 54 additions & 1 deletion tests/test_mux.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,51 @@ def create_and_test_acl(self, appdb, asicdb, dvs, dvs_acl):
self.set_mux_state(appdb, "Ethernet4", "active")
dvs_acl.verify_no_acl_rules()

def create_and_test_metrics(self, appdb, statedb, dvs):

# Set to active and test attributes for start and end time
self.set_mux_state(appdb, "Ethernet0", "active")
keys = statedb.get_keys("MUX_METRICS_TABLE")
assert len(keys) != 0

for key in keys:
if key != "Ethernet0":
continue
fvs = statedb.get_entry("MUX_METRICS_TABLE", key)
assert fvs != {}

start = end = False
for f,v in fvs.items():
if f == "orch_switch_active_start":
start = True
elif f == "orch_switch_active_end":
end = True

assert start
assert end

# Set to standby and test attributes for start and end time
self.set_mux_state(appdb, "Ethernet0", "standby")

keys = statedb.get_keys("MUX_METRICS_TABLE")
assert len(keys) != 0

for key in keys:
if key != "Ethernet0":
continue
fvs = statedb.get_entry("MUX_METRICS_TABLE", key)
assert fvs != {}

start = end = False
for f,v in fvs.items():
if f == "orch_switch_standby_start":
start = True
elif f == "orch_switch_standby_end":
end = True

assert start
assert end


def check_interface_exists_in_asicdb(self, asicdb, sai_oid):
asicdb.wait_for_entry(self.ASIC_RIF_TABLE, sai_oid)
Expand Down Expand Up @@ -643,13 +688,21 @@ def test_Route(self, dvs, dvs_route, testlog):


def test_acl(self, dvs, dvs_acl, testlog):
""" test Route entries and mux state change """
""" test acl and mux state change """

appdb = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
asicdb = dvs.get_asic_db()

self.create_and_test_acl(appdb, asicdb, dvs, dvs_acl)

def test_mux_metrics(self, dvs, testlog):
""" test metrics for mux state change """

appdb = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
statedb = dvs.get_state_db()

self.create_and_test_metrics(appdb, statedb, dvs)


# Add Dummy always-pass test at end as workaroud
# for issue when Flaky fail on final test it invokes module tear-down before retrying
Expand Down

0 comments on commit 849bdf9

Please sign in to comment.