mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
* experiments: move executor into a module * experiments: separate executor into base/local * rename LocalExecutor to TempDirExecutor, run in .dvc/tmp by default * git: restore HEAD using reset not checkout in detached_head() * experiments: support calling BaseExecutor.reproduce directly for workspace runs * experiments: run single experiments in local workspace by default * update experiments tests for workspace changes * experiments: update checkpoints for workspace runs * update checkpoints tests * update test_show * add force param for apply * exp apply: add --force option * exp run/res: add --temp option to force tempdir execution for single experiments * force apply in non-apply specific tests
195 lines
5.4 KiB
Python
195 lines
5.4 KiB
Python
import os
|
|
from datetime import datetime
|
|
|
|
import pytest
|
|
from funcy import first
|
|
|
|
from dvc.main import main
|
|
from dvc.repo.experiments.base import ExpRefInfo
|
|
|
|
|
|
def test_show_simple(tmp_dir, scm, dvc, exp_stage):
|
|
assert dvc.experiments.show()["workspace"] == {
|
|
"baseline": {
|
|
"metrics": {"metrics.yaml": {"foo": 1}},
|
|
"params": {"params.yaml": {"foo": 1}},
|
|
"queued": False,
|
|
"timestamp": None,
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize("workspace", [True, False])
|
|
def test_show_experiment(tmp_dir, scm, dvc, exp_stage, workspace):
|
|
baseline_rev = scm.get_rev()
|
|
timestamp = datetime.fromtimestamp(
|
|
scm.gitpython.repo.rev_parse(baseline_rev).committed_date
|
|
)
|
|
|
|
dvc.experiments.run(
|
|
exp_stage.addressing, params=["foo=2"], tmp_dir=not workspace
|
|
)
|
|
results = dvc.experiments.show()
|
|
|
|
expected_baseline = {
|
|
"metrics": {"metrics.yaml": {"foo": 1}},
|
|
"params": {"params.yaml": {"foo": 1}},
|
|
"queued": False,
|
|
"timestamp": timestamp,
|
|
"name": "master",
|
|
}
|
|
expected_params = {"foo": 2}
|
|
|
|
assert set(results.keys()) == {"workspace", baseline_rev}
|
|
experiments = results[baseline_rev]
|
|
assert len(experiments) == 2
|
|
for rev, exp in experiments.items():
|
|
if rev == "baseline":
|
|
assert exp == expected_baseline
|
|
else:
|
|
assert exp["metrics"]["metrics.yaml"] == expected_params
|
|
assert exp["params"]["params.yaml"] == expected_params
|
|
|
|
|
|
def test_show_queued(tmp_dir, scm, dvc, exp_stage):
|
|
from dvc.repo.experiments.base import EXPS_STASH
|
|
|
|
baseline_rev = scm.get_rev()
|
|
|
|
dvc.experiments.run(exp_stage.addressing, params=["foo=2"], queue=True)
|
|
exp_rev = dvc.experiments.scm.resolve_rev(f"{EXPS_STASH}@{{0}}")
|
|
|
|
results = dvc.experiments.show()[baseline_rev]
|
|
assert len(results) == 2
|
|
exp = results[exp_rev]
|
|
assert exp["queued"]
|
|
assert exp["params"]["params.yaml"] == {"foo": 2}
|
|
|
|
# test that only queued experiments for the current baseline are returned
|
|
tmp_dir.gen("foo", "foo")
|
|
scm.add(["foo"])
|
|
scm.commit("new commit")
|
|
new_rev = scm.get_rev()
|
|
|
|
dvc.experiments.run(exp_stage.addressing, params=["foo=3"], queue=True)
|
|
exp_rev = dvc.experiments.scm.resolve_rev(f"{EXPS_STASH}@{{0}}")
|
|
|
|
results = dvc.experiments.show()[new_rev]
|
|
assert len(results) == 2
|
|
exp = results[exp_rev]
|
|
assert exp["queued"]
|
|
assert exp["params"]["params.yaml"] == {"foo": 3}
|
|
|
|
|
|
@pytest.mark.parametrize("workspace", [True, False])
|
|
def test_show_checkpoint(
|
|
tmp_dir, scm, dvc, checkpoint_stage, capsys, workspace
|
|
):
|
|
baseline_rev = scm.get_rev()
|
|
results = dvc.experiments.run(
|
|
checkpoint_stage.addressing, params=["foo=2"], tmp_dir=not workspace
|
|
)
|
|
exp_rev = first(results)
|
|
|
|
results = dvc.experiments.show()[baseline_rev]
|
|
assert len(results) == 6
|
|
|
|
checkpoints = []
|
|
for rev, exp in results.items():
|
|
if rev != "baseline":
|
|
checkpoints.append(rev)
|
|
assert exp["checkpoint_tip"] == exp_rev
|
|
|
|
capsys.readouterr()
|
|
assert main(["exp", "show", "--no-pager"]) == 0
|
|
cap = capsys.readouterr()
|
|
|
|
for i, rev in enumerate(checkpoints):
|
|
if i == 0:
|
|
name = dvc.experiments.get_exact_name(rev)
|
|
tree = "╓"
|
|
elif i == len(checkpoints) - 1:
|
|
name = rev[:7]
|
|
tree = "╨"
|
|
else:
|
|
name = rev[:7]
|
|
tree = "╟"
|
|
assert f"{tree} {name}" in cap.out
|
|
|
|
|
|
@pytest.mark.parametrize("workspace", [True, False])
|
|
def test_show_checkpoint_branch(
|
|
tmp_dir, scm, dvc, checkpoint_stage, capsys, workspace
|
|
):
|
|
results = dvc.experiments.run(
|
|
checkpoint_stage.addressing, params=["foo=2"], tmp_dir=not workspace
|
|
)
|
|
branch_rev = first(results)
|
|
if not workspace:
|
|
dvc.experiments.apply(branch_rev)
|
|
|
|
results = dvc.experiments.run(
|
|
checkpoint_stage.addressing,
|
|
checkpoint_resume=branch_rev,
|
|
tmp_dir=not workspace,
|
|
)
|
|
checkpoint_a = first(results)
|
|
|
|
dvc.experiments.apply(branch_rev, force=True)
|
|
results = dvc.experiments.run(
|
|
checkpoint_stage.addressing,
|
|
checkpoint_resume=branch_rev,
|
|
params=["foo=100"],
|
|
tmp_dir=not workspace,
|
|
)
|
|
checkpoint_b = first(results)
|
|
|
|
capsys.readouterr()
|
|
assert main(["exp", "show", "--no-pager"]) == 0
|
|
cap = capsys.readouterr()
|
|
|
|
for rev in (checkpoint_a, checkpoint_b):
|
|
ref = dvc.experiments.get_branch_by_rev(rev)
|
|
ref_info = ExpRefInfo.from_ref(ref)
|
|
name = ref_info.name
|
|
assert f"╓ {name}" in cap.out
|
|
assert f"({branch_rev[:7]})" in cap.out
|
|
|
|
|
|
def test_show_filter(tmp_dir, scm, dvc, exp_stage, capsys):
|
|
capsys.readouterr()
|
|
assert (
|
|
main(
|
|
[
|
|
"exp",
|
|
"show",
|
|
"--no-pager",
|
|
"--no-timestamp",
|
|
"--include-metrics=foo",
|
|
"--include-params=foo",
|
|
]
|
|
)
|
|
== 0
|
|
)
|
|
cap = capsys.readouterr()
|
|
|
|
div = "│" if os.name == "nt" else "┃"
|
|
assert f"{div} foo {div} foo {div}" in cap.out
|
|
|
|
assert (
|
|
main(
|
|
[
|
|
"exp",
|
|
"show",
|
|
"--no-pager",
|
|
"--no-timestamp",
|
|
"--exclude-metrics=foo",
|
|
"--exclude-params=foo",
|
|
]
|
|
)
|
|
== 0
|
|
)
|
|
cap = capsys.readouterr()
|
|
|
|
assert f"{div} foo {div}" not in cap.out
|