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