core/tests: add nmtst_utils_host_id_{push,pop}() helpers to stub the host-id

The host-id gets read from /var/lib/NetworkManager/secret_key, and cached in
a global variable. Other parts of the code can get the host ID using a
singleton function.

For testing, we need to inject a different host-id. Add two push/pop
functions for that.

Unlike nm_utils_host_id_get(), these functions are not thread-safe (nor
is it possible to make them thread-safe in a reasonable manner).
This commit is contained in:
Thomas Haller 2021-09-07 09:34:43 +02:00
parent 0f5ed15008
commit 49e85bee0e
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 101 additions and 1 deletions

View file

@ -2877,10 +2877,11 @@ typedef struct {
bool timestamp_is_good : 1;
} HostIdData;
static const HostIdData *volatile host_id_static;
static const HostIdData *
_host_id_get(void)
{
static const HostIdData *volatile host_id_static;
const HostIdData *host_id;
again:
@ -2941,6 +2942,78 @@ nm_utils_host_id_get_timestamp_ns(void)
return _host_id_get()->timestamp_ns;
}
static GArray * nmtst_host_id_stack = NULL;
static GMutex nmtst_host_id_lock;
const HostIdData *nmtst_host_id_static_0 = NULL;
void
nmtst_utils_host_id_push(const guint8 *host_id,
gssize host_id_len,
gboolean is_good,
const gint64 *timestamp_ns)
{
NM_G_MUTEX_LOCKED(&nmtst_host_id_lock);
gs_free char *str1_to_free = NULL;
HostIdData * h;
g_assert(host_id_len >= -1);
if (host_id_len < 0)
host_id_len = host_id ? strlen((const char *) host_id) : 0;
nm_log_dbg(LOGD_CORE,
"nmtst: host-id push: \"%s\" (%zu), is-good=%d, timestamp=%" G_GINT64_FORMAT "%s",
nm_utils_buf_utf8safe_escape(host_id,
host_id_len,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&str1_to_free),
(gsize) host_id_len,
!!is_good,
timestamp_ns ? *timestamp_ns : 0,
timestamp_ns ? "" : " (not-good)");
if (!nmtst_host_id_stack) {
nmtst_host_id_stack = g_array_new(FALSE, FALSE, sizeof(HostIdData));
nmtst_host_id_static_0 = g_atomic_pointer_get(&host_id_static);
}
h = nm_g_array_append_new(nmtst_host_id_stack, HostIdData);
*h = (HostIdData){
.host_id = nm_memdup(host_id, host_id_len),
.host_id_len = host_id_len,
.timestamp_ns = timestamp_ns ? *timestamp_ns : 0,
.is_good = is_good,
.timestamp_is_good = !!timestamp_ns,
};
g_atomic_pointer_set(&host_id_static, h);
}
void
nmtst_utils_host_id_pop(void)
{
NM_G_MUTEX_LOCKED(&nmtst_host_id_lock);
HostIdData *h;
g_assert(nmtst_host_id_stack);
g_assert(nmtst_host_id_stack->len > 0);
nm_log_dbg(LOGD_CORE, "nmtst: host-id pop");
h = &g_array_index(nmtst_host_id_stack, HostIdData, nmtst_host_id_stack->len - 1);
g_free((char *) h->host_id);
g_array_set_size(nmtst_host_id_stack, nmtst_host_id_stack->len - 1u);
if (!g_atomic_pointer_compare_and_exchange(
&host_id_static,
h,
nmtst_host_id_stack->len == 0u ? nmtst_host_id_static_0
: nm_g_array_last(nmtst_host_id_stack, HostIdData)))
g_assert_not_reached();
}
/*****************************************************************************/
static const UuidData *

View file

@ -247,6 +247,33 @@ const char *const * nm_utils_proc_cmdline_split(void);
gboolean nm_utils_host_id_get(const guint8 **out_host_id, gsize *out_host_id_len);
gint64 nm_utils_host_id_get_timestamp_ns(void);
void nmtst_utils_host_id_push(const guint8 *host_id,
gssize host_id_len,
gboolean is_good,
const gint64 *timestamp_ns);
void nmtst_utils_host_id_pop(void);
static inline void
_nmtst_auto_utils_host_id_context_pop(const char *const *unused)
{
nmtst_utils_host_id_pop();
}
#define _NMTST_UTILS_HOST_ID_CONTEXT(uniq, host_id) \
_nm_unused nm_auto(_nmtst_auto_utils_host_id_context_pop) \
const char *const NM_UNIQ_T(_host_id_context_, uniq) = ({ \
const gint64 _timestamp_ns = 1631000672; \
\
nmtst_utils_host_id_push((const guint8 *) "" host_id "", \
NM_STRLEN(host_id), \
TRUE, \
&_timestamp_ns); \
"" host_id ""; \
})
#define NMTST_UTILS_HOST_ID_CONTEXT(host_id) _NMTST_UTILS_HOST_ID_CONTEXT(NM_UNIQ, host_id)
/*****************************************************************************/
int nm_utils_arp_type_detect_from_hwaddrlen(gsize hwaddr_len);