xref: /aosp_15_r20/tools/netsim/scripts/tasks/run_pytest_task.py (revision cf78ab8cffb8fc9207af348f23af247fb04370a6)
1#!/usr/bin/env python3
2#
3# Copyright 2024 - The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the',  help="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',  help="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
17import logging
18from pathlib import Path
19import platform
20
21from environment import get_default_environment
22from tasks.task import Task
23from utils import (
24    AOSP_ROOT,
25    EMULATOR_ARTIFACT_PATH,
26    binary_extension,
27    run,
28)
29
30PYTEST_DIR = AOSP_ROOT / "external" / "adt-infra" / "pytest" / "test_embedded"
31OBJS_DIR = AOSP_ROOT / "tools" / "netsim" / "objs"
32
33
34class RunPyTestTask(Task):
35
36  def __init__(self, args):
37    super().__init__("RunPyTest")
38    self.buildbot = args.buildbot
39    self.pytest_input_dir = args.pytest_input_dir
40
41  def do_run(self):
42    run_pytest_manager = RunPytestManager(self.buildbot, self.pytest_input_dir)
43    return run_pytest_manager.process()
44
45
46class RunPytestManager:
47  """Manager for running e2e integration pytests with Emulator
48
49  The prerequisite is that the emulator installation has to be completed.
50  RunPytestManager runs a run_tests shell script in external/adt-infra.
51  It will take the emulator binary installed as the argument for the
52  script.
53
54  Attributes:
55
56  buildbot: A boolean indicating if it's being invoked with Android Build
57    Bots
58  """
59
60  def __init__(self, buildbot, pytest_input_dir):
61    """Initializes the instances based on environment
62
63    Args:
64        buildbot: Defines if it's being invoked with Build Bots and defines
65          self.dir as the directory of the emulator binary
66        pytest_input_dir: Defined the directory that includes netsim and
67          emulator binaries and libraries. Ignore if the string is empty.
68    """
69    # Default self.dir
70    self.dir = EMULATOR_ARTIFACT_PATH / "emulator" if buildbot else OBJS_DIR
71
72    # If pytest_input_dir is provided, set self.dir accordingly
73    if pytest_input_dir:
74      try:
75        self.dir = AOSP_ROOT / "tools" / "netsim" / Path(pytest_input_dir)
76      except Exception as e:
77        logging.error(f"Invalid pytest_input_dir value: {e}")
78
79  def _run_with_n_attempts(cmd, n):
80    for attempt in range(1, n + 1):
81      try:
82        run(cmd, get_default_environment(AOSP_ROOT), "e2e_pytests")
83        return
84      except Exception as e:
85        if attempt == n:
86          raise e
87        else:
88          logging.error(f"PyTest Attempt {attempt} Error: {e}")
89
90  def process(self) -> bool:
91    """Process the emulator e2e pytests
92
93    The process will check if the emulator installation occurred
94    and run the run_tests.sh script.
95    """
96    emulator_bin = self.dir / binary_extension("emulator")
97    if not (self.dir.exists() and emulator_bin.exists()):
98      logging.info(
99          "Please run 'scripts/build_tools.sh --InstallEmulator' "
100          "before running RunPyTest"
101      )
102      return False
103    if platform.system() == "Windows":
104      run_tests_script = PYTEST_DIR / "run_tests.cmd"
105    else:
106      run_tests_script = PYTEST_DIR / "run_tests.sh"
107    if platform.system() == "Linux":
108      test_config = PYTEST_DIR / "cfg" / "netsim_linux_tests.json"
109    else:
110      test_config = PYTEST_DIR / "cfg" / "netsim_tests.json"
111    cmd = [
112        run_tests_script,
113        "--emulator",
114        emulator_bin,
115        "--test_config",
116        test_config,
117    ]
118    # TODO: Resolve Windows PyTest failure
119    if platform.system() != "Windows":
120      cmd.append("--failures_as_errors")
121      run(cmd, get_default_environment(AOSP_ROOT), "e2e_pytests")
122    return True
123