saiasiccmp/ViewCmp.cpp (184 lines of code) (raw):

#include "ViewCmp.h" #include "View.h" #include "SaiSwitchAsic.h" #include "syncd/ComparisonLogic.h" #include "meta/sai_serialize.h" #include "swss/logger.h" using namespace saiasiccmp; ViewCmp::ViewCmp( _In_ std::shared_ptr<View> a, _In_ std::shared_ptr<View> b): m_va(a), m_vb(b) { SWSS_LOG_ENTER(); if (a->m_asicView->m_soAll.size() != b->m_asicView->m_soAll.size()) { SWSS_LOG_WARN("different number of objects in views %zu vs %zu", a->m_asicView->m_soAll.size(), b->m_asicView->m_soAll.size()); } checkStartingPoint(); checkVidRidMaps(); checkHidden(); // since second view can be translated, and some objects could // been removed (vlan members, bridge ports) // checkColdVids(); } void ViewCmp::checkColdVids() { SWSS_LOG_ENTER(); // both cold vids should be the same, except when translated if (m_va->m_coldVids.size() != m_vb->m_coldVids.size()) { SWSS_LOG_THROW("cold vids sizes differ: %zu vs %zu", m_va->m_coldVids.size(), m_vb->m_coldVids.size()); } for (auto it: m_va->m_coldVids) { if (m_vb->m_coldVids.find(it.first) == m_vb->m_coldVids.end()) { SWSS_LOG_THROW("VID %s missing from second view", sai_serialize_object_id(it.first).c_str()); } } } void ViewCmp::checkHidden() { SWSS_LOG_ENTER(); if (m_va->m_hidden.size() != m_vb->m_hidden.size()) { SWSS_LOG_THROW("hidden size don't match"); } for (auto it: m_va->m_hidden) { auto key = it.first; auto val = it.second; if (m_vb->m_hidden.find(key) == m_vb->m_hidden.end()) { SWSS_LOG_THROW("second view missing hidden %s", key.c_str()); } if (m_vb->m_hidden.at(key) != val) { SWSS_LOG_THROW("second view hidden %s value missmatch", key.c_str()); } } } void ViewCmp::checkVidRidMaps() { SWSS_LOG_ENTER(); checkVidRidMaps(m_va, m_vb); checkVidRidMaps(m_vb, m_va); } void ViewCmp::checkVidRidMaps( _In_ std::shared_ptr<View> a, _In_ std::shared_ptr<View> b) { SWSS_LOG_ENTER(); for (auto it: a->m_vid2rid) { auto avid = it.first; auto arid = it.second; if (b->m_vid2rid.find(avid) != b->m_vid2rid.end() && b->m_vid2rid.at(avid) != arid) { SWSS_LOG_THROW("vid %s exists, but have different rid value %s vs %s", sai_serialize_object_id(avid).c_str(), sai_serialize_object_id(arid).c_str(), sai_serialize_object_id(b->m_vid2rid.at(avid)).c_str()); } } } void ViewCmp::checkStartingPoint() { SWSS_LOG_ENTER(); // we assume at starting point vid/rid will match // on switches, ports, queues, scheduler groups, ipgs std::vector<sai_object_type_t> ot = { SAI_OBJECT_TYPE_SWITCH, SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_QUEUE, SAI_OBJECT_TYPE_SCHEDULER_GROUP, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, }; for (auto o: ot) { checkStartingPoint(o); } SWSS_LOG_NOTICE("starting point success"); } void ViewCmp::checkStartingPoint( _In_ sai_object_type_t ot) { SWSS_LOG_ENTER(); if (m_va->m_oidTypeMap.size() != m_vb->m_oidTypeMap.size()) { SWSS_LOG_THROW("different object %s count: %zu vs %zu", sai_serialize_object_type(ot).c_str(), m_va->m_oidTypeMap.size(), m_vb->m_oidTypeMap.size()); } for (auto vid: m_va->m_oidTypeMap.at(ot)) { auto it = m_vb->m_vid2rid.find(vid); if (it == m_vb->m_vid2rid.end()) { SWSS_LOG_THROW("vid %s missing from second view", sai_serialize_object_id(vid).c_str()); } if (m_va->m_vid2rid.at(vid) != m_vb->m_vid2rid.at(vid)) { SWSS_LOG_THROW("vid %s has different RID values: %s vs %s", sai_serialize_object_id(vid).c_str(), sai_serialize_object_id(m_va->m_vid2rid.at(vid)).c_str(), sai_serialize_object_id(m_vb->m_vid2rid.at(vid)).c_str()); } } } bool ViewCmp::compareViews( _In_ bool dumpDiffToStdErr) { SWSS_LOG_ENTER(); auto breakConfig = std::make_shared<syncd::BreakConfig>(); std::set<sai_object_id_t> initViewRemovedVids; auto sw = std::make_shared<SaiSwitchAsic>( m_va->m_switchVid, m_va->m_switchRid, m_va->m_vid2rid, m_va->m_rid2vid, m_va->m_hidden, m_va->m_coldVids); auto cl = std::make_shared<syncd::ComparisonLogic>( nullptr, // m_vendorSai sw, nullptr, // handler initViewRemovedVids, m_va->m_asicView, // current m_vb->m_asicView, // temp breakConfig); cl->compareViews(); // TODO support multiple asic views (multiple switch) if (m_va->m_asicView->asicGetOperationsCount()) { SWSS_LOG_WARN("views are NOT EQUAL, operations count: %zu", m_va->m_asicView->asicGetOperationsCount()); if (dumpDiffToStdErr) { std::cerr << "views are NOT EQUAL, operations count: " << m_va->m_asicView->asicGetOperationsCount() << std::endl; } for (const auto &op: m_va->m_asicView->asicGetOperations()) { const std::string &key = kfvKey(*op.m_op); const std::string &opp = kfvOp(*op.m_op); SWSS_LOG_NOTICE("%s: %s", opp.c_str(), key.c_str()); if (dumpDiffToStdErr) { std::cerr << opp << ": " << key << std::endl; } const auto &values = kfvFieldsValues(*op.m_op); for (auto &val: values) { SWSS_LOG_NOTICE("- %s %s", fvField(val).c_str(), fvValue(val).c_str()); if (dumpDiffToStdErr) { std::cerr << "- " << fvField(val) << " " << fvValue(val) << std::endl; } } } return false; } SWSS_LOG_NOTICE("views are equal"); return true; }