diff --git a/asv/commands/profiling.py b/asv/commands/profiling.py index fc32dc8cf..94736126b 100644 --- a/asv/commands/profiling.py +++ b/asv/commands/profiling.py @@ -135,21 +135,24 @@ def run(cls, conf, benchmark, revision=None, gui=None, output=None, # First, we see if we already have the profile in the results # database + env = None if not force and commit_hash: for result in iter_results_for_machine( conf.results_dir, machine_name): if hash_equal(commit_hash, result.commit_hash): if result.has_profile(benchmark): - env_matched = any(result.env.name == env.name - for env in environments) + # Only take the first one + env_matched = util.get_matching_environment(environments, result) + if env_matched: - if result.env.name not in checked_out: + if result.env_name not in checked_out: # We need to checkout the correct commit so that # the line numbers in the profile data match up with # what's in the source tree. - result.env.checkout_project(repo, commit_hash) - checked_out.add(result.env.name) + env_matched.checkout_project(repo, commit_hash) + checked_out.add(result.env_name) profile_data = result.get_profile(benchmark) + env = env_matched break if profile_data is None: @@ -164,7 +167,9 @@ def run(cls, conf, benchmark, revision=None, gui=None, output=None, "An explicit revision may not be specified when " "using an existing environment.") - env = environments[0] + if env is None: + # Fallback + env = environments[0] if env.python != "{0}.{1}".format(*sys.version_info[:2]): raise util.UserError( diff --git a/asv/results.py b/asv/results.py index 579127070..c309d3f56 100644 --- a/asv/results.py +++ b/asv/results.py @@ -573,7 +573,7 @@ def has_profile(self, benchmark_name): """ Does the given benchmark data have profiling information? """ - return benchmark_name in self._profiles + return self._profiles.get(benchmark_name) def save(self, result_dir): """ diff --git a/asv/util.py b/asv/util.py index dada420b5..cf808b6dc 100644 --- a/asv/util.py +++ b/asv/util.py @@ -1418,3 +1418,14 @@ def construct_pip_call(pip_caller, parsed_declaration: ParsedPipDeclaration): ON_PYPY = True else: ON_PYPY = False + +def get_matching_environment(environments, result=None): + return next( + ( + env + for env in environments + if (result is None or result.env_name == env.name) + and env.python == "{0}.{1}".format(*sys.version_info[:2]) + ), + None, + ) diff --git a/test/test_profile.py b/test/test_profile.py index ecaab0b0d..463d9f70f 100644 --- a/test/test_profile.py +++ b/test/test_profile.py @@ -1,5 +1,9 @@ import re +import pytest + +from asv import util + from . import tools @@ -17,3 +21,45 @@ def test_profile_python_same(capsys, basic_conf): # Check that it did not clone or install assert "Cloning" not in text assert "Installing" not in text + + +def test_profile_python_commit(capsys, basic_conf): + + tmpdir, local, conf, machine_file = basic_conf + + # Create initial results with no profile results + tools.run_asv_with_conf(conf, 'run', "--quick", "--bench=time_secondary.track_value", + f'{util.git_default_branch()}^!', _machine_file=machine_file) + text, err = capsys.readouterr() + + assert "Installing" in text + + # Query the previous empty results results; there should be no issues here + if not util.ON_PYPY: + tools.run_asv_with_conf(conf, 'profile', "time_secondary.track_value", + f'{util.git_default_branch()}', _machine_file=machine_file) + text, err = capsys.readouterr() + + assert "Profile data does not already exist" in text + + tools.run_asv_with_conf(conf, 'run', "--quick", "--profile", + "--bench=time_secondary.track_value", + f'{util.git_default_branch()}^!', _machine_file=machine_file) + else: + # The ASV main process doesn't use PyPy + with pytest.raises(util.UserError): + tools.run_asv_with_conf(conf, 'profile', "time_secondary.track_value", + f'{util.git_default_branch()}', _machine_file=machine_file) + + # Profile results should be present now + if not util.ON_PYPY: + tools.run_asv_with_conf(conf, 'profile', "time_secondary.track_value", + f'{util.git_default_branch()}', _machine_file=machine_file) + text, err = capsys.readouterr() + + assert "Profile data does not already exist" not in text + else: + # The ASV main process doesn't use PyPy + with pytest.raises(util.UserError): + tools.run_asv_with_conf(conf, 'profile', "time_secondary.track_value", + f'{util.git_default_branch()}', _machine_file=machine_file)