From patchwork Wed Apr 6 14:55:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109218 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C1FFFA0507; Wed, 6 Apr 2022 16:56:41 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C63554286E; Wed, 6 Apr 2022 16:56:25 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id BA1ED42852 for ; Wed, 6 Apr 2022 16:56:22 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id DED441B27A4; Wed, 6 Apr 2022 16:56:21 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VhT84H9ub1EF; Wed, 6 Apr 2022 16:56:07 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 48A0D1A39D9; Wed, 6 Apr 2022 16:56:07 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 01/15] dts: merge DTS dep/tclclient.tgz to DPDK Date: Wed, 6 Apr 2022 14:55:52 +0000 Message-Id: <20220406145606.2913834-2-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/dep/tclclient.tgz | Bin 0 -> 199327 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dts/dep/tclclient.tgz GIT binary patch literal 199327 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

7Mr6)yF|V6Z2jElF}%UPcegq|zV* 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 literal 0 HcmV?d00001 diff --git a/dts/dep/tclclient.tgz b/dts/dep/tclclient.tgz new file mode 100644 index 0000000000000000000000000000000000000000..96038ffcbf3bef07fab73fc6348c5b6caa73d28a From patchwork Wed Apr 6 14:55:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109216 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9B120A0507; Wed, 6 Apr 2022 16:56:22 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 864B34284B; Wed, 6 Apr 2022 16:56:22 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 6E89C4014F for ; Wed, 6 Apr 2022 16:56:20 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id BEE8C1B27A3; Wed, 6 Apr 2022 16:56:19 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UxF7f-qHgciB; Wed, 6 Apr 2022 16:56:09 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id E5EA31A39DC; Wed, 6 Apr 2022 16:56:07 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 02/15] dts: merge DTS dep/tgen.tgz to DPDK Date: Wed, 6 Apr 2022 14:55:53 +0000 Message-Id: <20220406145606.2913834-3-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/dep/tgen.tgz | Bin 0 -> 134392 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dts/dep/tgen.tgz GIT binary patch literal 134392 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[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

3jcAv)Mf-e0 zw9h9*bCOf32D!x1kJWixTfW{CZWrp>{@az|p6xy6hO%h_=s7KH_|u+BF%&hYu$7se zN6emZml%|kg>MxjzsmeD?p$Py&)!F-u#SS+qjqC_Mwgkt@BN+`p9#|TcC)j-a)x

mrpS;kmhw$5VgnQ2%4 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 X-Patchwork-Id: 109217 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B92D5A0507; Wed, 6 Apr 2022 16:56:33 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D424342864; Wed, 6 Apr 2022 16:56:24 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id CD8934014F for ; Wed, 6 Apr 2022 16:56:21 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 1E5AD1A39DC; Wed, 6 Apr 2022 16:56:21 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lKjOTPzngvwf; Wed, 6 Apr 2022 16:56:20 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 776801B1F41; Wed, 6 Apr 2022 16:56:08 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 03/15] dts: merge DTS dts to DPDK Date: Wed, 6 Apr 2022 14:55:54 +0000 Message-Id: <20220406145606.2913834-4-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/dts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 dts/dts diff --git a/dts/dts b/dts/dts new file mode 100755 index 0000000000..4d29e01aa3 --- /dev/null +++ b/dts/dts @@ -0,0 +1,9 @@ +#!/bin/bash + +# + +PWD=`dirname $0` + +pushd $PWD +./main.py $@ +popd From patchwork Wed Apr 6 14:55:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109219 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D1B1AA0507; Wed, 6 Apr 2022 16:56:52 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CB1B542878; Wed, 6 Apr 2022 16:56:26 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 2BD004014F for ; Wed, 6 Apr 2022 16:56:23 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 72FF21B27A5; Wed, 6 Apr 2022 16:56:22 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XZannHSO1G5g; Wed, 6 Apr 2022 16:56:21 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 2288C1B1F48; Wed, 6 Apr 2022 16:56:09 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 04/15] dts: merge DTS framework/__init__.py to DPDK Date: Wed, 6 Apr 2022 14:55:55 +0000 Message-Id: <20220406145606.2913834-5-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/__init__.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dts/framework/__init__.py diff --git a/dts/framework/__init__.py b/dts/framework/__init__.py new file mode 100644 index 0000000000..ae0043b7ef --- /dev/null +++ b/dts/framework/__init__.py @@ -0,0 +1,30 @@ +#!/usr/bin/python3 +# BSD LICENSE +# +# Copyright (c) 2021 PANTHEON.tech s.r.o. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of PANTHEON.tech s.r.o. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From patchwork Wed Apr 6 14:55:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109220 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 96DF4A0507; Wed, 6 Apr 2022 16:57:05 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3A0CA42881; Wed, 6 Apr 2022 16:56:28 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id D391A42863 for ; Wed, 6 Apr 2022 16:56:24 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id ECCD51A39D9; Wed, 6 Apr 2022 16:56:23 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YvkVehIiX7Pd; Wed, 6 Apr 2022 16:56:22 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 9766119E0DA; Wed, 6 Apr 2022 16:56:09 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 05/15] dts: merge DTS framework/asan_test.py to DPDK Date: Wed, 6 Apr 2022 14:55:56 +0000 Message-Id: <20220406145606.2913834-6-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/asan_test.py | 439 +++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 dts/framework/asan_test.py diff --git a/dts/framework/asan_test.py b/dts/framework/asan_test.py new file mode 100644 index 0000000000..8ca0536bcc --- /dev/null +++ b/dts/framework/asan_test.py @@ -0,0 +1,439 @@ +import configparser +import os +import re +from contextlib import contextmanager + +import xlrd + +import framework.settings as settings +from framework.excel_reporter import ExcelReporter +from framework.test_result import Result + +from .json_reporter import JSONReporter +from .stats_reporter import StatsReporter + +ASan_CONFIG_SECT = "ASan" +ASan_FILTER_BOUNDS = "filter_bounds" +ASan_PARAM_KEY = "build_param" +ASan_CONFIG_FILE_PATH = "%s/asan.cfg" % settings.CONFIG_ROOT_PATH +COMMAND_PATTERN_OF_ADDRESS_RANDOM_SWITCH = ( + "echo %s > /proc/sys/kernel/randomize_va_space" +) +COMMAND_OF_CLOSE_ADDRESS_RANDOM = COMMAND_PATTERN_OF_ADDRESS_RANDOM_SWITCH % 0 +COMMAND_OF_OPEN_ADDRESS_RANDOM = COMMAND_PATTERN_OF_ADDRESS_RANDOM_SWITCH % 2 +NEW_TEST_REPORT_FILE = "asan_test_results.xls" +NEW_JSON_REPORT_FILE = "asan_test_results.json" +NEW_STATS_REPORT_FILE = "asan_statistics.txt" +ORIGIN_TEST_REPORT_FILE = "test_results.xls" +MIN_LENGTH_OF_FILTERED_OUTPUT = 50 +REPORT_OUTPUT_PATH = "" + + +class ASanTestProcess(object): + IS_SUPPORT_ASan_TEST = False + + @staticmethod + def test_prepare(is_support_ASan_test, output_dir): + if is_support_ASan_test: + ASanTestProcess.IS_SUPPORT_ASan_TEST = True + # use framework default or customer defined output dir + global REPORT_OUTPUT_PATH + REPORT_OUTPUT_PATH = output_dir + _FrameworkADAPTER.decorator_dts_run() + _FrameworkADAPTER.decorator_send_expect() + _FrameworkADAPTER.decorator_build_install_dpdk() + + @staticmethod + def test_process(): + if ASanTestProcess.IS_SUPPORT_ASan_TEST: + report_process_obj = _NewReport() + report_process_obj.process_report_header() + report_process_obj.process_report_detail() + report_process_obj.save_report() + + +class _FrameworkADAPTER(object): + @staticmethod + def decorator_build_install_dpdk(): + added_param = _ASanConfig().build_param + if added_param is not None: + from framework.project_dpdk import DPDKdut + + origin_func = DPDKdut.build_install_dpdk + + def new_func(*args, **kwargw): + kwargw["extra_options"] = " ".join( + [kwargw.get("extra_options", ""), added_param] + ) + origin_func(*args, **kwargw) + + DPDKdut.build_install_dpdk = new_func + + @staticmethod + def decorator_dts_run(): + import framework.dts as dts + + origin_func = dts.dts_run_suite + + def new_func(*args, **kwargs): + duts = args[0] + for dut in duts: + dut.send_expect(COMMAND_OF_CLOSE_ADDRESS_RANDOM, "#") + + origin_func(*args, **kwargs) + + for dut in duts: + dut.send_expect(COMMAND_OF_OPEN_ADDRESS_RANDOM, "#") + + dts.dts_run_suite = new_func + + @staticmethod + def decorator_send_expect(): + import framework.ssh_pexpect as ssh_pexpect + + origin_func = ssh_pexpect.SSHPexpect._SSHPexpect__flush + + def new_func(self): + DELETE_CONTENT_PATTERN = r"^\s*\[?PEXPECT\]?#?\s*$" + befored_info = re.sub( + DELETE_CONTENT_PATTERN, "", self.session.before + ).strip() + if len(befored_info) > MIN_LENGTH_OF_FILTERED_OUTPUT and self.logger: + self.logger.info(f"Buffered info: {befored_info}") + origin_func(self) + + ssh_pexpect.SSHPexpect._SSHPexpect__flush = new_func + + +class _ASanConfig(object): + def __init__( + self, + ): + self.config = configparser.ConfigParser() + self.config.read(ASan_CONFIG_FILE_PATH) + self._filter_list = None + self._build_params = None + + def _read_ASan_sect_conf(self, key): + return self.config.get(ASan_CONFIG_SECT, key) + + def _set_ASan_filter(self): + try: + origin_filter_string = self._read_ASan_sect_conf(ASan_FILTER_BOUNDS) + self._filter_list = [ + tuple(re.split(r":\s*", _filter)) + for _filter in re.split(r",\s*", origin_filter_string) + ] + except KeyError: + self._filter_list = [] + + def _set_ASan_param(self): + try: + param_string = self._read_ASan_sect_conf(ASan_PARAM_KEY) + except KeyError: + param_string = "" + self._build_params = param_string + + @property + def filter_list(self): + self._set_ASan_filter() + return self._filter_list + + @property + def build_param(self): + self._set_ASan_param() + return self._build_params + + +class _OldExcelReport(object): + def __init__(self): + self._report_file = os.path.join(REPORT_OUTPUT_PATH, ORIGIN_TEST_REPORT_FILE) + self._workbook: xlrd.Book = xlrd.open_workbook(self._report_file) + self._sheet_obj: xlrd.sheet.Sheet = self._workbook.sheets()[0] + self._rows = self._sheet_obj.nrows + self.current_row_num = 0 + + def generator_rows(self): + while True: + if self.current_row_num >= self._rows: + raise IndexError + row_number_of_jump_to = yield self._sheet_obj.row(self.current_row_num) + row = ( + row_number_of_jump_to + if row_number_of_jump_to is not None + else self.current_row_num + 1 + ) + self.current_row_num = row + + +class _OldExcelReportReader(object): + def __init__(self): + self._old_report = _OldExcelReport() + self._header_line_num = 1 + self._test_env_content_column = None + self._test_suite_content_column = None + self._gen_report_rows = self._old_report.generator_rows() + next(self._gen_report_rows) + self._report_content_dict = dict() + self._current_suite = None + + def get_report_info(self): + try: + self._get_first_line() + self._get_test_env() + self._get_cases_result() + except IndexError: + pass + return self._report_content_dict + + def _get_first_line(self): + header_row_title = self._gen_report_rows.send(self._header_line_num - 1) + header_row_content = self._gen_report_rows.send(self._header_line_num) + cell_num = 0 + while header_row_title[cell_num].value != "Test suite": + header_cell_title: str = header_row_title[cell_num].value + header_cell_content = header_row_content[cell_num].value + self._report_content_dict[ + header_cell_title.lower().replace(" ", "_") + ] = header_cell_content + cell_num = cell_num + 1 + self._test_env_content_column = cell_num - 1 + self._test_suite_content_column = cell_num + + @staticmethod + def _get_value_from_cell(cells_list_of_row): + return [cell.value for cell in cells_list_of_row] + + def _get_test_env(self): + env_key_list = ["driver", "kdriver", "firmware", "package"] + for env_key in env_key_list: + env_info_row = next(self._gen_report_rows) + env_cell_value = env_info_row[self._test_env_content_column].value + if env_cell_value: + env_value = env_cell_value.split(": ")[1] + self._report_content_dict[env_key] = env_value + else: + self._report_content_dict[env_key] = None + # back to previous line + self._gen_report_rows.send(self._old_report.current_row_num - 1) + + def _get_cases_result(self): + for row_cells in self._gen_report_rows: + suite_content_column_begin = self._test_suite_content_column + suite_content_column_end = self._test_suite_content_column + 3 + suite_name, case_name, original_result_msg = self._get_value_from_cell( + row_cells[suite_content_column_begin:suite_content_column_end] + ) + EMPTY_LINE_CONDITION = not suite_name and not case_name + NO_CASE_LINE_CONDITION = not case_name + SUITE_BEGIN_LINE_CONDITON = suite_name + if EMPTY_LINE_CONDITION or NO_CASE_LINE_CONDITION: + continue + + if SUITE_BEGIN_LINE_CONDITON: + self._add_suite_info(suite_name) + + self._add_case_info(case_name, original_result_msg) + + def _add_suite_info(self, _suite): + self._report_content_dict.setdefault(_suite, dict()) + self._current_suite = _suite + + def _add_case_info(self, _case, _result_msg): + self._report_content_dict.get(self._current_suite)[_case] = _result_msg + + +class _SuiteLogReader(object): + def __init__(self, suite_name): + self._suite_name = suite_name + + @contextmanager + def suite_log_file(self): + from framework.test_case import TestCase + from framework.utils import get_subclasses + + suite_full_name = "TestSuite_" + self._suite_name + suite_module = __import__( + "tests." + suite_full_name, fromlist=[suite_full_name] + ) + suite_class_name = [ + test_case_name + for test_case_name, _ in get_subclasses(suite_module, TestCase) + ][0] + log_file_path = os.path.join(REPORT_OUTPUT_PATH, suite_class_name) + log_file_obj = open(log_file_path + ".log", "r") + yield log_file_obj + log_file_obj.close() + + +class _NewReport(object): + def __init__(self): + self._excel_report_file = os.path.join(REPORT_OUTPUT_PATH, NEW_TEST_REPORT_FILE) + self._json_report_file = os.path.join(REPORT_OUTPUT_PATH, NEW_JSON_REPORT_FILE) + self._stats_report_file = os.path.join( + REPORT_OUTPUT_PATH, NEW_STATS_REPORT_FILE + ) + self._remove_history_asan_report() + self._excel_report = ExcelReporter(self._excel_report_file) + self._json_report = JSONReporter(self._json_report_file) + self._stats_report = StatsReporter(self._stats_report_file) + self._result_obj = Result() + self._old_report_reader = _OldExcelReportReader() + self._old_report_content: dict = self._old_report_reader.get_report_info() + self._new_suites_result = dict() + self._ASan_filter = _ASanConfig().filter_list + self._current_case = None + self._current_suite = None + self._filtered_line_cache = [] + self._filter_begin = None + self._filter_end = None + + def process_report_header(self): + head_key_list = [ + "dut", + "kdriver", + "firmware", + "package", + "driver", + "dpdk_version", + "target", + "nic", + ] + for head_key in head_key_list: + head_value = self._old_report_content.setdefault(head_key, None) + self._old_report_content.pop(head_key) + setattr(self._result_obj, head_key, head_value) + + def process_report_detail(self): + for suite in self._old_report_content.keys(): + self._get_suite_new_result(suite) + self._parse_suite_result_to_result_obj() + + def _get_suite_new_result(self, suite): + suite_log_reader = _SuiteLogReader(suite) + self._current_suite = suite + gen_suite_lines = suite_log_reader.suite_log_file() + self._get_case_result(gen_suite_lines) + + def _parse_suite_result_to_result_obj(self): + self._result_obj.test_suite = self._current_suite + for case in self._old_report_content[self._current_suite]: + self._result_obj.test_case = case + if case in self._new_suites_result: + self._result_obj._Result__set_test_case_result( + *self._new_suites_result[case] + ) + else: + origin_result = self._get_origin_case_result(case) + self._result_obj._Result__set_test_case_result(*origin_result) + + def save_report(self): + for report in (self._excel_report, self._json_report, self._stats_report): + report.save(self._result_obj) + + def _remove_history_asan_report(self): + for file in ( + self._excel_report_file, + self._json_report_file, + self._stats_report_file, + ): + if os.path.exists(file): + os.remove(file) + + def _get_origin_case_result(self, case_name): + origin_cases_result: dict = self._old_report_content.get(self._current_suite) + origin_case_result: str = origin_cases_result.get(case_name) + CASE_RESULT_AND_MSG_PATTERN = r"(\S+)\s?(.*)" + result, msg = re.search( + CASE_RESULT_AND_MSG_PATTERN, origin_case_result + ).groups() + if msg: + msg = msg.replace("'", "").replace('"', "") + + return result, msg + + def _get_case_result(self, suite_log_reader): + with suite_log_reader as log_file: + for line in log_file: + self._filter_asan_except(line) + + self._log_file_end_handler() + + def _filter_asan_except(self, line): + CASE_LOG_BEGIN_PATTERN = r"Test Case test_(\w+) Begin" + case_begin_match = re.search(CASE_LOG_BEGIN_PATTERN, line) + + if case_begin_match: + case_name = case_begin_match.groups()[0] + self._case_begin_handler(case_name) + return + + for filter_tuple in self._ASan_filter: + begin_filter, end_filter = filter_tuple + if begin_filter in line: + self._filter_matched_begin_handler(begin_filter, line) + return + + if self._filter_begin is not None: + self._filter_matched_line_handler(line) + return + + if end_filter in line: + self._filter_matched_end_handler(end_filter, line) + return + + def _case_begin_handler(self, case_name): + self._save_previous_case_result_and_clean_env() + self._current_case = case_name + + def _filter_matched_begin_handler(self, begin_key, line): + self._filter_begin = begin_key + self._filtered_line_cache.append(line) + + def _filter_matched_line_handler(self, line): + self._filtered_line_cache.append(line) + + def _filter_matched_end_handler(self, end_key, line): + self._filtered_line_cache.append(line) + self._filter_begin = end_key + + def _log_file_end_handler(self): + self._save_previous_case_result_and_clean_env() + + def _save_previous_case_result_and_clean_env(self): + exist_previous_case_condition = self._current_case is not None + origin_report_contain_previous_case_result = ( + self._current_case in self._old_report_content.get(self._current_suite) + ) + + if exist_previous_case_condition and origin_report_contain_previous_case_result: + self._save_case_result() + + self._filtered_line_cache.clear() + self._filter_begin = None + self._filter_end = None + + def _save_case_result(self): + cached_content = self._get_filtered_cached_result() + if self._current_case in self._new_suites_result: + # Run multiple times and keep the last result + self._new_suites_result.pop(self._current_case) + + if cached_content: + # filter hit scene + self._new_suites_result[self._current_case] = ("FAILED", cached_content) + else: + # filter not hit scene + self._new_suites_result[self._current_case] = self._get_origin_case_result( + self._current_case + ) + + def _get_filtered_cached_result(self): + ASan_FILTER_CONTENT_PATTERN = ( + rf"{self._filter_begin}[\s\S]+(?!{self._filter_end})?" + ) + key_search_result = re.findall( + ASan_FILTER_CONTENT_PATTERN, "".join(self._filtered_line_cache) + ) + + return key_search_result[0] if key_search_result else "" From patchwork Wed Apr 6 14:55:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109221 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id F30A2A0507; Wed, 6 Apr 2022 16:57:14 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 29F4A42886; Wed, 6 Apr 2022 16:56:29 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 08911410EF for ; Wed, 6 Apr 2022 16:56:25 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 18BCB1B1F48; Wed, 6 Apr 2022 16:56:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id XThaSeaigOVu; Wed, 6 Apr 2022 16:56:23 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 1216D1B1F4B; Wed, 6 Apr 2022 16:56:10 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 06/15] dts: merge DTS framework/checkCase.py to DPDK Date: Wed, 6 Apr 2022 14:55:57 +0000 Message-Id: <20220406145606.2913834-7-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/checkCase.py | 214 +++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 dts/framework/checkCase.py diff --git a/dts/framework/checkCase.py b/dts/framework/checkCase.py new file mode 100644 index 0000000000..7b2c22b3c0 --- /dev/null +++ b/dts/framework/checkCase.py @@ -0,0 +1,214 @@ +import collections +import json +import os + +from .settings import ( + CONFIG_ROOT_PATH, + HOST_DRIVER_SETTING, + get_nic_name, + load_global_setting, +) +from .utils import RED + +filter_json_file = os.path.join(CONFIG_ROOT_PATH, "test_case_checklist.json") +support_json_file = os.path.join(CONFIG_ROOT_PATH, "test_case_supportlist.json") + + +class CheckCase(object): + """ + Class for check test case running criteria. All information will be loaded + from DTS_CFG_FOLDER/test_case_*list.json. Current two files are maintained. One is + for check whether test case should skip, another one is for check whether + current environment support test case execution. + """ + + def __init__(self): + self.dut = None + self.comments = "" + + self.check_function_dict = {} + self.support_function_dict = {} + try: + self.check_function_dict = json.load( + open(filter_json_file), object_pairs_hook=collections.OrderedDict + ) + except: + print( + RED( + "Can't load check list for test cases, all case will be taken as supported" + ) + ) + + try: + self.support_function_dict = json.load( + open(support_json_file), object_pairs_hook=collections.OrderedDict + ) + except: + print( + RED( + "Can't load support list for test cases, all case will be taken as supported" + ) + ) + + def check_dut(self, dut): + """ + Change DUT instance for environment check + """ + self.dut = dut + + def _check_os(self, os_type): + if "all" == os_type[0].lower(): + return True + dut_os_type = self.dut.get_os_type() + if dut_os_type in os_type: + return True + else: + return False + + def _check_nic(self, nic_type): + if "all" == nic_type[0].lower(): + return True + dut_nic_type = get_nic_name(self.dut.ports_info[0]["type"]) + if dut_nic_type in nic_type: + return True + else: + return False + + def _check_target(self, target): + if "all" == target[0].lower(): + return True + if self.dut.target in target: + return True + else: + return False + + def _check_host_driver(self, drivers): + host_driver = load_global_setting(HOST_DRIVER_SETTING) + if "all" == drivers[0].lower(): + return True + if host_driver in drivers: + return True + else: + return False + + def case_skip(self, case_name): + """ + Check whether test case and DUT match skip criteria + Return True if skip should skip + """ + skip_flag = False + self.comments = "" + + if self.dut is None: + print(RED("No Dut assigned before case skip check")) + return skip_flag + + if case_name in list(self.check_function_dict.keys()): + case_checks = self.check_function_dict[case_name] + # each case may have several checks + for case_check in case_checks: + # init result for each check + skip_flag = False + for key in list(case_check.keys()): + # some items like "Bug ID" and "Comments" do not need check + try: + if "Comments" == key: + continue + if "Bug ID" == key: + continue + check_function = getattr(self, "_check_%s" % key.lower()) + except: + print(RED("can't check %s type" % key)) + + # skip this check if any item not matched + if check_function(case_check[key]): + skip_flag = True + else: + skip_flag = False + break + + # if all items matched, this case should skip + if skip_flag: + if "Comments" in list(case_check.keys()): + self.comments = case_check["Comments"] + return skip_flag + + return skip_flag + + def case_support(self, case_name): + """ + Check whether test case and DUT match support criteria + Return False if test case not supported + """ + support_flag = True + self.comments = "" + + if self.dut is None: + print(RED("No Dut assigned before case support check")) + return support_flag + + if case_name in list(self.support_function_dict.keys()): + # each case may have several supports + case_supports = self.support_function_dict[case_name] + for case_support in case_supports: + # init result for each check + support_flag = True + for key in list(case_support.keys()): + # some items like "Bug ID" and "Comments" do not need check + try: + if "Comments" == key: + continue + if "Bug ID" == key: + continue + check_function = getattr(self, "_check_%s" % key.lower()) + except: + print(RED("can't check %s type" % key)) + + # skip this case if any item not matched + if check_function(case_support[key]): + support_flag = True + else: + support_flag = False + break + + if support_flag is False: + if "Comments" in list(case_support.keys()): + self.comments = case_support["Comments"] + return support_flag + + return support_flag + + +class simple_dut(object): + def __init__(self, os="", target="", nic=""): + self.ports_info = [{}] + self.os = os + self.target = target + self.ports_info[0]["type"] = nic + + def get_os_type(self): + return self.os + + +if __name__ == "__main__": + dut = simple_dut(os="linux", target="x86_64-native-linuxapp-gcc", nic="177d:a034") + dut1 = simple_dut( + os="freebsd", target="x86_64-native-linuxapp-gcc", nic="8086:158b" + ) + + # create instance for check/support case list + case_inst = CheckCase() + + # check dut + case_inst.check_dut(dut) + print(case_inst.case_skip("fdir_flexword_drop_ipv4")) + print(case_inst.comments) + print(case_inst.case_support("Vxlan_tunnel")) + print(case_inst.comments) + + # check other dut + case_inst.check_dut(dut1) + print(case_inst.case_skip("fdir_flexword_drop_ipv4")) + print(case_inst.comments) + print(case_inst.case_support("Vxlan_tunnel")) + print(case_inst.comments) From patchwork Wed Apr 6 14:55:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109223 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D5C7BA0507; Wed, 6 Apr 2022 16:57:31 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E7B3E4286C; Wed, 6 Apr 2022 16:56:30 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 0539342855 for ; Wed, 6 Apr 2022 16:56:27 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 55D521B27A7; Wed, 6 Apr 2022 16:56:26 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uL9i8VW39e6z; Wed, 6 Apr 2022 16:56:24 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 7B1C11B1F4D; Wed, 6 Apr 2022 16:56:10 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 07/15] dts: merge DTS framework/dts.py to DPDK Date: Wed, 6 Apr 2022 14:55:58 +0000 Message-Id: <20220406145606.2913834-8-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/dts.py | 721 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 721 insertions(+) create mode 100644 dts/framework/dts.py diff --git a/dts/framework/dts.py b/dts/framework/dts.py new file mode 100644 index 0000000000..c06bcedf33 --- /dev/null +++ b/dts/framework/dts.py @@ -0,0 +1,721 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2019 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import atexit # register callback when exit +import configparser # config parse module +import copy # copy module for duplicate variable +import imp +import inspect # load attribute +import json # json format +import logging +import os # operation system module +import re # regular expressions module +import signal # signal module for debug mode +import sys # system module +import time # time module for unique output folder +import traceback # exception traceback + +import framework.debugger as debugger +import framework.logger as logger +import framework.rst as rst # rst file support +import framework.settings as settings # dts settings +from framework.asan_test import ASanTestProcess + +from .checkCase import CheckCase +from .config import CrbsConf +from .dut import Dut +from .excel_reporter import ExcelReporter +from .exception import ConfigParseException, TimeoutException, VerifyFailure +from .json_reporter import JSONReporter +from .logger import getLogger +from .serializer import Serializer +from .stats_reporter import StatsReporter +from .test_case import TestCase +from .test_result import Result +from .tester import Tester +from .utils import ( + check_dts_python_version, + copy_instance_attr, + create_parallel_locks, + get_subclasses, +) + +imp.reload(sys) + +requested_tests = None +result = None +excel_report = None +json_report = None +stats_report = None +log_handler = None + + +def dts_parse_param(config, section, log_handler): + """ + Parse execution file parameters. + """ + # default value + performance = False + functional = False + # Set parameters + shared_lib_parameters = "" + try: + shared_lib_parameters = config.get(section, "shared_lib_param") + except Exception as e: + shared_lib_parameters = "" + shared_lib_parameters = shared_lib_parameters.split(":") + + parameters = config.get(section, "parameters").split(":") + drivername = config.get(section, "drivername").split("=")[-1] + + driver = drivername.split(":") + if len(driver) == 2: + drivername = driver[0] + drivermode = driver[1] + settings.save_global_setting(settings.HOST_DRIVER_MODE_SETTING, drivermode) + else: + drivername = driver[0] + + settings.save_global_setting(settings.HOST_DRIVER_SETTING, drivername) + + shared_lib_paramDict = dict() + for param in shared_lib_parameters: + (key, _, value) = param.partition("=") + shared_lib_paramDict[key] = value + if ( + "use_shared_lib" in shared_lib_paramDict + and shared_lib_paramDict["use_shared_lib"].lower() == "true" + ): + settings.save_global_setting(settings.HOST_SHARED_LIB_SETTING, "true") + else: + settings.save_global_setting(settings.HOST_SHARED_LIB_SETTING, "false") + + if "shared_lib_path" in shared_lib_paramDict: + if not shared_lib_paramDict["shared_lib_path"] and settings.load_global_setting( + settings.HOST_SHARED_LIB_SETTING + ): + raise ValueError("use shared lib but shared lib path is empty") + settings.save_global_setting( + settings.HOST_SHARED_LIB_PATH, shared_lib_paramDict["shared_lib_path"] + ) + + paramDict = dict() + for param in parameters: + (key, _, value) = param.partition("=") + paramDict[key] = value + + if "perf" in paramDict and paramDict["perf"] == "true": + performance = True + if "func" in paramDict and paramDict["func"] == "true": + functional = True + + if "nic_type" not in paramDict: + paramDict["nic_type"] = "any" + + settings.save_global_setting(settings.HOST_NIC_SETTING, paramDict["nic_type"]) + + # save perf/function setting in environment + if performance: + settings.save_global_setting(settings.PERF_SETTING, "yes") + else: + settings.save_global_setting(settings.PERF_SETTING, "no") + + if functional: + settings.save_global_setting(settings.FUNC_SETTING, "yes") + else: + settings.save_global_setting(settings.FUNC_SETTING, "no") + + +def dts_parse_config(config, section): + """ + Parse execution file configuration. + """ + duts = [dut_.strip() for dut_ in config.get(section, "crbs").split(",")] + targets = [target.strip() for target in config.get(section, "targets").split(",")] + test_suites = [ + suite.strip() for suite in config.get(section, "test_suites").split(",") + ] + try: + rx_mode = config.get(section, "rx_mode").strip().lower() + except: + rx_mode = "default" + + settings.save_global_setting(settings.DPDK_RXMODE_SETTING, rx_mode) + + for suite in test_suites: + if suite == "": + test_suites.remove(suite) + + return duts, targets, test_suites + + +def dts_parse_commands(commands): + """ + Parse command information from dts arguments + """ + dts_commands = [] + + if commands is None: + return dts_commands + + args_format = {"shell": 0, "crb": 1, "stage": 2, "check": 3, "max_num": 4} + cmd_fmt = r"\[(.*)\]" + + for command in commands: + args = command.split(":") + if len(args) != args_format["max_num"]: + log_handler.error("Command [%s] is lack of arguments" % command) + raise VerifyFailure("commands input is not corrected") + continue + dts_command = {} + + m = re.match(cmd_fmt, args[0]) + if m: + cmds = m.group(1).split(",") + shell_cmd = "" + for cmd in cmds: + shell_cmd += cmd + shell_cmd += " " + dts_command["command"] = shell_cmd[:-1] + else: + dts_command["command"] = args[0] + if args[1] == "tester": + dts_command["host"] = "tester" + else: + dts_command["host"] = "dut" + if args[2] == "post-init": + dts_command["stage"] = "post-init" + else: + dts_command["stage"] = "pre-init" + if args[3] == "ignore": + dts_command["verify"] = False + else: + dts_command["verify"] = True + + dts_commands.append(dts_command) + + return dts_commands + + +def dts_run_commands(crb, dts_commands): + """ + Run dts input commands + """ + for dts_command in dts_commands: + command = dts_command["command"] + if dts_command["host"] in crb.NAME: + if crb.stage == dts_command["stage"]: + ret = crb.send_expect(command, expected="# ", verify=True) + if type(ret) is int: + log_handler.error("[%s] return failure" % command) + if dts_command["verify"] is True: + raise VerifyFailure("Command execution failed") + + +def get_project_obj(project_name, super_class, crbInst, serializer, dut_id): + """ + Load project module and return crb instance. + """ + project_obj = None + PROJECT_MODULE_PREFIX = "project_" + try: + _project_name = PROJECT_MODULE_PREFIX + project_name + project_module = __import__( + "framework." + _project_name, fromlist=[_project_name] + ) + + for project_subclassname, project_subclass in get_subclasses( + project_module, super_class + ): + project_obj = project_subclass(crbInst, serializer, dut_id) + if project_obj is None: + project_obj = super_class(crbInst, serializer, dut_id) + except Exception as e: + log_handler.info("LOAD PROJECT MODULE INFO: " + str(e)) + project_obj = super_class(crbInst, serializer, dut_id) + + return project_obj + + +def dts_log_testsuite(duts, tester, suite_obj, log_handler, test_classname): + """ + Change to SUITE self logger handler. + """ + log_handler.config_suite(test_classname, "dts") + tester.logger.config_suite(test_classname, "tester") + if hasattr(tester, "logger_alt"): + tester.logger_alt.config_suite(test_classname, "tester") + if hasattr(tester, "logger_scapy"): + tester.logger_scapy.config_suite(test_classname, "tester") + + for dutobj in duts: + dutobj.logger.config_suite(test_classname, "dut") + dutobj.test_classname = test_classname + + try: + if tester.it_uses_external_generator(): + if ( + tester.is_pktgen + and hasattr(tester, "pktgen") + and getattr(tester, "pktgen") + ): + tester.pktgen.logger.config_suite(test_classname, "pktgen") + except Exception as ex: + pass + + +def dts_log_execution(duts, tester, log_handler): + """ + Change to DTS default logger handler. + """ + log_handler.config_execution("dts") + tester.logger.config_execution("tester") + + for dutobj in duts: + dutobj.logger.config_execution( + "dut" + settings.LOG_NAME_SEP + "%s" % dutobj.crb["My IP"] + ) + + try: + if tester.it_uses_external_generator(): + if ( + tester.is_pktgen + and hasattr(tester, "pktgen") + and getattr(tester, "pktgen") + ): + tester.pktgen.logger.config_execution("pktgen") + except Exception as ex: + pass + + +def dts_crbs_init( + crbInsts, skip_setup, read_cache, project, base_dir, serializer, virttype +): + """ + Create dts dut/tester instance and initialize them. + """ + duts = [] + + serializer.set_serialized_filename( + settings.FOLDERS["Output"] + "/.%s.cache" % crbInsts[0]["IP"] + ) + serializer.load_from_file() + + testInst = copy.copy(crbInsts[0]) + testInst["My IP"] = crbInsts[0]["tester IP"] + tester = get_project_obj(project, Tester, testInst, serializer, dut_id=0) + + dut_id = 0 + for crbInst in crbInsts: + dutInst = copy.copy(crbInst) + dutInst["My IP"] = crbInst["IP"] + dutobj = get_project_obj(project, Dut, dutInst, serializer, dut_id=dut_id) + duts.append(dutobj) + dut_id += 1 + + dts_log_execution(duts, tester, log_handler) + + tester.duts = duts + show_speedup_options_messages(read_cache, skip_setup) + tester.set_speedup_options(read_cache, skip_setup) + try: + tester.init_ext_gen() + except Exception as e: + log_handler.error(str(e)) + tester.close() + for dutobj in duts: + dutobj.close() + raise e + + nic = settings.load_global_setting(settings.HOST_NIC_SETTING) + for dutobj in duts: + dutobj.tester = tester + dutobj.setup_virtenv(virttype) + dutobj.set_speedup_options(read_cache, skip_setup) + dutobj.set_directory(base_dir) + # save execution nic setting + dutobj.set_nic_type(nic) + + return duts, tester + + +def dts_crbs_exit(duts, tester): + """ + Call dut and tester exit function after execution finished + """ + for dutobj in duts: + dutobj.crb_exit() + + tester.crb_exit() + + +def dts_run_prerequisties(duts, tester, pkgName, patch, dts_commands, serializer): + """ + Run dts prerequisties function. + """ + try: + dts_run_commands(tester, dts_commands) + tester.prerequisites() + dts_run_commands(tester, dts_commands) + except Exception as ex: + log_handler.error(" PREREQ EXCEPTION " + traceback.format_exc()) + log_handler.info("CACHE: Discarding cache.") + serializer.discard_cache() + settings.report_error("TESTER_SETUP_ERR") + return False + + try: + for dutobj in duts: + dts_run_commands(dutobj, dts_commands) + dutobj.set_package(pkgName, patch) + dutobj.prerequisites() + dts_run_commands(dutobj, dts_commands) + + serializer.save_to_file() + except Exception as ex: + log_handler.error(" PREREQ EXCEPTION " + traceback.format_exc()) + result.add_failed_dut(duts[0], str(ex)) + log_handler.info("CACHE: Discarding cache.") + serializer.discard_cache() + settings.report_error("DUT_SETUP_ERR") + return False + + +def dts_run_target(duts, tester, targets, test_suites, subtitle): + """ + Run each target in execution targets. + """ + for target in targets: + log_handler.info("\nTARGET " + target) + result.target = target + + try: + drivername = settings.load_global_setting(settings.HOST_DRIVER_SETTING) + if drivername == "": + for dutobj in duts: + dutobj.set_target(target, bind_dev=False) + else: + for dutobj in duts: + dutobj.set_target(target) + except AssertionError as ex: + log_handler.error(" TARGET ERROR: " + str(ex)) + settings.report_error("DPDK_BUILD_ERR") + result.add_failed_target(result.dut, target, str(ex)) + continue + except Exception as ex: + settings.report_error("GENERIC_ERR") + log_handler.error(" !!! DEBUG IT: " + traceback.format_exc()) + result.add_failed_target(result.dut, target, str(ex)) + continue + + dts_run_suite(duts, tester, test_suites, target, subtitle) + + tester.restore_interfaces() + + for dutobj in duts: + dutobj.stop_ports() + dutobj.restore_interfaces() + dutobj.restore_modules() + + +def dts_run_suite(duts, tester, test_suites, target, subtitle): + """ + Run each suite in test suite list. + """ + for suite_name in test_suites: + try: + # check whether config the test cases + append_requested_case_list = None + if ":" in suite_name: + case_list = suite_name[suite_name.find(":") + 1 :] + append_requested_case_list = case_list.split("\\") + suite_name = suite_name[: suite_name.find(":")] + result.test_suite = suite_name + _suite_full_name = "TestSuite_" + suite_name + suite_module = __import__( + "tests." + _suite_full_name, fromlist=[_suite_full_name] + ) + for test_classname, test_class in get_subclasses(suite_module, TestCase): + + suite_obj = test_class(duts, tester, target, suite_name) + suite_obj.init_log() + suite_obj.set_requested_cases(requested_tests) + suite_obj.set_requested_cases(append_requested_case_list) + suite_obj.set_check_inst(check=check_case_inst) + suite_obj.set_subtitle(subtitle) + result.nic = suite_obj.nic + + dts_log_testsuite(duts, tester, suite_obj, log_handler, test_classname) + + log_handler.info("\nTEST SUITE : " + test_classname) + log_handler.info("NIC : " + result.nic) + + if suite_obj.execute_setup_all(): + suite_obj.execute_test_cases() + + # save suite cases result + result.copy_suite(suite_obj.get_result()) + + log_handler.info("\nTEST SUITE ENDED: " + test_classname) + dts_log_execution(duts, tester, log_handler) + except VerifyFailure: + settings.report_error("SUITE_EXECUTE_ERR") + log_handler.error(" !!! DEBUG IT: " + traceback.format_exc()) + except KeyboardInterrupt: + # stop/save result/skip execution + log_handler.error(" !!! STOPPING DTS") + break + except Exception as e: + settings.report_error("GENERIC_ERR") + log_handler.error(str(e)) + finally: + try: + suite_obj.execute_tear_downall() + except Exception as e: + settings.report_error("GENERIC_ERR") + log_handler.error(str(e)) + try: + save_all_results() + except Exception as e: + settings.report_error("GENERIC_ERR") + log_handler.error(str(e)) + + +def run_all( + config_file, + pkgName, + git, + patch, + skip_setup, + read_cache, + project, + suite_dir, + test_cases, + base_dir, + output_dir, + verbose, + virttype, + debug, + debugcase, + re_run, + commands, + subtitle, + update_expected, + asan, +): + """ + Main process of DTS, it will run all test suites in the config file. + """ + + global requested_tests + global result + global excel_report + global json_report + global stats_report + global log_handler + global check_case_inst + + # check the python version of the server that run dts + check_dts_python_version() + + # save global variable + serializer = Serializer() + + # load check/support case lists + check_case_inst = CheckCase() + + # prepare the output folder + if output_dir == "": + output_dir = settings.FOLDERS["Output"] + + # prepare ASan test + ASanTestProcess.test_prepare(asan, output_dir) + + if not os.path.exists(output_dir): + os.mkdir(output_dir) + + # enable debug mode + if debug is True: + settings.save_global_setting(settings.DEBUG_SETTING, "yes") + if debugcase is True: + settings.save_global_setting(settings.DEBUG_CASE_SETTING, "yes") + + # enable update-expected + if update_expected is True: + settings.save_global_setting(settings.UPDATE_EXPECTED, "yes") + + # init log_handler handler + if verbose is True: + logger.set_verbose() + + re_run = int(re_run) + if re_run < 0: + re_run = 0 + + logger.log_dir = output_dir + log_handler = getLogger("dts") + log_handler.config_execution("dts") + + # run designated test case + requested_tests = test_cases + + # Read config file + dts_cfg_folder = settings.load_global_setting(settings.DTS_CFG_FOLDER) + if dts_cfg_folder != "": + config_file = dts_cfg_folder + os.sep + config_file + + config = configparser.SafeConfigParser() + load_cfg = config.read(config_file) + if len(load_cfg) == 0: + raise ConfigParseException(config_file) + + # parse commands + dts_commands = dts_parse_commands(commands) + + os.environ["TERM"] = "dumb" + + # change rst output folder + rst.path2Result = output_dir + + # report objects + excel_report = ExcelReporter(output_dir + "/test_results.xls") + json_report = JSONReporter(output_dir + "/test_results.json") + stats_report = StatsReporter(output_dir + "/statistics.txt") + result = Result() + + crbs_conf = CrbsConf() + crbs = crbs_conf.load_crbs_config() + + # for all Execution sections + for section in config.sections(): + crbInsts = list() + dts_parse_param(config, section, log_handler) + + # verify if the delimiter is good if the lists are vertical + duts, targets, test_suites = dts_parse_config(config, section) + for dut in duts: + log_handler.info("\nDUT " + dut) + + # look up in crbs - to find the matching IP + for dut in duts: + for crb in crbs: + if crb["section"] == dut: + crbInsts.append(crb) + break + + # only run on the dut in known crbs + if len(crbInsts) == 0: + log_handler.error(" SKIP UNKNOWN CRB") + continue + + result.dut = duts[0] + + # init global lock + create_parallel_locks(len(duts)) + + # init dut, tester crb + duts, tester = dts_crbs_init( + crbInsts, skip_setup, read_cache, project, base_dir, serializer, virttype + ) + tester.set_re_run(re_run) + # register exit action + atexit.register(quit_execution, duts, tester) + + check_case_inst.check_dut(duts[0]) + + # Run DUT prerequisites + if ( + dts_run_prerequisties( + duts, tester, pkgName, patch, dts_commands, serializer + ) + is False + ): + dts_crbs_exit(duts, tester) + continue + result.kdriver = duts[0].nic.default_driver + "-" + duts[0].nic.driver_version + result.firmware = duts[0].nic.firmware + result.package = ( + duts[0].nic.pkg["type"] + " " + duts[0].nic.pkg["version"] + if duts[0].nic.pkg + else None + ) + result.driver = settings.load_global_setting(settings.HOST_DRIVER_SETTING) + result.dpdk_version = duts[0].dpdk_version + dts_run_target(duts, tester, targets, test_suites, subtitle) + + dts_crbs_exit(duts, tester) + + save_all_results() + + # process ASan test report + ASanTestProcess.test_process() + + +def show_speedup_options_messages(read_cache, skip_setup): + if read_cache: + log_handler.info("CACHE: All configuration will be read from cache.") + else: + log_handler.info("CACHE: Cache will not be read.") + + if skip_setup: + log_handler.info("SKIP: Skipping DPDK setup.") + else: + log_handler.info("SKIP: The DPDK setup steps will be executed.") + + +def save_all_results(): + """ + Save all result to files. + """ + excel_report.save(result) + json_report.save(result) + stats_report.save(result) + + +def quit_execution(duts, tester): + """ + Close session to DUT and tester before quit. + Return exit status when failure occurred. + """ + # close all nics + for dutobj in duts: + if getattr(dutobj, "ports_info", None) and dutobj.ports_info: + for port_info in dutobj.ports_info: + netdev = port_info["port"] + netdev.close() + # close all session + dutobj.close() + if tester is not None: + tester.close() + log_handler.info("DTS ended") + + # return value + settings.exit_error() From patchwork Wed Apr 6 14:55:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109222 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3A6F9A0507; Wed, 6 Apr 2022 16:57:23 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 09AFB4288C; Wed, 6 Apr 2022 16:56:30 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 7966842873 for ; Wed, 6 Apr 2022 16:56:26 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id C3E001B1F4B; Wed, 6 Apr 2022 16:56:25 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7-Qo93EohgFb; Wed, 6 Apr 2022 16:56:24 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id E195B1B1F4E; Wed, 6 Apr 2022 16:56:10 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 08/15] dts: merge DTS framework/exception.py to DPDK Date: Wed, 6 Apr 2022 14:55:59 +0000 Message-Id: <20220406145606.2913834-9-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/exception.py | 148 +++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 dts/framework/exception.py diff --git a/dts/framework/exception.py b/dts/framework/exception.py new file mode 100644 index 0000000000..fb0fa72e42 --- /dev/null +++ b/dts/framework/exception.py @@ -0,0 +1,148 @@ +""" +User-defined exceptions used across the framework. +""" +from typing import Any + + +class TimeoutException(Exception): + + """ + Command execution timeout. + """ + + def __init__(self, command, output): + self.command = command + self.output = output + + def __str__(self): + msg = "TIMEOUT on %s" % (self.command) + return msg + + def get_output(self): + return self.output + + +class VerifyFailure(Exception): + + """ + To be used within the test cases to verify if a command output + is as it was expected. + """ + + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +class VerifySkip(Exception): + + """ + To be used within the test cases to verify if case should be skipped. + """ + + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +class SSHConnectionException(Exception): + + """ + SSH connection error. + """ + + def __init__(self, host): + self.host = host + + def __str__(self): + return "Error trying to connect with %s" % self.host + + +class SSHSessionDeadException(Exception): + + """ + SSH session is not alive. + It can no longer be used. + """ + + def __init__(self, host): + self.host = host + + def __str__(self): + return "SSH session with %s has been dead" % self.host + + +class ParameterInvalidException(Exception): + pass + + +class StartVMFailedException(Exception): + + """ + Start VM failed. + """ + + def __init__(self, error): + self.error = error + + def __str__(self): + return repr(self.error) + + +class ConfigParseException(Exception): + + """ + Configuration file parse failure exception. + """ + + def __init__(self, conf_file): + self.config = conf_file + + def __str__(self): + return "Faile to parse config file [%s]" % (self.config) + + +class VirtConfigParseException(Exception): + pass + + +class PortConfigParseException(Exception): + pass + + +class VirtConfigParamException(Exception): + + """ + Virtualization param execution exception. + """ + + def __init__(self, param): + self.param = param + + def __str__(self): + return "Faile to execute param [%s]" % (self.param) + + +class VirtDutConnectException(Exception): + pass + + +class VirtDutInitException(Exception): + def __init__(self, vm_dut): + self.vm_dut = vm_dut + + +class VirtDeviceCreateException(Exception): + pass + + +class VirtVmOperationException(Exception): + pass + + +class VirtHostPrepareException(Exception): + pass From patchwork Wed Apr 6 14:56:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109224 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DBF85A0507; Wed, 6 Apr 2022 16:57:44 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 835EF4289F; Wed, 6 Apr 2022 16:56:32 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 716CD42883 for ; Wed, 6 Apr 2022 16:56:28 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id C8CFA1B1F4D; Wed, 6 Apr 2022 16:56:27 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 92zJ0mnBXaLV; Wed, 6 Apr 2022 16:56:26 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 52E2B1B1F57; Wed, 6 Apr 2022 16:56:11 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 09/15] dts: merge DTS framework/logger.py to DPDK Date: Wed, 6 Apr 2022 14:56:00 +0000 Message-Id: <20220406145606.2913834-10-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/logger.py | 474 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 dts/framework/logger.py diff --git a/dts/framework/logger.py b/dts/framework/logger.py new file mode 100644 index 0000000000..576a51dcf3 --- /dev/null +++ b/dts/framework/logger.py @@ -0,0 +1,474 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import inspect +import logging +import os +import re +import sys + +from .settings import DTS_PARALLEL_SETTING, FOLDERS, LOG_NAME_SEP, load_global_setting +from .utils import RED + +""" +DTS logger module with several log level. DTS framework and TestSuite log +will saved into different log files. +""" +verbose = False + +logging.DTS_DUT_CMD = logging.INFO + 1 +logging.DTS_DUT_OUTPUT = logging.DEBUG + 1 +logging.DTS_DUT_RESULT = logging.WARNING + 1 + +logging.DTS_TESTER_CMD = logging.INFO + 2 +logging.DTS_TESTER_OUTPUT = logging.DEBUG + 2 +logging.DTS_TESTER_RESULT = logging.WARNING + 2 + +logging.SUITE_DUT_CMD = logging.INFO + 3 +logging.SUITE_DUT_OUTPUT = logging.DEBUG + 3 + +logging.SUITE_TESTER_CMD = logging.INFO + 4 +logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4 + +logging.DTS_VIRTDUT_CMD = logging.INFO + 6 +logging.DTS_VIRTDUT_OUTPUT = logging.DEBUG + 6 + +logging.DTS_PKTGEN_CMD = logging.INFO + 7 +logging.DTS_PKTGEN_OUTPUT = logging.DEBUG + 7 + +logging.addLevelName(logging.DTS_DUT_CMD, "DTS_DUT_CMD") +logging.addLevelName(logging.DTS_DUT_OUTPUT, "DTS_DUT_OUTPUT") +logging.addLevelName(logging.DTS_DUT_RESULT, "DTS_DUT_RESULT") + +logging.addLevelName(logging.DTS_TESTER_CMD, "DTS_TESTER_CMD") +logging.addLevelName(logging.DTS_TESTER_OUTPUT, "DTS_TESTER_OUTPUT") +logging.addLevelName(logging.DTS_TESTER_RESULT, "DTS_TESTER_RESULT") + +logging.addLevelName(logging.DTS_VIRTDUT_CMD, "VIRTDUT_CMD") +logging.addLevelName(logging.DTS_VIRTDUT_OUTPUT, "VIRTDUT_OUTPUT") + +logging.addLevelName(logging.SUITE_DUT_CMD, "SUITE_DUT_CMD") +logging.addLevelName(logging.SUITE_DUT_OUTPUT, "SUITE_DUT_OUTPUT") + +logging.addLevelName(logging.SUITE_TESTER_CMD, "SUITE_TESTER_CMD") +logging.addLevelName(logging.SUITE_TESTER_OUTPUT, "SUITE_TESTER_OUTPUT") + +logging.addLevelName(logging.DTS_PKTGEN_CMD, "DTS_PKTGEN_CMD") +logging.addLevelName(logging.DTS_PKTGEN_OUTPUT, "DTS_PKTGEN_OUTPUT") + +date_fmt = "%d/%m/%Y %H:%M:%S" +RESET_COLOR = "\033[0m" +stream_fmt = "%(color)s%(name)30s: %(message)s" + RESET_COLOR +log_dir = None + +# List for saving all using loggers +global Loggers +Loggers = [] + + +def set_verbose(): + global verbose + verbose = True + + +class BaseLoggerAdapter(logging.LoggerAdapter): + """ + Upper layer of original logging module. + """ + + def dts_dut_cmd(self, msg, *args, **kwargs): + self.log(logging.DTS_DUT_CMD, msg, *args, **kwargs) + + def dts_dut_output(self, msg, *args, **kwargs): + self.log(logging.DTS_DUT_OUTPUT, msg, *args, **kwargs) + + def dts_dut_result(self, msg, *args, **kwargs): + self.log(logging.DTS_DUT_RESULT, msg, *args, **kwargs) + + def dts_tester_cmd(self, msg, *args, **kwargs): + self.log(logging.DTS_TESTER_CMD, msg, *args, **kwargs) + + def dts_tester_output(self, msg, *args, **kwargs): + self.log(logging.DTS_TESTER_CMD, msg, *args, **kwargs) + + def dts_tester_result(self, msg, *args, **kwargs): + self.log(logging.DTS_TESTER_RESULT, msg, *args, **kwargs) + + def suite_dut_cmd(self, msg, *args, **kwargs): + self.log(logging.SUITE_DUT_CMD, msg, *args, **kwargs) + + def suite_dut_output(self, msg, *args, **kwargs): + self.log(logging.SUITE_DUT_OUTPUT, msg, *args, **kwargs) + + def suite_tester_cmd(self, msg, *args, **kwargs): + self.log(logging.SUITE_TESTER_CMD, msg, *args, **kwargs) + + def suite_tester_output(self, msg, *args, **kwargs): + self.log(logging.SUITE_TESTER_OUTPUT, msg, *args, **kwargs) + + def dts_virtdut_cmd(self, msg, *args, **kwargs): + self.log(logging.DTS_VIRTDUT_CMD, msg, *args, **kwargs) + + def dts_virtdut_output(self, msg, *args, **kwargs): + self.log(logging.DTS_VIRTDUT_OUTPUT, msg, *args, **kwargs) + + def dts_pktgen_cmd(self, msg, *args, **kwargs): + self.log(logging.DTS_PKTGEN_CMD, msg, *args, **kwargs) + + def dts_pktgen_output(self, msg, *args, **kwargs): + self.log(logging.DTS_PKTGEN_OUTPUT, msg, *args, **kwargs) + + +class ColorHandler(logging.StreamHandler): + """ + Color of DTS log format. + """ + + LEVEL_COLORS = { + logging.DEBUG: "", # SYSTEM + logging.DTS_DUT_OUTPUT: "\033[00;37m", # WHITE + logging.DTS_TESTER_OUTPUT: "\033[00;37m", # WHITE + logging.SUITE_DUT_OUTPUT: "\033[00;37m", # WHITE + logging.SUITE_TESTER_OUTPUT: "\033[00;37m", # WHITE + logging.INFO: "\033[00;36m", # CYAN + logging.DTS_DUT_CMD: "", # SYSTEM + logging.DTS_TESTER_CMD: "", # SYSTEM + logging.SUITE_DUT_CMD: "", # SYSTEM + logging.SUITE_TESTER_CMD: "", # SYSTEM + logging.DTS_PKTGEN_CMD: "", # SYSTEM + logging.DTS_PKTGEN_OUTPUT: "", # SYSTEM + logging.DTS_VIRTDUT_CMD: "", # SYSTEM + logging.DTS_VIRTDUT_OUTPUT: "", # SYSTEM + logging.WARN: "\033[01;33m", # BOLD YELLOW + logging.DTS_DUT_RESULT: "\033[01;34m", # BOLD BLUE + logging.DTS_TESTER_RESULT: "\033[01;34m", # BOLD BLUE + logging.ERROR: "\033[01;31m", # BOLD RED + logging.CRITICAL: "\033[01;31m", # BOLD RED + } + + def format(self, record): + record.__dict__["color"] = self.LEVEL_COLORS[record.levelno] + return logging.StreamHandler.format(self, record) + + +class DTSLOG(BaseLoggerAdapter): + """ + DTS log class for framework and testsuite. + """ + + def __init__(self, logger, crb="suite"): + global log_dir + filename = inspect.stack()[1][1][:-3] + + self.error_lvl = logging.ERROR + self.warn_lvl = logging.WARNING + self.info_lvl = logging.INFO + self.debug_lvl = logging.DEBUG + + if log_dir is None: + self.log_path = os.getcwd() + "/../" + FOLDERS["Output"] + else: + self.log_path = ( + log_dir # log dir should contain tag/crb global value and mod in dts + ) + self.dts_log = "dts.log" + + self.logger = logger + self.logger.setLevel(logging.DEBUG) + + self.crb = crb + super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb)) + + self.fh = None + self.ch = None + + # add default log file + fh = logging.FileHandler(self.log_path + "/" + self.dts_log) + ch = ColorHandler() + self.__log_handler(fh, ch) + + def __log_handler(self, fh, ch): + """ + Config stream handler and file handler. + """ + if load_global_setting(DTS_PARALLEL_SETTING) == "yes": + message_fmt = "%(asctime)s %(name)30s %(threadName)s: %(message)s" + else: + message_fmt = "%(asctime)s %(name)30s: %(message)s" + + fh.setFormatter(logging.Formatter(message_fmt, date_fmt)) + ch.setFormatter(logging.Formatter(stream_fmt, date_fmt)) + + fh.setLevel(logging.DEBUG) # file handler default level + global verbose + if verbose is True: + ch.setLevel(logging.DEBUG) + else: + ch.setLevel(logging.INFO) # console handler default level + + self.logger.addHandler(fh) + self.logger.addHandler(ch) + + if self.fh is not None: + self.logger.removeHandler(self.fh) + if self.ch is not None: + self.logger.removeHandler(self.ch) + + self.fh = fh + self.ch = ch + + def warning(self, message): + """ + DTS warnning level log function. + """ + self.logger.log(self.warn_lvl, message) + + def info(self, message): + """ + DTS information level log function. + """ + self.logger.log(self.info_lvl, message) + + def error(self, message): + """ + DTS error level log function. + """ + self.logger.log(self.error_lvl, message) + + def debug(self, message): + """ + DTS debug level log function. + """ + self.logger.log(self.debug_lvl, message) + + def set_logfile_path(self, path): + """ + Configure the log file path. + """ + self.log_path = path + + def set_stream_level(self, lvl): + """ + Configure the stream level, logger level >= stream level will be + output on the screen. + """ + self.ch.setLevel(lvl) + + def set_logfile_level(self, lvl): + """ + Configure the file handler level, logger level >= logfile level will + be saved into log file. + """ + self.fh.setLevel(lvl) + + def config_execution(self, crb): + """ + Reconfigure stream&logfile level and reset info,debug,warn level. + """ + log_file = self.log_path + "/" + self.dts_log + fh = logging.FileHandler(log_file) + ch = ColorHandler() + self.__log_handler(fh, ch) + + if crb.startswith("dut"): + self.info_lvl = logging.DTS_DUT_CMD + self.debug_lvl = logging.DTS_DUT_OUTPUT + self.warn_lvl = logging.DTS_DUT_RESULT + elif crb.startswith("tester"): + self.info_lvl = logging.DTS_TESTER_CMD + self.debug_lvl = logging.DTS_TESTER_OUTPUT + self.warn_lvl = logging.DTS_TESTER_RESULT + elif crb.startswith("pktgen"): + self.info_lvl = logging.DTS_PKTGEN_CMD + self.debug_lvl = logging.DTS_PKTGEN_OUTPUT + elif crb.startswith("virtdut"): + self.info_lvl = logging.DTS_VIRTDUT_CMD + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT + else: + self.error_lvl = logging.ERROR + self.warn_lvl = logging.WARNING + self.info_lvl = logging.INFO + self.debug_lvl = logging.DEBUG + + def config_suite(self, suitename, crb=None): + """ + Reconfigure stream&logfile level and reset info,debug level. + """ + log_file = self.log_path + "/" + suitename + ".log" + fh = logging.FileHandler(log_file) + ch = ColorHandler() + + # exit first + self.logger_exit() + + # then add handler + self.__log_handler(fh, ch) + + if crb == "dut": + self.info_lvl = logging.SUITE_DUT_CMD + self.debug_lvl = logging.SUITE_DUT_OUTPUT + elif crb == "tester": + self.info_lvl = logging.SUITE_TESTER_CMD + self.debug_lvl = logging.SUITE_TESTER_OUTPUT + elif crb == "pktgen": + self.info_lvl = logging.DTS_PKTGEN_CMD + self.debug_lvl = logging.DTS_PKTGEN_OUTPUT + elif crb == "virtdut": + self.info_lvl = logging.DTS_VIRTDUT_CMD + self.debug_lvl = logging.DTS_VIRTDUT_OUTPUT + + def logger_exit(self): + """ + Remove stream handler and logfile handler. + """ + if self.fh is not None: + self.logger.removeHandler(self.fh) + if self.ch is not None: + self.logger.removeHandler(self.ch) + + +def getLogger(name, crb="suite"): + """ + Get logger handler and if there's no handler for specified CRB will create one. + """ + global Loggers + # return saved logger + for logger in Loggers: + if logger["name"] == name and logger["crb"] == crb: + return logger["logger"] + + # return new logger + logger = DTSLOG(logging.getLogger(name), crb) + Loggers.append({"logger": logger, "name": name, "crb": crb}) + return logger + + +_TESTSUITE_NAME_FORMAT_PATTERN = r"TEST SUITE : (.*)" +_TESTSUITE_ENDED_FORMAT_PATTERN = r"TEST SUITE ENDED: (.*)" +_TESTCASE_NAME_FORMAT_PATTERN = r"Test Case (.*) Begin" +_TESTCASE_RESULT_FORMAT_PATTERN = r"Test Case (.*) Result (.*):" + + +class LogParser(object): + """ + Module for parsing saved log file, will implement later. + """ + + def __init__(self, log_path): + self.log_path = log_path + + try: + self.log_handler = open(self.log_path, "r") + except: + print(RED("Failed to logfile %s" % log_path)) + return None + + self.suite_pattern = re.compile(_TESTSUITE_NAME_FORMAT_PATTERN) + self.end_pattern = re.compile(_TESTSUITE_ENDED_FORMAT_PATTERN) + self.case_pattern = re.compile(_TESTCASE_NAME_FORMAT_PATTERN) + self.result_pattern = re.compile(_TESTCASE_RESULT_FORMAT_PATTERN) + + self.loglist = self.parse_logfile() + self.log_handler.close() + + def locate_suite(self, suite_name=None): + begin = 0 + end = len(self.loglist) + for line in self.loglist: + m = self.suite_pattern.match(list(line.values())[0]) + if m: + if suite_name is None: + begin = self.loglist.index(line) + elif suite_name == m.group(1): + begin = self.loglist.index(line) + + for line in self.loglist[begin:]: + m = self.end_pattern.match(list(line.values())[0]) + if m: + if suite_name is None: + end = self.loglist.index(line) + elif suite_name == m.group(1): + end = self.loglist.index(line) + + return self.loglist[begin : end + 1] + + def locate_case(self, case_name=None): + begin = 0 + end = len(self.loglist) + for line in self.loglist: + # only handle case log + m = self.case_pattern.match(list(line.values())[0]) + if m: + # not determine case will start from beginning + if case_name is None: + begin = self.loglist.index(line) + # start from the determined case + elif case_name == m.group(1): + begin = self.loglist.index(line) + + for line in self.loglist[begin:]: + m = self.result_pattern.match(list(line.values())[0]) + if m: + # not determine case will stop to the end + if case_name is None: + end = self.loglist.index(line) + # stop to the determined case + elif case_name == m.group(1): + end = self.loglist.index(line) + + return self.loglist[begin : end + 1] + + def __dict_log(self, lvl_name, msg): + tmp = {} + if lvl_name != "": + tmp[lvl_name] = msg + return tmp + + def parse_logfile(self): + loglist = [] + + out_type = "DTS_DUT_OUTPUT" + for line in self.log_handler: + tmp = {} + line = line.replace("\n", "") + line = line.replace("^M", "") + m = re.match("(\d{2}/\d{2}/\d{4}) (\d{2}:\d{2}:\d{2}) (.{20}): (.*)", line) + if m: + lvl_name = m.group(3).strip() + tmp = self.__dict_log(lvl_name, m.group(4)) + if "OUTPUT" in lvl_name: + out_type = lvl_name + else: + tmp[out_type] = line + + loglist.append(tmp) + + return loglist From patchwork Wed Apr 6 14:56:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109225 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 09EEEA0507; Wed, 6 Apr 2022 16:57:52 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 57C7842899; Wed, 6 Apr 2022 16:56:33 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id DB1C942867 for ; Wed, 6 Apr 2022 16:56:29 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 3CE161B1F57; Wed, 6 Apr 2022 16:56:29 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0hyC1MNS6DWt; Wed, 6 Apr 2022 16:56:26 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id C102F1B1F6C; Wed, 6 Apr 2022 16:56:11 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 10/15] dts: merge DTS framework/packet.py to DPDK Date: Wed, 6 Apr 2022 14:56:01 +0000 Message-Id: <20220406145606.2913834-11-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/packet.py | 1292 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1292 insertions(+) create mode 100644 dts/framework/packet.py diff --git a/dts/framework/packet.py b/dts/framework/packet.py new file mode 100644 index 0000000000..251f9875bf --- /dev/null +++ b/dts/framework/packet.py @@ -0,0 +1,1292 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +Generic packet create, transmit and analyze module +Base on scapy(python program for packet manipulation) +""" +import os +import random +import re +import shutil +import socket +import struct +import sys +import time +from importlib import import_module +from socket import AF_INET6 + +from scapy.contrib.lldp import LLDPDU, LLDPDUManagementAddress +from scapy.contrib.mpls import MPLS +from scapy.contrib.nsh import NSH +from scapy.layers.inet import ICMP, IP, TCP, UDP +from scapy.layers.inet6 import IPv6, IPv6ExtHdrFragment, IPv6ExtHdrRouting +from scapy.layers.l2 import ARP, GRE, Dot1Q, Ether +from scapy.layers.sctp import SCTP +from scapy.layers.vxlan import VXLAN +from scapy.packet import Raw +from scapy.sendrecv import sendp +from scapy.utils import hexstr, rdpcap, wrpcap + +from .utils import convert_int2ip, convert_ip2int, get_module_path + +# load extension layers +exec_file = os.path.realpath(__file__) +DTS_PATH = exec_file.replace("/framework/packet.py", "") + +# exec_file might be .pyc file, if so, remove 'c'. +TMP_PATH = ( + DTS_PATH[:-1] + "/output/tmp/pcap/" + if exec_file.endswith(".pyc") + else DTS_PATH + "/output/tmp/pcap/" +) +if not os.path.exists(TMP_PATH): + os.system("mkdir -p %s" % TMP_PATH) + +scapy_modules_required = { + "scapy.contrib.gtp": ["GTP_U_Header", "GTPPDUSessionContainer"], + "scapy.contrib.lldp": ["LLDPDU", "LLDPDUManagementAddress"], + "scapy.contrib.pfcp": ["PFCP"], + "scapy.contrib.nsh": ["NSH"], + "scapy.contrib.igmp": ["IGMP"], + "scapy.contrib.mpls": ["MPLS"], +} + +for m in scapy_modules_required: + try: + module = import_module(m) + for clazz in scapy_modules_required[m]: + locals().update({clazz: getattr(module, clazz)}) + except Exception as e: + print(e) + + +def get_scapy_module_impcmd(): + cmd_li = list() + for m in scapy_modules_required: + cmd_li.append(f'from {m} import {",".join(scapy_modules_required[m])}') + return ";".join(cmd_li) + + +# packet generator type should be configured later +PACKETGEN = "scapy" + +LayersTypes = { + "L2": ["ether", "vlan", "1588", "arp", "lldp", "mpls", "nsh"], + # ipv4_ext_unknown, ipv6_ext_unknown + "L3": ["ipv4", "ipv4ihl", "ipv6", "ipv4_ext", "ipv6_ext", "ipv6_ext2", "ipv6_frag"], + "L4": ["tcp", "udp", "frag", "sctp", "icmp", "nofrag"], + # The NVGRE pkt format is + # <'ether type'=0x0800 'version'=4, 'protocol'=47 'protocol type'=0x6558> + # or + # <'ether type'=0x86DD 'version'=6, 'next header'=47 'protocol type'=0x6558'> + # The GRE pkt format is + # <'ether type'=0x0800 'version'=4, 'protocol'=17 'destination port'=4789> + # or + # <'ether type'=0x86DD 'version'=6, 'next header'=17 'destination port'=4789> + "TUNNEL": ["ip", "gre", "vxlan", "nvgre", "geneve", "grenat"], + "INNER L2": ["inner_mac", "inner_vlan"], + # inner_ipv4_unknown, inner_ipv6_unknown + "INNER L3": ["inner_ipv4", "inner_ipv4_ext", "inner_ipv6", "inner_ipv6_ext"], + "INNER L4": [ + "inner_tcp", + "inner_udp", + "inner_frag", + "inner_sctp", + "inner_icmp", + "inner_nofrag", + ], + "PAYLOAD": ["raw"], +} + +# Saved background sniff process id +SNIFF_PIDS = {} + +# Saved packet generator process id +# used in pktgen or tgen +PKTGEN_PIDS = {} + +# default filter for LLDP packet +LLDP_FILTER = {"layer": "ether", "config": {"type": "not lldp"}} + + +def write_raw_pkt(pkt_str, file_name): + tmp = eval(pkt_str) + tmp = bytearray(bytes(tmp)) + with open(file_name, "wb") as w: + w.write(tmp) + w.close() + + +class scapy(object): + SCAPY_LAYERS = { + "ether": Ether(dst="ff:ff:ff:ff:ff:ff"), + "vlan": Dot1Q(), + "1588": Ether(type=0x88F7), + "arp": ARP(), + "ipv4": IP(), + "ipv4ihl": IP(ihl=10), + "ipv4_ext": IP(frag=5), + "ipv6": IPv6(src="::1"), + "ipv6_ext": IPv6(src="::1", nh=43) / IPv6ExtHdrRouting(), + "ipv6_ext2": IPv6() / IPv6ExtHdrRouting(), + "udp": UDP(), + "tcp": TCP(), + "sctp": SCTP(), + "icmp": ICMP(), + "gre": GRE(), + "raw": Raw(), + "vxlan": VXLAN(), + "nsh": NSH(), + "mpls": MPLS(), + "inner_mac": Ether(), + "inner_vlan": Dot1Q(), + "inner_ipv4": IP(), + "inner_ipv4_ext": IP(), + "inner_ipv6": IPv6(src="::1"), + "inner_ipv6_ext": IPv6(src="::1"), + "inner_tcp": TCP(), + "inner_udp": UDP(), + "inner_sctp": SCTP(), + "inner_icmp": ICMP(), + "lldp": LLDPDU() + / LLDPDUManagementAddress( + _length=6, _management_address_string_length=6, management_address=":12" + ) + / IP(), + "ip_frag": IP(frag=5), + "ipv6_frag": IPv6(src="::1") / IPv6ExtHdrFragment(), + "ip_in_ip": IP() / IP(), + "ip_in_ip_frag": IP() / IP(frag=5), + "ipv6_in_ip": IP() / IPv6(src="::1"), + "ipv6_frag_in_ip": IP() / IPv6(src="::1", nh=44) / IPv6ExtHdrFragment(), + "nvgre": GRE(key_present=1, proto=0x6558, key=0x00000100), + "geneve": "Not Implement", + } + + def __init__(self): + self.pkt = None + self.pkts = list() + + def append_pkts(self): + self.pkts.append(self.pkt) + + def update_pkts(self): + if not self.pkts: # update pkt to a null pkt list. + self.pkts.append(self.pkt) + else: + self.pkts[-1] = self.pkt + + def assign_pkt(self, pkt): + self.pkt = pkt + + def add_layers(self, layers): + self.pkt = None + for layer in layers: + if self.pkt is not None: + self.pkt = self.pkt / self.SCAPY_LAYERS[layer] + else: + self.pkt = self.SCAPY_LAYERS[layer] + + def ether( + self, pkt_layer, dst="ff:ff:ff:ff:ff:ff", src="00:00:20:00:00:00", type=None + ): + if pkt_layer.name != "Ethernet": + return + pkt_layer.dst = dst + pkt_layer.src = src + if type is not None: + pkt_layer.type = type + + def vlan(self, pkt_layer, vlan, prio=0, type=None): + if pkt_layer.name != "802.1Q": + return + pkt_layer.vlan = int(vlan) + pkt_layer.prio = prio + if type is not None: + pkt_layer.type = type + + def strip_vlan(self, element, p_index=0): + value = None + + if self.pkts[p_index].haslayer("Dot1Q") == 0: + return None + + if element == "vlan": + value = int(str(self.pkts[p_index][Dot1Q].vlan)) + return value + + def strip_layer2(self, element, p_index=0): + value = None + layer = self.pkts[p_index].getlayer(0) + if layer is None: + return None + + if element == "src": + value = layer.src + elif element == "dst": + value = layer.dst + elif element == "type": + value = layer.type + + return value + + def strip_layer3(self, element, p_index=0): + value = None + layer = self.pkts[p_index].getlayer(1) + if layer is None: + return None + + if element == "src": + value = layer.src + elif element == "dst": + value = layer.dst + else: + value = layer.getfieldval(element) + + return value + + def strip_layer4(self, element, p_index=0): + value = None + layer = self.pkts[p_index].getlayer(2) + if layer is None: + return None + + if element == "src": + value = layer.sport + elif element == "dst": + value = layer.dport + else: + value = layer.getfieldval(element) + + return value + + def ipv4( + self, + pkt_layer, + frag=0, + src="127.0.0.1", + proto=None, + tos=0, + dst="127.0.0.1", + chksum=None, + len=None, + version=4, + flags=None, + ihl=None, + ttl=64, + id=1, + options=None, + ): + pkt_layer.frag = frag + pkt_layer.src = src + if proto is not None: + pkt_layer.proto = proto + pkt_layer.tos = tos + pkt_layer.dst = dst + if chksum is not None: + pkt_layer.chksum = chksum + if len is not None: + pkt_layer.len = len + pkt_layer.version = version + if flags is not None: + pkt_layer.flags = flags + if ihl is not None: + pkt_layer.ihl = ihl + pkt_layer.ttl = ttl + pkt_layer.id = id + if options is not None: + pkt_layer.options = options + + def ipv6( + self, + pkt_layer, + version=6, + tc=0, + fl=0, + plen=0, + nh=0, + hlim=64, + src="::1", + dst="::1", + ): + """ + Configure IPv6 protocol. + """ + pkt_layer.version = version + pkt_layer.tc = tc + pkt_layer.fl = fl + if plen: + pkt_layer.plen = plen + if nh: + pkt_layer.nh = nh + pkt_layer.src = src + pkt_layer.dst = dst + pkt_layer.hlim = hlim + + def tcp(self, pkt_layer, src=53, dst=53, flags=0, len=None, chksum=None): + pkt_layer.sport = src + pkt_layer.dport = dst + if flags is not None: + pkt_layer.flags = flags + if len is not None: + pkt_layer.len = len + if chksum is not None: + pkt_layer.chksum = chksum + + def udp(self, pkt_layer, src=53, dst=53, len=None, chksum=None): + pkt_layer.sport = src + pkt_layer.dport = dst + if len is not None: + pkt_layer.len = len + if chksum is not None: + pkt_layer.chksum = chksum + + def sctp(self, pkt_layer, src=53, dst=53, tag=None, len=None, chksum=None): + pkt_layer.sport = src + pkt_layer.dport = dst + if tag is not None: + pkt_layer.tag = tag + if len is not None: + pkt_layer.len = len + if chksum is not None: + pkt_layer.chksum = chksum + + def raw(self, pkt_layer, payload=None): + if payload is not None: + pkt_layer.load = "" + for hex1, hex2 in payload: + pkt_layer.load += struct.pack("=B", int("%s%s" % (hex1, hex2), 16)) + + def gre(self, pkt_layer, proto=None): + if proto is not None: + pkt_layer.proto = proto + + def vxlan(self, pkt_layer, vni=0): + pkt_layer.vni = vni + + def nsh( + self, + pkt_layer, + ver=0, + oam=0, + critical=0, + reserved=0, + len=0, + mdtype=1, + nextproto=3, + nsp=0x0, + nsi=1, + npc=0x0, + nsc=0x0, + spc=0x0, + ssc=0x0, + ): + pkt_layer.Ver = ver + pkt_layer.OAM = oam + pkt_layer.Critical = critical + pkt_layer.Reserved = reserved + if len != 0: + pkt_layer.Len = len + pkt_layer.MDType = mdtype + pkt_layer.NextProto = nextproto + pkt_layer.NSP = nsp + pkt_layer.NSI = nsi + if mdtype == 1: + pkt_layer.NPC = npc + pkt_layer.NSC = nsc + pkt_layer.SPC = spc + pkt_layer.SSC = ssc + + def mpls(self, pkt_layer, label=0, cos=0, s=0, ttl=64): + pkt_layer.label = label + pkt_layer.cos = cos + pkt_layer.s = s + pkt_layer.ttl = ttl + + +class Packet(object): + """ + Module for config/create packet + Based on scapy module + Usage: assign_layers([layers list]) + config_layer('layername', {layer config}) + ... + """ + + def_packet = { + "TIMESYNC": {"layers": ["ether", "raw"], "cfgload": False}, + "ARP": {"layers": ["ether", "arp"], "cfgload": False}, + "LLDP": {"layers": ["ether", "lldp"], "cfgload": False}, + "IP_RAW": {"layers": ["ether", "ipv4", "raw"], "cfgload": True}, + "TCP": {"layers": ["ether", "ipv4", "tcp", "raw"], "cfgload": True}, + "UDP": {"layers": ["ether", "ipv4", "udp", "raw"], "cfgload": True}, + "VLAN_UDP": { + "layers": ["ether", "vlan", "ipv4", "udp", "raw"], + "cfgload": True, + }, + "SCTP": {"layers": ["ether", "ipv4", "sctp", "raw"], "cfgload": True}, + "IPv6_TCP": {"layers": ["ether", "ipv6", "tcp", "raw"], "cfgload": True}, + "IPv6_UDP": {"layers": ["ether", "ipv6", "udp", "raw"], "cfgload": True}, + "IPv6_SCTP": {"layers": ["ether", "ipv6", "sctp", "raw"], "cfgload": True}, + } + + def __init__(self, pkt_str=None, **options): + """ + pkt_type: description of packet type + defined in def_packet + args: specify a packet with a string explicitly, will ignore options + options: special option for Packet module + pkt_len: length of network packet + ran_payload: whether payload of packet is random + pkt_file: + pkt_gen: packet generator type + now only support scapy + """ + self.pkt_opts = options + self.pkt_layers = [] + + if "pkt_gen" in list(self.pkt_opts.keys()): + if self.pkt_opts["pkt_gen"] == "scapy": + self.pktgen = scapy() + else: + print("Not support other pktgen yet!!!") + else: + self.pktgen = scapy() + + if pkt_str is not None and type(pkt_str) == str: + self._scapy_str_to_pkt(pkt_str) + elif len(options) != 0: + self._add_pkt(self.pkt_opts) + if self.pktgen.pkt is not None: + self.pktgen.append_pkts() + + def __len__(self): + return len(self.pktgen.pkts) + + def __getitem__(self, item): + return self.pktgen.pkts[item] + + def _add_pkt(self, options): + """ + :param options: packt configuration, dictionary type + :return: + """ + self.pkt_len = 64 + self.pkt_type = "UDP" + if "pkt_type" in list(options.keys()): + self.pkt_type = options["pkt_type"] + + if self.pkt_type in list(self.def_packet.keys()): + self.pkt_layers = self.def_packet[self.pkt_type]["layers"] + self.pkt_cfgload = self.def_packet[self.pkt_type]["cfgload"] + if "IPv6" in self.pkt_type: + self.pkt_len = 128 + else: + self._load_pkt_layers() + + if "pkt_len" in list(options.keys()): + self.pkt_len = options["pkt_len"] + + self._load_assign_layers() + + def _load_assign_layers(self): + # assign layer + self.assign_layers() + + # config special layer + self.config_def_layers() + + # handle packet options + payload_len = self.pkt_len - len(self.pktgen.pkt) - 4 + + # if raw data has not been configured and payload should configured + if hasattr(self, "configured_layer_raw") is False and self.pkt_cfgload is True: + payload = [] + raw_confs = {} + if "ran_payload" in list(self.pkt_opts.keys()): + for loop in range(payload_len): + payload.append("%02x" % random.randrange(0, 255)) + else: + for loop in range(payload_len): + payload.append("58") # 'X' + + raw_confs["payload"] = payload + self.config_layer("raw", raw_confs) + + def _scapy_str_to_pkt(self, scapy_str): + """ + + :param scapy_str: packet str, eg. 'Ether()/IP()/UDP()' + :return: None + """ + layer_li = [re.sub("\(.*?\)", "", i) for i in scapy_str.split("/")] + self.pkt_type = "_".join(layer_li) + self._load_pkt_layers() + self.pktgen.assign_pkt(scapy_str) + + def append_pkt(self, args=None, **kwargs): + """ + :param args: take str type as pkt to append + :param kwargs: take dictory type as pkt to append + :return: None + """ + if isinstance(args, str): + self._scapy_str_to_pkt(args) + elif isinstance(kwargs, dict): + self.pkt_opts = kwargs + if hasattr(self, "configured_layer_raw"): + delattr(self, "configured_layer_raw") + self._add_pkt(kwargs) + self.pktgen.append_pkts() + + def update_pkt_str(self, pkt): + self._scapy_str_to_pkt(pkt) + self.pktgen.append_pkts() + + def update_pkt_dict(self, pkt): + self.pkt_opts = pkt + if hasattr(self, "configured_layer_raw"): + delattr(self, "configured_layer_raw") + self._add_pkt(pkt) + self.pktgen.append_pkts() + + def update_pkt(self, pkts): + """ + update pkts to packet object + :param pkts: pkts to update + :type str|dict|list + :return: None + """ + self.pktgen = scapy() + self.pkt_layers = [] + if isinstance(pkts, str): + self.update_pkt_str(pkts) + elif isinstance(pkts, dict): + self.update_pkt_dict(pkts) + elif isinstance(pkts, list): + for i in pkts: + if isinstance(i, str): + try: + self.update_pkt_str(i) + except: + print(("warning: packet %s update failed" % i)) + elif isinstance(i, dict): + try: + self.update_pkt_dict(i) + except: + print(("warning: packet %s update failed" % i)) + else: + print(("packet {} is not acceptable".format(i))) + + def generate_random_pkts( + self, + dstmac=None, + pktnum=100, + random_type=None, + ip_increase=True, + random_payload=False, + options=None, + ): + """ + # generate random packets + :param dstmac: specify the dst mac + :param pktnum: packet number to generate + :param random_type: specify random packet type + :param ip_increase: auto increase ip value + :param random_payload: if True, generate random packets with random payload + :param options: packet layer configuration + :return: None + """ + + random_type = ( + ["TCP", "UDP", "IPv6_TCP", "IPv6_UDP"] + if random_type is None + else random_type + ) + options = ( + {"ip": {"src": "192.168.0.1", "dst": "192.168.1.1"}, "layers_config": []} + if options is None + else options + ) + # give a default value to ip + try: + src_ip_num = convert_ip2int(options["ip"]["src"]) + except: + src_ip_num = 0 + try: + dst_ip_num = convert_ip2int(options["ip"]["dst"]) + except: + dst_ip_num = 0 + + for i in range(pktnum): + # random the packet type + self.pkt_type = random.choice(random_type) + self.pkt_layers = self.def_packet[self.pkt_type]["layers"] + self.check_layer_config() + self.pktgen.add_layers(self.pkt_layers) + # hardcode src/dst port for some protocol may cause issue + if "TCP" in self.pkt_type: + self.config_layer("tcp", {"src": 65535, "dst": 65535}) + if "UDP" in self.pkt_type: + self.config_layer("udp", {"src": 65535, "dst": 65535}) + if "layers_config" in options: + self.config_layers(options["layers_config"]) + if dstmac: + self.config_layer("ether", {"dst": "%s" % dstmac}) + # generate auto increase dst ip packet + if ip_increase: + if "v6" in self.pkt_type: + dstip = convert_int2ip(dst_ip_num, ip_type=6) + srcip = convert_int2ip(src_ip_num, ip_type=6) + self.config_layer( + "ipv6", config={"dst": "%s" % (dstip), "src": "%s" % srcip} + ) + else: + dstip = convert_int2ip(dst_ip_num, ip_type=4) + srcip = convert_int2ip(src_ip_num, ip_type=4) + self.config_layer( + "ipv4", config={"dst": "%s" % (dstip), "src": "%s" % srcip} + ) + dst_ip_num += 1 + # generate random payload of packet + if random_payload and self.def_packet[self.pkt_type]["cfgload"]: + # TCP packet has a default flags S, packet should not load data, so set it to A if has payload + if "TCP" in self.pkt_type: + self.config_layer("tcp", {"src": 65535, "dst": 65535, "flags": "A"}) + + payload_len = random.randint(64, 100) + payload = [] + for _ in range(payload_len): + payload.append("%02x" % random.randrange(0, 255)) + self.config_layer("raw", config={"payload": payload}) + self.pktgen.append_pkts() + + def save_pcapfile(self, crb=None, filename="saved_pkts.pcap"): + """ + + :param crb: session or crb object + :param filename: location and name for packets to be saved + :return: None + """ + # save pkts to pcap file to local path, then copy to remote tester tmp directory, + if crb: + trans_path = crb.tmp_file + file_name = filename + if os.path.isabs(filename): # check if the given filename with a abs path + file_dir = os.path.dirname(filename) + out = crb.send_expect("ls -d %s" % file_dir, "# ", verify=True) + if not isinstance(out, str): + raise Exception("%s may not existed on %s" % (file_dir, crb.name)) + wrpcap(filename, self.pktgen.pkts) + trans_path = os.path.abspath(filename) + file_name = filename.split(os.path.sep)[-1] + # write packets to local tmp path $dts/ouput/tmp/pcap/ + wrpcap(TMP_PATH + file_name, self.pktgen.pkts) + # copy to remote tester tmp path /tmp/tester + crb.session.copy_file_to(TMP_PATH + file_name, trans_path) + else: + wrpcap(filename, self.pktgen.pkts) + + def read_pcapfile(self, filename, crb=None): + """ + + :param filename: packet to be read from + :param crb: session or crb object + :return: scapy type packet + """ + # read pcap file from local or remote, then append to pkts list + # if crb, read pakcet from remote server, else read from local location + if crb: + out = crb.send_expect("ls -d %s" % filename, "# ", verify=True) + if not isinstance(out, str): + raise Exception("%s may not existed on %s" % (filename, crb.name)) + crb.session.copy_file_from(filename, TMP_PATH) + p = rdpcap(TMP_PATH + filename.split(os.path.sep)[-1]) + else: + p = rdpcap(filename) + if len(p) == 0: + return None + self.pktgen.assign_pkt(p[-1]) + for i in p: + self.pktgen.pkts.append(i) + return p + + def send_pkt_bg_with_pcapfile(self, crb, tx_port="", count=1, loop=0, inter=0): + """ + send packet background with a pcap file, got an advantage in sending a large number of packets + :param crb: session or crb object + :param tx_port: ether to send packet + :param count: send times + :param loop: send packet in a loop + :param inter: interval time per packet + :return: send session + """ + if crb.name != "tester": + raise Exception("crb should be tester") + wrpcap("_", self.pktgen.pkts) + file_path = "/tmp/%s.pcap" % tx_port + scapy_session_bg = crb.prepare_scapy_env() + scapy_session_bg.copy_file_to("_", file_path) + scapy_session_bg.send_expect('pkts = rdpcap("%s")' % file_path, ">>> ") + scapy_session_bg.send_command( + 'sendp(pkts, iface="%s",count=%s,loop=%s,inter=%s)' + % (tx_port, count, loop, inter) + ) + return scapy_session_bg + + def _recompose_pkts_str(self, pkts_str): + method_pattern = re.compile("<.+?>") + method_li = method_pattern.findall(pkts_str) + for i in method_li: + pkts_str = method_pattern.sub(i.strip("<>") + "()", pkts_str, count=1) + return pkts_str + + # use the GRE to configure the nvgre package + # the field key last Byte configure the reserved1 of NVGRE, first 3 Bytes configure the TNI value of NVGRE + def transform_nvgre_layer(self, pkt_str): + tni = re.search("TNI\s*=\s*(0x)*(\d*)", pkt_str) + if tni is None: + nvgre = "GRE(key_present=1,proto=0x6558,key=0x00000100)" + else: + tni = int(tni.group(2)) + tni = tni << 8 + nvgre = "GRE(key_present=1,proto=0x6558,key=%d)" % tni + pkt_str = re.sub(r"NVGRE\(\)|NVGRE\(TNI=\s*(0x)*\d*\)", nvgre, pkt_str) + return pkt_str + + def gernerator_pkt_str(self): + pkt_str_list = [] + for p in self.pktgen.pkts: + if not isinstance(p, str): + p_str = p.command() + else: + p_str = p + # process the NVGRE + if "NVGRE" in p_str: + p_str = self.transform_nvgre_layer(p_str) + pkt_str_list.append(p_str) + return "[" + ",".join(pkt_str_list) + "]" + + def send_pkt(self, crb, tx_port="", count=1, interval=0, timeout=120): + p_str = self.gernerator_pkt_str() + pkts_str = self._recompose_pkts_str(pkts_str=p_str) + cmd = ( + "sendp(" + + pkts_str + + f',iface="{tx_port}",count={count},inter={interval},verbose=False)' + ) + if crb.name == "tester": + crb.scapy_session.send_expect(cmd, ">>> ", timeout=timeout) + elif crb.name.startswith("tester_scapy"): + crb.send_expect(cmd, ">>> ", timeout=timeout) + else: + raise Exception("crb should be tester's session and initialized") + + def send_pkt_bg(self, crb, tx_port="", count=-1, interval=0, loop=1): + if crb.name != "tester": + raise Exception("crb should be tester") + scapy_session_bg = crb.prepare_scapy_env() + p_str = self.gernerator_pkt_str() + pkts_str = self._recompose_pkts_str(pkts_str=p_str) + cmd = ( + "sendp(" + + pkts_str + + f',iface="{tx_port}",count={count},inter={interval},loop={loop},verbose=False)' + ) + scapy_session_bg.send_command(cmd) + return scapy_session_bg + + @staticmethod + def stop_send_pkt_bg(session): + # stop sending action + session.send_expect("^C", ">>> ") + + def check_layer_config(self): + """ + check the format of layer configuration + every layer should has different check function + """ + for layer in self.pkt_layers: + found = False + l_type = layer.lower() + + for types in list(LayersTypes.values()): + if l_type in types: + found = True + break + + if found is False: + self.pkt_layers.remove(l_type) + print("INVAILD LAYER TYPE [%s]" % l_type.upper()) + + def assign_layers(self, layers=None): + """ + assign layer for this packet + maybe need add check layer function + """ + if layers is not None: + self.pkt_layers = layers + + for layer in self.pkt_layers: + found = False + l_type = layer.lower() + + for types in list(LayersTypes.values()): + if l_type in types: + found = True + break + + if found is False: + self.pkt_layers.remove(l_type) + print("INVAILD LAYER TYPE [%s]" % l_type.upper()) + + self.pktgen.add_layers(self.pkt_layers) + if layers: + self.pktgen.update_pkts() + + def _load_pkt_layers(self): + name2type = { + "MAC": "ether", + "VLAN": "vlan", + "IP": "ipv4", + "IPv4-TUNNEL": "inner_ipv4", + "IPihl": "ipv4ihl", + "IPFRAG": "ipv4_ext", + "IPv6": "ipv6", + "IPv6-TUNNEL": "inner_ipv6", + "IPv6FRAG": "ipv6_frag", + "IPv6EXT": "ipv6_ext", + "IPv6EXT2": "ipv6_ext2", + "TCP": "tcp", + "UDP": "udp", + "SCTP": "sctp", + "ICMP": "icmp", + "NVGRE": "nvgre", + "GRE": "gre", + "VXLAN": "vxlan", + "PKT": "raw", + "MPLS": "mpls", + "NSH": "nsh", + } + + layers = self.pkt_type.split("_") + self.pkt_layers = [] + self.pkt_cfgload = True + for layer in layers: + if layer in list(name2type.keys()): + self.pkt_layers.append(name2type[layer]) + + def config_def_layers(self): + """ + Handel config packet layers by default + """ + if self.pkt_type == "TIMESYNC": + self.config_layer("ether", {"dst": "FF:FF:FF:FF:FF:FF", "type": 0x88F7}) + self.config_layer("raw", {"payload": ["00", "02"]}) + + if self.pkt_type == "ARP": + self.config_layer("ether", {"dst": "FF:FF:FF:FF:FF:FF"}) + + if self.pkt_type == "IPv6_SCTP": + self.config_layer("ipv6", {"nh": 132}) + + if "IPv6_NVGRE" in self.pkt_type: + self.config_layer("ipv6", {"nh": 47}) + if "IPv6_SCTP" in self.pkt_type: + self.config_layer("inner_ipv6", {"nh": 132}) + if "IPv6_ICMP" in self.pkt_type: + self.config_layer("inner_ipv6", {"nh": 58}) + if "IPFRAG" in self.pkt_type: + self.config_layer("raw", {"payload": ["00"] * 40}) + else: + self.config_layer("raw", {"payload": ["00"] * 18}) + + if ( + "MAC_IP_IPv6" in self.pkt_type + or "MAC_IP_NVGRE" in self.pkt_type + or "MAC_IP_UDP_VXLAN" in self.pkt_type + ): + if "IPv6_SCTP" in self.pkt_type: + self.config_layer("ipv6", {"nh": 132}) + if "IPv6_ICMP" in self.pkt_type: + self.config_layer("ipv6", {"nh": 58}) + if "IPFRAG" in self.pkt_type: + self.config_layer("raw", {"payload": ["00"] * 40}) + else: + self.config_layer("raw", {"payload": ["00"] * 18}) + if "TCP" in self.pkt_type: + self.config_layer("tcp", {"flags": 0}) + + def config_layer(self, layer, config={}): + """ + Configure packet assigned layer + return the status of configure result + """ + try: + idx = self.pkt_layers.index(layer) + except Exception as e: + print("INVALID LAYER ID %s" % layer) + return False + + if self.check_layer_config() is False: + return False + + if "inner" in layer: + layer = layer[6:] + if isinstance(self.pktgen.pkt, str): + raise Exception("string type packet not support config layer") + pkt_layer = self.pktgen.pkt.getlayer(idx) + layer_conf = getattr(self.pktgen, layer) + setattr(self, "configured_layer_%s" % layer, True) + + layer_conf(pkt_layer, **config) + + def config_layers(self, layers=None): + """ + Configure packet with multi configurations + """ + layers = [] if layers is None else layers # None object is not Iterable + for layer in layers: + name, config = layer + if name not in self.pkt_layers: + print("[%s] is missing in packet!!!" % name) + raise Exception(f"{name} is missing in packet!!!") + if self.config_layer(name, config) is False: + print("[%s] failed to configure!!!" % name) + raise Exception(f"{name} failed to configure!!!") + + def strip_layer_element(self, layer, element, p_index=0): + """ + Strip packet layer elements + return the status of configure result + """ + strip_element = getattr(self, "strip_element_%s" % layer) + return strip_element(element, p_index) + + def strip_element_layer2(self, element, p_index=0): + return self.pktgen.strip_layer2(element, p_index) + + def strip_element_layer3(self, element, p_index=0): + return self.pktgen.strip_layer3(element, p_index) + + def strip_element_vlan(self, element, p_index=0): + return self.pktgen.strip_vlan(element, p_index) + + def strip_element_layer4(self, element, p_index=0): + return self.pktgen.strip_layer4(element, p_index) + + +def IncreaseIP(addr): + """ + Returns the IP address from a given one, like + 192.168.1.1 ->192.168.1.2 + If disable ip hw chksum, csum routine will increase ip + """ + ip2int = lambda ipstr: struct.unpack("!I", socket.inet_aton(ipstr))[0] + x = ip2int(addr) + int2ip = lambda n: socket.inet_ntoa(struct.pack("!I", n)) + return int2ip(x + 1) + + +def IncreaseIPv6(addr): + """ + Returns the IP address from a given one, like + FE80:0:0:0:0:0:0:0 -> FE80::1 + csum routine will increase ip + """ + ipv6addr = struct.unpack("!8H", socket.inet_pton(AF_INET6, addr)) + addr = list(ipv6addr) + addr[7] += 1 + ipv6 = socket.inet_ntop( + AF_INET6, + struct.pack( + "!8H", + addr[0], + addr[1], + addr[2], + addr[3], + addr[4], + addr[5], + addr[6], + addr[7], + ), + ) + return ipv6 + + +def get_ether_type(eth_type=""): + # need add more types later + if eth_type.lower() == "lldp": + return "0x88cc" + elif eth_type.lower() == "ip": + return "0x0800" + elif eth_type.lower() == "ipv6": + return "0x86dd" + + return "not support" + + +def get_filter_cmd(filters=[]): + """ + Return bpf formated filter string, only support ether layer now + """ + filter_sep = " and " + filter_cmds = "" + for pktfilter in filters: + filter_cmd = "" + if pktfilter["layer"] == "ether": + if list(pktfilter["config"].keys())[0] == "dst": + dmac = pktfilter["config"]["dst"] + filter_cmd = "ether dst %s" % dmac + elif list(pktfilter["config"].keys())[0] == "src": + smac = pktfilter["config"]["src"] + filter_cmd = "ether src %s" % smac + elif list(pktfilter["config"].keys())[0] == "type": + eth_type = pktfilter["config"]["type"] + eth_format = r"(\w+) (\w+)" + m = re.match(eth_format, eth_type) + if m: + type_hex = get_ether_type(m.group(2)) + if type_hex == "not support": + continue + if m.group(1) == "is": + filter_cmd = "ether[12:2] = %s" % type_hex + elif m.group(1) == "not": + filter_cmd = "ether[12:2] != %s" % type_hex + elif pktfilter["layer"] == "network": + if list(pktfilter["config"].keys())[0] == "srcport": + sport = pktfilter["config"]["srcport"] + filter_cmd = "src port %s" % sport + elif list(pktfilter["config"].keys())[0] == "dstport": + dport = pktfilter["config"]["dstport"] + filter_cmd = "dst port %s" % dport + elif pktfilter["layer"] == "userdefined": + if list(pktfilter["config"].keys())[0] == "pcap-filter": + filter_cmd = pktfilter["config"]["pcap-filter"] + + if len(filter_cmds): + if len(filter_cmd): + filter_cmds += filter_sep + filter_cmds += filter_cmd + else: + filter_cmds = filter_cmd + + if len(filter_cmds): + return " '" + filter_cmds + "' " + else: + return "" + + +def start_tcpdump(crb, intf, count=0, filters=None, lldp_forbid=True): + """ + sniff all packets from certain port + """ + filters = [] if filters is None else filters + out = crb.send_expect("ls -d %s" % crb.tmp_file, "# ", verify=True) + if out == 2: + crb.send_expect("mkdir -p %s" % crb.tmp_file, "# ") + filename = "{}sniff_{}.pcap".format(crb.tmp_file, intf) + # delete old pcap file + crb.send_expect("rm -rf %s" % filename, "# ") + + param = "" + direct_param = r"(\s+)\[ (\S+) in\|out\|inout \]" + tcpdump_session = crb.create_session("tcpdump_session" + str(time.time())) + setattr(tcpdump_session, "tmp_file", crb.tmp_file) + tcpdump_help = tcpdump_session.send_command("tcpdump -h") + + for line in tcpdump_help.split("\n"): + m = re.match(direct_param, line) + if m: + opt = re.search("-Q", m.group(2)) + if opt: + param = "-Q" + " in" + else: + opt = re.search("-P", m.group(2)) + if opt: + param = "-P" + " in" + + if len(param) == 0: + print("tcpdump not support direction choice!!!") + + if lldp_forbid and (LLDP_FILTER not in filters): + filters.append(LLDP_FILTER) + + filter_cmd = get_filter_cmd(filters) + + sniff_cmd = "tcpdump -i %(INTF)s %(FILTER)s %(IN_PARAM)s -w %(FILE)s" + options = { + "INTF": intf, + "COUNT": count, + "IN_PARAM": param, + "FILE": filename, + "FILTER": filter_cmd, + } + if count: + sniff_cmd += " -c %(COUNT)d" + cmd = sniff_cmd % options + else: + cmd = sniff_cmd % options + + tcpdump_session.send_command(cmd) + + index = str(time.time()) + SNIFF_PIDS[index] = (tcpdump_session, intf, filename) + time.sleep(1) + return index + + +def stop_and_load_tcpdump_packets(index="", timeout=1): + """ + Stop sniffer and return packet object + """ + if index in list(SNIFF_PIDS.keys()): + pipe, intf, filename = SNIFF_PIDS.pop(index) + pipe.get_session_before(timeout) + pipe.send_command("^C") + pipe.copy_file_from(filename, TMP_PATH) + p = Packet() + p.read_pcapfile(TMP_PATH + filename.split(os.sep)[-1]) + pipe.close() + return p + + +def compare_pktload(pkt1=None, pkt2=None, layer="L2"): + l_idx = 0 + if layer == "L2": + l_idx = 0 + elif layer == "L3": + l_idx = 1 + elif layer == "L4": + l_idx = 2 + try: + load1 = hexstr(str(pkt1.getlayer(l_idx))) + load2 = hexstr(str(pkt2.getlayer(l_idx))) + except: + # return pass when scapy failed to extract packet + return True + + if load1 == load2: + return True + else: + return False + + +def strip_pktload(pkt=None, layer="L2", p_index=0): + if layer == "L2": + l_idx = 0 + elif layer == "L3": + l_idx = 1 + elif layer == "L4": + l_idx = 2 + else: + l_idx = 0 + try: + load = hexstr(str(pkt.pktgen.pkts[p_index].getlayer(l_idx)), onlyhex=1) + except: + # return pass when scapy failed to extract packet + load = "" + + return load + + +############################################################################### +############################################################################### +if __name__ == "__main__": + pkt = Packet("Ether(type=0x894f)/NSH(Len=0x6,NextProto=0x0,NSP=0x000002,NSI=0xff)") + sendp(pkt, iface="lo") + pkt.append_pkt(pkt_type="IPv6_TCP", pkt_len=100) + pkt.append_pkt(pkt_type="TCP", pkt_len=100) + pkt.config_layer("tcp", config={"flags": "A"}) + pkt.append_pkt( + "Ether(dst='11:22:33:44:55:11')/IP(dst='192.168.5.2')/TCP(flags=0)/Raw(load='bbbb')" + ) + pkt.generate_random_pkts( + "11:22:33:44:55:55", + random_type=["TCP", "IPv6_TCP"], + random_payload=True, + pktnum=10, + ) + sendp(pkt, iface="lo") + + pkt = Packet(pkt_type="UDP", pkt_len=1500, ran_payload=True) + sendp(pkt, iface="lo") + pkt = Packet(pkt_type="IPv6_SCTP") + sendp(pkt, iface="lo") + pkt = Packet(pkt_type="VLAN_UDP") + pkt.config_layer("vlan", {"vlan": 2}) + sendp(pkt, iface="lo") + + pkt.assign_layers( + [ + "ether", + "vlan", + "ipv4", + "udp", + "vxlan", + "inner_mac", + "inner_ipv4", + "inner_udp", + "raw", + ] + ) + pkt.config_layer("ether", {"dst": "00:11:22:33:44:55"}) + pkt.config_layer("vlan", {"vlan": 2}) + pkt.config_layer("ipv4", {"dst": "1.1.1.1"}) + pkt.config_layer("udp", {"src": 4789, "dst": 4789, "chksum": 0x1111}) + pkt.config_layer("vxlan", {"vni": 2}) + pkt.config_layer("raw", {"payload": ["58"] * 18}) + sendp(pkt, iface="lo") + + pkt.assign_layers( + [ + "ether", + "vlan", + "ipv4", + "udp", + "vxlan", + "inner_mac", + "inner_ipv4", + "inner_udp", + "raw", + ] + ) + # config packet + pkt.config_layers( + [ + ("ether", {"dst": "00:11:22:33:44:55"}), + ("ipv4", {"dst": "1.1.1.1"}), + ("vxlan", {"vni": 2}), + ("raw", {"payload": ["01"] * 18}), + ] + ) + + sendp(pkt, iface="lo") From patchwork Wed Apr 6 14:56:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109226 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4426BA0507; Wed, 6 Apr 2022 16:58:00 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3F8DF428A8; Wed, 6 Apr 2022 16:56:34 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 92FE44288E for ; Wed, 6 Apr 2022 16:56:30 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id EEE9B1B1F6C; Wed, 6 Apr 2022 16:56:29 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xsWheZYvLLQ6; Wed, 6 Apr 2022 16:56:28 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 4BC6A1B1F79; Wed, 6 Apr 2022 16:56:12 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 11/15] dts: merge DTS framework/project_dpdk.py to DPDK Date: Wed, 6 Apr 2022 14:56:02 +0000 Message-Id: <20220406145606.2913834-12-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/project_dpdk.py | 627 ++++++++++++++++++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 dts/framework/project_dpdk.py diff --git a/dts/framework/project_dpdk.py b/dts/framework/project_dpdk.py new file mode 100644 index 0000000000..4104e016a3 --- /dev/null +++ b/dts/framework/project_dpdk.py @@ -0,0 +1,627 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import re + +from .crb import Crb +from .dut import Dut +from .logger import getLogger +from .settings import ( + CONFIG_ROOT_PATH, + DPDK_RXMODE_SETTING, + DRIVERS, + HOST_DRIVER_MODE_SETTING, + HOST_DRIVER_SETTING, + HOST_SHARED_LIB_PATH, + HOST_SHARED_LIB_SETTING, + NICS, + accepted_nic, + load_global_setting, + save_global_setting, +) +from .ssh_connection import SSHConnection +from .tester import Tester +from .utils import RED + + +class DPDKdut(Dut): + + """ + DPDK project class for DUT. DTS will call set_target function to setup + build, memory and kernel module. + """ + + def __init__(self, crb, serializer, dut_id=0, name=None, alt_session=True): + super(DPDKdut, self).__init__(crb, serializer, dut_id, name, alt_session) + self.testpmd = None + + def set_target(self, target, bind_dev=True): + """ + Set env variable, these have to be setup all the time. Some tests + need to compile example apps by themselves and will fail otherwise. + Set hugepage on DUT and install modules required by DPDK. + Configure default ixgbe PMD function. + """ + self.target = target + + self.set_toolchain(target) + + # set env variable + self.set_env_variable() + + self.set_rxtx_mode() + + self.apps_name = self.apps_name_conf["meson"] + # use the dut target directory instead of 'target' string in app name + for app in self.apps_name: + cur_app_path = self.apps_name[app].replace("target", self.target) + self.apps_name[app] = cur_app_path + " " + + if not self.skip_setup: + self.build_install_dpdk(target) + + self.setup_memory() + + drivername = load_global_setting(HOST_DRIVER_SETTING) + drivermode = load_global_setting(HOST_DRIVER_MODE_SETTING) + self.setup_modules(target, drivername, drivermode) + + if bind_dev and self.get_os_type() == "linux": + self.bind_interfaces_linux(drivername) + self.extra_nic_setup() + + def set_env_variable(self): + # These have to be setup all the time. Some tests need to compile + # example apps by themselves and will fail otherwise. + self.send_expect("export RTE_TARGET=" + self.target, "#") + self.send_expect("export RTE_SDK=`pwd`", "#") + + def setup_modules(self, target, drivername, drivermode): + """ + Install DPDK required kernel module on DUT. + """ + setup_modules = getattr(self, "setup_modules_%s" % self.get_os_type()) + setup_modules(target, drivername, drivermode) + + def setup_modules_linux(self, target, drivername, drivermode): + if drivername == "vfio-pci": + self.send_expect("rmmod vfio_pci", "#") + self.send_expect("rmmod vfio_iommu_type1", "#") + self.send_expect("rmmod vfio", "#") + self.send_expect("modprobe vfio", "#") + self.send_expect("modprobe vfio-pci", "#") + if drivermode == "noiommu": + self.send_expect( + "echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode", + "#", + ) + out = self.send_expect("ls /sys/module|grep vfio_pci", "#") + assert "vfio_pci" in out, "load vfio_pci failed" + + elif drivername == "uio_pci_generic": + self.send_expect("modprobe uio", "#", 70) + self.send_expect("modprobe uio_pci_generic", "#", 70) + out = self.send_expect("lsmod | grep uio_pci_generic", "#") + assert "uio_pci_generic" in out, "Failed to setup uio_pci_generic" + + elif drivername == "mlx5_core": + pass + + elif drivername == "igb_uio": + self.send_expect("modprobe uio", "#", 70) + out = self.send_expect("lsmod | grep igb_uio", "#") + if "igb_uio" in out: + self.send_expect("rmmod -f igb_uio", "#", 70) + self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko", "#", 60) + + out = self.send_expect("lsmod | grep igb_uio", "#") + assert "igb_uio" in out, "Failed to insmod igb_uio" + + else: + pass + + def setup_modules_freebsd(self, target, drivername, drivermode): + """ + Install DPDK required Freebsd kernel module on DUT. + """ + binding_list = "" + + for (pci_bus, pci_id) in self.pci_devices_info: + if accepted_nic(pci_id): + binding_list += "%s," % (pci_bus) + + self.send_expect("kldunload if_ixgbe.ko", "#") + self.send_expect('kenv hw.nic_uio.bdfs="%s"' % binding_list[:-1], "# ") + self.send_expect("kldload ./%s/kmod/nic_uio.ko" % target, "#", 20) + out = self.send_expect("kldstat", "#") + assert "nic_uio" in out, "Failed to insmod nic_uio" + + def restore_modules(self): + """ + Restore DPDK kernel module on DUT. + """ + restore_modules = getattr(self, "restore_modules_%s" % self.get_os_type()) + restore_modules() + + def restore_modules_linux(self): + """ + Restore DPDK Linux kernel module on DUT. + """ + drivername = load_global_setting(HOST_DRIVER_SETTING) + if drivername == "vfio-pci": + drivermode = load_global_setting(HOST_DRIVER_MODE_SETTING) + if drivermode == "noiommu": + self.send_expect( + "echo 0 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode", + "#", + 70, + ) + + def restore_modules_freebsd(self): + """ + Restore DPDK Freebsd kernel module on DUT. + """ + pass + + def set_rxtx_mode(self): + """ + Set default RX/TX PMD function, + the rx mode scalar/full/novector are supported dynamically since DPDK 20.11, + Rx mode avx512 is only supported in DPDK 20.11 and later version. + """ + + mode = load_global_setting(DPDK_RXMODE_SETTING) + if mode == "avx512": + out = self.send_expect("lscpu | grep avx512", "#") + if "avx512f" not in out or "no-avx512f" in out: + self.logger.warning( + RED("*********The DUT CPU do not support AVX512 test!!!********") + ) + self.logger.warning( + RED("*********Now set the rx_mode to default!!!**********") + ) + save_global_setting(DPDK_RXMODE_SETTING, "default") + + def set_package(self, pkg_name="", patch_list=[]): + self.package = pkg_name + self.patches = patch_list + + def set_build_options(self, config_parms, config_file=""): + self.set_build_options_meson(config_parms, config_file) + + def set_build_options_meson(self, config_parms, config_file=""): + """ + Set dpdk build options of meson + """ + if len(config_parms) == 0: + return + if config_file == "": + config_file = "config/rte_config.h" + + for key in config_parms.keys(): + value = config_parms[key] + if value == "n": + def_str = "#undef" + " " + key + else: + if isinstance(value, int): + def_str = "#define %s %d" % (key, value) + elif value == "" or value == "y": + def_str = "#define %s %d" % (key, 1) + else: + value = '\\"%s\\"' % value + def_str = "#define %s %s" % (key, value) + + # delete the marco define in the config file + self.send_expect("sed -i '/%s/d' %s" % (key, config_file), "# ") + self.send_expect("sed -i '$a\%s' %s" % (def_str, config_file), "# ") + + def build_install_dpdk(self, target, extra_options=""): + """ + Build DPDK source code with specified target. + """ + use_shared_lib = load_global_setting(HOST_SHARED_LIB_SETTING) + if use_shared_lib == "true" and "Virt" not in str(self): + extra_options += " -Dc_args=-DRTE_BUILD_SHARED_LIB" + if self.get_os_type() == "linux": + self.build_install_dpdk_linux_meson(target, extra_options) + elif self.get_os_type() == "freebsd": + self.build_install_dpdk_freebsd_meson(target, extra_options) + + def build_install_dpdk_linux_meson(self, target, extra_options): + """ + Build DPDK source code on linux use meson + """ + build_time = 1800 + target_info = target.split("-") + arch = target_info[0] + machine = target_info[1] + execenv = target_info[2] + toolchain = target_info[3] + + default_library = "static" + use_shared_lib = load_global_setting(HOST_SHARED_LIB_SETTING) + if use_shared_lib == "true" and "Virt" not in str(self): + default_library = "shared" + if arch == "i686": + # find the pkg-config path and set the PKG_CONFIG_LIBDIR environmental variable to point it + out = self.send_expect("find /usr -type d -name pkgconfig", "# ") + pkg_path = "" + default_cflags = self.send_expect("echo $CFLAGS", "# ") + default_pkg_config = self.send_expect("echo $PKG_CONFIG_LIBDIR", "# ") + res_path = out.split("\r\n") + for cur_path in res_path: + if "i386" in cur_path: + pkg_path = cur_path + break + assert ( + pkg_path != "" + ), "please make sure you env have the i386 pkg-config path" + + self.send_expect("export CFLAGS=-m32", "# ") + self.send_expect("export PKG_CONFIG_LIBDIR=%s" % pkg_path, "# ") + + self.send_expect("rm -rf " + target, "#") + out = self.send_expect( + "CC=%s meson -Denable_kmods=True -Dlibdir=lib %s --default-library=%s %s" + % (toolchain, extra_options, default_library, target), + "[~|~\]]# ", + build_time, + ) + assert "FAILED" not in out, "meson setup failed ..." + + out = self.send_expect("ninja -C %s" % target, "[~|~\]]# ", build_time) + assert "FAILED" not in out, "ninja complie failed ..." + + # copy kmod file to the folder same as make + out = self.send_expect( + "find ./%s/kernel/ -name *.ko" % target, "# ", verify=True + ) + self.send_expect("mkdir -p %s/kmod" % target, "# ") + if not isinstance(out, int) and len(out) > 0: + kmod = out.split("\r\n") + for mod in kmod: + self.send_expect("cp %s %s/kmod/" % (mod, target), "# ") + + def build_install_dpdk_freebsd_meson(self, target, extra_options): + # meson build same as linux + self.build_install_dpdk_linux_meson(target, extra_options) + + # the uio name different with linux, find the nic_uio + out = self.send_expect( + "find ./%s/kernel/ -name nic_uio" % target, "# ", verify=True + ) + self.send_expect("mkdir -p %s/kmod" % target, "# ") + if not isinstance(out, int) and len(out) > 0: + self.send_expect("cp %s %s/kmod/" % (out, target), "# ") + + def prepare_package(self): + if not self.skip_setup: + session_info = None + # if snapshot_load_side=dut, will copy the dpdk tar from dut side + # and will judge whether the path of tar is existed on dut + if self.crb["snapshot_load_side"] == "dut": + if not os.path.isabs(self.package): + raise ValueError( + "As snapshot_load_side=dut, will copy dpdk.tar " + "from dut, please specify a abs path use params " + "--snapshot when run dts" + ) + # if ':' in session, this is vm dut, use the dut session + if ":" in self.session.name: + session_info = self.host_session + else: + session_info = self.alt_session + out = session_info.send_expect("ls -F %s" % self.package, "# ") + assert out == self.package, "Invalid package" + else: + assert os.path.isfile(self.package) is True, "Invalid package" + + p_dir, _ = os.path.split(self.base_dir) + # ToDo: make this configurable + dst_dir = "/tmp/" + + out = self.send_expect("ls -d %s" % p_dir, "# ", verify=True) + if out == 2: + self.send_expect("mkdir -p %s" % p_dir, "# ") + + out = self.send_expect( + "ls %s && cd %s" % (dst_dir, p_dir), "#", verify=True + ) + if out == -1: + raise ValueError( + "Directory %s or %s does not exist," + "please check params -d" % (p_dir, dst_dir) + ) + self.session.copy_file_to(self.package, dst_dir, crb_session=session_info) + + # put patches to p_dir/patches/ + if self.patches is not None: + for p in self.patches: + self.session.copy_file_to("dep/" + p, dst_dir) + + # copy QMP file to dut + if ":" not in self.session.name: + out = self.send_expect("ls -d ~/QMP", "# ", verify=True) + if isinstance(out, int): + self.send_expect("mkdir -p ~/QMP", "# ") + self.session.copy_file_to("dep/QMP/qemu-ga-client", "~/QMP/") + self.session.copy_file_to("dep/QMP/qmp.py", "~/QMP/") + self.kill_all() + + # enable core dump + self.send_expect("ulimit -c unlimited", "#") + + # unpack the code and change to the working folder + self.send_expect("rm -rf %s" % self.base_dir, "#") + + # unpack dpdk + out = self.send_expect( + "tar zxfm %s%s -C %s" % (dst_dir, self.package.split("/")[-1], p_dir), + "# ", + 60, + verify=True, + ) + if out == -1: + raise ValueError( + "Extract dpdk package to %s failure," + "please check params -d" % (p_dir) + ) + + # check dpdk dir name is expect + out = self.send_expect("ls %s" % self.base_dir, "# ", 20, verify=True) + if out == -1: + raise ValueError( + "dpdk dir %s mismatch, please check params -d" % self.base_dir + ) + + if self.patches is not None: + for p in self.patches: + out = self.send_expect( + "patch -d %s -p1 < %s" % (self.base_dir, dst_dir + p), "# " + ) + assert "****" not in out + + def prerequisites(self): + """ + Copy DPDK package to DUT and apply patch files. + """ + self.prepare_package() + self.dut_prerequisites() + self.stage = "post-init" + + def extra_nic_setup(self): + """ + Some nic like RRC required additional setup after module installed + """ + for port_info in self.ports_info: + netdev = port_info["port"] + netdev.setup() + + def bind_interfaces_linux(self, driver="igb_uio", nics_to_bind=None): + """ + Bind the interfaces to the selected driver. nics_to_bind can be None + to bind all interfaces or an array with the port indexes + """ + binding_list = "--bind=%s " % driver + + current_nic = 0 + for port_info in self.ports_info: + if nics_to_bind is None or current_nic in nics_to_bind: + binding_list += "%s " % (port_info["pci"]) + current_nic += 1 + + bind_script_path = self.get_dpdk_bind_script() + return self.send_expect( + "%s --force %s" % (bind_script_path, binding_list), "# " + ) + + def unbind_interfaces_linux(self, nics_to_bind=None): + """ + Unbind the interfaces + """ + + binding_list = "-u " + + current_nic = 0 + for port_info in self.ports_info: + if nics_to_bind is None or current_nic in nics_to_bind: + binding_list += "%s " % (port_info["pci"]) + current_nic += 1 + + bind_script_path = self.get_dpdk_bind_script() + self.send_expect("%s --force %s" % (bind_script_path, binding_list), "# ") + + def build_dpdk_apps(self, folder, extra_options=""): + """ + Build dpdk sample applications. + """ + if self.get_os_type() == "linux": + return self.build_dpdk_apps_linux_meson(folder, extra_options) + elif self.get_os_type() == "freebsd": + return self.build_dpdk_apps_freebsd_meson(folder, extra_options) + + def build_dpdk_apps_linux_meson(self, folder, extra_options): + """ + Build dpdk sample applications on linux use meson + """ + # icc compile need more time + if "icc" in self.target: + timeout = 300 + else: + timeout = 90 + + target_info = self.target.split("-") + arch = target_info[0] + if arch == "i686": + # find the pkg-config path and set the PKG_CONFIG_LIBDIR environmental variable to point it + out = self.send_expect("find /usr -type d -name pkgconfig", "# ") + pkg_path = "" + default_cflags = self.send_expect("echo $CFLAGS", "# ") + default_pkg_config = self.send_expect("echo $PKG_CONFIG_LIBDIR", "# ") + res_path = out.split("\r\n") + for cur_path in res_path: + if "i386" in cur_path: + pkg_path = cur_path + break + assert ( + pkg_path != "" + ), "please make sure you env have the i386 pkg-config path" + + self.send_expect("export CFLAGS=-m32", "# ", alt_session=True) + self.send_expect( + "export PKG_CONFIG_LIBDIR=%s" % pkg_path, "# ", alt_session=True + ) + + folder_info = folder.split("/") + name = folder_info[-1] + if name != "examples" and name not in self.apps_name: + raise Exception( + f'Please config {name} file path on {os.path.join(CONFIG_ROOT_PATH, "app_name.cfg")}' + ) + + if name == "examples": + example = "all" + else: + example = "/".join(folder_info[folder_info.index("examples") + 1 :]) + out = self.send_expect( + "meson configure -Dexamples=%s %s" % (example, self.target), "# " + ) + assert "FAILED" not in out, "Compilation error..." + out = self.send_expect("ninja -C %s" % self.target, "[~|~\]]# ", timeout) + assert "FAILED" not in out, "Compilation error..." + + # verify the app build in the config path + if example != "all": + out = self.send_expect("ls %s" % self.apps_name[name], "# ", verify=True) + assert isinstance(out, str), ( + "please confirm %s app path and name in app_name.cfg" % name + ) + + return out + + def build_dpdk_apps_freebsd_meson(self, folder, extra_options): + # meson build same as linux + return self.build_dpdk_apps_linux_meson(folder, extra_options) + + def get_blocklist_string(self, target, nic): + """ + Get block list command string. + """ + get_blocklist_string = getattr( + self, "get_blocklist_string_%s" % self.get_os_type() + ) + return get_blocklist_string(target, nic) + + def get_blocklist_string_linux(self, target, nic): + """ + Get block list command string on Linux. + """ + blocklist = "" + dutPorts = self.get_ports(nic) + self.restore_interfaces() + self.send_expect("insmod ./%s/kmod/igb_uio.ko" % target, "# ") + self.bind_interfaces_linux() + for port in range(0, len(self.ports_info)): + if port not in dutPorts: + blocklist += "-b %s " % self.ports_info[port]["pci"] + return blocklist + + def get_blocklist_string_freebsd(self, target, nic): + """ + Get block list command string on Freebsd. + """ + blocklist = "" + # No blocklist option in FreeBSD + return blocklist + + +class DPDKtester(Tester): + + """ + DPDK project class for tester. DTS will call prerequisites function to setup + interface and generate port map. + """ + + def __init__(self, crb, serializer, dut_id): + self.NAME = "tester" + super(DPDKtester, self).__init__(crb, serializer) + + def prerequisites(self, perf_test=False): + """ + Setup hugepage on tester and copy validation required files to tester. + """ + self.kill_all() + + if not self.skip_setup: + total_huge_pages = self.get_total_huge_pages() + hugepages_size = self.send_expect( + "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# " + ) + if total_huge_pages == 0: + self.mount_huge_pages() + if hugepages_size == "524288": + self.set_huge_pages(8) + else: + self.set_huge_pages(1024) + + self.session.copy_file_to("dep/tgen.tgz") + self.session.copy_file_to("dep/tclclient.tgz") + # unpack tgen + out = self.send_expect("tar zxfm tgen.tgz", "# ") + assert "Error" not in out + # unpack tclclient + out = self.send_expect("tar zxfm tclclient.tgz", "# ") + assert "Error" not in out + + self.send_expect("modprobe uio", "# ") + + self.tester_prerequisites() + + self.set_promisc() + + self.stage = "post-init" + + def setup_memory(self, hugepages=-1): + """ + Setup hugepage on tester. + """ + hugepages_size = self.send_expect( + "awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# " + ) + + if int(hugepages_size) < (2048 * 2048): + arch_huge_pages = hugepages if hugepages > 0 else 2048 + total_huge_pages = self.get_total_huge_pages() + + self.mount_huge_pages() + if total_huge_pages != arch_huge_pages: + self.set_huge_pages(arch_huge_pages) From patchwork Wed Apr 6 14:56:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109227 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DBA4FA0507; Wed, 6 Apr 2022 16:58:09 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 84EE9428B0; Wed, 6 Apr 2022 16:56:35 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 5C1E942892 for ; Wed, 6 Apr 2022 16:56:31 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id A81C01B1F79; Wed, 6 Apr 2022 16:56:30 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id r6G9RXMwLqUF; Wed, 6 Apr 2022 16:56:29 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id BC7F71B1F7F; Wed, 6 Apr 2022 16:56:12 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 12/15] dts: merge DTS framework/serializer.py to DPDK Date: Wed, 6 Apr 2022 14:56:03 +0000 Message-Id: <20220406145606.2913834-13-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/serializer.py | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 dts/framework/serializer.py diff --git a/dts/framework/serializer.py b/dts/framework/serializer.py new file mode 100644 index 0000000000..0ffa16a592 --- /dev/null +++ b/dts/framework/serializer.py @@ -0,0 +1,115 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +Wrapper class for serializer module +""" +import os +import pickle + + +class Singleton(type): + _instances = {} + + def __call__(self, *args, **kwargs): + if self not in self._instances: + self._instances[self] = super(Singleton, self).__call__(*args, **kwargs) + return self._instances[self] + + +class Serializer(object): + + """ + Two-levels cache implementation for storing/retrieving any kind of object + using using a key-value model. It uses the pickle module to store objects + into a file. + This class implements the Singleton pattern. Everytime its constructor + is called it will return a reference to the same instance. + """ + + def __init__(self): + self.volatile_cache = {} + self.filename = "serializer.cache" + + def save(self, object_name, object_to_save): + """ + Saves an object into the volatile dictionary cache - which + resides in memory. + """ + self.volatile_cache[object_name] = object_to_save + + def load(self, object_name): + """ + Loads and returns an object from the volatile cache. + """ + return self.volatile_cache.get(object_name, None) + + def set_serialized_filename(self, filename): + """ + Sets the name of the non-volatile cache file to be used in the future + """ + self.filename = filename + + def save_to_file(self): + """ + Saves the volatile cache to a file (non-volatile) using the pickle + module. Returns True in case everything went OK, False otherwise. + """ + try: + serialized_file = open(self.filename, "w") + pickle.dump(self.volatile_cache, serialized_file) + serialized_file.close() + return True + except: + return False + + def load_from_file(self): + """ + Reads from a pickle-like file using pickle module and populates the + volatile cache. Returns True in case everything went OK, False + otherwise. + """ + try: + serialized_file = open(self.filename, "r") + self.volatile_cache = pickle.load(serialized_file) + serialized_file.close() + return True + except: + self.volatile_cache.clear() + return False + + def discard_cache(self): + """ + Discards both volatile and non-volatile cache. + """ + self.volatile_cache.clear() + if os.path.exists(self.filename): + os.remove(self.filename) From patchwork Wed Apr 6 14:56:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109228 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D35ABA0507; Wed, 6 Apr 2022 16:58:18 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AE622428BC; Wed, 6 Apr 2022 16:56:36 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 3E10D4289C for ; Wed, 6 Apr 2022 16:56:32 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 97DDF1B1F7F; Wed, 6 Apr 2022 16:56:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bQTCHK04VASP; Wed, 6 Apr 2022 16:56:30 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 2A16C1B27A0; Wed, 6 Apr 2022 16:56:13 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 13/15] dts: merge DTS framework/utils.py to DPDK Date: Wed, 6 Apr 2022 14:56:04 +0000 Message-Id: <20220406145606.2913834-14-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/framework/utils.py | 353 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 dts/framework/utils.py diff --git a/dts/framework/utils.py b/dts/framework/utils.py new file mode 100644 index 0000000000..8b22d24b0c --- /dev/null +++ b/dts/framework/utils.py @@ -0,0 +1,353 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import inspect +import json # json format +import os +import re +import socket +import struct +import sys +import threading +import types +from functools import wraps + +DTS_ENV_PAT = r"DTS_*" + + +def create_parallel_locks(num_duts): + """ + Create thread lock dictionary based on DUTs number + """ + global locks_info + locks_info = [] + for _ in range(num_duts): + lock_info = dict() + lock_info["update_lock"] = threading.RLock() + locks_info.append(lock_info) + + +def parallel_lock(num=1): + """ + Wrapper function for protect parallel threads, allow multiple threads + share one lock. Locks are created based on function name. Thread locks are + separated between duts according to argument 'dut_id'. + Parameter: + num: Number of parallel threads for the lock + """ + global locks_info + + def decorate(func): + @wraps(func) + def wrapper(*args, **kwargs): + if "dut_id" in kwargs: + dut_id = kwargs["dut_id"] + else: + dut_id = 0 + + # in case function arguments is not correct + if dut_id >= len(locks_info): + dut_id = 0 + + lock_info = locks_info[dut_id] + uplock = lock_info["update_lock"] + + name = func.__name__ + uplock.acquire() + + if name not in lock_info: + lock_info[name] = dict() + lock_info[name]["lock"] = threading.RLock() + lock_info[name]["current_thread"] = 1 + else: + lock_info[name]["current_thread"] += 1 + + lock = lock_info[name]["lock"] + + # make sure when owned global lock, should also own update lock + if lock_info[name]["current_thread"] >= num: + if lock._is_owned(): + print( + RED( + "DUT%d %s waiting for func lock %s" + % (dut_id, threading.current_thread().name, func.__name__) + ) + ) + lock.acquire() + else: + uplock.release() + + try: + ret = func(*args, **kwargs) + except Exception as e: + if not uplock._is_owned(): + uplock.acquire() + + if lock._is_owned(): + lock.release() + lock_info[name]["current_thread"] = 0 + uplock.release() + raise e + + if not uplock._is_owned(): + uplock.acquire() + + if lock._is_owned(): + lock.release() + lock_info[name]["current_thread"] = 0 + + uplock.release() + + return ret + + return wrapper + + return decorate + + +def RED(text): + return "\x1B[" + "31;1m" + str(text) + "\x1B[" + "0m" + + +def BLUE(text): + return "\x1B[" + "36;1m" + str(text) + "\x1B[" + "0m" + + +def GREEN(text): + return "\x1B[" + "32;1m" + str(text) + "\x1B[" + "0m" + + +def pprint(some_dict, serialzer=None): + """ + Print JSON format dictionary object. + """ + return json.dumps(some_dict, sort_keys=True, indent=4, default=serialzer) + + +def regexp(s, to_match, allString=False): + """ + Ensure that the re `to_match' only has one group in it. + """ + + scanner = re.compile(to_match, re.DOTALL) + if allString: + return scanner.findall(s) + m = scanner.search(s) + if m is None: + print(RED("Failed to match " + to_match + " in the string " + s)) + return None + return m.group(1) + + +def get_obj_funcs(obj, func_name_regex): + """ + Return function list which name matched regex. + """ + for func_name in dir(obj): + func = getattr(obj, func_name) + if callable(func) and re.match(func_name_regex, func.__name__): + yield func + + +@parallel_lock() +def remove_old_rsa_key(crb, ip): + """ + Remove the old RSA key of specified IP on crb. + """ + rsa_key_path = "~/.ssh/known_hosts" + remove_rsa_key_cmd = "sed -i '/%s/d' %s" % (ip, rsa_key_path) + crb.send_expect(remove_rsa_key_cmd, "# ") + + +def human_read_number(num): + if num > 1000000: + num /= 1000000 + return str(num) + "M" + elif num > 1000: + num /= 1000 + return str(num) + "K" + else: + return str(num) + + +def get_subclasses(module, clazz): + """ + Get module attribute name and attribute. + """ + for subclazz_name, subclazz in inspect.getmembers(module): + if ( + hasattr(subclazz, "__bases__") + and subclazz.__bases__ + and clazz in subclazz.__bases__ + ): + yield (subclazz_name, subclazz) + + +def copy_instance_attr(from_inst, to_inst): + for key in list(from_inst.__dict__.keys()): + to_inst.__dict__[key] = from_inst.__dict__[key] + + +def create_mask(indexes): + """ + Convert index to hex mask. + """ + val = 0 + for index in indexes: + val |= 1 << int(index) + + return hex(val).rstrip("L") + + +def convert_int2ip(value, ip_type=4): + """ + @change: + 2019.0403 set default value + """ + if ip_type == 4: + ip_str = socket.inet_ntop(socket.AF_INET, struct.pack("!I", value)) + else: + h = value >> 64 + l = value & ((1 << 64) - 1) + ip_str = socket.inet_ntop(socket.AF_INET6, struct.pack("!QQ", h, l)) + + return ip_str + + +def convert_ip2int(ip_str, ip_type=4): + """ + @change: + 2019.0403 set default value + """ + if ip_type == 4: + ip_val = struct.unpack("!I", socket.inet_aton(ip_str))[0] + else: + _hex = socket.inet_pton(socket.AF_INET6, ip_str) + h, l = struct.unpack("!QQ", _hex) + ip_val = (h << 64) | l + + return ip_val + + +def convert_mac2long(mac_str): + """ + convert the MAC type from the string into the int. + """ + mac_hex = "0x" + for mac_part in mac_str.lower().split(":"): + mac_hex += mac_part + ret = int(mac_hex, 16) + return ret + + +def convert_mac2str(mac_long): + """ + convert the MAC type from the int into the string. + """ + mac = hex(mac_long)[2:].zfill(12) + b = [] + [b.append(mac[n : n + 2]) for n in range(len(mac)) if n % 2 == 0] + new_mac = ":".join(b) + return new_mac + + +def get_backtrace_object(file_name, obj_name): + import inspect + + frame = inspect.currentframe() + obj = None + found = False + while frame: + file_path = inspect.getsourcefile(frame) + call_file = file_path.split(os.sep)[-1] + if file_name == call_file: + found = True + break + + frame = frame.f_back + + if found: + obj = getattr(frame.f_locals["self"], obj_name, None) + + return obj + + +def check_crb_python_version(crb): + cmd = "python3 -V" + out = crb.send_expect(cmd, "#", 5) + pat = "Python (\d+).(\d+).(\d+)" + result = re.findall(pat, out) + if ( + not result + or int(result[0][0]) < 3 + or (int(result[0][0]) == 3 and int(result[0][1]) < 6) + or (int(result[0][0]) == 3 and int(result[0][1]) == 6 and int(result[0][2]) < 9) + ): + crb.logger.warning( + ( + "WARNING: Tester node python version is lower than python 3.6, " + "it is deprecated for use in DTS, " + "and will not work in future releases." + ) + ) + crb.logger.warning("Please use Python >= 3.6.9 instead") + + +def check_dts_python_version(): + if ( + sys.version_info.major < 3 + or (sys.version_info.major == 3 and sys.version_info.minor < 6) + or ( + sys.version_info.major == 3 + and sys.version_info.minor == 6 + and sys.version_info.micro < 9 + ) + ): + print( + RED( + ( + "WARNING: Dts running node python version is lower than python 3.6, " + "it is deprecated for use in DTS, " + "and will not work in future releases." + ) + ), + file=sys.stderr, + ) + print(RED("Please use Python >= 3.6.9 instead"), file=sys.stderr) + + +def get_module_path(module_name): + from importlib import import_module + + _module = import_module(module_name) + _module_file_path = _module.__file__ + del _module + return os.path.dirname(_module_file_path) From patchwork Wed Apr 6 14:56:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109229 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DDD61A0507; Wed, 6 Apr 2022 16:58:24 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 911FB428C0; Wed, 6 Apr 2022 16:56:37 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 5DD3A428A4 for ; Wed, 6 Apr 2022 16:56:33 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 948FE1B27A9; Wed, 6 Apr 2022 16:56:32 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oCYRn13maJnv; Wed, 6 Apr 2022 16:56:31 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id A178B1B27A1; Wed, 6 Apr 2022 16:56:13 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 14/15] dts: merge DTS main.py to DPDK Date: Wed, 6 Apr 2022 14:56:05 +0000 Message-Id: <20220406145606.2913834-15-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/main.py | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100755 dts/main.py diff --git a/dts/main.py b/dts/main.py new file mode 100755 index 0000000000..f4f5e03a88 --- /dev/null +++ b/dts/main.py @@ -0,0 +1,236 @@ +#!/usr/bin/python3 +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +A test framework for testing DPDK. +""" + +import argparse +import os +import subprocess +import sys + +from framework import dts + +# change operation directory +cwd = os.getcwd() + + +def git_build_package(gitLabel, pkgName): + """ + generate package from git, if dpdk existed will pull latest code + """ + gitURL = r"http://dpdk.org/git/dpdk" + gitPrefix = r"dpdk/" + depot = r"dep" + if os.path.exists("%s/%s" % (depot, gitPrefix)) is True: + os.chdir("%s/%s" % (depot, gitPrefix)) + ret = os.system("git pull --force") + os.chdir(cwd) + else: + print("git clone %s %s/%s" % (gitURL, depot, gitPrefix)) + ret = os.system("git clone %s %s/%s" % (gitURL, depot, gitPrefix)) + if ret != 0: + raise EnvironmentError + + print( + "git archive --format=tar.gz --prefix=%s %s -o %s" + % (gitPrefix, gitLabel, pkgName) + ) + os.chdir("%s/%s/%s" % (cwd, depot, gitPrefix)) + try: + ret = subprocess.run( + [ + "git", + "archive", + "--format=tar.gz", + "--prefix=%s/" % gitPrefix, + "%s" % gitLabel, + "-o", + "../%s" % pkgName, + ], + shell=False, + ) + except Exception as e: + print("git archive failed of : %s" % str(e)) + sys.exit() + + os.chdir(cwd) + if ret.returncode != 0: + print(ret) + raise EnvironmentError + + +# Read cmd-line args +parser = argparse.ArgumentParser(description="DPDK test framework.") + +parser.add_argument( + "--config-file", + default="execution.cfg", + help="configuration file that describes the test " + "cases, DUTs and targets", +) + +parser.add_argument("--git", help="git label to use as input") + +parser.add_argument( + "--patch", action="append", help="apply a patch to the package under test" +) + +parser.add_argument( + "--snapshot", default="dep/dpdk.tar.gz", help="snapshot .tgz file to use as input" +) + +parser.add_argument( + "--output", default="", help="Output directory where dts log and result saved" +) + +parser.add_argument( + "-s", + "--skip-setup", + action="store_true", + help="skips all possible setup steps done on both DUT" + " and tester boards.", +) + +parser.add_argument( + "-r", + "--read-cache", + action="store_true", + help="reads the DUT configuration from a cache. If not " + + "specified, the DUT configuration will be calculated " + + "as usual and cached.", +) + +parser.add_argument( + "-p", "--project", default="dpdk", help="specify that which project will be tested" +) + +parser.add_argument( + "--suite-dir", + default="tests", + help="Test suite directory where test suites will be imported", +) + +parser.add_argument( + "-t", + "--test-cases", + action="append", + help="executes only the followings test cases", +) + +parser.add_argument( + "-d", + "--dir", + default="~/dpdk", + help="Output directory where dpdk package is extracted", +) + +parser.add_argument( + "-v", + "--verbose", + action="store_true", + help="enable verbose output, all message output on screen", +) + +parser.add_argument( + "--virttype", default="kvm", help="set virt type,support kvm, libvirtd" +) + +parser.add_argument( + "--debug", + action="store_true", + help="enable debug mode, user can enter debug mode in process", +) + +parser.add_argument( + "--debugcase", + action="store_true", + help="enable debug mode in the first case, user can further debug", +) +parser.add_argument( + "--re_run", + default=0, + help="when case failed will re-run times, and this value must >= 0", +) + +parser.add_argument( + "--commands", + action="append", + help="run command on tester or dut. The command format is " + + "[commands]:dut|tester:pre-init|post-init:check|ignore", +) + +parser.add_argument("--subtitle", help="add a subtitle to the rst report") + +parser.add_argument( + "--update-expected", + action="store_true", + help="update expected values based on test results", +) + +parser.add_argument( + "--asan", action="store_true", help="add function to support ASan test" +) + +args = parser.parse_args() + + +# prepare DPDK source test package, DTS will exited when failed. +if args.git is not None: + try: + git_build_package(args.git, os.path.split(args.snapshot)[1]) + except Exception: + print("FAILED TO PREPARE DPDK PACKAGE!!!") + sys.exit() + +# Main program begins here +dts.run_all( + args.config_file, + args.snapshot, + args.git, + args.patch, + args.skip_setup, + args.read_cache, + args.project, + args.suite_dir, + args.test_cases, + args.dir, + args.output, + args.verbose, + args.virttype, + args.debug, + args.debugcase, + args.re_run, + args.commands, + args.subtitle, + args.update_expected, + args.asan, +) From patchwork Wed Apr 6 14:56:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Juraj_Linke=C5=A1?= X-Patchwork-Id: 109230 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D5686A0507; Wed, 6 Apr 2022 16:58:30 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7AF56428C3; Wed, 6 Apr 2022 16:56:38 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id A9F31428A4 for ; Wed, 6 Apr 2022 16:56:33 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id D95CA1B27AA; Wed, 6 Apr 2022 16:56:32 +0200 (CEST) X-Virus-Scanned: amavisd-new at siecit.sk Received: from lb.pantheon.sk ([127.0.0.1]) by localhost (lb.pantheon.sk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gGfDFo10bmEs; Wed, 6 Apr 2022 16:56:32 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 0FD9C1B27A2; Wed, 6 Apr 2022 16:56:14 +0200 (CEST) From: =?utf-8?q?Juraj_Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?utf-8?q?Juraj_Linke=C5=A1?= Subject: [RFC PATCH v1 15/15] dts: merge DTS version.py to DPDK Date: Wed, 6 Apr 2022 14:56:06 +0000 Message-Id: <20220406145606.2913834-16-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> References: <20220406145606.2913834-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --- dts/version.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 dts/version.py diff --git a/dts/version.py b/dts/version.py new file mode 100755 index 0000000000..9f23357435 --- /dev/null +++ b/dts/version.py @@ -0,0 +1,21 @@ +# + +VERSION_MAJOR = "21" +VERSION_MINOR = "11" +VERSION_PATCH = "0" +VERSION_EXTRA = "" + +__version__ = "%s.%s.%s" % (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) + +if VERSION_EXTRA: + __version__ = "%s-%s" % (__version__, VERSION_EXTRA) + + +def dts_version(): + """ + Return the version of dts package + """ + return __version__ + + +__all__ = ["dts_version", "__version__"]