From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7F8BFA0543; Wed, 24 Aug 2022 18:25:04 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id F3139427F2; Wed, 24 Aug 2022 18:25:00 +0200 (CEST) Received: from lb.pantheon.sk (lb.pantheon.sk [46.229.239.20]) by mails.dpdk.org (Postfix) with ESMTP id 389964067B for ; Wed, 24 Aug 2022 18:24:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lb.pantheon.sk (Postfix) with ESMTP id 1B611CD261; Wed, 24 Aug 2022 18:24:58 +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 B2Ov44iDuPcn; Wed, 24 Aug 2022 18:24:55 +0200 (CEST) Received: from entguard.lab.pantheon.local (unknown [46.229.239.141]) by lb.pantheon.sk (Postfix) with ESMTP id 2AB34CD26A; Wed, 24 Aug 2022 18:24:55 +0200 (CEST) From: =?UTF-8?q?Juraj=20Linke=C5=A1?= To: thomas@monjalon.net, david.marchand@redhat.com, ronan.randles@intel.com, Honnappa.Nagarahalli@arm.com, ohilyard@iol.unh.edu, lijuan.tu@intel.com Cc: dev@dpdk.org, =?UTF-8?q?Juraj=20Linke=C5=A1?= Subject: [RFC PATCH v1 01/10] dts: hello world config options Date: Wed, 24 Aug 2022 16:24:45 +0000 Message-Id: <20220824162454.394285-2-juraj.linkes@pantheon.tech> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220824162454.394285-1-juraj.linkes@pantheon.tech> References: <20220824162454.394285-1-juraj.linkes@pantheon.tech> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 There are two categories of new config options: DPDK build/config options and testing options. Signed-off-by: Juraj Linkeš --- dts/conf.yaml | 20 ++- dts/framework/config/__init__.py | 141 ++++++++++++++++++++- dts/framework/config/conf_yaml_schema.json | 139 +++++++++++++++++++- 3 files changed, 289 insertions(+), 11 deletions(-) diff --git a/dts/conf.yaml b/dts/conf.yaml index cb12ea3d0f..36399c6e74 100644 --- a/dts/conf.yaml +++ b/dts/conf.yaml @@ -1,7 +1,21 @@ executions: - - system_under_test: "SUT 1" + - target_descriptions: + - cpu: native + compiler: gcc + arch: x86_64 + os: linux + perf: false + func: true + test_suites: + - hello_world + system_under_test: "SUT 1" nodes: - name: "SUT 1" - hostname: "SUT IP address or hostname" + hostname: sut1.change.me.localhost + os: linux user: root - password: "Leave blank to use SSH keys" + password: a + arch: x86_64 + bypass_core0: true + cores: 1 + memory_channels: 4 diff --git a/dts/framework/config/__init__.py b/dts/framework/config/__init__.py index a0fdffcd77..158baac143 100644 --- a/dts/framework/config/__init__.py +++ b/dts/framework/config/__init__.py @@ -6,11 +6,14 @@ """ Generic port and topology nodes configuration file load function """ +import abc import json import os.path import pathlib +from abc import abstractmethod from dataclasses import dataclass -from typing import Any, Optional +from enum import Enum, auto, unique +from typing import Any, Optional, TypedDict, Union import warlock import yaml @@ -18,6 +21,53 @@ from framework.settings import SETTINGS +class StrEnum(Enum): + @staticmethod + def _generate_next_value_( + name: str, start: int, count: int, last_values: object + ) -> str: + return name + + +@unique +class OS(StrEnum): + linux = auto() + freebsd = auto() + windows = auto() + + +@unique +class Architecture(StrEnum): + i686 = auto() + x86_64 = auto() + x86_32 = auto() + arm64 = auto() + ppc64le = auto() + + +@unique +class Compiler(StrEnum): + gcc = auto() + clang = auto() + icc = auto() + msvc = auto() + + +@unique +class CPU(StrEnum): + native = auto() + armv8a = auto() + dpaa2 = auto() + thunderx = auto() + xgene1 = auto() + + +@unique +class NodeType(StrEnum): + physical = auto() + virtual = auto() + + # Slots enables some optimizations, by pre-allocating space for the defined # attributes in the underlying data structure. # @@ -28,7 +78,12 @@ class NodeConfiguration: name: str hostname: str user: str + os: OS + arch: Architecture password: Optional[str] + bypass_core0: bool + cores: str + memory_channels: int @staticmethod def from_dict(d: dict) -> "NodeConfiguration": @@ -36,20 +91,101 @@ def from_dict(d: dict) -> "NodeConfiguration": name=d["name"], hostname=d["hostname"], user=d["user"], + os=OS(d["os"]), + arch=Architecture(d["arch"]), password=d.get("password"), + bypass_core0=d.get("bypass_core0", False), + cores=d["cores"], + memory_channels=d["memory_channels"], ) +@dataclass(slots=True, frozen=True) +class TargetDescription: + cpu: CPU + compiler: Compiler + arch: Architecture + os: OS + + @staticmethod + def from_dict(d: dict) -> "TargetDescription": + return TargetDescription( + cpu=CPU(d["cpu"]), + compiler=Compiler(d["compiler"]), + arch=Architecture(d["arch"]), + os=OS(d["os"]), + ) + + def __str__(self): + return f"{self.arch}-{self.os}-{self.cpu}-{self.compiler}" + + +class TestSuiteConfigDict(TypedDict): + suite: str + cases: list[str] + + +# https://github.com/python/mypy/issues/5374 +@dataclass(slots=True, frozen=True) # type: ignore +class TestSuiteConfig(abc.ABC): + test_suite: str + + @staticmethod + def from_dict( + entry: str | TestSuiteConfigDict, + ) -> Union["AllTestCasesTestSuiteConfig", "SelectedTestCasesTestSuiteConfig"]: + if isinstance(entry, str): + return AllTestCasesTestSuiteConfig(test_suite=entry) + elif isinstance(entry, dict): + return SelectedTestCasesTestSuiteConfig( + test_suite=entry["suite"], test_cases=entry["cases"] + ) + else: + raise TypeError(f"{type(entry)} is not valid for a test suite config.") + + @abstractmethod + def get_requested_test_cases(self) -> Optional[list[str]]: + raise NotImplementedError() + + +@dataclass(slots=True, frozen=True) +class AllTestCasesTestSuiteConfig(TestSuiteConfig): + def get_requested_test_cases(self) -> Optional[list[str]]: + return None + + +@dataclass(slots=True, frozen=True) +class SelectedTestCasesTestSuiteConfig(TestSuiteConfig): + test_cases: list[str] + + def get_requested_test_cases(self) -> Optional[list[str]]: + return self.test_cases + + @dataclass(slots=True, frozen=True) class ExecutionConfiguration: + target_descriptions: list[TargetDescription] + perf: bool + func: bool + test_suites: list[TestSuiteConfig] system_under_test: NodeConfiguration @staticmethod def from_dict(d: dict, node_map: dict) -> "ExecutionConfiguration": + target_descriptions: list[TargetDescription] = list( + map(TargetDescription.from_dict, d["target_descriptions"]) + ) + test_suites: list[TestSuiteConfig] = list( + map(TestSuiteConfig.from_dict, d["test_suites"]) + ) sut_name = d["system_under_test"] assert sut_name in node_map, f"Unknown SUT {sut_name} in execution {d}" return ExecutionConfiguration( + target_descriptions=target_descriptions, + perf=d["perf"], + func=d["func"], + test_suites=test_suites, system_under_test=node_map[sut_name], ) @@ -57,6 +193,7 @@ def from_dict(d: dict, node_map: dict) -> "ExecutionConfiguration": @dataclass(slots=True, frozen=True) class Configuration: executions: list[ExecutionConfiguration] + nodes: list[NodeConfiguration] @staticmethod def from_dict(d: dict) -> "Configuration": @@ -74,7 +211,7 @@ def from_dict(d: dict) -> "Configuration": ) ) - return Configuration(executions=executions) + return Configuration(executions=executions, nodes=nodes) def load_config() -> Configuration: diff --git a/dts/framework/config/conf_yaml_schema.json b/dts/framework/config/conf_yaml_schema.json index 04b2bec3a5..d1cc990fd5 100644 --- a/dts/framework/config/conf_yaml_schema.json +++ b/dts/framework/config/conf_yaml_schema.json @@ -6,13 +6,88 @@ "type": "string", "description": "A unique identifier for a node" }, - "node_role": { + "OS": { "type": "string", - "description": "The role a node plays in DTS", "enum": [ - "system_under_test", - "traffic_generator" + "linux" ] + }, + "ARCH": { + "type": "string", + "enum": [ + "x86_64" + ] + }, + "compiler": { + "type": "string", + "enum": [ + "gcc", + "clang", + "icc", + "mscv" + ] + }, + "cpu": { + "type": "string", + "description": "Native should be the default on x86", + "enum": [ + "native", + "armv8a", + "dpaa2", + "thunderx", + "xgene1" + ] + }, + "target": { + "type": "object", + "description": "Targets supported by DTS", + "properties": { + "arch": { + "type": "string", + "enum": [ + "ALL", + "x86_64", + "arm64", + "ppc64le", + "other" + ] + }, + "cpu": { + "$ref": "#/definitions/cpu" + }, + "os": { + "$ref": "#/definitions/OS" + }, + "compiler": { + "$ref": "#/definitions/compiler" + } + }, + "additionalProperties": false + }, + "test_suite": { + "type": "string", + "enum": [ + "hello_world" + ] + }, + "test_target": { + "type": "object", + "properties": { + "suite": { + "$ref": "#/definitions/test_suite" + }, + "cases": { + "type": "array", + "items": { + "type": "string" + }, + "minimum": 1 + } + }, + "required": [ + "suite" + ], + "additionalProperties": false } }, "type": "object", @@ -34,16 +109,36 @@ "type": "string", "description": "The user to access this node with." }, + "os": { + "$ref": "#/definitions/OS" + }, + "arch": { + "$ref": "#/definitions/ARCH" + }, "password": { "type": "string", "description": "The password to use on this node. SSH keys are preferred." + }, + "bypass_core0": { + "type": "boolean", + "description": "Indicate whether DPDK should omit using the first core or not." + }, + "cores": { + "type": "string", + "description": "Comma-separated list of cores to use, e.g.: 1,2,3,4,5,18-22" + }, + "memory_channels": { + "type": "integer", + "description": "How many memory channels to use." } }, "additionalProperties": false, "required": [ "name", + "os", + "user", "hostname", - "user" + "arch" ] }, "minimum": 1 @@ -55,11 +150,43 @@ "properties": { "system_under_test": { "$ref": "#/definitions/node_name" + }, + "target_descriptions": { + "type": "array", + "items": { + "$ref": "#/definitions/target" + }, + "minimum": 1 + }, + "test_suites": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/test_suite" + }, + { + "$ref": "#/definitions/test_target" + } + ] + } + }, + "perf": { + "type": "boolean", + "description": "Enable performance testing" + }, + "func": { + "type": "boolean", + "description": "Enable functional testing" } }, "additionalProperties": false, "required": [ - "system_under_test" + "system_under_test", + "target_descriptions", + "perf", + "func", + "test_suites" ] }, "minimum": 1 -- 2.30.2