Skip to content
Open
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
55 changes: 34 additions & 21 deletions benchexec/tablegenerator/htmltable.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,14 @@ def prepare_value(column, value, run_result):
formatted_value = column.format_value(value, "html_cell")
result = {}
if column.href:
result["href"] = _create_link(column.href, base_dir, run_result, href_base)
# We use raw_value for the ${value} placeholder.
# If the cell is empty, we fall back to the column pattern if it exists.
subst_value = raw_value
if not subst_value and not formatted_value:
subst_value = column.pattern
result["href"] = _create_link(
column.href, base_dir, run_result, href_base, value=subst_value
)
if not raw_value and not formatted_value:
raw_value = column.pattern
if raw_value is not None and not raw_value == "":
Expand All @@ -450,7 +457,9 @@ def clean_up_results(res):
if getattr(res, k) is not None
}
if toolHref:
result["href"] = _create_link(toolHref, base_dir, res, href_base)
result["href"] = _create_link(
toolHref, base_dir, res, href_base, value=res.status
)
result["values"] = values
return result

Expand All @@ -474,31 +483,35 @@ def clean_up_row(row):
return [clean_up_row(row) for row in rows]


def _create_link(href, base_dir, runResult=None, href_base=None):
def _create_link(href, base_dir, runResult=None, href_base=None, value=None):
def get_replacements(task_file):
var_prefix = "taskdef_" if task_file.endswith(".yml") else "inputfile_"
return (
replacements = [
(var_prefix + "name", os.path.basename(task_file)),
(var_prefix + "path", os.path.dirname(task_file) or "."),
(var_prefix + "path_abs", os.path.dirname(os.path.abspath(task_file))),
) + (
(
("logfile_name", os.path.basename(runResult.log_file)),
(
"logfile_path",
os.path.dirname(
os.path.relpath(runResult.log_file, href_base or ".")
)
or ".",
),
(
"logfile_path_abs",
os.path.dirname(os.path.abspath(runResult.log_file)),
),
]
if value is not None:
replacements.append(("value", str(value)))

if runResult and runResult.log_file:
replacements.extend(
[
("logfile_name", os.path.basename(runResult.log_file)),
(
"logfile_path",
os.path.dirname(
os.path.relpath(runResult.log_file, href_base or ".")
)
or ".",
),
(
"logfile_path_abs",
os.path.dirname(os.path.abspath(runResult.log_file)),
),
]
)
if runResult.log_file
else ()
)
return tuple(replacements)

source_file = (
# os.path.relpath creates os-dependant paths, so standardize the output between OSs
Expand Down
68 changes: 68 additions & 0 deletions benchexec/tablegenerator/test_href_substitution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# This file is part of BenchExec, a framework for reliable benchmarking:
# https://github.com/sosy-lab/benchexec
#
# SPDX-FileCopyrightText: 2007-2026 Dirk Beyer <https://www.sosy-lab.org>
#
# SPDX-License-Identifier: Apache-2.0

import unittest
from benchexec.tablegenerator import htmltable


class TestHrefSubstitution(unittest.TestCase):
def test_create_link_with_value_substitution(self):
href = "http://example.com/${value}"
base_dir = "."
value = "test-value"

# We need a dummy runResult for _create_link to work if it tries to get source_file
# or we can pass None if we handle it.
# Looking at _create_link, it uses runResult to get source_file.

class DummyTaskId:
def __init__(self, name):
self.name = name

class DummyRunResult:
def __init__(self, task_name, log_file=None):
self.task_id = DummyTaskId(task_name)
self.log_file = log_file

def __getitem__(self, key):
return getattr(self, key)

run_result = DummyRunResult("task1")

# Test basic substitution
link = htmltable._create_link(href, base_dir, runResult=run_result, value=value)
self.assertEqual(link, "http://example.com/test-value")

def test_create_link_with_value_substitution_and_other_vars(self):
href = "http://example.com/${inputfile_name}?v=${value}"
base_dir = "."
value = "123"

class DummyTaskId:
def __init__(self, name):
self.name = name

class DummyRunResult:
def __init__(self, task_name, log_file=None):
self.task_id = DummyTaskId(task_name)
self.log_file = log_file

run_result = DummyRunResult("dir/task1.c")

link = htmltable._create_link(href, base_dir, runResult=run_result, value=value)
self.assertEqual(link, "http://example.com/task1.c?v=123")

def test_create_link_backward_compatibility(self):
href = "http://example.com/static"
base_dir = "."

link = htmltable._create_link(href, base_dir)
self.assertEqual(link, "http://example.com/static")


if __name__ == "__main__":
unittest.main()