Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SAI attributes usage in test logging #227

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/sai.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from saichallenger.common.sai_client.sai_client import SaiClient
from saichallenger.common.sai_data import SaiObjType
from saichallenger.common.sai_logger import SaiAttrsJsonLogger


class CommandProcessor:
Expand Down Expand Up @@ -241,6 +242,7 @@ def get(self, obj, attrs, do_assert=True):
attr = attrs[0]
attr_type = self.get_obj_attr_type(obj_type, attr)
status, data = self.get_by_type(obj, attr, attr_type)
SaiAttrsJsonLogger.insert_attr_use(obj_type, attr, "get")
if do_assert:
assert status == "SAI_STATUS_SUCCESS", f"Failed to retrieve {attr}: {status}"
return data
Expand Down
5 changes: 5 additions & 0 deletions common/sai_client/sai_redis_client/sai_redis_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from saichallenger.common.sai_client.sai_client import SaiClient
from saichallenger.common.sai_data import SaiObjType, SaiData
from saichallenger.common.sai_logger import SaiAttrsJsonLogger


class SaiRedisClient(SaiClient):
Expand Down Expand Up @@ -120,6 +121,10 @@ def operate(self, obj, attrs, op):
self.r.delete("GETRESPONSE_KEY_VALUE_OP_QUEUE")

assert len(status) == 3, f"SAI \"{op[1:]}\" operation failure!"
attrs_list = json.loads(attrs)
if attrs_list:
for attr in attrs_list[::2]:
SaiAttrsJsonLogger.insert_attr_use(obj.split(":")[0], attr, op[1:])
return status

def create(self, obj, attrs, do_assert=True):
Expand Down
5 changes: 5 additions & 0 deletions common/sai_client/sai_thrift_client/sai_thrift_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from saichallenger.common.sai_client.sai_thrift_client.sai_thrift_utils import *
from saichallenger.common.sai_data import SaiData
from saichallenger.common.sai_data import SaiObjType
from saichallenger.common.sai_logger import SaiAttrsJsonLogger
from sai_thrift import sai_rpc, sai_adapter
from thrift.protocol import TBinaryProtocol
from thrift.transport import TSocket, TTransport
Expand Down Expand Up @@ -164,6 +165,10 @@ def _operate(self, operation, attrs=(), oid=None, obj_type=None, key=None):
result = key if key is not None else result
else:
result = None

for attr in attrs[::2]:
SaiAttrsJsonLogger.insert_attr_use(f"SAI_OBJECT_TYPE_{obj_type_name.upper()}", attr, operation)

return status, result

def _operate_attributes(self, operation, attrs=(), oid=None, obj_type=None, key=None):
Expand Down
31 changes: 31 additions & 0 deletions common/sai_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import json
import os


class SaiAttrsJsonLogger:

used_attrs_json = dict()

@classmethod
def dump(cls, log_path=None) -> None:
log_file_path = log_path or os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tests', 'sai_attrs.json')
with open(log_file_path, '+w') as log_fp:
json.dump(cls.used_attrs_json, log_fp, indent=4)

@classmethod
def insert_attr_use(cls, obj_type, attr_name, oper):
test_name = os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
cls.used_attrs_json[obj_type] = cls.used_attrs_json.get(obj_type, None) or dict()
cls.used_attrs_json[obj_type][oper] = cls.used_attrs_json[obj_type].get(oper, None) or dict()
cls.used_attrs_json[obj_type][oper][attr_name] = cls.used_attrs_json[obj_type][oper].get(attr_name, None) or dict()
cls.used_attrs_json[obj_type][oper][attr_name][test_name] = "passed"

@classmethod
def update_test_result(cls, cur_test_name, result):
for obj_type in cls.used_attrs_json:
for oper in cls.used_attrs_json[obj_type]:
for attr_name in cls.used_attrs_json[obj_type][oper]:
for test_name in cls.used_attrs_json[obj_type][oper][attr_name]:
if test_name == cur_test_name:
cls.used_attrs_json[obj_type][oper][attr_name][test_name] = result

18 changes: 18 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
from saichallenger.common.sai_phy import SaiPhy
from saichallenger.common.sai_testbed import SaiTestbed
from saichallenger.common.sai_data import SaiObjType
from saichallenger.common.sai_logger import SaiAttrsJsonLogger

_previous_test_failed = False
log_attrs = False

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
Expand Down Expand Up @@ -40,6 +42,17 @@ def pytest_runtest_makereport(item, call):
elif not _previous_test_failed:
# Update the outcome only in case all previous phases were successful
_previous_test_failed = rep.outcome not in ["passed", "skipped"]

if log_attrs:
log_file_path = f"{curdir}/sai_attr_log.json"
SaiAttrsJsonLogger.dump(log_file_path)


@pytest.hookimpl
def pytest_report_teststatus(report):
if report.when == "call":
if report.outcome == "failed" and log_attrs:
SaiAttrsJsonLogger.update_test_result(report.head_line, report.outcome)


@pytest.fixture
Expand All @@ -51,6 +64,7 @@ def prev_test_failed():
def pytest_addoption(parser):
parser.addoption("--traffic", action="store_true", help="run tests with traffic")
parser.addoption("--testbed", action="store", help="Testbed name", required=True)
parser.addoption("--log_attrs", action="store_true", help="run tests with traffic")


def pytest_sessionstart(session):
Expand All @@ -64,7 +78,11 @@ def exec_params(request):
# Generic parameters
"traffic": request.config.getoption("--traffic"),
"testbed": request.config.getoption("--testbed"),
"log_attrs": request.config.getoption("--log_attrs"),
}
if config_param["log_attrs"]:
global log_attrs
log_attrs = True
return config_param


Expand Down