This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch tvm-simplify-jenkins-pytest-sharding
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to
refs/heads/tvm-simplify-jenkins-pytest-sharding by this push:
new 9f4feee101 [CI] Remove pytest JUnit reporting
9f4feee101 is described below
commit 9f4feee10113767bcec5676ba6b9e1c0ebdae4ac
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Jul 5 01:36:07 2026 +0000
[CI] Remove pytest JUnit reporting
---
ci/jenkins/generated/arm_jenkinsfile.groovy | 9 +-
ci/jenkins/generated/cpu_jenkinsfile.groovy | 21 +-
ci/jenkins/generated/docker_jenkinsfile.groovy | 9 +-
ci/jenkins/generated/gpu_jenkinsfile.groovy | 33 +--
ci/jenkins/generated/wasm_jenkinsfile.groovy | 10 +-
ci/jenkins/templates/cpu_jenkinsfile.groovy.j2 | 1 -
ci/jenkins/templates/gpu_jenkinsfile.groovy.j2 | 2 -
ci/jenkins/templates/utils/Build.groovy.j2 | 7 -
ci/jenkins/templates/utils/macros.j2 | 15 --
ci/jenkins/templates/wasm_jenkinsfile.groovy.j2 | 1 -
ci/scripts/github/__init__.py | 2 +-
ci/scripts/github/github_pr_comment.py | 4 -
ci/scripts/github/github_skipped_tests_comment.py | 263 -------------------
python/tvm/testing/plugin.py | 9 -
tests/python/ci/test_ci.py | 280 +--------------------
.../meta_schedule/test_meta_schedule_cost_model.py | 11 +-
.../test_meta_schedule_search_strategy.py | 1 +
.../test_meta_schedule_task_scheduler.py | 13 +
tests/python/testing/test_tvm_testing_features.py | 42 +++-
tests/scripts/task_clear_pytest.sh | 24 --
tests/scripts/task_python_nightly.sh | 39 ---
tests/scripts/task_python_unittest.sh | 33 ++-
tests/scripts/task_python_unittest_gpuonly.sh | 13 +-
23 files changed, 88 insertions(+), 754 deletions(-)
diff --git a/ci/jenkins/generated/arm_jenkinsfile.groovy
b/ci/jenkins/generated/arm_jenkinsfile.groovy
index 573885545a..3442caded7 100644
--- a/ci/jenkins/generated/arm_jenkinsfile.groovy
+++ b/ci/jenkins/generated/arm_jenkinsfile.groovy
@@ -60,7 +60,7 @@
// 'python3 jenkins/generate.py'
// Note: This timestamp is here to ensure that updates to the Jenkinsfile are
// always rebased on main before merging:
-// Generated at 2026-07-04T23:53:56.833713
+// Generated at 2026-07-05T01:05:57.719405
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
// These are set at runtime from data in ci/jenkins/docker-images.yml, update
@@ -404,13 +404,6 @@ def prepare(node_type) {
}
}
}
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
diff --git a/ci/jenkins/generated/cpu_jenkinsfile.groovy
b/ci/jenkins/generated/cpu_jenkinsfile.groovy
index dc944096ab..0d3e408235 100644
--- a/ci/jenkins/generated/cpu_jenkinsfile.groovy
+++ b/ci/jenkins/generated/cpu_jenkinsfile.groovy
@@ -60,7 +60,7 @@
// 'python3 jenkins/generate.py'
// Note: This timestamp is here to ensure that updates to the Jenkinsfile are
// always rebased on main before merging:
-// Generated at 2026-07-04T23:53:56.855205
+// Generated at 2026-07-05T01:05:57.741181
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
// These are set at runtime from data in ci/jenkins/docker-images.yml, update
@@ -404,13 +404,6 @@ def prepare(node_type) {
}
}
}
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
@@ -528,22 +521,10 @@ def run_unittest_CPU(node_type) {
label: 'Download artifacts from S3',
)
- ci_setup(ci_cpu)
cpp_unittest(ci_cpu)
python_unittest(ci_cpu)
})
}
- // only run upload if things are successful
- try {
- sh(
- script: "./${jenkins_scripts_root}/s3.py --action upload --bucket
${s3_bucket} --prefix ${s3_prefix}/pytest-results/unittest_CPU --items
build/pytest-results",
- label: 'Upload JUnits to S3',
- )
-
- junit 'build/pytest-results/*.xml'
- } catch (Exception e) {
- echo 'Exception during JUnit upload: ' + e.toString()
- }
}
}
echo 'End running on node_type ' + node_type
diff --git a/ci/jenkins/generated/docker_jenkinsfile.groovy
b/ci/jenkins/generated/docker_jenkinsfile.groovy
index 95f2fd8dd6..8ffe78942a 100644
--- a/ci/jenkins/generated/docker_jenkinsfile.groovy
+++ b/ci/jenkins/generated/docker_jenkinsfile.groovy
@@ -60,7 +60,7 @@
// 'python3 jenkins/generate.py'
// Note: This timestamp is here to ensure that updates to the Jenkinsfile are
// always rebased on main before merging:
-// Generated at 2026-07-04T23:53:56.875051
+// Generated at 2026-07-05T01:05:57.759905
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
// These are set at runtime from data in ci/jenkins/docker-images.yml, update
@@ -404,13 +404,6 @@ def prepare(node_type) {
}
}
}
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
diff --git a/ci/jenkins/generated/gpu_jenkinsfile.groovy
b/ci/jenkins/generated/gpu_jenkinsfile.groovy
index d31160dd52..792b7eadc4 100644
--- a/ci/jenkins/generated/gpu_jenkinsfile.groovy
+++ b/ci/jenkins/generated/gpu_jenkinsfile.groovy
@@ -60,7 +60,7 @@
// 'python3 jenkins/generate.py'
// Note: This timestamp is here to ensure that updates to the Jenkinsfile are
// always rebased on main before merging:
-// Generated at 2026-07-04T23:53:56.896868
+// Generated at 2026-07-05T01:05:57.780838
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
// These are set at runtime from data in ci/jenkins/docker-images.yml, update
@@ -404,13 +404,6 @@ def prepare(node_type) {
}
}
}
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
@@ -533,7 +526,6 @@ def run_unittest_GPU(node_type) {
label: 'Download artifacts from S3',
)
- ci_setup(ci_gpu)
sh (
script: "${docker_run} ${ci_gpu}
./tests/scripts/task_java_unittest.sh",
label: 'Run Java unit tests',
@@ -548,17 +540,6 @@ def run_unittest_GPU(node_type) {
)
})
}
- // only run upload if things are successful
- try {
- sh(
- script: "./${jenkins_scripts_root}/s3.py --action upload --bucket
${s3_bucket} --prefix ${s3_prefix}/pytest-results/unittest_GPU --items
build/pytest-results",
- label: 'Upload JUnits to S3',
- )
-
- junit 'build/pytest-results/*.xml'
- } catch (Exception e) {
- echo 'Exception during JUnit upload: ' + e.toString()
- }
}
}
echo 'End running on node_type ' + node_type
@@ -587,7 +568,6 @@ def run_docs_GPU(node_type) {
label: 'Download artifacts from S3',
)
- ci_setup(ci_gpu)
sh (
script: "${docker_run} ${ci_gpu}
./tests/scripts/task_python_docs.sh",
label: 'Build docs',
@@ -603,17 +583,6 @@ def run_docs_GPU(node_type) {
)
})
}
- // only run upload if things are successful
- try {
- sh(
- script: "./${jenkins_scripts_root}/s3.py --action upload --bucket
${s3_bucket} --prefix ${s3_prefix}/pytest-results/docs_GPU --items
build/pytest-results",
- label: 'Upload JUnits to S3',
- )
-
- junit 'build/pytest-results/*.xml'
- } catch (Exception e) {
- echo 'Exception during JUnit upload: ' + e.toString()
- }
}
}
echo 'End running on node_type ' + node_type
diff --git a/ci/jenkins/generated/wasm_jenkinsfile.groovy
b/ci/jenkins/generated/wasm_jenkinsfile.groovy
index b6946a40fe..7421fa86ca 100644
--- a/ci/jenkins/generated/wasm_jenkinsfile.groovy
+++ b/ci/jenkins/generated/wasm_jenkinsfile.groovy
@@ -60,7 +60,7 @@
// 'python3 jenkins/generate.py'
// Note: This timestamp is here to ensure that updates to the Jenkinsfile are
// always rebased on main before merging:
-// Generated at 2026-07-04T23:53:56.918767
+// Generated at 2026-07-05T01:05:57.802104
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
// These are set at runtime from data in ci/jenkins/docker-images.yml, update
@@ -404,13 +404,6 @@ def prepare(node_type) {
}
}
}
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
@@ -471,7 +464,6 @@ def run_build(node_type) {
cmake_build(ci_wasm, 'build')
make_cpp_tests(ci_wasm, 'build')
cpp_unittest(ci_wasm)
- ci_setup(ci_wasm)
sh (
script: "${docker_run} ${ci_wasm} ./tests/scripts/task_web_wasm.sh",
label: 'Run WASM lint and tests',
diff --git a/ci/jenkins/templates/cpu_jenkinsfile.groovy.j2
b/ci/jenkins/templates/cpu_jenkinsfile.groovy.j2
index 75b43c52a8..62b7c3dfea 100644
--- a/ci/jenkins/templates/cpu_jenkinsfile.groovy.j2
+++ b/ci/jenkins/templates/cpu_jenkinsfile.groovy.j2
@@ -45,7 +45,6 @@
test_method_names=test_method_names,
) %}
{{ m.download_artifacts(tag='cpu') }}
- ci_setup(ci_cpu)
cpp_unittest(ci_cpu)
python_unittest(ci_cpu)
{% endcall %}
diff --git a/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
b/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
index 33e5a8aed5..3a13dfe7f3 100644
--- a/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
+++ b/ci/jenkins/templates/gpu_jenkinsfile.groovy.j2
@@ -46,7 +46,6 @@
test_method_names=test_method_names,
) %}
{{ m.download_artifacts(tag='gpu') }}
- ci_setup(ci_gpu)
sh (
script: "${docker_run} ${ci_gpu} ./tests/scripts/task_java_unittest.sh",
label: 'Run Java unit tests',
@@ -71,7 +70,6 @@
test_method_names=test_method_names,
) %}
{{ m.download_artifacts(tag='gpu') }}
- ci_setup(ci_gpu)
sh (
script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_docs.sh",
label: 'Build docs',
diff --git a/ci/jenkins/templates/utils/Build.groovy.j2
b/ci/jenkins/templates/utils/Build.groovy.j2
index c20a1c5c43..42bd4a991f 100644
--- a/ci/jenkins/templates/utils/Build.groovy.j2
+++ b/ci/jenkins/templates/utils/Build.groovy.j2
@@ -1,10 +1,3 @@
-def ci_setup(image) {
- sh (
- script: "${docker_run} ${image} ./tests/scripts/task_clear_pytest.sh",
- label: 'Clean up old workspace',
- )
-}
-
def python_unittest(image) {
sh (
script: "${docker_run} ${image} ./tests/scripts/task_python_unittest.sh",
diff --git a/ci/jenkins/templates/utils/macros.j2
b/ci/jenkins/templates/utils/macros.j2
index bd0e0d4ee4..959d91725f 100644
--- a/ci/jenkins/templates/utils/macros.j2
+++ b/ci/jenkins/templates/utils/macros.j2
@@ -19,16 +19,8 @@
"workspace/exec_${env.EXECUTOR_NUMBER}/{{ folder }}"
{%- endmacro -%}
-{% macro junit_to_s3(test_dir_name) %}
-sh(
- script: "./${jenkins_scripts_root}/s3.py --action upload --bucket
${s3_bucket} --prefix ${s3_prefix}/pytest-results/{{ test_dir_name }} --items
build/pytest-results",
- label: 'Upload JUnits to S3',
- )
-{% endmacro %}
-
{% macro test_step(name, ws, docker_image, platform, test_method_names,
condition="!skip_ci && is_docs_only_build != 1") %}
{% set method_name = "run_" + name.replace(":", "").replace(" ",
"-").replace("-", "_") %}
-{% set test_dir_name = name.replace(":", "").replace(" ", "-").replace("-",
"_")|string %}
def {{ method_name }}(node_type) {
echo 'Begin running on node_type ' + node_type
if ({{ condition }}) {
@@ -45,13 +37,6 @@ def {{ method_name }}(node_type) {
{{ caller() | trim | indent(width=12) }}
})
}
- // only run upload if things are successful
- try {
- {{ junit_to_s3(test_dir_name) }}
- junit 'build/pytest-results/*.xml'
- } catch (Exception e) {
- echo 'Exception during JUnit upload: ' + e.toString()
- }
}
}
echo 'End running on node_type ' + node_type
diff --git a/ci/jenkins/templates/wasm_jenkinsfile.groovy.j2
b/ci/jenkins/templates/wasm_jenkinsfile.groovy.j2
index 0d119f043e..8e7d909bd1 100644
--- a/ci/jenkins/templates/wasm_jenkinsfile.groovy.j2
+++ b/ci/jenkins/templates/wasm_jenkinsfile.groovy.j2
@@ -32,7 +32,6 @@
cmake_build(ci_wasm, 'build')
make_cpp_tests(ci_wasm, 'build')
cpp_unittest(ci_wasm)
- ci_setup(ci_wasm)
sh (
script: "${docker_run} ${ci_wasm} ./tests/scripts/task_web_wasm.sh",
label: 'Run WASM lint and tests',
diff --git a/ci/scripts/github/__init__.py b/ci/scripts/github/__init__.py
index a6226fec29..0e55424eee 100644
--- a/ci/scripts/github/__init__.py
+++ b/ci/scripts/github/__init__.py
@@ -17,4 +17,4 @@
# under the License.
"""Package to enable testing of GitHub scripts"""
-from . import github_skipped_tests_comment, github_pr_comment,
github_tag_teams, github_docs_comment
+from . import github_docs_comment, github_pr_comment, github_tag_teams
diff --git a/ci/scripts/github/github_pr_comment.py
b/ci/scripts/github/github_pr_comment.py
index 2d523b21b3..81347659d9 100755
--- a/ci/scripts/github/github_pr_comment.py
+++ b/ci/scripts/github/github_pr_comment.py
@@ -30,7 +30,6 @@ from cmd_utils import init_log
from git_utils import DRY_RUN, GitHubRepo, git, parse_remote
from github_commenter import BotCommentBuilder
from github_docs_comment import get_doc_url
-from github_skipped_tests_comment import get_skipped_tests_comment
from github_tag_teams import get_tags
PR_QUERY = """
@@ -132,17 +131,14 @@ if __name__ == "__main__":
if args.test_comments is not None:
test_comments = json.loads(args.test_comments)
- skipped_tests = test_comments["skipped-tests"]
ccs = test_comments["ccs"]
docs_info = test_comments["docs"]
else:
- skipped_tests = get_skipped_tests_comment(pr_data, github=github)
ccs = get_tags(pr_data, github, team_issue=10317)
docs_info = get_doc_url(pr_data)
items = {
"ccs": ccs,
- "skipped-tests": skipped_tests,
"docs": docs_info,
}
commenter.post_items(items=items.items())
diff --git a/ci/scripts/github/github_skipped_tests_comment.py
b/ci/scripts/github/github_skipped_tests_comment.py
deleted file mode 100755
index 10789f7561..0000000000
--- a/ci/scripts/github/github_skipped_tests_comment.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env python3
-# 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.
-# ruff: noqa: E501
-import json
-import logging
-import os
-import subprocess
-from pathlib import Path
-from typing import Any
-from xml.etree import ElementTree
-
-
-def run_subprocess(command):
- logging.info(f"Running command {command}")
- proc = subprocess.run(command, shell=True, stdout=subprocess.PIPE,
encoding="utf-8")
- if proc.returncode != 0:
- raise RuntimeError(f"Command failed
{command}:\nstdout:\n{proc.stdout}")
- return proc
-
-
-def retrieve_test_report(s3_url, target_dir):
- command = f"aws --region us-west-2 s3 cp {s3_url} {target_dir} --recursive
--no-sign-request"
- run_subprocess(command)
-
-
-def get_common_commit_sha():
- command = "git merge-base origin/main HEAD"
- proc = run_subprocess(command)
- return proc.stdout.strip()
-
-
-def get_main_jenkins_build_number(github, common_commit):
- json = github.get(f"commits/{common_commit}/status")
- for status in reversed(json["statuses"]):
- if status["context"] != "tvm-ci/branch":
- continue
- state = status["state"]
- target_url = str(status["target_url"])
- build_number = (
- target_url[target_url.find("job/main") : len(target_url)]
- .strip("job/main/")
- .strip("/display/redirect")
- )
- assert build_number.isdigit()
- return {"build_number": build_number, "state": state}
- raise RuntimeError(f"Failed to find main build number for commit
{common_commit}")
-
-
-def retrieve_test_reports(
- common_main_build, pr_number, build_number, s3_prefix, pr_test_report_dir,
main_test_report_dir
-):
- cur_build_s3_link =
f"s3://{s3_prefix}/tvm/PR-{pr_number!s}/{build_number!s}/pytest-results"
- retrieve_test_report(cur_build_s3_link, pr_test_report_dir)
-
- common_build_s3_link =
f"s3://{s3_prefix}/tvm/main/{common_main_build}/pytest-results"
- retrieve_test_report(common_build_s3_link, main_test_report_dir)
-
-
-def get_pr_and_build_numbers(target_url):
- target_url = target_url[target_url.find("PR-") : len(target_url)]
- split = target_url.split("/")
- pr_number = split[0].strip("PR-")
- build_number = split[1]
- return {"pr_number": pr_number, "build_number": build_number}
-
-
-def build_test_set(directory):
- directory = Path(directory)
- subdir_to_skipped = {}
- subdirs = [
- item for item in os.listdir(directory) if
os.path.isdir(os.path.join(directory, item))
- ]
- for subdir in subdirs:
- subdir_to_skipped[subdir] = set()
- for root, _, files in os.walk(directory / subdir):
- for file in files:
- test_report = ElementTree.parse(Path(root) / file)
- for testcase in test_report.iter("testcase"):
- skipped = testcase.find("skipped")
- if skipped is not None:
- key = testcase.attrib["classname"] + "#" +
testcase.attrib["name"]
- subdir_to_skipped[subdir].add(key)
- return subdir_to_skipped
-
-
-def to_node_name(dir_name: str):
- return dir_name.replace("_", ": ", 1)
-
-
-def build_diff_comment_with_main(
- common_commit_sha,
- skipped_list,
- commit_sha,
-):
- if len(skipped_list) == 0:
- return f"No diff in skipped tests with main found in this branch for
commit {commit_sha}.\n"
-
- text = (
- f"The list below shows tests that ran in main {common_commit_sha} but
were "
- f"skipped in the CI build of {commit_sha}:\n"
- f"```\n"
- )
- for skip in skipped_list:
- text += skip + "\n"
- text += "```\n"
- return text
-
-
-def build_comment(
- common_commit_sha,
- common_main_build,
- skipped_list,
- additional_skipped_list,
- pr_number,
- build_number,
- commit_sha,
- jenkins_prefix,
-):
- if common_main_build["state"] != "success":
- return f"Unable to run tests bot because main failed to pass CI at
{common_commit_sha}."
-
- text = build_diff_comment_with_main(common_commit_sha, skipped_list,
commit_sha)
-
- if len(additional_skipped_list) != 0:
- text += "\n"
- text += (
- "Additional tests that were skipped in the CI build and present in
the [`required_tests_to_run`]"
-
"(https://github.com/apache/tvm/blob/main/ci/scripts/github/required_tests_to_run.json)
file:"
- "\n```\n"
- )
- for skip in additional_skipped_list:
- text += skip + "\n"
- text += "```\n"
-
- text += (
- f"A detailed report of ran tests is
[here](https://{jenkins_prefix}/job/tvm/job/PR-{pr_number!s}"
- f"/{build_number!s}/testReport/)."
- )
- return text
-
-
-def find_target_url(pr_head: dict[str, Any]):
- for status in pr_head["statusCheckRollup"]["contexts"]["nodes"]:
- if status.get("context", "") == "tvm-ci/pr-head":
- return status["targetUrl"]
-
- raise RuntimeError(f"Unable to find tvm-ci/pr-head status in {pr_head}")
-
-
-def get_skipped_tests_comment(
- pr: dict[str, Any],
- github,
- s3_prefix: str = "tvm-jenkins-artifacts-prod",
- jenkins_prefix: str = "ci.tlcpack.ai",
- pr_test_report_dir: str = "pr-reports",
- main_test_report_dir: str = "main-reports",
- common_commit_sha: str | None = None,
- common_main_build: dict[str, Any] | None = None,
- additional_tests_to_check_file: str = "required_tests_to_run.json",
-) -> str:
- pr_head = pr["commits"]["nodes"][0]["commit"]
- target_url = find_target_url(pr_head)
- pr_and_build = get_pr_and_build_numbers(target_url)
- logging.info(f"Getting comment for {pr_head} with target {target_url}")
-
- commit_sha = pr_head["oid"]
-
- is_dry_run = common_commit_sha is not None
-
- if not is_dry_run:
- logging.info("Fetching common commit sha and build info")
- common_commit_sha = get_common_commit_sha()
- common_main_build = get_main_jenkins_build_number(github,
common_commit_sha)
-
- retrieve_test_reports(
- common_main_build=common_main_build["build_number"],
- pr_number=pr_and_build["pr_number"],
- build_number=pr_and_build["build_number"],
- s3_prefix=s3_prefix,
- main_test_report_dir=main_test_report_dir,
- pr_test_report_dir=pr_test_report_dir,
- )
- else:
- logging.info("Dry run, expecting PR and main reports on disk")
-
- main_tests = build_test_set(main_test_report_dir)
- build_tests = build_test_set(pr_test_report_dir)
-
- skipped_list = []
- for subdir, skipped_set in build_tests.items():
- skipped_main = main_tests[subdir]
- if skipped_main is None:
- logging.warning(f"Could not find directory {subdir} in main.")
- continue
-
- diff_set = skipped_set - skipped_main
- if len(diff_set) != 0:
- for test in diff_set:
- skipped_list.append(f"{to_node_name(subdir)} -> {test}")
-
- # Sort the list to maintain an order in the output. Helps when validating
the output in tests.
- skipped_list.sort()
-
- if len(skipped_list) == 0:
- logging.info("No skipped tests found.")
-
- if not is_dry_run:
- current_file = Path(__file__).resolve()
- additional_tests_to_check_file = Path(current_file).parent /
"required_tests_to_run.json"
-
- logging.info(
- f"Checking additional tests in file {additional_tests_to_check_file}
are not skipped."
- )
- try:
- with open(additional_tests_to_check_file) as f:
- additional_tests_to_check = json.load(f)
- except OSError:
- logging.info(
- f"Failed to read additional tests from file:
{additional_tests_to_check_file}."
- )
- additional_tests_to_check = {}
-
- # Assert that tests present in "required_tests_to_run.json" are not
skipped.
- additional_skipped_tests = []
- for subdir, test_set in additional_tests_to_check.items():
- if subdir not in build_tests.keys():
- logging.warning(f"Could not find directory {subdir} in the build
test set.")
- continue
-
- for test in test_set:
- if test in build_tests[subdir]:
- additional_skipped_tests.append(f"{to_node_name(subdir)} ->
{test}")
-
- if len(additional_skipped_tests) == 0:
- logging.info("No skipped tests found in the additional list.")
-
- body = build_comment(
- common_commit_sha,
- common_main_build,
- skipped_list,
- additional_skipped_tests,
- pr_and_build["pr_number"],
- pr_and_build["build_number"],
- commit_sha,
- jenkins_prefix,
- )
-
- return body
diff --git a/python/tvm/testing/plugin.py b/python/tvm/testing/plugin.py
index dfb858f1b8..2869664842 100644
--- a/python/tvm/testing/plugin.py
+++ b/python/tvm/testing/plugin.py
@@ -33,7 +33,6 @@ directory as the test scripts.
"""
import _pytest
-import pytest
def pytest_collection_modifyitems(config, items):
@@ -44,14 +43,6 @@ def pytest_collection_modifyitems(config, items):
_sort_tests(items)
-def pytest_sessionfinish(session, exitstatus):
- # Don't exit with an error if we select a subset of tests that doesn't
- # include anything
- if session.config.option.markexpr != "":
- if exitstatus == pytest.ExitCode.NO_TESTS_COLLECTED:
- session.exitstatus = pytest.ExitCode.OK
-
-
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().
diff --git a/tests/python/ci/test_ci.py b/tests/python/ci/test_ci.py
index bfd4b32491..e152d8cb41 100644
--- a/tests/python/ci/test_ci.py
+++ b/tests/python/ci/test_ci.py
@@ -18,8 +18,6 @@
"""Test various CI scripts and GitHub Actions workflows"""
import json
-import logging
-import shutil
import subprocess
import sys
import textwrap
@@ -50,277 +48,6 @@ def parameterize_named(**kwargs):
)
-# pylint: disable=line-too-long
-TEST_DATA_SKIPPED_BOT = {
- "found-diff-no-additional": {
- "main_xml_file": "unittest/file1.xml",
- "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "pr_xml_file": "unittest/file2.xml",
- "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- <testcase
classname="ctypes.tests.python.unittest.test_roofline"
- name="test_estimate_peak_bandwidth[cuda]"
time="4.679">
- <skipped message="This is another skippe test"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "additional_tests_to_check": """{
- "unittest": ["dummy_class#dummy_test"],
- "unittest_GPU": ["another_dummy_class#another_dummy_test"]
- }
- """,
- "target_url":
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect",
- "s3_prefix": "tvm-jenkins-artifacts-prod",
- "jenkins_prefix": "ci.tlcpack.ai",
- "common_main_build": """{"build_number": "4115", "state":
"success"}""",
- "commit_sha": "sha1234",
- "expected_body": "The list below shows tests that ran in main sha1234
but were skipped in the CI build of sha1234:\n```\nunittest ->
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\nunittest
->
ctypes.tests.python.unittest.test_roofline#test_estimate_peak_bandwidth[cuda]\n```\nA
detailed report of ran tests is
[here](https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/testReport/).",
- },
- "found-diff-skipped-additional": {
- "main_xml_file": "unittest/file1.xml",
- "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "pr_xml_file": "unittest/file2.xml",
- "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- <testcase
classname="ctypes.tests.python.unittest.test_roofline"
- name="test_estimate_peak_bandwidth[cuda]"
time="4.679">
- <skipped message="This is another skippe test"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "additional_tests_to_check": """{
- "unittest":
["ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner",
"dummy_class#dummy_test"],
- "unittest_GPU": ["another_dummy_class#another_dummy_test"]
- }
- """,
- "target_url":
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect",
- "s3_prefix": "tvm-jenkins-artifacts-prod",
- "jenkins_prefix": "ci.tlcpack.ai",
- "common_main_build": """{"build_number": "4115", "state":
"success"}""",
- "commit_sha": "sha1234",
- "expected_body": "The list below shows tests that ran in main sha1234
but were skipped in the CI build of sha1234:\n```\nunittest ->
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\nunittest
->
ctypes.tests.python.unittest.test_roofline#test_estimate_peak_bandwidth[cuda]\n```\n\nAdditional
tests that were skipped in the CI build and present in the
[`required_tests_to_run`](https://github.com/apache/tvm/blob/main/ci/scripts/
[...]
- },
- "no-diff": {
- "main_xml_file": "unittest/file1.xml",
- "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "pr_xml_file": "unittest/file2.xml",
- "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "additional_tests_to_check": """{
- }
- """,
- "target_url":
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect",
- "s3_prefix": "tvm-jenkins-artifacts-prod",
- "jenkins_prefix": "ci.tlcpack.ai",
- "common_main_build": """{"build_number": "4115", "state":
"success"}""",
- "commit_sha": "sha1234",
- "expected_body": "No diff in skipped tests with main found in this
branch for commit sha1234.\nA detailed report of ran tests is
[here](https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/testReport/).",
- },
- "no-diff-skipped-additional": {
- "main_xml_file": "unittest/file1.xml",
- "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "pr_xml_file": "unittest/file2.xml",
- "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- <testsuite errors="0" failures="0" hostname="13e7c5f749d8"
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
- tests="165" time="79.312"
timestamp="2022-08-10T22:39:36.673781">
- <testcase
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
- <skipped message="This test is skipped"
type="pytest.skip">
- Skipped
- </skipped>
- </testcase>
- </testsuite>
- </testsuites>
- """,
- "additional_tests_to_check": """{
- "unittest": ["dummy_class#dummy_test",
"ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner"],
- "unittest_GPU": ["another_dummy_class#another_dummy_test"]
- }
- """,
- "target_url":
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect",
- "s3_prefix": "tvm-jenkins-artifacts-prod",
- "jenkins_prefix": "ci.tlcpack.ai",
- "common_main_build": """{"build_number": "4115", "state":
"success"}""",
- "commit_sha": "sha1234",
- "expected_body": "No diff in skipped tests with main found in this
branch for commit sha1234.\n\nAdditional tests that were skipped in the CI
build and present in the
[`required_tests_to_run`](https://github.com/apache/tvm/blob/main/ci/scripts/github/required_tests_to_run.json)
file:\n```\nunittest ->
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\n```\nA
detailed report of ran tests is [here](https://ci.tlcpack.ai/job/tvm [...]
- },
- "unable-to-run": {
- "main_xml_file": "unittest/file1.xml",
- "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- </testsuites>
- """,
- "pr_xml_file": "unittest/file2.xml",
- "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
- <testsuites>
- </testsuites>
- """,
- "additional_tests_to_check": """{
- "unittest":
["ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner",
"dummy_class#dummy_test"],
- "unittest_GPU": ["another_dummy_class#another_dummy_test"]
- }
- """,
- "target_url":
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect",
- "s3_prefix": "tvm-jenkins-artifacts-prod",
- "jenkins_prefix": "ci.tlcpack.ai",
- "common_main_build": """{"build_number": "4115", "state": "failed"}""",
- "commit_sha": "sha1234",
- "expected_body": "Unable to run tests bot because main failed to pass
CI at sha1234.",
- },
-}
-# pylint: enable=line-too-long
-
-
[email protected]_if_wheel_test
-@parameterize_named(**TEST_DATA_SKIPPED_BOT)
-# pylint: enable=line-too-long
-def test_skipped_tests_comment(
- caplog,
- tmpdir_factory,
- main_xml_file,
- main_xml_content,
- pr_xml_file,
- pr_xml_content,
- additional_tests_to_check,
- target_url,
- s3_prefix,
- jenkins_prefix,
- common_main_build,
- commit_sha,
- expected_body,
-):
- """
- Test that a comment with a link to the docs is successfully left on PRs
- """
-
- def write_xml_file(root_dir, xml_file, xml_content):
- shutil.rmtree(root_dir, ignore_errors=True)
- file = root_dir / xml_file
- file.parent.mkdir(parents=True)
- with open(file, "w") as f:
- f.write(textwrap.dedent(xml_content))
-
- git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
- pr_test_report_dir = Path(git.cwd) / "pr-reports"
- write_xml_file(pr_test_report_dir, pr_xml_file, pr_xml_content)
- main_test_report_dir = Path(git.cwd) / "main-reports"
- write_xml_file(main_test_report_dir, main_xml_file, main_xml_content)
- with open(Path(git.cwd) / "required_tests_to_run.json", "w") as f:
- f.write(additional_tests_to_check)
-
- pr_data = {
- "commits": {
- "nodes": [
- {
- "commit": {
- "oid": commit_sha,
- "statusCheckRollup": {
- "contexts": {
- "nodes": [
- {
- "context": "tvm-ci/pr-head",
- "targetUrl": target_url,
- }
- ]
- }
- },
- }
- }
- ]
- }
- }
- with caplog.at_level(logging.INFO):
- comment =
scripts.github.github_skipped_tests_comment.get_skipped_tests_comment(
- pr=pr_data,
- github=None,
- s3_prefix=s3_prefix,
- jenkins_prefix=jenkins_prefix,
- common_commit_sha=commit_sha,
- pr_test_report_dir=pr_test_report_dir,
- main_test_report_dir=main_test_report_dir,
- common_main_build=json.loads(common_main_build),
- additional_tests_to_check_file=Path(git.cwd) /
"required_tests_to_run.json",
- )
- assert_in(expected_body, comment)
- assert_in(f"with target {target_url}", caplog.text)
-
-
@tvm.testing.skip_if_wheel_test
@parameterize_named(
doc_link=dict(
@@ -548,8 +275,7 @@ def test_update_branch(tmpdir_factory, statuses,
expected_rc, expected_output):
Thanks for contributing to TVM! Please refer to the contributing
guidelines https://tvm.apache.org/docs/contribute/ for useful information and
tips. Please request code reviews from
[Reviewers](https://github.com/apache/incubator-tvm/blob/master/CONTRIBUTORS.md#reviewers)
by @-ing them in a comment.
<!--bot-comment-ccs-start-->
- * the
cc<!--bot-comment-ccs-end--><!--bot-comment-skipped-tests-start-->
- * the skipped
tests<!--bot-comment-skipped-tests-end--><!--bot-comment-docs-start-->
+ * the cc<!--bot-comment-ccs-end--><!--bot-comment-docs-start-->
* the docs<!--bot-comment-docs-end-->
"""
).strip(),
@@ -584,8 +310,7 @@ def test_update_branch(tmpdir_factory, statuses,
expected_rc, expected_output):
<!--bot-comment-ccs-start-->
* the
cc<!--bot-comment-ccs-end--><!--bot-comment-something-tests-start-->
* something
else<!--bot-comment-something-tests-end--><!--bot-comment-docs-start-->
- * the
docs<!--bot-comment-docs-end--><!--bot-comment-skipped-tests-start-->
- * the skipped tests<!--bot-comment-skipped-tests-end-->
+ * the docs<!--bot-comment-docs-end-->
"""
).strip(),
),
@@ -638,7 +363,6 @@ def test_pr_comment(tmpdir_factory, pr_author, comments,
expected):
comments = {
"ccs": "the cc",
"docs": "the docs",
- "skipped-tests": "the skipped tests",
}
proc = run_script(
[
diff --git a/tests/python/s_tir/meta_schedule/test_meta_schedule_cost_model.py
b/tests/python/s_tir/meta_schedule/test_meta_schedule_cost_model.py
index 1e209cacbc..97c9469ccf 100644
--- a/tests/python/s_tir/meta_schedule/test_meta_schedule_cost_model.py
+++ b/tests/python/s_tir/meta_schedule/test_meta_schedule_cost_model.py
@@ -149,7 +149,7 @@ def _dummy_result(num_samples: int = 4, max_run_sec: int =
10):
@requires_xgboost
def test_meta_schedule_xgb_model():
extractor = RandomFeatureExtractor()
- model = XGBModel(extractor=extractor, num_warmup_samples=2)
+ model = XGBModel(extractor=extractor, num_warmup_samples=2,
num_tuning_cores=1)
update_sample_count = 10
predict_sample_count = 100
model.update(
@@ -162,9 +162,10 @@ def test_meta_schedule_xgb_model():
@requires_xgboost
def test_meta_schedule_xgb_model_no_feature():
- model = XGBModel(num_warmup_samples=0)
+ model = XGBModel(num_warmup_samples=0, num_tuning_cores=1)
tune_ctx = TuneContext(
FullModule,
+ num_threads=1,
target={"kind": "llvm", "num-cores": 16},
space_generator="post-order-apply",
search_strategy="evolutionary",
@@ -177,7 +178,7 @@ def test_meta_schedule_xgb_model_no_feature():
@requires_xgboost
def test_meta_schedule_xgb_model_reload():
extractor = RandomFeatureExtractor()
- model = XGBModel(extractor=extractor, num_warmup_samples=10)
+ model = XGBModel(extractor=extractor, num_warmup_samples=10,
num_tuning_cores=1)
update_sample_count = 20
predict_sample_count = 30
model.update(
@@ -221,7 +222,7 @@ def test_meta_schedule_xgb_model_reload():
@requires_xgboost
def test_meta_schedule_xgb_model_reupdate():
extractor = RandomFeatureExtractor()
- model = XGBModel(extractor=extractor, num_warmup_samples=2)
+ model = XGBModel(extractor=extractor, num_warmup_samples=2,
num_tuning_cores=1)
update_sample_count = 60
predict_sample_count = 100
model.update(
@@ -252,7 +253,7 @@ def test_meta_schedule_xgb_model_callback_as_function():
# pylint: enable=import-outside-toplevel
extractor = RandomFeatureExtractor()
- model = XGBModel(extractor=extractor, num_warmup_samples=10)
+ model = XGBModel(extractor=extractor, num_warmup_samples=10,
num_tuning_cores=1)
update_sample_count = 20
predict_sample_count = 30
diff --git
a/tests/python/s_tir/meta_schedule/test_meta_schedule_search_strategy.py
b/tests/python/s_tir/meta_schedule/test_meta_schedule_search_strategy.py
index 002741c6bf..6451a94ec9 100644
--- a/tests/python/s_tir/meta_schedule/test_meta_schedule_search_strategy.py
+++ b/tests/python/s_tir/meta_schedule/test_meta_schedule_search_strategy.py
@@ -103,6 +103,7 @@ def test_meta_schedule_replay_func(
context = ms.TuneContext(
mod=Matmul,
+ num_threads=1,
space_generator=ms.space_generator.ScheduleFn(sch_fn=_schedule_matmul,
postprocs=[]),
search_strategy=TestClass(),
)
diff --git
a/tests/python/s_tir/meta_schedule/test_meta_schedule_task_scheduler.py
b/tests/python/s_tir/meta_schedule/test_meta_schedule_task_scheduler.py
index 61f5583c2a..6dc351761a 100644
--- a/tests/python/s_tir/meta_schedule/test_meta_schedule_task_scheduler.py
+++ b/tests/python/s_tir/meta_schedule/test_meta_schedule_task_scheduler.py
@@ -157,6 +157,7 @@ def test_meta_schedule_task_scheduler_single():
[
ms.TuneContext(
MatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -183,6 +184,7 @@ def test_meta_schedule_task_scheduler_multiple():
tasks = [
ms.TuneContext(
MatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -191,6 +193,7 @@ def test_meta_schedule_task_scheduler_multiple():
),
ms.TuneContext(
MatmulReluModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -199,6 +202,7 @@ def test_meta_schedule_task_scheduler_multiple():
),
ms.TuneContext(
BatchMatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_batch_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -255,6 +259,7 @@ def
test_meta_schedule_task_scheduler_override_next_task_id_only(): # pylint: d
tasks = [
ms.TuneContext(
MatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -263,6 +268,7 @@ def
test_meta_schedule_task_scheduler_override_next_task_id_only(): # pylint: d
),
ms.TuneContext(
MatmulReluModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -271,6 +277,7 @@ def
test_meta_schedule_task_scheduler_override_next_task_id_only(): # pylint: d
),
ms.TuneContext(
BatchMatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_batch_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -310,6 +317,7 @@ def
test_meta_schedule_task_scheduler_multiple_gradient_based():
tasks = [
ms.TuneContext(
MatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -318,6 +326,7 @@ def
test_meta_schedule_task_scheduler_multiple_gradient_based():
),
ms.TuneContext(
MatmulReluModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -326,6 +335,7 @@ def
test_meta_schedule_task_scheduler_multiple_gradient_based():
),
ms.TuneContext(
BatchMatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_batch_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
@@ -394,6 +404,7 @@ def
test_meta_schedule_task_scheduler_gradient_based_with_null_search_strategy()
tasks = [
ms.TuneContext(
MatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=NullSearchStrategy(rounds_with_empty_candidates=5),
@@ -402,6 +413,7 @@ def
test_meta_schedule_task_scheduler_gradient_based_with_null_search_strategy()
),
ms.TuneContext(
BatchMatmulModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_batch_matmul,
search_strategy=NullSearchStrategy(rounds_with_empty_candidates=0),
@@ -410,6 +422,7 @@ def
test_meta_schedule_task_scheduler_gradient_based_with_null_search_strategy()
),
ms.TuneContext(
MatmulReluModule,
+ num_threads=1,
target=tvm.target.Target("llvm"),
space_generator=_schedule_matmul,
search_strategy=ms.search_strategy.ReplayTrace(),
diff --git a/tests/python/testing/test_tvm_testing_features.py
b/tests/python/testing/test_tvm_testing_features.py
index 549aedda6a..ba2faf2a45 100644
--- a/tests/python/testing/test_tvm_testing_features.py
+++ b/tests/python/testing/test_tvm_testing_features.py
@@ -14,9 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-# ruff: noqa: F401, RUF012
+# ruff: noqa: RUF012
import os
+import subprocess
import sys
import pytest
@@ -189,5 +190,44 @@ class TestPytestCache:
assert cached_fixture == param * param
+def test_empty_marker_selection_is_an_error(tmp_path):
+ test_file = tmp_path / "test_no_gpu.py"
+ test_file.write_text("def test_cpu_only():\n pass\n")
+ env = os.environ.copy()
+ env.pop("PYTEST_ADDOPTS", None)
+
+ result = subprocess.run(
+ [
+ sys.executable,
+ "-m",
+ "pytest",
+ "-q",
+ "-p",
+ "tvm.testing.plugin",
+ "-m",
+ "gpu",
+ str(test_file),
+ ],
+ env=env,
+ check=False,
+ capture_output=True,
+ text=True,
+ )
+
+ assert result.returncode == pytest.ExitCode.NO_TESTS_COLLECTED,
result.stdout + result.stderr
+
+ test_file.write_text("def test_failure():\n assert False\n")
+ result = subprocess.run(
+ [sys.executable, "-m", "pytest", "-q", "-p", "tvm.testing.plugin",
str(test_file)],
+ env=env,
+ check=False,
+ capture_output=True,
+ text=True,
+ )
+
+ assert result.returncode == pytest.ExitCode.TESTS_FAILED, result.stdout +
result.stderr
+ assert not list(tmp_path.glob("*.xml"))
+
+
if __name__ == "__main__":
tvm.testing.main()
diff --git a/tests/scripts/task_clear_pytest.sh
b/tests/scripts/task_clear_pytest.sh
deleted file mode 100755
index 0a24f62531..0000000000
--- a/tests/scripts/task_clear_pytest.sh
+++ /dev/null
@@ -1,24 +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
-
-# Ensure no stale pytest-results remain from a previous test run.
-pushd build
-rm -rf pytest-results
-popd
diff --git a/tests/scripts/task_python_nightly.sh
b/tests/scripts/task_python_nightly.sh
deleted file mode 100755
index 05070f0a04..0000000000
--- a/tests/scripts/task_python_nightly.sh
+++ /dev/null
@@ -1,39 +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 PYTEST_ADDOPTS="-s -vv ${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
-mkdir -p build/pytest-results
-
-# setup tvm-ffi into python folder
-uv pip install -v --target=python ./3rdparty/tvm-ffi/
-
-# cleanup pycache
-find . -type f -path "*.pyc" | xargs rm -f
-
-python3 -m pytest -n auto \
- -o junit_suite_name=python-topi-nightly \
- --junit-xml=build/pytest-results/python-topi-nightly.xml \
- --junit-prefix=cython \
- tests/python/topi/nightly
-
-# Tensorflow device verification and network tests on nightly
-export CI_ENV_NIGHTLY
-python3 tests/python/relax/test_frontend_tflite.py
diff --git a/tests/scripts/task_python_unittest.sh
b/tests/scripts/task_python_unittest.sh
index 30e5bb2bf3..c05f8503d3 100755
--- a/tests/scripts/task_python_unittest.sh
+++ b/tests/scripts/task_python_unittest.sh
@@ -20,7 +20,6 @@ set -euxo pipefail
export PYTHONPATH="$(pwd)/python"
export PYTEST_ADDOPTS="-s -vv ${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
-mkdir -p build/pytest-results
# cleanup pycache
find . -type f -path "*.pyc" | xargs rm -f
@@ -28,27 +27,20 @@ find . -type f -path "*.pyc" | xargs rm -f
# setup tvm-ffi into python folder
uv pip install -v --target=python ./3rdparty/tvm-ffi/
-# NOTE: also set by task_python_unittest_gpuonly.sh.
-if [ -z "${TVM_UNITTEST_TESTSUITE_NAME:-}" ]; then
- TVM_UNITTEST_TESTSUITE_NAME=python-unittest
-fi
-
# First run the minimal platform test. A GPU-only run can select no tests
here.
-python3 -m pytest -n auto \
- -o "junit_suite_name=${TVM_UNITTEST_TESTSUITE_NAME}-platform-minimal-test"
\
-
"--junit-xml=build/pytest-results/${TVM_UNITTEST_TESTSUITE_NAME}-platform-minimal-test.xml"
\
- --junit-prefix=cython \
- tests/python/all-platform-minimal-test || [ "$?" -eq 5 ]
+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=(
- "ffi"
"arith"
"ci"
"codegen"
"driver"
"ir"
- "meta_schedule"
"runtime"
"target"
"te"
@@ -57,6 +49,7 @@ TEST_FILES=(
"s_tir/schedule"
"s_tir/dlight"
"s_tir/analysis"
+ "s_tir/meta_schedule"
"s_tir/transform"
"tirx-analysis"
"tirx-base"
@@ -68,11 +61,13 @@ TEST_FILES=(
PYTEST_TARGETS=()
for TEST_FILE in "${TEST_FILES[@]}"; do
- PYTEST_TARGETS+=("tests/python/${TEST_FILE}")
+ TEST_PATH="tests/python/${TEST_FILE}"
+ if [ ! -d "${TEST_PATH}" ]; then
+ echo "Missing pytest target: ${TEST_PATH}" >&2
+ exit 1
+ fi
+ PYTEST_TARGETS+=("${TEST_PATH}")
done
-python3 -m pytest -n auto --dist=loadgroup \
- -o "junit_suite_name=${TVM_UNITTEST_TESTSUITE_NAME}" \
- "--junit-xml=build/pytest-results/${TVM_UNITTEST_TESTSUITE_NAME}.xml" \
- --junit-prefix=cython \
- "${PYTEST_TARGETS[@]}"
+# Do not mask pytest's exit 5: an unexpectedly empty broad suite must fail CI.
+python3 -m pytest -n auto --dist=loadgroup "${PYTEST_TARGETS[@]}"
diff --git a/tests/scripts/task_python_unittest_gpuonly.sh
b/tests/scripts/task_python_unittest_gpuonly.sh
index 6bbd85dc10..8194b23ac4 100755
--- a/tests/scripts/task_python_unittest_gpuonly.sh
+++ b/tests/scripts/task_python_unittest_gpuonly.sh
@@ -24,21 +24,18 @@ export PYTEST_ADDOPTS="-m gpu ${PYTEST_ADDOPTS:-}"
# Test most of the enabled runtimes here.
# TODO: disabled opencl tests due to segmentation fault.
export TVM_TEST_TARGETS='cuda;metal;rocm;nvptx'
-export TVM_UNITTEST_TESTSUITE_NAME=python-unittest-gpu
./tests/scripts/task_python_unittest.sh
# Kept separate to avoid increasing time needed to run CI, testing
# only minimal functionality of Vulkan runtime.
export TVM_TEST_TARGETS='{"kind":"vulkan","from_device":0}'
-export TVM_UNITTEST_TESTSUITE_NAME=python-codegen-vulkan
export PYTHONPATH="$(pwd)/python"
export PYTEST_ADDOPTS="-s -vv ${CI_PYTEST_ADD_OPTIONS:-} ${PYTEST_ADDOPTS:-}"
-mkdir -p build/pytest-results
-python3 -m pytest -n auto \
- -o "junit_suite_name=${TVM_UNITTEST_TESTSUITE_NAME}" \
- "--junit-xml=build/pytest-results/${TVM_UNITTEST_TESTSUITE_NAME}.xml" \
- --junit-prefix=cython \
- tests/python/codegen/test_target_codegen_vulkan.py
+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