On 10/6/26 14:28, Joseph Myers wrote:
One limitation of the DejaGnu board file interface is the lack of
support for setting environment variables on a board.  As a
consequence, various GCC tests that depend on environment variable
setting are either skipped for remote targets, or do not function
correctly in the remote target case, unless a hack is used in the
board file to copy relevant environment variables (set directly on the
build system in the current testsuite code) from the build system to
the target.
This feature has actually been on the TODO list for some time and is planned as part of a larger refactoring of the remote target support in a future release.  The current aim is for 1.6.4 to mostly consolidate bugfixes.

A sufficiently simple API can be carried into the future easily, (and perhaps even be slipped into 1.6.4) but I am very reluctant to establish more conventions on the board_info array, which appears to be intended to be an internal variable in the framework, since we have accessor procedures for it.

For an immediate workaround, do the affected targets have the env(1) command?  Using env(1) would have the advantage of backwards compatibility with current and previous releases of DejaGnu.

Add support for the most common environment variable cases (as used in
the GCC testsuites) to the board file interface, and implement the
underlying support in ssh.exp as well as for the local testing case.

The basic operations provided are setenv and unsetenv, with a
convention for how remote boards store the current environment
variable settings in board_info($dest,env_$var).  Since a common use
case is setting a variable only for a given test or group of tests,
and restoring the previous state afterwards, there are also saveenv
and restoreenv operations, and, building on top of those, pushenv and
popenv operations that maintain a stack of saved state for a given
environment variable and restore from that stack.

What prevents simply adding an env-override-list optional argument to remote_exec?  If the backend sets environment variables only for each test rather than manipulating global state on the target, why should the framework treat that state as global inside DejaGnu?

Merely adding an additional option would also be less work to document.  (The remote_* procedures are documented.)  The intermediate optional arguments for remote_exec are already documented as accepting an empty string as a neutral value, and an empty list of environment overrides would also naturally be neutral.

Why a group of related procedures and not a single remote_env command with get/set/unset/push/pop subcommands?

These are either related and remote-protocol-specific or target-specific, or the entire set could be condensed into a shared implementation with a get-all operation for remote drivers to use.

Why a remote_env command at all?  Why not simply propagate local environment changes to a remote target?  (This could be done by setting traces on ::env or simply snapshotting the environment when runtest starts and comparing.)

Further, as I read this, it seems that the intention is for testsuites to specify short-lived target environment variable overrides. If we are adding new API to a future DejaGnu release, the (also relatively new) "testcase group" infrastructure is designed to frame this kind of dynamic variable; there will eventually be infrastructure in the framework to run each test script in its own group, for example.

(Perhaps "testcase group captures environment" to save the current environment and mark it for restoration upon the end of the current group? What else could "testcase group captures FOO" be useful for in the future? Maybe Tcl global variables with group-extent values? "testcase group captures variable NAME"?)

Some of the main limitations in this interface are as follows:

* There is no getenv interface; tests should generally only need to
   set a controlled environment on the board rather than retrieve the
   original uncontrolled state, except for the save/restore case (which
   can hopefully be handled, as in ssh.exp, b only ever setting
   variables in the context of an individual test being run, rather
   than actually changing some kind of global state on the board).

* The unsetenv interface unsets a variable in the local state, but
   restores it to its initial state (not necessarily unset) in the
   remote case.  Similarly, the pushenv interface only supports setting
   a string value (with previous state saved) rather than setting
   either "unset" or "initial" (with previous state saved).

* There is no handling for PATH-like variables, where appropriate
   handling is prepending a new value (plus colon) rather than fully
   replacing a previous value.  This is not in practice an important
   limitation for testing GCC, since the use of variables such as
   LD_LIBRARY_PATH in the GCC testsuites is readily avoided in remote
   testing, either by testing an installed compiler (with the required
   shared libraries installed in the root filesystem) or by using a
   board file that links with options such as -rpath.  If it were
   desired to handle such variables, however, I'd be inclined to prefer
   a "prepend with colon" interface rather than building it on a getenv
   interface.

A getenv interface solves not only PATH but also all other cases where replacing a value is inappropriate by enabling testcase code to simply examine the effects of previous code before making its own changes.

A major part of DejaGnu's purpose is to "paper over" irrelevant differences between targets.  Having unsetenv do significantly different things with local and remote targets is a serious deficiency that I do not want lurking in the framework for users to trip over.

This feature is desirable, but this interface as suggested is not suitable for DejaGnu.


-- Jacob

Reply via email to