[igt-dev] [PATCH i-g-t 4/7] runner: Add the --environment flag
Ryszard Knop
ryszard.knop at intel.com
Tue Jun 28 09:44:32 UTC 2022
Allows specifying additional environment variables to be set for the
launched test processes. This commit introduces the argument parsing.
Signed-off-by: Ryszard Knop <ryszard.knop at intel.com>
---
runner/settings.c | 116 +++++++++++++++++++++++++++++++++++++++++++++-
runner/settings.h | 9 ++++
2 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/runner/settings.c b/runner/settings.c
index d153954a..de339484 100644
--- a/runner/settings.c
+++ b/runner/settings.c
@@ -35,6 +35,7 @@ enum {
OPT_DRY_RUN = 'd',
OPT_INCLUDE = 't',
OPT_EXCLUDE = 'x',
+ OPT_ENVIRONMENT = 'e',
OPT_SYNC = 's',
OPT_LOG_LEVEL = 'l',
OPT_OVERWRITE = 'o',
@@ -389,6 +390,113 @@ static void free_regexes(struct regex_list *regexes)
free(regexes->regexes);
}
+/**
+ * string_trim_and_duplicate() - returns a duplicated, trimmed string
+ * @string: string to trim and duplicate
+ *
+ * If the provided string is NULL, a NULL is returned. In any other case, a
+ * newly-allocated string of length up to strlen(string) is returned. The
+ * returned string has its whitespace removed (as detected by isspace), while
+ * the original string is left unmodified.
+ */
+static char *string_trim_and_duplicate(const char *string) {
+ size_t length;
+
+ if (string == NULL)
+ return NULL;
+
+ length = strlen(string);
+
+ while (length > 0 && isspace(string[0])) {
+ string++;
+ length--;
+ }
+
+ while (length > 0 && isspace(string[length - 1])) {
+ length--;
+ }
+
+ return strndup(string, length);
+}
+
+/**
+ * add_env_var() - Adds a new environment variable to the runner settings.
+ * @env_vars: Pointer to the env var list head from the settings.
+ * @env_kv: Environment variable key-value pair string to add.
+ *
+ * env_kv must be a string like "KEY=VALUE" or just "KEY" if the value is to
+ * be loaded from the runner's environment variables. In the latter case, if
+ * the requested variable is not set, the operation will fail.
+ *
+ * An empty variable may be set by providing an env_kv of "KEY=" or setting
+ * an empty variable for the runner process, then providing just "KEY".
+ */
+static bool add_env_var(struct igt_list_head *env_vars, char *env_kv) {
+ char *current_env_value, *kv_split;
+ struct environment_variable *var = NULL;
+
+ if (env_vars == NULL || env_kv == NULL || strlen(env_kv) == 0)
+ goto error;
+
+ env_kv = strdup(env_kv);
+ kv_split = strchr(env_kv, '=');
+ if (kv_split == env_kv) {
+ fprintf(stderr, "Missing key for --environment \"%s\"\n", env_kv);
+ goto error;
+ }
+
+ var = malloc(sizeof(struct environment_variable));
+ if (kv_split != NULL) {
+ /* value provided - copy string contents after '=' */
+ kv_split[0] = NULL;
+
+ var->key = string_trim_and_duplicate(env_kv);
+ var->value = strdup(kv_split + 1); /* Can be empty, that's okay */
+ } else {
+ /* use the runner's environment, if set */
+ current_env_value = getenv(env_kv);
+ if (current_env_value == NULL) {
+ fprintf(stderr, "No value provided for --environment \"%s\" and "
+ "variable is not set for igt_runner\n", env_kv);
+ goto error;
+ }
+
+ var->key = string_trim_and_duplicate(env_kv);
+ var->value = strdup(current_env_value);
+ }
+
+ if (igt_list_empty_or_null(env_vars))
+ IGT_INIT_LIST_HEAD(env_vars);
+
+ igt_list_add_tail(var, env_vars);
+
+ free(env_kv);
+ return true;
+
+error:
+ if (var != NULL)
+ free(var);
+
+ if (env_kv != NULL)
+ free(env_kv);
+
+ return false;
+}
+
+static void free_env_vars(struct igt_list_head *env_vars) {
+ struct environment_variable *iter;
+
+ while (!igt_list_empty_or_null(env_vars)) {
+ iter = igt_list_first_entry(env_vars, iter, link);
+
+ free(iter->key);
+ free(iter->value);
+
+ igt_list_del(iter);
+ free(iter);
+ }
+}
+
static bool readable_file(const char *filename)
{
return !access(filename, R_OK);
@@ -496,6 +604,7 @@ void clear_settings(struct settings *settings)
free_regexes(&settings->include_regexes);
free_regexes(&settings->exclude_regexes);
+ free_env_vars(&settings->env_vars);
init_settings(settings);
}
@@ -514,6 +623,7 @@ bool parse_options(int argc, char **argv,
{"allow-non-root", no_argument, NULL, OPT_ALLOW_NON_ROOT},
{"include-tests", required_argument, NULL, OPT_INCLUDE},
{"exclude-tests", required_argument, NULL, OPT_EXCLUDE},
+ {"environment", required_argument, NULL, OPT_ENVIRONMENT},
{"abort-on-monitored-error", optional_argument, NULL, OPT_ABORT_ON_ERROR},
{"disk-usage-limit", required_argument, NULL, OPT_DISK_USAGE_LIMIT},
{"sync", no_argument, NULL, OPT_SYNC},
@@ -543,7 +653,7 @@ bool parse_options(int argc, char **argv,
settings->dmesg_warn_level = -1;
- while ((c = getopt_long(argc, argv, "hn:dt:x:sl:omb:L",
+ while ((c = getopt_long(argc, argv, "hn:dt:x:e:sl:omb:L",
long_options, NULL)) != -1) {
switch (c) {
case OPT_VERSION:
@@ -569,6 +679,10 @@ bool parse_options(int argc, char **argv,
if (!add_regex(&settings->exclude_regexes, strdup(optarg)))
goto error;
break;
+ case OPT_ENVIRONMENT:
+ if (!add_env_var(&settings->env_vars, optarg))
+ goto error;
+ break;
case OPT_ABORT_ON_ERROR:
if (!parse_abort_conditions(settings, optarg))
goto error;
diff --git a/runner/settings.h b/runner/settings.h
index 6d444d01..819c3460 100644
--- a/runner/settings.h
+++ b/runner/settings.h
@@ -7,6 +7,8 @@
#include <stdio.h>
#include <glib.h>
+#include "igt_list.h"
+
enum {
LOG_LEVEL_NORMAL = 0,
LOG_LEVEL_QUIET = -1,
@@ -37,6 +39,12 @@ struct regex_list {
size_t size;
};
+struct environment_variable {
+ struct igt_list_head link;
+ char * key;
+ char * value;
+};
+
struct settings {
int abort_mask;
size_t disk_usage_limit;
@@ -46,6 +54,7 @@ struct settings {
bool allow_non_root;
struct regex_list include_regexes;
struct regex_list exclude_regexes;
+ struct igt_list_head env_vars;
bool sync;
int log_level;
bool overwrite;
--
2.36.1
More information about the igt-dev
mailing list