twister: Better manage gcov sym link
In twister coverage runs we create the gcov sym link to llvm-cov executable. This code runs multiple times which causes errors with the current implementation since creating the symlink will fail; then copying will also fail because we're using the symlink (self copy the file). Add a helper function to `try_making_symlink` which will handle the following cases: 1. If the symlink already exists and is correct, do nothing. 2. If the symlink exists but points to the wrong file, replace it. 3. If the symlink doesn't exist create it. 4. If creating a symlink fails, just copy the file. Signed-off-by: Yuval Peress <peress@google.com>
This commit is contained in:
parent
3cf4e2f933
commit
5b19a9b94d
1 changed files with 41 additions and 4 deletions
|
@ -4,6 +4,7 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import filecmp
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -502,6 +503,45 @@ class Gcovr(CoverageTool):
|
||||||
|
|
||||||
return ret, { 'report': coverage_file, 'ztest': ztest_file, 'summary': coverage_summary }
|
return ret, { 'report': coverage_file, 'ztest': ztest_file, 'summary': coverage_summary }
|
||||||
|
|
||||||
|
def try_making_symlink(source: str, link: str):
|
||||||
|
"""
|
||||||
|
Attempts to create a symbolic link from source to link.
|
||||||
|
If the link already exists:
|
||||||
|
- If it's a symlink pointing to a different source, it's replaced.
|
||||||
|
- If it's a regular file with the same content, no action is taken.
|
||||||
|
- If it's a regular file with different content, it's replaced with a
|
||||||
|
symlink (if possible, otherwise a copy).
|
||||||
|
If symlinking fails for any reason (other than the link already existing and
|
||||||
|
being correct), it attempts to copy the source to the link.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
source (str): The path to the source file.
|
||||||
|
link (str): The path where the symbolic link should be created.
|
||||||
|
"""
|
||||||
|
if os.path.exists(link):
|
||||||
|
if os.path.islink(link):
|
||||||
|
if os.readlink(link) == source:
|
||||||
|
# Link is already set up
|
||||||
|
return
|
||||||
|
# Link is pointing to the wrong file, fall below this if/else and
|
||||||
|
# it will be replaced
|
||||||
|
elif filecmp.cmp(source, link):
|
||||||
|
# File contents are the same
|
||||||
|
return
|
||||||
|
|
||||||
|
# link exists, but points to a different file, remove the link. We'll
|
||||||
|
# try to create a new one below
|
||||||
|
os.remove(link)
|
||||||
|
|
||||||
|
# Create the symlink
|
||||||
|
try:
|
||||||
|
os.symlink(source, link)
|
||||||
|
except OSError as e:
|
||||||
|
logger.error(
|
||||||
|
"Error creating symlink: %s, attempting to copy.". str(e)
|
||||||
|
)
|
||||||
|
shutil.copy(source, link)
|
||||||
|
|
||||||
|
|
||||||
def choose_gcov_tool(options, is_system_gcov):
|
def choose_gcov_tool(options, is_system_gcov):
|
||||||
gcov_tool = None
|
gcov_tool = None
|
||||||
|
@ -516,10 +556,7 @@ def choose_gcov_tool(options, is_system_gcov):
|
||||||
llvm_cov = shutil.which("llvm-cov", path=llvm_path)
|
llvm_cov = shutil.which("llvm-cov", path=llvm_path)
|
||||||
llvm_cov_ext = pathlib.Path(llvm_cov).suffix
|
llvm_cov_ext = pathlib.Path(llvm_cov).suffix
|
||||||
gcov_lnk = os.path.join(options.outdir, f"gcov{llvm_cov_ext}")
|
gcov_lnk = os.path.join(options.outdir, f"gcov{llvm_cov_ext}")
|
||||||
try:
|
try_making_symlink(llvm_cov, gcov_lnk)
|
||||||
os.symlink(llvm_cov, gcov_lnk)
|
|
||||||
except OSError:
|
|
||||||
shutil.copy(llvm_cov, gcov_lnk)
|
|
||||||
gcov_tool = gcov_lnk
|
gcov_tool = gcov_lnk
|
||||||
elif is_system_gcov:
|
elif is_system_gcov:
|
||||||
gcov_tool = "gcov"
|
gcov_tool = "gcov"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue