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 98 99def build_directory_tree(test_dir: TestDirectory) -> None: 100 subdirs = [] 101 for name in os.listdir(str(test_dir.path)): 102 if (test_dir.path / name).is_dir(): 103 subdirs.append(TestDirectory( 104 parent=test_dir, path=(test_dir.path / name))) 105 subdirs = sorted(subdirs, key=lambda dir: dir.test_id) 106 107 for sub_dir in subdirs: 108 test_dir.add_subdir(sub_dir) 109 build_directory_tree(sub_dir) 110 111 112def print_tree(test_dir: TestDirectory) -> None: 113 for sub_dir in test_dir.subdirs: 114 left_space = " " * 2 * len(sub_dir.full_index()) 115 section_index = str(sub_dir.test_id) 116 section_name = sub_dir.name.replace("_", " ").title() 117 right_space = 90 - len(left_space) - \ 118 len(section_index) - len(section_name) 119 120 print(left_space, section_index, section_name, "." * right_space, "\n") 121 print_tree(sub_dir) 122