Coverage for mlos_bench/mlos_bench/tests/util_git_test.py: 85%
47 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:51 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:51 +0000
1#
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4#
5"""Unit tests for get_git_info utility function."""
6import os
7import re
8import tempfile
9from pathlib import Path
10from subprocess import CalledProcessError
11from subprocess import check_call as run
13import pytest
15from mlos_bench.util import get_git_info, get_git_root, path_join
18def test_get_git_info() -> None:
19 """Check that we can retrieve git info about the current repository correctly from a
20 file.
21 """
22 (git_repo, git_commit, rel_path, abs_path) = get_git_info(__file__)
23 assert "mlos" in git_repo.lower()
24 assert re.match(r"[0-9a-f]{40}", git_commit) is not None
25 assert rel_path == "mlos_bench/mlos_bench/tests/util_git_test.py"
26 assert abs_path == path_join(__file__, abs_path=True)
29def test_get_git_info_dir() -> None:
30 """Check that we can retrieve git info about the current repository correctly from a
31 directory.
32 """
33 dirname = os.path.dirname(__file__)
34 (git_repo, git_commit, rel_path, abs_path) = get_git_info(dirname)
35 assert "mlos" in git_repo.lower()
36 assert re.match(r"[0-9a-f]{40}", git_commit) is not None
37 assert rel_path == "mlos_bench/mlos_bench/tests"
38 assert abs_path == path_join(dirname, abs_path=True)
41def test_non_git_dir() -> None:
42 """Check that we can handle a non-git directory."""
43 with tempfile.TemporaryDirectory() as non_git_dir:
44 with pytest.raises(CalledProcessError):
45 # This should raise an error because the directory is not a git repository.
46 get_git_root(non_git_dir)
49def test_non_upstream_git() -> None:
50 """Check that we can handle a git directory without an upstream."""
51 with tempfile.TemporaryDirectory() as local_git_dir:
52 local_git_dir = path_join(local_git_dir, abs_path=True)
53 # Initialize a new git repository.
54 run(["git", "init", local_git_dir, "-b", "main"])
55 run(["git", "-C", local_git_dir, "config", "--local", "user.email", "pytest@example.com"])
56 run(["git", "-C", local_git_dir, "config", "--local", "user.name", "PyTest User"])
57 Path(local_git_dir).joinpath("README.md").touch()
58 run(["git", "-C", local_git_dir, "add", "README.md"])
59 run(["git", "-C", local_git_dir, "commit", "-m", "Initial commit"])
60 # This should have slightly different behavior when there is no upstream.
61 (git_repo, _git_commit, rel_path, abs_path) = get_git_info(local_git_dir)
62 assert git_repo == f"file://{local_git_dir}"
63 assert abs_path == local_git_dir
64 assert rel_path == "."
67@pytest.mark.skipif(
68 os.environ.get("GITHUB_ACTIONS") != "true",
69 reason="Not running in GitHub Actions CI.",
70)
71def test_github_actions_git_info() -> None:
72 """
73 Test that get_git_info matches GitHub Actions environment variables if running in
74 CI.
76 Examples
77 --------
78 Test locally with the following command:
80 .. code-block:: shell
82 export GITHUB_ACTIONS=true
83 export GITHUB_SHA=$(git rev-parse HEAD)
84 # GITHUB_REPOSITORY should be in "owner/repo" format.
85 # e.g., GITHUB_REPOSITORY="bpkroth/MLOS" or "microsoft/MLOS"
86 export GITHUB_REPOSITORY=$(git rev-parse --abbrev-ref --symbolic-full-name HEAD@{u} | cut -d/ -f1 | xargs git remote get-url | grep https://github.com | cut -d/ -f4-)
87 pytest -n0 mlos_bench/mlos_bench/tests/util_git_test.py
88 """ # pylint: disable=line-too-long # noqa: E501
89 repo_env = os.environ.get("GITHUB_REPOSITORY") # "owner/repo" format
90 sha_env = os.environ.get("GITHUB_SHA")
91 assert repo_env, "GITHUB_REPOSITORY not set in environment."
92 assert sha_env, "GITHUB_SHA not set in environment."
93 git_repo, git_commit, _rel_path, _abs_path = get_git_info(__file__)
94 assert git_repo.endswith(repo_env), f"git_repo '{git_repo}' does not end with '{repo_env}'"
95 assert (
96 git_commit == sha_env
97 ), f"git_commit '{git_commit}' does not match GITHUB_SHA '{sha_env}'"