Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

include teardown time in autopart calculation #1114

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions doc/en/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,12 @@ Command line

{
"<Multitest>": {
"execution_time": 199.99,
"setup_time": 39.99,
| "execution_time": 199.99,
| "setup_time": 39.99,
| "teardown_time": 39.99, // optional
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra vertical bar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its so each line is formatted as a new line

},
......
}

--skip-remaining {cases-on-failed,cases-on-error,suites-on-failed,suites-on-error,tests-on-failed,tests-on-error}

Make Testplan break from the current execution flow and skip remaining iterations at certain level (choose one from all the options). "on-error" make this skip upon exception raised, and "on-failed" make this skip upon both exception raised and test failure. In other words, "on-failed" has higher precedence.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add optional ``teardown_time`` for Multitest auto-part calculation.
9 changes: 8 additions & 1 deletion testplan/runnable/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,8 @@ def _get_tasks(

tasks: List[TaskInformation] = []
time_info = runtime_data.get(uid, None)
if time_info and "teardown_time" not in time_info:
time_info["teardown_time"] = 0
if num_of_parts:

if not isinstance(task_info.materialized_test, MultiTest):
Expand Down Expand Up @@ -605,6 +607,7 @@ def _get_tasks(
/ (
self.cfg.auto_part_runtime_limit {self.cfg.auto_part_runtime_limit}
- time_info["setup_time"] {time_info["setup_time"]}
- time_info["teardown_time"] {time_info["teardown_time"]}
)
)
"""
Expand All @@ -614,6 +617,7 @@ def _get_tasks(
/ (
self.cfg.auto_part_runtime_limit
- time_info["setup_time"]
- time_info["teardown_time"]
)
)
except ZeroDivisionError:
Expand All @@ -638,6 +642,7 @@ def _get_tasks(
math.ceil(
(time_info["execution_time"] / num_of_parts)
+ time_info["setup_time"]
+ time_info["teardown_time"]
)
if time_info
else self.cfg.auto_part_runtime_limit
Expand All @@ -664,7 +669,9 @@ def _get_tasks(
else:
if time_info and not task.weight:
task_info.target.weight = math.ceil(
time_info["execution_time"] + time_info["setup_time"]
time_info["execution_time"]
+ time_info["setup_time"]
+ time_info["teardown_time"]
)
self.logger.user_info(
"%s: weight=%d", uid, task_info.target.weight
Expand Down
155 changes: 155 additions & 0 deletions tests/functional/testplan/runners/pools/test_auto_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,158 @@ def test_auto_parts_cap_parts():
assert task.weight == 64
mockplan.run()
assert pool.size == 1


def test_auto_parts_discover_with_teardown_time():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
runtime_data={
"Proj1-suite": {
"execution_time": 199.99,
"setup_time": 2.5,
"teardown_time": 2.5,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 5
for task in pool.added_items.values():
assert task.weight == 45
mockplan.run()
assert pool.size == 2


def test_auto_parts_discover_interactive_with_teardown_time(runpath):
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
interactive_port=0,
runtime_data={
"Proj1-suite": {
"execution_time": 199.99,
"setup_time": 5,
"teardown_time": 5,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = Path(__file__).resolve().parent
mockplan.schedule_all(
path=current_folder / "discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)

local_pool = mockplan.resources.get(mockplan.resources.first())
# validate that only one task added to the local pool without split

assert len(pool.added_items) == 0
assert len(local_pool.added_items) == 1


def test_auto_weight_discover_with_teardown_time():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
plan_runtime_target=300,
runtime_data={
"Proj1-suite": {
"execution_time": 199.99,
"setup_time": 19.99,
"teardown_time": 19.99,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_weight_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 2
for task in pool.added_items.values():
assert task.weight == 140
mockplan.run()
assert pool.size == 1


def test_auto_parts_zero_neg_parts_with_teardown_time():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
runtime_data={
"Proj1-suite": {
"execution_time": 50,
"setup_time": 25, # setup_time + teardown_time > runtime_limit -> negtive num_of_parts
"teardown_time": 25,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 1
for task in pool.added_items.values():
assert task.weight == 100
mockplan.run()
assert pool.size == 1


def test_auto_parts_cap_parts_with_teardown_time():
with tempfile.TemporaryDirectory() as runpath:
mockplan = TestplanMock(
"plan",
runpath=runpath,
merge_scheduled_parts=True,
auto_part_runtime_limit=45,
plan_runtime_target=200,
runtime_data={
"Proj1-suite": {
"execution_time": 60,
"setup_time": 22,
"teardown_time": 22,
}
},
)
pool = ProcessPool(name="MyPool", size="auto")
mockplan.add_resource(pool)
current_folder = os.path.dirname(os.path.realpath(__file__))
mockplan.schedule_all(
path=f"{current_folder}/discover_tasks",
name_pattern=r".*auto_parts_tasks\.py$",
resource="MyPool",
)
assert len(pool.added_items) == 3
for task in pool.added_items.values():
assert task.weight == 64
mockplan.run()
assert pool.size == 1