1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2021-2024 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 defines the CTS file structure 18# The entrypoint is the function 'walk_test_subdirs' 19from __future__ import annotations 20 21import os 22from dataclasses import dataclass 23from pathlib import Path 24from typing import List, Optional, Iterator 25 26 27@dataclass 28class TestDirectory: 29 path: Path 30 name: str 31 32 parent: Optional[TestDirectory] 33 subdirs: List[TestDirectory] 34 35 def __init__(self, path: Path, 36 test_id: int = 0, 37 name: str = "", 38 parent: Optional[TestDirectory] = None, 39 subdirs: Optional[List[TestDirectory]] = None) -> None: 40 41 self.path = path 42 43 if test_id == 0 or name == "": 44 self.name = str(path) 45 else: 46 self.test_id = test_id 47 self.name = name 48 49 self.parent = parent 50 self.subdirs = subdirs if subdirs is not None else [] 51 52 def full_index(self) -> List[int]: 53 cur: Optional[TestDirectory] = self 54 result = [] 55 while cur is not None: 56 result.append(cur.test_id) 57 cur = cur.parent 58 return list(reversed(result)) 59 60 def iter_files(self, allowed_ext: Optional[List[str]] = None) -> Iterator[Path]: 61 for filename in os.listdir(str(self.path)): 62 filepath: Path = self.path / filename 63 if allowed_ext and filepath.suffix not in allowed_ext: 64 continue 65 yield filepath 66 67 def add_subdir(self, test_dir: TestDirectory) -> None: 68 test_dir.parent = self 69 self.subdirs.append(test_dir) 70 71 def find_subdir_by_name(self, name: str) -> Optional[TestDirectory]: 72 # decrease complexity 73 for sub_dir in self.subdirs: 74 if sub_dir.name == name: 75 return sub_dir 76 return None 77 78 def is_empty(self) -> bool: 79 return len(os.listdir(str(self.path))) == 0 80 81 82def walk_test_subdirs(path: Path, parent: Optional[TestDirectory] = None) -> Iterator[TestDirectory]: 83 """ 84 Walks the file system from the CTS root, yielding TestDirectories, in correct order: 85 For example, if only directories 1, 1/1, 1/1/1, 1/1/2, 1/2 exist, they will be yielded in that order. 86 """ 87 subdirs = [] 88 for name in os.listdir(str(path)): 89 if (path / name).is_dir(): 90 subdirs.append(TestDirectory(parent=parent, path=(path / name))) 91 92 for subdir in subdirs: 93 yield subdir 94 # walk recursively 95 for subsubdir in walk_test_subdirs(subdir.path, subdir): 96 yield subsubdir 97