Skip to content

Commit

Permalink
[SAI-PTF] add invocation logger (#1651)
Browse files Browse the repository at this point in the history
* add invocation logger

Signed-off-by: richardyu-ms <richard.yu@microsoft.com>

* reformat code

Signed-off-by: richardyu-ms <richard.yu@microsoft.com>

Signed-off-by: richardyu-ms <richard.yu@microsoft.com>
Co-authored-by: richardyu <richardyu@contoso.com>
  • Loading branch information
richardyu-ms and richardyu committed Nov 20, 2022
1 parent bb50de8 commit 80ebb3f
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 6 deletions.
7 changes: 5 additions & 2 deletions meta/gensairpc.pl
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
[ 'verbose|v', 'Print more details', { default => 0 } ],
[ 'mandatory-attrs', 'Make mandatory attributes obligatory in sai_adapter.py', { default => 0 } ],
[ 'dev-utils:s', 'Generate additional development utils within the generated code. Additional options: [=log,zero]', { default => 0 } ],
[ 'skip_error:s', 'Skip test on specified error code. Additional options: [=-2]', { default => 0 } ],
[ 'skip_error:s', 'Skip test on specified error code. Additional options: [=-2]', { default => 0 } ],
[ 'adapter_logger', 'Enable the logger in sai_adapter, it will log all the method invocation.', { default => 0} ],
[ 'attr-header', 'Generate additional header of attributes definitions (including object types)', { default => 0 } ],
[ 'help|h', 'Print this help', { shortcircuit => 1 } ],
);
Expand All @@ -116,6 +117,7 @@
my $mandatory_attrs = $args->mandatory_attrs;
my $dev_utils = ( $args->dev_utils ne q{} ? $args->dev_utils : 1 );
my $skip_error = ( $args->skip_error ne q{} ? $args->skip_error : 1 );
my $adapter_logger = ( $args->adapter_logger ne q{} ? $args->adapter_logger : 1 );
my $attr_header = $args->attr_header;

# Configure SAI meta
Expand Down Expand Up @@ -161,7 +163,8 @@
dbg => $dbg,
mandatory_attrs => $mandatory_attrs,
dev_utils => $dev_utils,
skip_error => $skip_error,
skip_error => $skip_error,
adapter_logger => $adapter_logger,
templates_dir => $templates_dir
};

Expand Down
3 changes: 2 additions & 1 deletion meta/rpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Optional arguments are useful for development purposes.
| `-d` `--dump` | Dump all data to the file. **Should be used during development**. |
| `--mandatory-attrs` | Make mandatory attributes obligatory in *sai\_adapter.py*. It removes `=None` from attributes, which are passed as arguments into python functions. Can be useful for debugging purposes, but since most of attributes are **optionally** mandatory, this is not as useful as it could be. |
| `--dev-utils[=STR]` | Generate additional development utils within the generated code. Additional options: [=log,zero]. Useful for tests development and debugging. The generated code **should not** be committed. |
| `--skip_error[=STR]` | Skip test on specified error code. Additional options: [=-2]. The generated code **should not** be committed. |
| `--skip_error[=STR]` | Skip test on specified error code. Additional options: [=-2]. The generated code **should not** be committed. |
| `--adapter_logger` | Enable the logger in sai_adapter, it will log all the method invocation. |
| `-h` `--help` | Print the help. |

*gensairpc.pl* development
Expand Down
3 changes: 3 additions & 0 deletions meta/templates/sai_adapter.py.tt
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ client.[% function.thrift_name %](

[%- PROCESS decorate_method IF dev_utils -%]
[%- PROCESS decorate_skip_test_on_error IF skip_error -%]
[%- PROCESS decorate_invocation_logger IF adapter_logger -%]
[%- PROCESS function_header %]
[%- PROCESS function_docstring %]

Expand Down Expand Up @@ -489,6 +490,7 @@ Thrift SAI interface basic tests

[%- PROCESS dev_utils_imports IF dev_utils -%]
[%- PROCESS skip_test_on_error_imports IF skip_error -%]
[%- PROCESS invocation_logger_imports IF adapter_logger -%]

from sai_thrift.ttypes import *
from sai_thrift.sai_headers import *
Expand All @@ -505,6 +507,7 @@ status = 0

[%- PROCESS dev_utils IF dev_utils -%]
[%- PROCESS skip_error IF skip_error -%]
[%- PROCESS invocation_logger IF adapter_logger -%]

[%- FOREACH api IN apis.keys.sort -%]
[%- IF apis.$api.functions.size %]
Expand Down
37 changes: 37 additions & 0 deletions meta/templates/sai_adapter_utils.tt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ from unittest import SkipTest
from ptf import testutils
[% END -%]

[%- BLOCK invocation_logger_imports %]
import inspect
import logging
[% END -%]

[%- ######################################################################## -%]

[%- ######################################################################## -%]
Expand All @@ -31,6 +36,13 @@ from ptf import testutils
[% PROCESS skip_test_on_error %]
[% END -%]

[%- BLOCK invocation_logger %]

# invocation_logger

[% PROCESS invocation_logger_func %]
[% END -%]

[%- ######################################################################## -%]

[%- ######################################################################## -%]
Expand Down Expand Up @@ -207,6 +219,27 @@ def skip_test_on_error(errorcode=[-2]):
return skip_test_on_error_decorator
[%- END -%]

[%- BLOCK invocation_logger_func -%]
def invocation_logger(func):
"""
SAI interface invocation logger.
Use it to log all the invocated method in this sai_adapater.
"""

def inner_logger(*args, **kwargs):

args_name = inspect.getargspec(func)[0]

args_dict = dict(zip(args_name, args))
args_dict.update(kwargs)
logging.info("sai_adapter_invoke func:[{}] args: [{}]".format(func.__name__, args_dict))

args_values = args_dict.values()
return func(*args, **kwargs)

return inner_logger
[%- END -%]

[%- ######################################################################## -%]

[%- ######################################################################## -%]
Expand All @@ -219,4 +252,8 @@ def skip_test_on_error(errorcode=[-2]):
@skip_test_on_error([% IF skip_error %]errorcode=[[% skip_error %]][% END %])
[%- END -%]

[%- BLOCK decorate_invocation_logger %]
@invocation_logger
[%- END -%]

[%- ######################################################################## -%]
45 changes: 45 additions & 0 deletions ptf/LogConfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import logging
import os
import sys
from logging.handlers import RotatingFileHandler

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
LOG_FILE_DIR = os.path.join(ROOT_DIR, 'logs')
LOG_FILE_PATH = os.path.join(LOG_FILE_DIR, 'output.log')


def set_logging(loggerName='main'):
"""Set the logger.
"""

# Create formatters and add it to handlers
c_debug_format = '%(name)s - %(filename)s - %(levelname)s - %(message)s'
c_error_format = '%(filename)s - %(levelname)s - %(message)s'
f_format = '%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s'
datafmt = '%m/%d/%Y %I:%M:%S %p'

if not os.path.exists(LOG_FILE_DIR):
os.mkdir(LOG_FILE_DIR)

# Create a custom logger
logger = logging.getLogger()
logger.name = loggerName
logger.setLevel(logging.INFO)

file_formatter = logging.Formatter(f_format, datafmt)

# Create handlers
# Add a new file handler
file_handler = logging.FileHandler(LOG_FILE_PATH)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)


# Add a new stream handler
console_formatter = logging.Formatter(
c_error_format, datafmt)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.ERROR)
stream_handler.setFormatter(console_formatter)
logger.addHandler(stream_handler)
17 changes: 15 additions & 2 deletions ptf/sai_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"""
import os
import time
import inspect
from threading import Thread

from collections import OrderedDict
Expand All @@ -34,6 +35,7 @@
from thrift.protocol import TBinaryProtocol

from sai_thrift import sai_rpc
import LogConfig

from sai_utils import *
import sai_thrift.sai_adapter as adapter
Expand All @@ -53,7 +55,6 @@ class ThriftInterface(BaseTest):
"""
def setUp(self):
super(ThriftInterface, self).setUp()

self.interface_to_front_mapping = {}
self.port_map_loaded = False
self.transport = None
Expand Down Expand Up @@ -120,6 +121,7 @@ def createRpcClient(self):
self.transport.open()



class ThriftInterfaceDataPlane(ThriftInterface):
"""
Sets up the thrift interface and dataplane
Expand Down Expand Up @@ -155,6 +157,17 @@ class SaiHelperBase(ThriftInterfaceDataPlane):
"""

platform = 'common'

def set_logger_name(self):
"""
Set Logger name as filename:classname
"""

file_name = inspect.getfile(self.__class__)
class_name = self.__class__.__name__
logger_name = "{}:{}".format(file_name, class_name)
LogConfig.set_logging(loggerName = logger_name)


def get_active_port_list(self):
'''
Expand Down Expand Up @@ -294,7 +307,7 @@ def start_switch(self):

def setUp(self):
super(SaiHelperBase, self).setUp()

self.set_logger_name()
self.getSwitchPorts()
# initialize switch
self.start_switch()
Expand Down
27 changes: 27 additions & 0 deletions ptf/utest/BasicTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

import unittest
import inspect

import LogConfig

"""
Base class of the unit test
"""

class BasicMockedTest(unittest.TestCase):
"""Basic test case, use to simualate the sai_base_test class
"""

def setUp(self):
unittest.TestCase.setUp(self)

def set_logger_name(self):
"""
Set Logger name as filename:classname
"""

file_name = inspect.getfile(self.__class__)
class_name = self.__class__.__name__
logger_name = "{}:{}".format(file_name, class_name)
LogConfig.set_logging(loggerName = logger_name)
45 changes: 45 additions & 0 deletions ptf/utest/LogConfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import logging
import os
import sys
from logging.handlers import RotatingFileHandler

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
LOG_FILE_DIR = os.path.join(ROOT_DIR, 'logs')
LOG_FILE_PATH = os.path.join(LOG_FILE_DIR, 'output.log')


def set_logging(loggerName='main'):
"""Set the logger.
"""

# Create formatters and add it to handlers
c_debug_format = '%(name)s - %(filename)s - %(levelname)s - %(message)s'
c_error_format = '%(filename)s - %(levelname)s - %(message)s'
f_format = '%(asctime)s - %(name)s - %(filename)s - %(levelname)s - %(message)s'
datafmt = '%m/%d/%Y %I:%M:%S %p'

if not os.path.exists(LOG_FILE_DIR):
os.mkdir(LOG_FILE_DIR)

# Create a custom logger
logger = logging.getLogger()
logger.name = loggerName
logger.setLevel(logging.INFO)

file_formatter = logging.Formatter(f_format, datafmt)

# Create handlers
# Add a new file handler
file_handler = logging.FileHandler(LOG_FILE_PATH)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)


# Add a new stream handler
console_formatter = logging.Formatter(
c_error_format, datafmt)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.ERROR)
stream_handler.setFormatter(console_formatter)
logger.addHandler(stream_handler)
91 changes: 91 additions & 0 deletions ptf/utest/MockClient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
class MockSuccessClient():

def sai_thrift_remove_acl_table(self, var):
return 0

def sai_thrift_create_switch(client,
init_switch=None,
hardware_access_bus=None,
platfrom_context=None,
register_read=None,
register_write=None,
switch_id=None,
max_system_cores=None,
system_port_config_list=None,
ingress_acl=None,
egress_acl=None,
restart_warm=None,
warm_recover=None,
switching_mode=None,
bcast_cpu_flood_enable=None,
mcast_cpu_flood_enable=None,
src_mac_address=None,
max_learned_addresses=None,
fdb_aging_time=None,
fdb_unicast_miss_packet_action=None,
fdb_broadcast_miss_packet_action=None,
fdb_multicast_miss_packet_action=None,
ecmp_default_hash_algorithm=None,
ecmp_default_hash_seed=None,
ecmp_default_symmetric_hash=None,
ecmp_hash_ipv4=None,
ecmp_hash_ipv4_in_ipv4=None,
ecmp_hash_ipv6=None,
lag_default_hash_algorithm=None,
lag_default_hash_seed=None,
lag_default_symmetric_hash=None,
lag_hash_ipv4=None,
lag_hash_ipv4_in_ipv4=None,
lag_hash_ipv6=None,
counter_refresh_interval=None,
qos_default_tc=None,
qos_dot1p_to_tc_map=None,
qos_dot1p_to_color_map=None,
qos_dscp_to_tc_map=None,
qos_dscp_to_color_map=None,
qos_tc_to_queue_map=None,
qos_tc_and_color_to_dot1p_map=None,
qos_tc_and_color_to_dscp_map=None,
switch_shell_enable=None,
switch_profile_id=None,
switch_hardware_info=None,
firmware_path_name=None,
switch_state_change_notify=None,
switch_shutdown_request_notify=None,
fdb_event_notify=None,
port_state_change_notify=None,
packet_event_notify=None,
fast_api_enable=None,
mirror_tc=None,
queue_pfc_deadlock_notify=None,
pfc_dlr_packet_action=None,
pfc_tc_dld_interval=None,
pfc_tc_dlr_interval=None,
tpid_outer_vlan=None,
tpid_inner_vlan=None,
crc_check_enable=None,
crc_recalculation_enable=None,
bfd_session_state_change_notify=None,
ecn_ect_threshold_enable=None,
vxlan_default_router_mac=None,
vxlan_default_port=None,
uninit_data_plane_on_removal=None,
tam_object_id=None,
tam_event_notify=None,
pre_shutdown=None,
nat_zone_counter_object_id=None,
nat_enable=None,
firmware_download_broadcast=None,
firmware_load_method=None,
firmware_load_type=None,
firmware_download_execute=None,
firmware_broadcast_stop=None,
firmware_verify_and_init_switch=None,
type=None,
macsec_object_id=None,
qos_mpls_exp_to_tc_map=None,
qos_mpls_exp_to_color_map=None,
qos_tc_and_color_to_mpls_exp_map=None,
failover_config_mode=None,
tunnel_objects_list=None):
return 0
Loading

0 comments on commit 80ebb3f

Please sign in to comment.