1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021-2023 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17# This file does only contain a selection of the most common options. For a 18# full list see the documentation: 19# http://www.sphinx-doc.org/en/master/config 20 21import re 22from dataclasses import dataclass, field 23from enum import Enum 24from pathlib import Path 25from typing import Optional, Any, List 26 27import yaml 28 29METADATA_PATTERN = re.compile(r"(?<=\/\*---)(.*?)(?=---\*\/)", flags=re.DOTALL) 30PACKAGE_PATTERN = re.compile(r"\n\s*package[\t\f\v ]+(?P<package_name>\w+(\.\w+)*)\b") 31 32 33class Tags: 34 class EtsTag(Enum): 35 COMPILE_ONLY = "compile-only" 36 NO_WARMUP = "no-warmup" 37 NOT_A_TEST = "not-a-test" 38 NEGATIVE = "negative" 39 40 def __init__(self, tags: Optional[List[str]] = None) -> None: 41 self.__compile_only = Tags.__contains(Tags.EtsTag.COMPILE_ONLY.value, tags) 42 self.__negative = Tags.__contains(Tags.EtsTag.NEGATIVE.value, tags) 43 self.__not_a_test = Tags.__contains(Tags.EtsTag.NOT_A_TEST.value, tags) 44 self.__no_warmup = Tags.__contains(Tags.EtsTag.NO_WARMUP.value, tags) 45 46 @staticmethod 47 def __contains(tag: str, tags: Optional[List[str]]) -> bool: 48 return tag in tags if tags is not None else False 49 50 @property 51 def compile_only(self) -> bool: 52 return self.__compile_only 53 54 @property 55 def negative(self) -> bool: 56 return self.__negative 57 58 @property 59 def not_a_test(self) -> bool: 60 return self.__not_a_test 61 62 @property 63 def no_warmup(self) -> bool: 64 return self.__no_warmup 65 66 67@dataclass 68class TestMetadata: 69 tags: Tags 70 desc: Optional[str] = None 71 files: Optional[List[str]] = None 72 assertion: Optional[str] = None 73 params: Optional[Any] = None 74 name: Optional[str] = None 75 package: Optional[str] = None 76 ark_options: List[str] = field(default_factory=list) 77 timeout: Optional[int] = None 78 79 80def get_metadata(path: Path) -> TestMetadata: 81 data = Path.read_text(path) 82 yaml_text = "\n".join(re.findall(METADATA_PATTERN, data)) 83 metadata = yaml.safe_load(yaml_text) 84 if metadata is None: 85 metadata = {} 86 metadata['tags'] = Tags(metadata.get('tags')) 87 metadata['assertion'] = metadata.get('assert') 88 if 'assert' in metadata: 89 del metadata['assert'] 90 if isinstance(type(metadata.get('ark_options')), str): 91 metadata['ark_options'] = [metadata['ark_options']] 92 metadata['package'] = metadata.get("package") 93 if metadata['package'] is None: 94 metadata['package'] = get_package_statement(path) 95 return TestMetadata(**metadata) 96 97 98def get_package_statement(path: Path) -> Optional[str]: 99 data = Path.read_text(path) 100 match = PACKAGE_PATTERN.search(data) 101 if match is None: 102 return None 103 return stmt if (stmt := match.group("package_name")) is not None else None 104