eb8b6e
From ccdf0a116dcba01ec4d8caec0baef2910d8d9800 Mon Sep 17 00:00:00 2001
eb8b6e
From: Frantisek Sumsal <frantisek@sumsal.cz>
eb8b6e
Date: Mon, 29 Nov 2021 13:00:21 +0100
eb8b6e
Subject: [PATCH] tests: add helper function to autodetect CI environments
eb8b6e
eb8b6e
Sadly there is no standarized way to check if we're running in some
eb8b6e
CI environment. So let's try to gather the heuristics in one helper
eb8b6e
function.
eb8b6e
eb8b6e
(cherry picked from commit 6fbbf368f5a6d181b21f448255d5a4182dc2ab3a)
eb8b6e
eb8b6e
Related: #2039327
eb8b6e
---
eb8b6e
 src/basic/string-util.h |  6 ++++++
eb8b6e
 src/shared/tests.c      | 42 +++++++++++++++++++++++++++++++++++++++++
eb8b6e
 src/shared/tests.h      |  3 +++
eb8b6e
 3 files changed, 51 insertions(+)
eb8b6e
eb8b6e
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
eb8b6e
index 96a9260f93..742b566932 100644
eb8b6e
--- a/src/basic/string-util.h
eb8b6e
+++ b/src/basic/string-util.h
eb8b6e
@@ -32,6 +32,12 @@ static inline bool streq_ptr(const char *a, const char *b) {
eb8b6e
         return strcmp_ptr(a, b) == 0;
eb8b6e
 }
eb8b6e
 
eb8b6e
+static inline char* strstr_ptr(const char *haystack, const char *needle) {
eb8b6e
+        if (!haystack || !needle)
eb8b6e
+                return NULL;
eb8b6e
+        return strstr(haystack, needle);
eb8b6e
+}
eb8b6e
+
eb8b6e
 static inline const char* strempty(const char *s) {
eb8b6e
         return s ?: "";
eb8b6e
 }
eb8b6e
diff --git a/src/shared/tests.c b/src/shared/tests.c
eb8b6e
index 100b62b9b0..1da80d653f 100644
eb8b6e
--- a/src/shared/tests.c
eb8b6e
+++ b/src/shared/tests.c
eb8b6e
@@ -7,7 +7,9 @@
eb8b6e
 #include <util.h>
eb8b6e
 
eb8b6e
 #include "tests.h"
eb8b6e
+#include "env-util.h"
eb8b6e
 #include "path-util.h"
eb8b6e
+#include "strv.h"
eb8b6e
 
eb8b6e
 char* setup_fake_runtime_dir(void) {
eb8b6e
         char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
eb8b6e
@@ -75,3 +77,43 @@ void test_setup_logging(int level) {
eb8b6e
         log_parse_environment();
eb8b6e
         log_open();
eb8b6e
 }
eb8b6e
+
eb8b6e
+const char *ci_environment(void) {
eb8b6e
+        /* We return a string because we might want to provide multiple bits of information later on: not
eb8b6e
+         * just the general CI environment type, but also whether we're sanitizing or not, etc. The caller is
eb8b6e
+         * expected to use strstr on the returned value. */
eb8b6e
+        static const char *ans = (void*) UINTPTR_MAX;
eb8b6e
+        const char *p;
eb8b6e
+        int r;
eb8b6e
+
eb8b6e
+        if (ans != (void*) UINTPTR_MAX)
eb8b6e
+                return ans;
eb8b6e
+
eb8b6e
+        /* We allow specifying the environment with $CITYPE. Nobody uses this so far, but we are ready. */
eb8b6e
+        p = getenv("CITYPE");
eb8b6e
+        if (!isempty(p))
eb8b6e
+                return (ans = p);
eb8b6e
+
eb8b6e
+        if (getenv_bool("TRAVIS") > 0)
eb8b6e
+                return (ans = "travis");
eb8b6e
+        if (getenv_bool("SEMAPHORE") > 0)
eb8b6e
+                return (ans = "semaphore");
eb8b6e
+        if (getenv_bool("GITHUB_ACTIONS") > 0)
eb8b6e
+                return (ans = "github-actions");
eb8b6e
+        if (getenv("AUTOPKGTEST_ARTIFACTS") || getenv("AUTOPKGTEST_TMP"))
eb8b6e
+                return (ans = "autopkgtest");
eb8b6e
+
eb8b6e
+        FOREACH_STRING(p, "CI", "CONTINOUS_INTEGRATION") {
eb8b6e
+                /* Those vars are booleans according to Semaphore and Travis docs:
eb8b6e
+                 * https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
eb8b6e
+                 * https://docs.semaphoreci.com/ci-cd-environment/environment-variables/#ci
eb8b6e
+                 */
eb8b6e
+                r = getenv_bool(p);
eb8b6e
+                if (r > 0)
eb8b6e
+                        return (ans = "unknown"); /* Some other unknown thing */
eb8b6e
+                if (r == 0)
eb8b6e
+                        return (ans = NULL);
eb8b6e
+        }
eb8b6e
+
eb8b6e
+        return (ans = NULL);
eb8b6e
+}
eb8b6e
diff --git a/src/shared/tests.h b/src/shared/tests.h
eb8b6e
index 3d696d02fd..4f8f349097 100644
eb8b6e
--- a/src/shared/tests.h
eb8b6e
+++ b/src/shared/tests.h
eb8b6e
@@ -5,3 +5,6 @@ char* setup_fake_runtime_dir(void);
eb8b6e
 bool test_is_running_from_builddir(char **exedir);
eb8b6e
 const char* get_testdata_dir(void);
eb8b6e
 void test_setup_logging(int level);
eb8b6e
+
eb8b6e
+/* Provide a convenient way to check if we're running in CI. */
eb8b6e
+const char *ci_environment(void);