Skip to content

Commit

Permalink
Add @slow decorator to run tests on main (apache#10057)
Browse files Browse the repository at this point in the history
* Add @slow decorator to run tests on `main`

This adds the infrastructure discussed in https://discuss.tvm.apache.org/t/rfc-ci-skip-slow-tests-on-prs/11910, but without affecting any tests. As we investigate reasons behind [slow tests](https://gist.github.com/driazati/e009f09ff44c6bc91c4d95a8e17fd6f1) in CI, this decorator will allow us to move these to run only on `main` and not PRs after checking with all concerned parties.

* cleanup

Co-authored-by: driazati <driazati@users.noreply.github.com>
  • Loading branch information
2 people authored and pfk-beta committed Apr 11, 2022
1 parent c3464fe commit ac6c35b
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 3 deletions.
28 changes: 25 additions & 3 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ def init_git() {
}
}

def should_skip_slow_tests(pr_number) {
withCredentials([string(
credentialsId: 'tvm-bot-jenkins-reader',
variable: 'GITHUB_TOKEN',
)]) {
// Exit code of 1 means run slow tests, exit code of 0 means skip slow tests
result = sh (
returnStatus: true,
script: "./tests/scripts/should_run_slow_tests.py --pr '${pr_number}'",
label: 'Check if CI should run slow tests',
)
}
return result == 0
}

def cancel_previous_build() {
// cancel previous build if it is not on main.
if (env.BRANCH_NAME != 'main') {
Expand Down Expand Up @@ -169,6 +184,7 @@ stage('Sanity Check') {
label: 'Check for docs only changes',
)
skip_ci = should_skip_ci(env.CHANGE_ID)
skip_slow_tests = should_skip_slow_tests(env.CHANGE_ID)
sh (
script: "${docker_run} ${ci_lint} ./tests/scripts/task_lint.sh",
label: 'Run lint',
Expand Down Expand Up @@ -257,6 +273,9 @@ def cpp_unittest(image) {
}

stage('Build') {
environment {
SKIP_SLOW_TESTS = "${skip_slow_tests}"
}
parallel 'BUILD: GPU': {
if (!skip_ci) {
node('GPUBUILD') {
Expand Down Expand Up @@ -287,7 +306,7 @@ stage('Build') {
ci_setup(ci_cpu)
// sh "${docker_run} ${ci_cpu} ./tests/scripts/task_golang.sh"
// TODO(@jroesch): need to resolve CI issue will turn back on in follow up patch
sh (script: "${docker_run} ${ci_cpu} ./tests/scripts/task_rust.sh", label: "Rust build and test")
sh (script: "${docker_run} ${ci_cpu} ./tests/scripts/task_rust.sh", label: 'Rust build and test')
}
}
}
Expand Down Expand Up @@ -414,6 +433,9 @@ stage('Build') {
}

stage('Test') {
environment {
SKIP_SLOW_TESTS = "${skip_slow_tests}"
}
parallel 'unittest: GPU': {
if (!skip_ci && is_docs_only_build != 1) {
node('TensorCore') {
Expand Down Expand Up @@ -471,7 +493,7 @@ stage('Test') {
'unittest: CPU': {
if (!skip_ci && is_docs_only_build != 1) {
node('CPU') {
ws(per_exec_ws("tvm/ut-python-cpu")) {
ws(per_exec_ws('tvm/ut-python-cpu')) {
try {
init_git()
unpack_lib('cpu', tvm_multilib_tsim)
Expand All @@ -481,7 +503,7 @@ stage('Test') {
fsim_test(ci_cpu)
sh (
script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_vta_tsim.sh",
label: "Run VTA tests in TSIM",
label: 'Run VTA tests in TSIM',
)
}
} finally {
Expand Down
13 changes: 13 additions & 0 deletions python/tvm/testing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def test_something():
from tvm.relay.op.contrib.ethosn import ethosn_available
from tvm.relay.op.contrib import cmsisnn

SKIP_SLOW_TESTS = os.getenv("SKIP_SLOW_TESTS", "").lower() in {"true", "1", "yes"}


def assert_allclose(actual, desired, rtol=1e-7, atol=1e-7):
"""Version of np.testing.assert_allclose with `atol` and `rtol` fields set
Expand Down Expand Up @@ -516,6 +518,17 @@ def _compose(args, decs):
return decs


def slow(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
if SKIP_SLOW_TESTS:
pytest.skip("Skipping slow test since RUN_SLOW_TESTS environment variables is 'true'")
else:
fn(*args, **kwargs)

return wrapper


def uses_gpu(*args):
"""Mark to differentiate tests that use the GPU in some capacity.
Expand Down
104 changes: 104 additions & 0 deletions tests/scripts/should_run_slow_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/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.

import os
import json
import argparse
import subprocess
import re
import textwrap
from urllib import request
from typing import Dict, Tuple, Any, List, Optional


from git_utils import GitHubRepo, parse_remote, git


SLOW_TEST_TRIGGERS = [
"@ci run slow tests",
"@ci run slow test",
"@ci run slow",
"@ci slow tests",
"@ci slow test",
"@ci slow",
]


def check_match(s: str, searches: List[str]) -> Tuple[bool, Optional[str]]:
for search in searches:
if search in s:
return True, search

return False, None


def display(long_str: str) -> str:
return textwrap.indent(long_str, " ")


if __name__ == "__main__":
help = "Exits with 1 if CI should run slow tests, 0 otherwise"
parser = argparse.ArgumentParser(description=help)
parser.add_argument("--pr", required=True)
parser.add_argument("--remote", default="origin", help="ssh remote to parse")
parser.add_argument(
"--pr-body", help="(testing) PR body to use instead of fetching from GitHub"
)
args = parser.parse_args()

branch = git(["rev-parse", "--abbrev-ref", "HEAD"])

# Don't skip slow tests on main or ci-docker-staging
skip_branches = {"main", "ci-docker-staging"}
if branch in skip_branches:
print(f"Branch {branch} is in {skip_branches}, running slow tests")
exit(1)
print(f"Branch {branch} is not in {skip_branches}, checking last commit...")

log = git(["log", "--format=%B", "-1"])

# Check if anything in the last commit's body message matches
log_match, reason = check_match(log, SLOW_TEST_TRIGGERS)
if log_match:
print(f"Matched {reason} in commit message:\n{display(log)}, running slow tests")
exit(1)

print(
f"Last commit:\n{display(log)}\ndid not have any of {SLOW_TEST_TRIGGERS}, checking PR body..."
)

if args.pr_body:
body = args.pr_body
else:
remote = git(["config", "--get", f"remote.{args.remote}.url"])
user, repo = parse_remote(remote)

github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, repo=repo)
pr = github.get(f"pulls/{args.pr}")
body = pr["body"]

body_match, reason = check_match(body, SLOW_TEST_TRIGGERS)

if body_match:
print(f"Matched {reason} in PR body:\n{display(body)}, running slow tests")
exit(1)

print(
f"PR Body:\n{display(body)}\ndid not have any of {SLOW_TEST_TRIGGERS}, skipping slow tests"
)
exit(0)

0 comments on commit ac6c35b

Please sign in to comment.