This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch tvm-further-cleanup-python-tests-followup
in repository https://gitbox.apache.org/repos/asf/tvm.git

commit 847a618c9d7e7e359157faebdd5ef05b85dc8e6e
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Jul 5 15:17:37 2026 +0000

    [CI] Simplify Python test execution
    
    Run the regular Python suite from its canonical test root while preserving 
load-group scheduling for fixture ordering. Keep test-only pytest hooks local, 
move NNAPI tests under the nightly tree, and remove inert launchers and stale 
platform exclusions.
---
 ci/jenkins/generated/gpu_jenkinsfile.groovy        |   4 -
 ci/jenkins/templates/gpu_jenkinsfile.groovy.j2     |   4 -
 conftest.py                                        |  32 -------
 docs/contribute/code_guide.rst                     |   5 +-
 docs/contribute/pull_request.rst                   |   2 +-
 docs/contribute/testing.rst                        |   4 +-
 python/tvm/testing/plugin.py                       | 104 ---------------------
 python/tvm/testing/utils.py                        |  12 +--
 .../python}/test_nnapi/__init__.py                 |   0
 .../python}/test_nnapi/conftest.py                 |   0
 .../python}/test_nnapi/infrastructure.py           |   0
 .../test_nnapi/test_from_exported_to_cuda.py       |   0
 .../python}/test_nnapi/test_network.py             |   0
 .../python}/test_nnapi/test_ops.py                 |   0
 tests/python/conftest.py                           |  60 +++++++++---
 tests/python/disco/test_ccl.py                     |   3 +
 tests/python/disco/test_custom_allreduce.py        |   3 +-
 .../request_hook => python}/request_hook.py        |   2 +-
 tests/python/tirx/conftest.py                      |   6 +-
 tests/scripts/ci.py                                |   5 -
 tests/scripts/task_clear_pytest.sh                 |  22 -----
 tests/scripts/task_python_integration.sh           |  32 -------
 tests/scripts/task_python_integration_gpuonly.sh   |  27 ------
 tests/scripts/task_python_unittest.sh              |  51 +---------
 tests/scripts/task_python_unittest_gpuonly.sh      |   8 +-
 25 files changed, 76 insertions(+), 310 deletions(-)

diff --git a/ci/jenkins/generated/gpu_jenkinsfile.groovy 
b/ci/jenkins/generated/gpu_jenkinsfile.groovy
index 8624efbea8..e7ce14c4ba 100644
--- a/ci/jenkins/generated/gpu_jenkinsfile.groovy
+++ b/ci/jenkins/generated/gpu_jenkinsfile.groovy
@@ -530,10 +530,6 @@ def run_unittest_GPU(node_type) {
                 script: "${docker_run} ${ci_gpu} 
./tests/scripts/task_python_unittest_gpuonly.sh",
                 label: 'Run Python GPU unit tests',
               )
-              sh (
-                script: "${docker_run} ${ci_gpu} 
./tests/scripts/task_python_integration_gpuonly.sh",
-                label: 'Run Python GPU integration tests',
-              )
           })
         }
       }
diff --git a/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2 
b/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
index b05e84c7e7..4553fbefa2 100644
--- a/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
+++ b/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
@@ -53,10 +53,6 @@
     script: "${docker_run} ${ci_gpu} 
./tests/scripts/task_python_unittest_gpuonly.sh",
     label: 'Run Python GPU unit tests',
   )
-  sh (
-    script: "${docker_run} ${ci_gpu} 
./tests/scripts/task_python_integration_gpuonly.sh",
-    label: 'Run Python GPU integration tests',
-  )
 {% endcall %}
 
 
diff --git a/conftest.py b/conftest.py
deleted file mode 100644
index dd294ea548..0000000000
--- a/conftest.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-import os
-import sys
-from pathlib import Path
-
-pytest_plugins = ["tvm.testing.plugin"]
-IS_IN_CI = os.getenv("CI", "") == "true"
-REPO_ROOT = Path(__file__).resolve().parent
-
-
-def pytest_sessionstart():
-    if IS_IN_CI:
-        hook_script_dir = REPO_ROOT / "tests" / "scripts" / "request_hook"
-        sys.path.append(str(hook_script_dir))
-        import request_hook  # pylint: disable=import-outside-toplevel
-
-        request_hook.init()
diff --git a/docs/contribute/code_guide.rst b/docs/contribute/code_guide.rst
index 1622af120c..5136b9d4d6 100644
--- a/docs/contribute/code_guide.rst
+++ b/docs/contribute/code_guide.rst
@@ -127,7 +127,8 @@ Python Code Styles
 
 Writing Python Tests
 --------------------
-We use `pytest <https://docs.pytest.org/en/stable/>`_ for all python testing. 
``tests/python`` contains all the tests.
+We use `pytest <https://docs.pytest.org/en/stable/>`_ for all Python testing. 
Regular tests live
+under ``tests/python``, while environment-specific nightly tests live under 
``tests/nightly/python``.
 See :doc:`testing` for details on running tests, target parametrization,
 and the target-specific marks used by CI.
 
@@ -162,7 +163,7 @@ server can go down or be slow), so try to avoid using the 
network at all during
 this isn't a reasonable proposition (e.g. the docs tutorials which need to 
download models).
 
 New network downloads are rejected by the CI `request hook
-<https://github.com/apache/tvm/blob/main/tests/scripts/request_hook/request_hook.py>`_.
 Prefer
+<https://github.com/apache/tvm/blob/main/tests/python/request_hook.py>`_. 
Prefer
 checked-in fixtures or generated data. If a download is unavoidable, arrange a 
stable
 project-managed mirror with the maintainers and add an explicit ``URL_MAP`` 
entry.
 
diff --git a/docs/contribute/pull_request.rst b/docs/contribute/pull_request.rst
index a6c41b755f..969bb6f7d8 100644
--- a/docs/contribute/pull_request.rst
+++ b/docs/contribute/pull_request.rst
@@ -251,7 +251,7 @@ If you want to run all tests:
   # build tvm (see install-from-source for CMake build instructions)
   cd build && cmake .. && cmake --build . --parallel $(nproc) && cd ..
 
-  ./tests/scripts/task_python_unittest.sh
+  python -m pytest -vvs -n auto --dist=loadgroup tests/python
 
 If you want to run a single test:
 
diff --git a/docs/contribute/testing.rst b/docs/contribute/testing.rst
index 74a308945a..f30fd7d03b 100644
--- a/docs/contribute/testing.rst
+++ b/docs/contribute/testing.rst
@@ -299,8 +299,8 @@ in which stages.
 
 - Which tests run
 
-  The ``Unit Test`` and ``Integration Test`` stages of the Jenkinsfile
-  determine how ``pytest`` is called.  Each task starts by unpacking a
+  The ``Unit Test`` stage of the Jenkinsfile determines how ``pytest``
+  is called.  Each task starts by unpacking a
   compiled library that was previous compiled in the ``BUILD`` stage,
   then runs a test script
   (e.g. ``tests/scripts/task_python_unittest.sh``).  These scripts set
diff --git a/python/tvm/testing/plugin.py b/python/tvm/testing/plugin.py
deleted file mode 100644
index 2869664842..0000000000
--- a/python/tvm/testing/plugin.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# pylint: disable=unused-argument
-
-"""Pytest plugin for using tvm testing extensions.
-
-TVM provides utilities for testing across all supported targets, and
-to more easily parametrize across many inputs.  For more information
-on usage of these features, see documentation in the tvm.testing
-module.
-
-These are enabled by default in all pytests provided by tvm, but may
-be useful externally for one-off testing.  To enable, add the
-following line to the test script, or to the conftest.py in the same
-directory as the test scripts.
-
-     pytest_plugins = ['tvm.testing.plugin']
-
-"""
-
-import _pytest
-
-
-def pytest_collection_modifyitems(config, items):
-    """Called after all tests are chosen, currently used for bookkeeping."""
-    # pylint: disable=unused-argument
-    _count_num_fixture_uses(items)
-    _remove_global_fixture_definitions(items)
-    _sort_tests(items)
-
-
-def _count_num_fixture_uses(items):
-    # Helper function, counts the number of tests that use each cached
-    # fixture.  Should be called from pytest_collection_modifyitems().
-    for item in items:
-        is_skipped = item.get_closest_marker("skip") or any(
-            mark.args[0] for mark in item.iter_markers("skipif")
-        )
-        if is_skipped:
-            continue
-
-        for fixturedefs in item._fixtureinfo.name2fixturedefs.values():
-            # Only increment the active fixturedef, in a name has been 
overridden.
-            fixturedef = fixturedefs[-1]
-            if hasattr(fixturedef.func, "num_tests_use_this_fixture"):
-                fixturedef.func.num_tests_use_this_fixture[0] += 1
-
-
-def _remove_global_fixture_definitions(items):
-    # Helper function, removes fixture definitions from the global
-    # variables of the modules they were defined in.  This is intended
-    # to improve readability of error messages by giving a NameError
-    # if a test function accesses a pytest fixture but doesn't include
-    # it as an argument.  Should be called from
-    # pytest_collection_modifyitems().
-
-    modules = set(item.module for item in items)
-
-    for module in modules:
-        for name in dir(module):
-            obj = getattr(module, name)
-            if hasattr(obj, "_pytestfixturefunction") and isinstance(
-                obj._pytestfixturefunction, 
_pytest.fixtures.FixtureFunctionMarker
-            ):
-                delattr(module, name)
-
-
-def _sort_tests(items):
-    """Sort tests by file/function.
-
-    By default, pytest will sort tests to maximize the re-use of
-    fixtures.  However, this assumes that all fixtures have an equal
-    cost to generate, and no caches outside of those managed by
-    pytest.  A tvm.testing.parameter is effectively free, while
-    reference data for testing may be quite large.  Since most of the
-    TVM fixtures are specific to a python function, sort the test
-    ordering by python function, so that
-    tvm.testing.utils._fixture_cache can be cleared sooner rather than
-    later.
-
-    Should be called from pytest_collection_modifyitems.
-
-    """
-
-    def sort_key(item):
-        filename, lineno, test_name = item.location
-        test_name = test_name.split("[")[0]
-        return filename, lineno, test_name
-
-    items.sort(key=sort_key)
diff --git a/python/tvm/testing/utils.py b/python/tvm/testing/utils.py
index 6b1c02b01e..2e1e04a7f0 100644
--- a/python/tvm/testing/utils.py
+++ b/python/tvm/testing/utils.py
@@ -824,9 +824,8 @@ def _fixture_cache(func):
         if num_tests_use_this_fixture[0] == 0:
             raise RuntimeError(
                 "Fixture use count is 0.  "
-                "This can occur if tvm.testing.plugin isn't registered.  "
-                "If using outside of the TVM test directory, "
-                "please add `pytest_plugins = ['tvm.testing.plugin']` to your 
conftest.py"
+                "Cached tvm.testing fixtures must be collected from 
tests/python "
+                "so its conftest can count fixture uses."
             )
 
         try:
@@ -925,9 +924,10 @@ def install_request_hook(depth: int) -> None:
         depth -= 1
 
     # Ensure the specified dir is valid
-    hook_script_dir = hook_script_dir / "tests" / "scripts" / "request_hook"
-    if not hook_script_dir.exists():
-        raise RuntimeError(f"Directory {hook_script_dir} does not 
exist:\n{msg}")
+    hook_script_dir = hook_script_dir / "tests" / "python"
+    hook_script = hook_script_dir / "request_hook.py"
+    if not hook_script.is_file():
+        raise RuntimeError(f"File {hook_script} does not exist:\n{msg}")
 
     # Import the hook and start it up (it's not included here directly to avoid
     # keeping a database of URLs inside the tvm Python package
diff --git a/tests/python/nightly/test_nnapi/__init__.py 
b/tests/nightly/python/test_nnapi/__init__.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/__init__.py
rename to tests/nightly/python/test_nnapi/__init__.py
diff --git a/tests/python/nightly/test_nnapi/conftest.py 
b/tests/nightly/python/test_nnapi/conftest.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/conftest.py
rename to tests/nightly/python/test_nnapi/conftest.py
diff --git a/tests/python/nightly/test_nnapi/infrastructure.py 
b/tests/nightly/python/test_nnapi/infrastructure.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/infrastructure.py
rename to tests/nightly/python/test_nnapi/infrastructure.py
diff --git a/tests/python/nightly/test_nnapi/test_from_exported_to_cuda.py 
b/tests/nightly/python/test_nnapi/test_from_exported_to_cuda.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/test_from_exported_to_cuda.py
rename to tests/nightly/python/test_nnapi/test_from_exported_to_cuda.py
diff --git a/tests/python/nightly/test_nnapi/test_network.py 
b/tests/nightly/python/test_nnapi/test_network.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/test_network.py
rename to tests/nightly/python/test_nnapi/test_network.py
diff --git a/tests/python/nightly/test_nnapi/test_ops.py 
b/tests/nightly/python/test_nnapi/test_ops.py
similarity index 100%
rename from tests/python/nightly/test_nnapi/test_ops.py
rename to tests/nightly/python/test_nnapi/test_ops.py
diff --git a/tests/python/conftest.py b/tests/python/conftest.py
index 5d55ba5c6a..bf105ae97c 100644
--- a/tests/python/conftest.py
+++ b/tests/python/conftest.py
@@ -14,17 +14,55 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-"""Configure pytest"""
+"""Configure pytest for TVM's Python test suite."""
 
-import sys
+import os
 
-COLLECT_IGNORE = []
-if sys.platform.startswith("win"):
-    COLLECT_IGNORE.append("frontend/coreml")
-    COLLECT_IGNORE.append("frontend/keras")
-    COLLECT_IGNORE.append("frontend/pytorch")
-    COLLECT_IGNORE.append("frontend/tensorflow")
-    COLLECT_IGNORE.append("frontend/tflite")
-    COLLECT_IGNORE.append("frontend/onnx")
+import _pytest
 
-    COLLECT_IGNORE.append("tir_base/test_tir_intrin.py")
+
+def pytest_collection_modifyitems(items):
+    """Maintain the ordering and cache bookkeeping required by TVM fixtures."""
+    _count_num_fixture_uses(items)
+    _remove_global_fixture_definitions(items)
+    _sort_tests(items)
+
+
+def _count_num_fixture_uses(items):
+    for item in items:
+        is_skipped = item.get_closest_marker("skip") or any(
+            mark.args[0] for mark in item.iter_markers("skipif")
+        )
+        if is_skipped:
+            continue
+
+        for fixturedefs in item._fixtureinfo.name2fixturedefs.values():
+            fixturedef = fixturedefs[-1]
+            if hasattr(fixturedef.func, "num_tests_use_this_fixture"):
+                fixturedef.func.num_tests_use_this_fixture[0] += 1
+
+
+def _remove_global_fixture_definitions(items):
+    modules = {item.module for item in items}
+    for module in modules:
+        for name in dir(module):
+            obj = getattr(module, name)
+            if hasattr(obj, "_pytestfixturefunction") and isinstance(
+                obj._pytestfixturefunction, 
_pytest.fixtures.FixtureFunctionMarker
+            ):
+                delattr(module, name)
+
+
+def _sort_tests(items):
+    def sort_key(item):
+        filename, lineno, test_name = item.location
+        return filename, lineno, test_name.split("[")[0]
+
+    items.sort(key=sort_key)
+
+
+def pytest_sessionstart():
+    if os.getenv("CI", "") == "true":
+        from request_hook import init  # pylint: 
disable=import-outside-toplevel
+
+        init()
diff --git a/tests/python/disco/test_ccl.py b/tests/python/disco/test_ccl.py
index 29d46d4ec1..82dbc27ab7 100644
--- a/tests/python/disco/test_ccl.py
+++ b/tests/python/disco/test_ccl.py
@@ -31,6 +31,9 @@ from tvm.runtime.vm import VirtualMachine
 from tvm.s_tir import dlight as dl
 from tvm.script import relax as R
 
+if di is None:
+    pytest.skip("disco runtime is not available", allow_module_level=True)
+
 _all_session_kinds = [di.ThreadedSession, di.ProcessSession]
 _compiled_ccl = get_global_func("runtime.disco.compiled_ccl", 
allow_missing=True)
 if _compiled_ccl is None:
diff --git a/tests/python/disco/test_custom_allreduce.py 
b/tests/python/disco/test_custom_allreduce.py
index f49da02836..6728e3115d 100644
--- a/tests/python/disco/test_custom_allreduce.py
+++ b/tests/python/disco/test_custom_allreduce.py
@@ -26,7 +26,6 @@ from tvm_ffi import Shape
 import tvm
 import tvm.testing
 from tvm.runtime import DataType, disco
-from tvm.runtime.disco import Session
 
 
 class AllReduceStrategyType(enum.IntEnum):
@@ -56,7 +55,7 @@ _ccl = [ccl for ccl in _compiled_ccl() if ccl == "nccl"]
 @pytest.mark.parametrize("strategy", _strategies)
 def test_allreduce(shape, ccl, strategy):
     devices = [0, 1]
-    sess: Session = disco.ProcessSession(num_workers=len(devices))
+    sess: disco.Session = disco.ProcessSession(num_workers=len(devices))
     sess.init_ccl(ccl, *devices)
 
     num_elements = reduce(lambda x, y: x * y, shape)
diff --git a/tests/scripts/request_hook/request_hook.py 
b/tests/python/request_hook.py
similarity index 95%
rename from tests/scripts/request_hook/request_hook.py
rename to tests/python/request_hook.py
index 48ac5e2a30..5a00a11cdd 100644
--- a/tests/scripts/request_hook/request_hook.py
+++ b/tests/python/request_hook.py
@@ -35,7 +35,7 @@ class TvmRequestHook(urllib.request.Request):
             msg = (
                 f"Uncaught URL found in CI: {url}. "
                 "Avoid network access or arrange a stable project-managed 
mirror, "
-                "then add it to URL_MAP in 
tests/scripts/request_hook/request_hook.py."
+                "then add it to URL_MAP in tests/python/request_hook.py."
             )
             raise RuntimeError(msg)
 
diff --git a/tests/python/tirx/conftest.py b/tests/python/tirx/conftest.py
index fb8ba62f4f..c2a7a28d28 100644
--- a/tests/python/tirx/conftest.py
+++ b/tests/python/tirx/conftest.py
@@ -25,6 +25,8 @@ real sm_100a device so it skips cleanly where the hardware is 
absent and runs
 in full where it is present.
 """
 
+from pathlib import Path
+
 import pytest
 
 from tvm.testing import env
@@ -33,8 +35,10 @@ from tvm.testing import env
 def pytest_collection_modifyitems(config, items):
     if env.has_cuda_compute(10):
         return
+    suite_root = Path(__file__).parent
     skip = pytest.mark.skip(
         reason="tirx suite requires a CUDA compute capability 10.0 (sm_100a) 
device"
     )
     for item in items:
-        item.add_marker(skip)
+        if item.path.is_relative_to(suite_root):
+            item.add_marker(skip)
diff --git a/tests/scripts/ci.py b/tests/scripts/ci.py
index bea70e0b52..fa027c150a 100755
--- a/tests/scripts/ci.py
+++ b/tests/scripts/ci.py
@@ -591,7 +591,6 @@ generated = [
                 [
                     "./tests/scripts/task_java_unittest.sh",
                     "./tests/scripts/task_python_unittest_gpuonly.sh",
-                    "./tests/scripts/task_python_integration_gpuonly.sh",
                 ],
             ),
         },
@@ -601,10 +600,6 @@ generated = [
         help="Run CPU build and test(s)",
         options={
             "cpp": CPP_UNITTEST,
-            "integration": (
-                "run integration tests",
-                ["./tests/scripts/task_python_integration.sh"],
-            ),
             "unittest": (
                 "run unit tests",
                 [
diff --git a/tests/scripts/task_clear_pytest.sh 
b/tests/scripts/task_clear_pytest.sh
deleted file mode 100755
index 430425791c..0000000000
--- a/tests/scripts/task_clear_pytest.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -euo pipefail
-
-# PR jobs evaluate their Jenkinsfile from the trusted base branch.  Keep this
-# inert entry point until the Jenkinsfile update has landed on the base branch.
diff --git a/tests/scripts/task_python_integration.sh 
b/tests/scripts/task_python_integration.sh
deleted file mode 100755
index 7dd3c9b578..0000000000
--- a/tests/scripts/task_python_integration.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -euxo pipefail
-
-export PYTHONPATH="$(pwd)/python"
-export LD_LIBRARY_PATH="build:${LD_LIBRARY_PATH:-}"
-
-# to avoid CI CPU thread throttling.
-export TVM_BIND_THREADS=0
-export TVM_NUM_THREADS=2
-
-# cleanup pycache
-find . -type f -path "*.pyc" | xargs rm -f
-
-# setup tvm-ffi into python folder
-uv pip install -v --target=python ./3rdparty/tvm-ffi/
diff --git a/tests/scripts/task_python_integration_gpuonly.sh 
b/tests/scripts/task_python_integration_gpuonly.sh
deleted file mode 100755
index 9b825b9182..0000000000
--- a/tests/scripts/task_python_integration_gpuonly.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -exo pipefail
-
-export 
TVM_TEST_TARGETS='cuda;opencl;metal;rocm;nvptx;{"kind":"opencl","device":"mali,adreno"}'
-# Every GPU test carries the `gpu` marker; the specific backend is gated by 
skipif.
-export PYTEST_ADDOPTS="-m gpu $PYTEST_ADDOPTS"
-export TVM_RELAY_TEST_TARGETS="cuda"
-export TVM_INTEGRATION_GPU_ONLY=1
-
-./tests/scripts/task_python_integration.sh
diff --git a/tests/scripts/task_python_unittest.sh 
b/tests/scripts/task_python_unittest.sh
index 0728743fb5..1cf297fc28 100755
--- a/tests/scripts/task_python_unittest.sh
+++ b/tests/scripts/task_python_unittest.sh
@@ -19,55 +19,10 @@
 set -euxo pipefail
 
 export PYTHONPATH="$(pwd)/python"
-export PYTEST_ADDOPTS="-s -vv ${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
-
-# cleanup pycache
-find . -type f -path "*.pyc" | xargs rm -f
+export PYTEST_ADDOPTS="${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
 
 # setup tvm-ffi into python folder
 uv pip install -v --target=python ./3rdparty/tvm-ffi/
 
-# First run the minimal platform test.  A GPU-only run can select no tests 
here.
-if [ ! -d tests/python/all-platform-minimal-test ]; then
-    echo "Missing pytest target: tests/python/all-platform-minimal-test" >&2
-    exit 1
-fi
-python3 -m pytest -n auto tests/python/all-platform-minimal-test || [ "$?" -eq 
5 ]
-
-# Then run all unit tests.
-TEST_FILES=(
-  "arith"
-  "ci"
-  "codegen"
-  "driver"
-  "ir"
-  "runtime"
-  "target"
-  "te"
-  "testing"
-  "s_tir/base"
-  "s_tir/schedule"
-  "s_tir/dlight"
-  "s_tir/analysis"
-  "s_tir/meta_schedule"
-  "s_tir/transform"
-  "tirx-analysis"
-  "tirx-base"
-  "tirx-transform"
-  "tirx"
-  "tvmscript"
-  "relax"
-)
-
-PYTEST_TARGETS=()
-for TEST_FILE in "${TEST_FILES[@]}"; do
-    TEST_PATH="tests/python/${TEST_FILE}"
-    if [ ! -e "${TEST_PATH}" ]; then
-        echo "Missing pytest target: ${TEST_PATH}" >&2
-        exit 1
-    fi
-    PYTEST_TARGETS+=("${TEST_PATH}")
-done
-
-# Do not mask pytest's exit 5: an unexpectedly empty broad suite must fail CI.
-python3 -m pytest -n auto --dist=loadgroup "${PYTEST_TARGETS[@]}"
+# Load-group distribution keeps the order-dependent fixture tests on one 
worker.
+python3 -m pytest -vvs -n auto --dist=loadgroup tests/python
diff --git a/tests/scripts/task_python_unittest_gpuonly.sh 
b/tests/scripts/task_python_unittest_gpuonly.sh
index 8194b23ac4..e6ac397c45 100755
--- a/tests/scripts/task_python_unittest_gpuonly.sh
+++ b/tests/scripts/task_python_unittest_gpuonly.sh
@@ -32,10 +32,6 @@ export TVM_TEST_TARGETS='cuda;metal;rocm;nvptx'
 export TVM_TEST_TARGETS='{"kind":"vulkan","from_device":0}'
 
 export PYTHONPATH="$(pwd)/python"
-export PYTEST_ADDOPTS="-s -vv ${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
+export PYTEST_ADDOPTS="${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
 
-if [ ! -f tests/python/codegen/test_target_codegen_vulkan.py ]; then
-    echo "Missing pytest target: 
tests/python/codegen/test_target_codegen_vulkan.py" >&2
-    exit 1
-fi
-python3 -m pytest -n auto tests/python/codegen/test_target_codegen_vulkan.py
+python3 -m pytest -vvs -n auto 
tests/python/codegen/test_target_codegen_vulkan.py

Reply via email to