diff --git a/testplan/common/entity/base.py b/testplan/common/entity/base.py index 6af947d19..23b10c171 100644 --- a/testplan/common/entity/base.py +++ b/testplan/common/entity/base.py @@ -742,16 +742,15 @@ def filter_locals(cls, local_vars): if key not in EXCLUDE and value is not None } - def context_input(self) -> Dict[str, Any]: + def context_input(self, exclude: list = None) -> Dict[str, Any]: """All attr of self in a dict for context resolution""" ctx = {} + exclude = exclude or [] for attr in dir(self): - if attr == "env": - ctx["env"] = self._env - elif attr: - ctx[attr] = getattr(self, attr) + if attr in exclude: + continue + ctx[attr] = getattr(self, attr) return ctx - # return {attr: getattr(self, attr) for attr in dir(self)} class RunnableStatus(EntityStatus): diff --git a/testplan/testing/base.py b/testplan/testing/base.py index 27a2450b4..36ad93a1c 100644 --- a/testplan/testing/base.py +++ b/testplan/testing/base.py @@ -543,20 +543,24 @@ def __init__(self, **options): self._resolved_bin = None # resolved binary path @property - def stderr(self) -> str: - return os.path.join(self._runpath, "stderr") + def stderr(self) -> Optional[str]: + if self._runpath: + return os.path.join(self._runpath, "stderr") @property - def stdout(self) -> str: - return os.path.join(self._runpath, "stdout") + def stdout(self) -> Optional[str]: + if self._runpath: + return os.path.join(self._runpath, "stdout") @property - def timeout_log(self) -> str: - return os.path.join(self._runpath, "timeout.log") + def timeout_log(self) -> Optional[str]: + if self._runpath: + return os.path.join(self._runpath, "timeout.log") @property - def report_path(self) -> str: - return os.path.join(self._runpath, "report.xml") + def report_path(self) -> Optional[str]: + if self._runpath: + return os.path.join(self._runpath, "report.xml") @property def resolved_bin(self) -> str: @@ -726,7 +730,9 @@ def get_proc_env(self): # override with user specified values if isinstance(self.cfg.proc_env, dict): proc_env = { - key.upper(): render(val, self.context_input()) + key.upper(): render( + val, self.context_input(exclude=["test_context"]) + ) for key, val in self.cfg.proc_env.items() } env.update(proc_env) diff --git a/testplan/testing/multitest/driver/app.py b/testplan/testing/multitest/driver/app.py index 904576b02..88a7279b3 100644 --- a/testplan/testing/multitest/driver/app.py +++ b/testplan/testing/multitest/driver/app.py @@ -189,7 +189,7 @@ def env(self) -> Optional[Dict[str, str]]: return self._env if isinstance(self.cfg.env, dict): - ctx = self.context_input() + ctx = self.context_input(exclude=["env"]) self._env = { key: expand(val, self.context, str) if is_context(val) # allowing None val for child class use case diff --git a/tests/functional/testplan/testing/cpp/test_gtest.py b/tests/functional/testplan/testing/cpp/test_gtest.py index 8a80d92ec..b8a4a84b6 100644 --- a/tests/functional/testplan/testing/cpp/test_gtest.py +++ b/tests/functional/testplan/testing/cpp/test_gtest.py @@ -52,7 +52,11 @@ def test_gtest(mockplan, binary_dir, expected_report, report_status): ) pytest.skip(msg) - mockplan.add(GTest(name="My GTest", binary=binary_path)) + mockplan.add( + GTest( + name="My GTest", binary=binary_path, proc_env={"NAME": "{{name}}"} + ) + ) assert mockplan.run().run is True