Blame shared/nm-glib-aux/tests/test-shared-general.c

Packit Service b23acc
// SPDX-License-Identifier: LGPL-2.1+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2018 Red Hat, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#define NM_TEST_UTILS_NO_LIBNM 1
Packit Service b23acc
Packit Service b23acc
#include "nm-default.h"
Packit Service b23acc
Packit Service b23acc
#include "nm-std-aux/unaligned.h"
Packit Service b23acc
#include "nm-glib-aux/nm-random-utils.h"
Packit Service b23acc
#include "nm-glib-aux/nm-str-buf.h"
Packit Service b23acc
#include "nm-glib-aux/nm-time-utils.h"
Packit Service b23acc
#include "nm-glib-aux/nm-ref-string.h"
Packit Service b23acc
Packit Service b23acc
#include "nm-utils/nm-test-utils.h"
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_gpid (void)
Packit Service b23acc
{
Packit Service b23acc
	const int *int_ptr;
Packit Service b23acc
	GPid pid = 42;
Packit Service b23acc
Packit Service b23acc
	/* We redefine G_PID_FORMAT, because it's only available since glib 2.53.5.
Packit Service b23acc
	 *
Packit Service b23acc
	 * Also, this is the format for GPid, which for glib is always a typedef
Packit Service b23acc
	 * for "int". Add a check for that here.
Packit Service b23acc
	 *
Packit Service b23acc
	 * G_PID_FORMAT is not about pid_t, which might be a smaller int, and which we would
Packit Service b23acc
	 * check with SIZEOF_PID_T. */
Packit Service b23acc
	G_STATIC_ASSERT (sizeof (GPid) == sizeof (int));
Packit Service b23acc
Packit Service b23acc
	g_assert_cmpstr (""G_PID_FORMAT, ==, "i");
Packit Service b23acc
Packit Service b23acc
	/* check that it's really "int". We will get a compiler warning, if that's not
Packit Service b23acc
	 * the case. */
Packit Service b23acc
	int_ptr = &pid;
Packit Service b23acc
	g_assert_cmpint (*int_ptr, ==, 42);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_monotonic_timestamp (void)
Packit Service b23acc
{
Packit Service b23acc
	g_assert (nm_utils_get_monotonic_timestamp_sec () > 0);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nmhash (void)
Packit Service b23acc
{
Packit Service b23acc
	int rnd;
Packit Service b23acc
Packit Service b23acc
	nm_utils_random_bytes (&rnd, sizeof (rnd));
Packit Service b23acc
Packit Service b23acc
	g_assert (nm_hash_val (555, 4) != 0);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static const char *
Packit Service b23acc
_make_strv_foo (void)
Packit Service b23acc
{
Packit Service b23acc
	return "foo";
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static const char *const*const _tst_make_strv_1 = NM_MAKE_STRV ("1", "2");
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_make_strv (void)
Packit Service b23acc
{
Packit Service b23acc
	const char *const*v1a = NM_MAKE_STRV ("a");
Packit Service b23acc
	const char *const*v1b = NM_MAKE_STRV ("a", );
Packit Service b23acc
	const char *const*v2a = NM_MAKE_STRV ("a", "b");
Packit Service b23acc
	const char *const*v2b = NM_MAKE_STRV ("a", "b", );
Packit Service b23acc
	const char *const v3[] = { "a", "b", };
Packit Service b23acc
	const char *const*v4b = NM_MAKE_STRV ("a", _make_strv_foo (), );
Packit Service b23acc
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (v1a) == 1);
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (v1b) == 1);
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (v2a) == 2);
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (v2b) == 2);
Packit Service b23acc
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (_tst_make_strv_1) == 2);
Packit Service b23acc
	g_assert_cmpstr (_tst_make_strv_1[0], ==, "1");
Packit Service b23acc
	g_assert_cmpstr (_tst_make_strv_1[1], ==, "2");
Packit Service b23acc
	/* writing the static read-only variable leads to crash .*/
Packit Service b23acc
	//((char **) _tst_make_strv_1)[0] = NULL;
Packit Service b23acc
	//((char **) _tst_make_strv_1)[2] = "c";
Packit Service b23acc
Packit Service b23acc
	G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (v3) == 2);
Packit Service b23acc
Packit Service b23acc
	g_assert (NM_PTRARRAY_LEN (v4b) == 2);
Packit Service b23acc
Packit Service b23acc
	G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (NM_MAKE_STRV ("a", "b"  )) == 3);
Packit Service b23acc
	G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (NM_MAKE_STRV ("a", "b", )) == 3);
Packit Service b23acc
Packit Service b23acc
	nm_strquote_a (300, "");
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
typedef enum {
Packit Service b23acc
	TEST_NM_STRDUP_ENUM_m1 = -1,
Packit Service b23acc
	TEST_NM_STRDUP_ENUM_3  = 3,
Packit Service b23acc
} TestNMStrdupIntEnum;
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_strdup_int (void)
Packit Service b23acc
{
Packit Service b23acc
#define _NM_STRDUP_INT_TEST(num, str) \
Packit Service b23acc
	G_STMT_START { \
Packit Service b23acc
		gs_free char *_s1 = NULL; \
Packit Service b23acc
		\
Packit Service b23acc
		_s1 = nm_strdup_int ((num)); \
Packit Service b23acc
		\
Packit Service b23acc
		g_assert (_s1); \
Packit Service b23acc
		g_assert_cmpstr (_s1, ==, str); \
Packit Service b23acc
	} G_STMT_END
Packit Service b23acc
Packit Service b23acc
#define _NM_STRDUP_INT_TEST_TYPED(type, num) \
Packit Service b23acc
	G_STMT_START { \
Packit Service b23acc
		type _num = ((type) num); \
Packit Service b23acc
		\
Packit Service b23acc
		_NM_STRDUP_INT_TEST (_num, G_STRINGIFY (num)); \
Packit Service b23acc
	} G_STMT_END
Packit Service b23acc
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (char, 0);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (char, 1);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (guint8, 0);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (gint8, 25);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (char, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (short, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (int, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (long, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (unsigned char, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (unsigned short, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (unsigned, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (unsigned long, 47);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (gint64, 9223372036854775807);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (gint64, -9223372036854775807);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (guint64, 0);
Packit Service b23acc
	_NM_STRDUP_INT_TEST_TYPED (guint64, 9223372036854775807);
Packit Service b23acc
Packit Service b23acc
	_NM_STRDUP_INT_TEST (TEST_NM_STRDUP_ENUM_m1, "-1");
Packit Service b23acc
	_NM_STRDUP_INT_TEST (TEST_NM_STRDUP_ENUM_3,  "3");
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_strndup_a (void)
Packit Service b23acc
{
Packit Service b23acc
	int run;
Packit Service b23acc
Packit Service b23acc
	for (run = 0; run < 20; run++) {
Packit Service b23acc
		gs_free char *input = NULL;
Packit Service b23acc
		char ch;
Packit Service b23acc
		gsize i, l;
Packit Service b23acc
Packit Service b23acc
		input = g_strnfill (nmtst_get_rand_uint32 () % 20, 'x');
Packit Service b23acc
Packit Service b23acc
		for (i = 0; input[i]; i++) {
Packit Service b23acc
			while ((ch = ((char) nmtst_get_rand_uint32 ())) == '\0') {
Packit Service b23acc
				/* repeat. */
Packit Service b23acc
			}
Packit Service b23acc
			input[i] = ch;
Packit Service b23acc
		}
Packit Service b23acc
Packit Service b23acc
		{
Packit Service b23acc
			gs_free char *dup_free = NULL;
Packit Service b23acc
			const char *dup;
Packit Service b23acc
Packit Service b23acc
			l = strlen (input) + 1;
Packit Service b23acc
			dup = nm_strndup_a (10, input, l - 1, &dup_free);
Packit Service b23acc
			g_assert_cmpstr (dup, ==, input);
Packit Service b23acc
			if (strlen (dup) < 10)
Packit Service b23acc
				g_assert (!dup_free);
Packit Service b23acc
			else
Packit Service b23acc
				g_assert (dup == dup_free);
Packit Service b23acc
		}
Packit Service b23acc
Packit Service b23acc
		{
Packit Service b23acc
			gs_free char *dup_free = NULL;
Packit Service b23acc
			const char *dup;
Packit Service b23acc
Packit Service b23acc
			l = nmtst_get_rand_uint32 () % 23;
Packit Service b23acc
			dup = nm_strndup_a (10, input, l, &dup_free);
Packit Service b23acc
			g_assert (strncmp (dup, input, l) == 0);
Packit Service b23acc
			g_assert (strlen (dup) <= l);
Packit Service b23acc
			if (l < 10)
Packit Service b23acc
				g_assert (!dup_free);
Packit Service b23acc
			else
Packit Service b23acc
				g_assert (dup == dup_free);
Packit Service b23acc
			if (strlen (input) < l)
Packit Service b23acc
				g_assert (nm_utils_memeqzero (&dup[strlen (input)], l - strlen (input)));
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_ip4_addr_is_localhost (void)
Packit Service b23acc
{
Packit Service b23acc
	g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.0.0.0")));
Packit Service b23acc
	g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.0.0.1")));
Packit Service b23acc
	g_assert ( nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("127.5.0.1")));
Packit Service b23acc
	g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("126.5.0.1")));
Packit Service b23acc
	g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("128.5.0.1")));
Packit Service b23acc
	g_assert (!nm_ip4_addr_is_localhost (nmtst_inet4_from_string ("129.5.0.1")));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_unaligned (void)
Packit Service b23acc
{
Packit Service b23acc
	int shift;
Packit Service b23acc
Packit Service b23acc
	for (shift = 0; shift <= 32; shift++) {
Packit Service b23acc
		guint8 buf[100] = { };
Packit Service b23acc
		guint8 val = 0;
Packit Service b23acc
Packit Service b23acc
		while (val == 0)
Packit Service b23acc
			val = nmtst_get_rand_uint32 () % 256;
Packit Service b23acc
Packit Service b23acc
		buf[shift] = val;
Packit Service b23acc
Packit Service b23acc
		g_assert_cmpint (unaligned_read_le64 (&buf[shift]), ==, (guint64) val);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_be64 (&buf[shift]), ==, ((guint64) val) << 56);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_ne64 (&buf[shift]), !=, 0);
Packit Service b23acc
Packit Service b23acc
		g_assert_cmpint (unaligned_read_le32 (&buf[shift]), ==, (guint32) val);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_be32 (&buf[shift]), ==, ((guint32) val) << 24);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_ne32 (&buf[shift]), !=, 0);
Packit Service b23acc
Packit Service b23acc
		g_assert_cmpint (unaligned_read_le16 (&buf[shift]), ==, (guint16) val);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_be16 (&buf[shift]), ==, ((guint16) val) << 8);
Packit Service b23acc
		g_assert_cmpint (unaligned_read_ne16 (&buf[shift]), !=, 0);
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
_strv_cmp_fuzz_input (const char *const*in,
Packit Service b23acc
                      gssize l,
Packit Service b23acc
                      const char ***out_strv_free_shallow,
Packit Service b23acc
                      char ***out_strv_free_deep,
Packit Service b23acc
                      const char *const* *out_s1,
Packit Service b23acc
                      const char *const* *out_s2)
Packit Service b23acc
{
Packit Service b23acc
	const char **strv;
Packit Service b23acc
	gsize i;
Packit Service b23acc
Packit Service b23acc
	/* Fuzz the input argument. It will return two output arrays that are semantically
Packit Service b23acc
	 * equal the input. */
Packit Service b23acc
Packit Service b23acc
	if (nmtst_get_rand_bool ()) {
Packit Service b23acc
		char **ss;
Packit Service b23acc
Packit Service b23acc
		if (l < 0)
Packit Service b23acc
			ss = g_strdupv ((char **) in);
Packit Service b23acc
		else if (l == 0) {
Packit Service b23acc
			ss =   nmtst_get_rand_bool ()
Packit Service b23acc
			     ? NULL
Packit Service b23acc
			     : g_new0 (char *, 1);
Packit Service b23acc
		} else {
Packit Service b23acc
			ss = nm_memdup (in, sizeof (const char *) * l);
Packit Service b23acc
			for (i = 0; i < (gsize) l; i++)
Packit Service b23acc
				ss[i] = g_strdup (ss[i]);
Packit Service b23acc
		}
Packit Service b23acc
		strv = (const char **) ss;
Packit Service b23acc
		*out_strv_free_deep = ss;
Packit Service b23acc
	} else {
Packit Service b23acc
		if (l < 0) {
Packit Service b23acc
			strv =   in
Packit Service b23acc
			       ? nm_memdup (in, sizeof (const char *) * (NM_PTRARRAY_LEN (in) + 1))
Packit Service b23acc
			       : NULL;
Packit Service b23acc
		} else if (l == 0) {
Packit Service b23acc
			strv =   nmtst_get_rand_bool ()
Packit Service b23acc
			       ? NULL
Packit Service b23acc
			       : g_new0 (const char *, 1);
Packit Service b23acc
		} else
Packit Service b23acc
			strv = nm_memdup (in, sizeof (const char *) * l);
Packit Service b23acc
		*out_strv_free_shallow = strv;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	*out_s1 = in;
Packit Service b23acc
	*out_s2 = strv;
Packit Service b23acc
Packit Service b23acc
	if (nmtst_get_rand_bool ()) {
Packit Service b23acc
		/* randomly swap the original and the clone. That means, out_s1 is either
Packit Service b23acc
		 * the input argument (as-is) or the sementically equal clone. */
Packit Service b23acc
		NM_SWAP (*out_s1, *out_s2);
Packit Service b23acc
	}
Packit Service b23acc
	if (nmtst_get_rand_bool ()) {
Packit Service b23acc
		/* randomly make s1 and s2 the same. This is for testing that
Packit Service b23acc
		 * comparing two identical pointers yields the same result. */
Packit Service b23acc
		*out_s2 = *out_s1;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
_strv_cmp_free_deep (char **strv,
Packit Service b23acc
                     gssize len)
Packit Service b23acc
{
Packit Service b23acc
	gssize i;
Packit Service b23acc
Packit Service b23acc
	if (strv) {
Packit Service b23acc
		if (len < 0)
Packit Service b23acc
			g_strfreev (strv);
Packit Service b23acc
		else {
Packit Service b23acc
			for (i = 0; i < len; i++)
Packit Service b23acc
				g_free (strv[i]);
Packit Service b23acc
			g_free (strv);
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_strv_cmp (void)
Packit Service b23acc
{
Packit Service b23acc
	const char *const strv0[1] = { };
Packit Service b23acc
	const char *const strv1[2] = { "", };
Packit Service b23acc
Packit Service b23acc
#define _STRV_CMP(a1, l1, a2, l2, equal) \
Packit Service b23acc
	G_STMT_START { \
Packit Service b23acc
		gssize _l1 = (l1); \
Packit Service b23acc
		gssize _l2 = (l2); \
Packit Service b23acc
		const char *const*_a1; \
Packit Service b23acc
		const char *const*_a2; \
Packit Service b23acc
		const char *const*_a1x; \
Packit Service b23acc
		const char *const*_a2x; \
Packit Service b23acc
		char **_a1_free_deep = NULL; \
Packit Service b23acc
		char **_a2_free_deep = NULL; \
Packit Service b23acc
		gs_free const char **_a1_free_shallow = NULL; \
Packit Service b23acc
		gs_free const char **_a2_free_shallow = NULL; \
Packit Service b23acc
		int _c1, _c2; \
Packit Service b23acc
		\
Packit Service b23acc
		_strv_cmp_fuzz_input ((a1), _l1, &_a1_free_shallow, &_a1_free_deep, &_a1, &_a1x); \
Packit Service b23acc
		_strv_cmp_fuzz_input ((a2), _l2, &_a2_free_shallow, &_a2_free_deep, &_a2, &_a2x); \
Packit Service b23acc
		\
Packit Service b23acc
		_c1 = _nm_utils_strv_cmp_n (_a1, _l1, _a2, _l2); \
Packit Service b23acc
		_c2 = _nm_utils_strv_cmp_n (_a2, _l2, _a1, _l1); \
Packit Service b23acc
		if (equal) { \
Packit Service b23acc
			g_assert_cmpint (_c1, ==, 0); \
Packit Service b23acc
			g_assert_cmpint (_c2, ==, 0); \
Packit Service b23acc
		} else { \
Packit Service b23acc
			g_assert_cmpint (_c1, ==, -1); \
Packit Service b23acc
			g_assert_cmpint (_c2, ==, 1); \
Packit Service b23acc
		} \
Packit Service b23acc
		\
Packit Service b23acc
		/* Compare with self. _strv_cmp_fuzz_input() randomly swapped the arguments (_a1 and _a1x).
Packit Service b23acc
		 * Either way, the arrays must compare equal to their semantically equal alternative. */ \
Packit Service b23acc
		g_assert_cmpint (_nm_utils_strv_cmp_n (_a1, _l1, _a1x, _l1), ==, 0); \
Packit Service b23acc
		g_assert_cmpint (_nm_utils_strv_cmp_n (_a2, _l2, _a2x, _l2), ==, 0); \
Packit Service b23acc
		\
Packit Service b23acc
		_strv_cmp_free_deep (_a1_free_deep, _l1); \
Packit Service b23acc
		_strv_cmp_free_deep (_a2_free_deep, _l2); \
Packit Service b23acc
	} G_STMT_END
Packit Service b23acc
Packit Service b23acc
	_STRV_CMP (NULL,  -1, NULL,  -1, TRUE);
Packit Service b23acc
Packit Service b23acc
	_STRV_CMP (NULL,  -1, NULL,   0, FALSE);
Packit Service b23acc
	_STRV_CMP (NULL,  -1, strv0,  0, FALSE);
Packit Service b23acc
	_STRV_CMP (NULL,  -1, strv0, -1, FALSE);
Packit Service b23acc
Packit Service b23acc
	_STRV_CMP (NULL,   0, NULL,   0, TRUE);
Packit Service b23acc
	_STRV_CMP (NULL,   0, strv0,  0, TRUE);
Packit Service b23acc
	_STRV_CMP (NULL,   0, strv0, -1, TRUE);
Packit Service b23acc
	_STRV_CMP (strv0,  0, strv0,  0, TRUE);
Packit Service b23acc
	_STRV_CMP (strv0,  0, strv0, -1, TRUE);
Packit Service b23acc
	_STRV_CMP (strv0, -1, strv0, -1, TRUE);
Packit Service b23acc
Packit Service b23acc
	_STRV_CMP (NULL,   0, strv1, -1, FALSE);
Packit Service b23acc
	_STRV_CMP (NULL,   0, strv1,  1, FALSE);
Packit Service b23acc
	_STRV_CMP (strv0,  0, strv1, -1, FALSE);
Packit Service b23acc
	_STRV_CMP (strv0,  0, strv1,  1, FALSE);
Packit Service b23acc
	_STRV_CMP (strv0, -1, strv1, -1, FALSE);
Packit Service b23acc
	_STRV_CMP (strv0, -1, strv1,  1, FALSE);
Packit Service b23acc
Packit Service b23acc
	_STRV_CMP (strv1, -1, strv1,  1, TRUE);
Packit Service b23acc
	_STRV_CMP (strv1,  1, strv1,  1, TRUE);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
_do_strstrip_avoid_copy (const char *str)
Packit Service b23acc
{
Packit Service b23acc
	gs_free char *str1 = g_strdup (str);
Packit Service b23acc
	gs_free char *str2 = g_strdup (str);
Packit Service b23acc
	gs_free char *str3 = NULL;
Packit Service b23acc
	gs_free char *str4 = NULL;
Packit Service b23acc
	const char *s3;
Packit Service b23acc
	const char *s4;
Packit Service b23acc
Packit Service b23acc
	if (str1)
Packit Service b23acc
		g_strstrip (str1);
Packit Service b23acc
Packit Service b23acc
	nm_strstrip (str2);
Packit Service b23acc
Packit Service b23acc
	g_assert_cmpstr (str1, ==, str2);
Packit Service b23acc
Packit Service b23acc
	s3 = nm_strstrip_avoid_copy (str, &str3;;
Packit Service b23acc
	g_assert_cmpstr (str1, ==, s3);
Packit Service b23acc
Packit Service b23acc
	s4 = nm_strstrip_avoid_copy_a (10, str, &str4;;
Packit Service b23acc
	g_assert_cmpstr (str1, ==, s4);
Packit Service b23acc
	g_assert (!str == !s4);
Packit Service b23acc
	g_assert (!s4 || strlen (s4) <= strlen (str));
Packit Service b23acc
	if (s4 && s4 == &str[strlen (str) - strlen (s4)]) {
Packit Service b23acc
		g_assert (!str4);
Packit Service b23acc
		g_assert (s3 == s4);
Packit Service b23acc
	} else if (s4 && strlen (s4) >= 10) {
Packit Service b23acc
		g_assert (str4);
Packit Service b23acc
		g_assert (s4 == str4);
Packit Service b23acc
	} else
Packit Service b23acc
		g_assert (!str4);
Packit Service b23acc
Packit Service b23acc
	if (!nm_streq0 (str1, str))
Packit Service b23acc
		_do_strstrip_avoid_copy (str1);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_strstrip_avoid_copy (void)
Packit Service b23acc
{
Packit Service b23acc
	_do_strstrip_avoid_copy (NULL);
Packit Service b23acc
	_do_strstrip_avoid_copy ("");
Packit Service b23acc
	_do_strstrip_avoid_copy (" ");
Packit Service b23acc
	_do_strstrip_avoid_copy (" a ");
Packit Service b23acc
	_do_strstrip_avoid_copy (" 012345678 ");
Packit Service b23acc
	_do_strstrip_avoid_copy (" 0123456789 ");
Packit Service b23acc
	_do_strstrip_avoid_copy (" 01234567890 ");
Packit Service b23acc
	_do_strstrip_avoid_copy (" 012345678901 ");
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_utils_bin2hexstr (void)
Packit Service b23acc
{
Packit Service b23acc
	int n_run;
Packit Service b23acc
Packit Service b23acc
	for (n_run = 0; n_run < 100; n_run++) {
Packit Service b23acc
		guint8 buf[100];
Packit Service b23acc
		guint8 buf2[G_N_ELEMENTS (buf) + 1];
Packit Service b23acc
		gsize len = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (buf) + 1);
Packit Service b23acc
		char strbuf1[G_N_ELEMENTS (buf) * 3];
Packit Service b23acc
		gboolean allocate = nmtst_get_rand_bool ();
Packit Service b23acc
		char delimiter = nmtst_get_rand_bool () ? ':' : '\0';
Packit Service b23acc
		gboolean upper_case = nmtst_get_rand_bool ();
Packit Service b23acc
		gsize expected_strlen;
Packit Service b23acc
		char *str_hex;
Packit Service b23acc
		gsize required_len;
Packit Service b23acc
		gboolean outlen_set;
Packit Service b23acc
		gsize outlen;
Packit Service b23acc
		guint8 *bin2;
Packit Service b23acc
Packit Service b23acc
		nmtst_rand_buf (NULL, buf, len);
Packit Service b23acc
Packit Service b23acc
		if (len == 0)
Packit Service b23acc
			expected_strlen = 0;
Packit Service b23acc
		else if (delimiter != '\0')
Packit Service b23acc
			expected_strlen = (len * 3u) - 1;
Packit Service b23acc
		else
Packit Service b23acc
			expected_strlen = len * 2u;
Packit Service b23acc
Packit Service b23acc
		g_assert_cmpint (expected_strlen, <, G_N_ELEMENTS (strbuf1));
Packit Service b23acc
Packit Service b23acc
		str_hex = nm_utils_bin2hexstr_full (buf, len, delimiter, upper_case, !allocate ? strbuf1 : NULL);
Packit Service b23acc
Packit Service b23acc
		g_assert (str_hex);
Packit Service b23acc
		if (!allocate)
Packit Service b23acc
			g_assert (str_hex == strbuf1);
Packit Service b23acc
		g_assert_cmpint (strlen (str_hex), ==, expected_strlen);
Packit Service b23acc
Packit Service b23acc
		g_assert (NM_STRCHAR_ALL (str_hex, ch,    (ch >= '0' && ch <= '9')
Packit Service b23acc
		                                       || ch == delimiter
Packit Service b23acc
		                                       || (  upper_case
Packit Service b23acc
		                                           ? (ch >= 'A' && ch <= 'F')
Packit Service b23acc
		                                           : (ch >= 'a' && ch <= 'f'))));
Packit Service b23acc
Packit Service b23acc
		required_len = nmtst_get_rand_bool () ? len : 0u;
Packit Service b23acc
Packit Service b23acc
		outlen_set = required_len == 0 || nmtst_get_rand_bool ();
Packit Service b23acc
Packit Service b23acc
		memset (buf2, 0, sizeof (buf2));
Packit Service b23acc
Packit Service b23acc
		bin2 = nm_utils_hexstr2bin_full (str_hex,
Packit Service b23acc
		                                 nmtst_get_rand_bool (),
Packit Service b23acc
		                                 delimiter != '\0' && nmtst_get_rand_bool (),
Packit Service b23acc
		                                   delimiter != '\0'
Packit Service b23acc
		                                 ? nmtst_rand_select ((const char *) ":", ":-")
Packit Service b23acc
		                                 : nmtst_rand_select ((const char *) ":", ":-", "", NULL),
Packit Service b23acc
		                                 required_len,
Packit Service b23acc
		                                 buf2,
Packit Service b23acc
		                                 len,
Packit Service b23acc
		                                 outlen_set ? &outlen : NULL);
Packit Service b23acc
		if (len > 0) {
Packit Service b23acc
			g_assert (bin2);
Packit Service b23acc
			g_assert (bin2 == buf2);
Packit Service b23acc
		} else
Packit Service b23acc
			g_assert (!bin2);
Packit Service b23acc
Packit Service b23acc
		if (outlen_set)
Packit Service b23acc
			g_assert_cmpint (outlen, ==, len);
Packit Service b23acc
Packit Service b23acc
		g_assert_cmpmem (buf, len, buf2, len);
Packit Service b23acc
Packit Service b23acc
		g_assert (buf2[len] == '\0');
Packit Service b23acc
Packit Service b23acc
		if (allocate)
Packit Service b23acc
			g_free (str_hex);
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_ref_string (void)
Packit Service b23acc
{
Packit Service b23acc
	nm_auto_ref_string NMRefString *s1 = NULL;
Packit Service b23acc
	NMRefString *s2;
Packit Service b23acc
Packit Service b23acc
	s1 = nm_ref_string_new ("hallo");
Packit Service b23acc
	g_assert (s1);
Packit Service b23acc
	g_assert_cmpstr (s1->str, ==, "hallo");
Packit Service b23acc
	g_assert_cmpint (s1->len, ==, strlen ("hallo"));
Packit Service b23acc
Packit Service b23acc
	s2 = nm_ref_string_new ("hallo");
Packit Service b23acc
	g_assert (s2 == s1);
Packit Service b23acc
	nm_ref_string_unref (s2);
Packit Service b23acc
Packit Service b23acc
	s2 = nm_ref_string_new (NULL);
Packit Service b23acc
	g_assert (!s2);
Packit Service b23acc
	nm_ref_string_unref (s2);
Packit Service b23acc
Packit Service b23acc
#define STR_WITH_NUL "hallo\0test\0"
Packit Service b23acc
	s2 = nm_ref_string_new_len (STR_WITH_NUL, NM_STRLEN (STR_WITH_NUL));
Packit Service b23acc
	g_assert (s2);
Packit Service b23acc
	g_assert_cmpstr (s2->str, ==, "hallo");
Packit Service b23acc
	g_assert_cmpint (s2->len, ==, NM_STRLEN (STR_WITH_NUL));
Packit Service b23acc
	g_assert_cmpint (s2->len, >, strlen (s2->str));
Packit Service b23acc
	g_assert_cmpmem (s2->str, s2->len, STR_WITH_NUL, NM_STRLEN (STR_WITH_NUL));
Packit Service b23acc
	g_assert (s2->str[s2->len] == '\0');
Packit Service b23acc
	nm_ref_string_unref (s2);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static
Packit Service b23acc
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
Packit Service b23acc
	_do_string_table_lookup,
Packit Service b23acc
	int,
Packit Service b23acc
	{ ; },
Packit Service b23acc
	{ return -1; },
Packit Service b23acc
	{ "0", 0 },
Packit Service b23acc
	{ "1", 1 },
Packit Service b23acc
	{ "2", 2 },
Packit Service b23acc
	{ "3", 3 },
Packit Service b23acc
)
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_string_table_lookup (void)
Packit Service b23acc
{
Packit Service b23acc
	const char *const args[] = { NULL, "0", "1", "2", "3", "x", };
Packit Service b23acc
	int i;
Packit Service b23acc
Packit Service b23acc
	for (i = 0; i < G_N_ELEMENTS (args); i++) {
Packit Service b23acc
		const char *needle = args[i];
Packit Service b23acc
		const int val2 = _nm_utils_ascii_str_to_int64 (needle, 10, 0, 100, -1);
Packit Service b23acc
		int val;
Packit Service b23acc
Packit Service b23acc
		val = _do_string_table_lookup (needle);
Packit Service b23acc
		g_assert_cmpint (val, ==, val2);
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_utils_get_next_realloc_size (void)
Packit Service b23acc
{
Packit Service b23acc
	static const struct {
Packit Service b23acc
		gsize requested;
Packit Service b23acc
		gsize reserved_true;
Packit Service b23acc
		gsize reserved_false;
Packit Service b23acc
	} test_data[] = {
Packit Service b23acc
		{      0,     8,     8 },
Packit Service b23acc
		{      1,     8,     8 },
Packit Service b23acc
		{      8,     8,     8 },
Packit Service b23acc
		{      9,    16,    16 },
Packit Service b23acc
		{     16,    16,    16 },
Packit Service b23acc
		{     17,    32,    32 },
Packit Service b23acc
		{     32,    32,    32 },
Packit Service b23acc
		{     33,    40,    40 },
Packit Service b23acc
		{     40,    40,    40 },
Packit Service b23acc
		{     41,   104,   104 },
Packit Service b23acc
		{    104,   104,   104 },
Packit Service b23acc
		{    105,   232,   232 },
Packit Service b23acc
		{    232,   232,   232 },
Packit Service b23acc
		{    233,   488,   488 },
Packit Service b23acc
		{    488,   488,   488 },
Packit Service b23acc
		{    489,  1000,  1000 },
Packit Service b23acc
		{   1000,  1000,  1000 },
Packit Service b23acc
		{   1001,  2024,  2024 },
Packit Service b23acc
		{   2024,  2024,  2024 },
Packit Service b23acc
		{   2025,  4072,  4072 },
Packit Service b23acc
		{   4072,  4072,  4072 },
Packit Service b23acc
		{   4073,  8168,  8168 },
Packit Service b23acc
		{   8168,  8168,  8168 },
Packit Service b23acc
		{   8169, 12264, 16360 },
Packit Service b23acc
		{  12263, 12264, 16360 },
Packit Service b23acc
		{  12264, 12264, 16360 },
Packit Service b23acc
		{  12265, 16360, 16360 },
Packit Service b23acc
		{  16360, 16360, 16360 },
Packit Service b23acc
		{  16361, 20456, 32744 },
Packit Service b23acc
		{  20456, 20456, 32744 },
Packit Service b23acc
		{  20457, 24552, 32744 },
Packit Service b23acc
		{  24552, 24552, 32744 },
Packit Service b23acc
		{  24553, 28648, 32744 },
Packit Service b23acc
		{  28648, 28648, 32744 },
Packit Service b23acc
		{  28649, 32744, 32744 },
Packit Service b23acc
		{  32744, 32744, 32744 },
Packit Service b23acc
		{  32745, 36840, 65512 },
Packit Service b23acc
		{  36840, 36840, 65512 },
Packit Service b23acc
		{  G_MAXSIZE - 0x1000u,  G_MAXSIZE, G_MAXSIZE },
Packit Service b23acc
		{  G_MAXSIZE - 25u,      G_MAXSIZE, G_MAXSIZE },
Packit Service b23acc
		{  G_MAXSIZE - 24u,      G_MAXSIZE, G_MAXSIZE },
Packit Service b23acc
		{  G_MAXSIZE - 1u,       G_MAXSIZE, G_MAXSIZE },
Packit Service b23acc
		{  G_MAXSIZE,            G_MAXSIZE, G_MAXSIZE },
Packit Service b23acc
		{  NM_UTILS_GET_NEXT_REALLOC_SIZE_104,  NM_UTILS_GET_NEXT_REALLOC_SIZE_104,  NM_UTILS_GET_NEXT_REALLOC_SIZE_104 },
Packit Service b23acc
		{  NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 },
Packit Service b23acc
	};
Packit Service b23acc
	guint i;
Packit Service b23acc
Packit Service b23acc
	G_STATIC_ASSERT_EXPR (NM_UTILS_GET_NEXT_REALLOC_SIZE_104  == 104u);
Packit Service b23acc
	G_STATIC_ASSERT_EXPR (NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 == 1000u);
Packit Service b23acc
Packit Service b23acc
	for (i = 0; i < G_N_ELEMENTS (test_data) + 5000u; i++) {
Packit Service b23acc
		gsize requested0;
Packit Service b23acc
Packit Service b23acc
		if (i < G_N_ELEMENTS (test_data))
Packit Service b23acc
			requested0 = test_data[i].requested;
Packit Service b23acc
		else {
Packit Service b23acc
			/* find some interesting random values for testing. */
Packit Service b23acc
			switch (nmtst_get_rand_uint32 () % 5) {
Packit Service b23acc
			case 0:
Packit Service b23acc
				requested0 = nmtst_get_rand_size ();
Packit Service b23acc
				break;
Packit Service b23acc
			case 1:
Packit Service b23acc
				/* values close to G_MAXSIZE. */
Packit Service b23acc
				requested0 = G_MAXSIZE - (nmtst_get_rand_uint32 () % 12000u);
Packit Service b23acc
				break;
Packit Service b23acc
			case 2:
Packit Service b23acc
				/* values around G_MAXSIZE/2. */
Packit Service b23acc
				requested0 = (G_MAXSIZE / 2u) + 6000u - (nmtst_get_rand_uint32 () % 12000u);
Packit Service b23acc
				break;
Packit Service b23acc
			case 3:
Packit Service b23acc
				/* values around powers of 2. */
Packit Service b23acc
				requested0 = (((gsize) 1) << (nmtst_get_rand_uint32 () % (sizeof (gsize) * 8u))) + 6000u - (nmtst_get_rand_uint32 () % 12000u);
Packit Service b23acc
				break;
Packit Service b23acc
			case 4:
Packit Service b23acc
				/* values around 4k borders. */
Packit Service b23acc
				requested0 = (nmtst_get_rand_size () & ~((gsize) 0xFFFu)) + 30u - (nmtst_get_rand_uint32 () % 60u);
Packit Service b23acc
				break;
Packit Service b23acc
			default: g_assert_not_reached ();
Packit Service b23acc
			}
Packit Service b23acc
		}
Packit Service b23acc
Packit Service b23acc
		{
Packit Service b23acc
			const gsize requested = requested0;
Packit Service b23acc
			const gsize reserved_true = nm_utils_get_next_realloc_size (TRUE, requested);
Packit Service b23acc
			const gsize reserved_false = nm_utils_get_next_realloc_size (FALSE, requested);
Packit Service b23acc
Packit Service b23acc
			g_assert_cmpuint (reserved_true, >, 0);
Packit Service b23acc
			g_assert_cmpuint (reserved_false, >, 0);
Packit Service b23acc
			g_assert_cmpuint (reserved_true, >=, requested);
Packit Service b23acc
			g_assert_cmpuint (reserved_false, >=, requested);
Packit Service b23acc
			g_assert_cmpuint (reserved_false, >=, reserved_true);
Packit Service b23acc
Packit Service b23acc
			if (i < G_N_ELEMENTS (test_data)) {
Packit Service b23acc
				g_assert_cmpuint (reserved_true, ==, test_data[i].reserved_true);
Packit Service b23acc
				g_assert_cmpuint (reserved_false, ==, test_data[i].reserved_false);
Packit Service b23acc
			}
Packit Service b23acc
Packit Service b23acc
			/* reserved_false is generally the next power of two - 24. */
Packit Service b23acc
			if (reserved_false == G_MAXSIZE)
Packit Service b23acc
				g_assert_cmpuint (requested, >, G_MAXSIZE / 2u - 24u);
Packit Service b23acc
			else {
Packit Service b23acc
				g_assert_cmpuint (reserved_false, <=, G_MAXSIZE - 24u);
Packit Service b23acc
				if (reserved_false >= 40) {
Packit Service b23acc
					const gsize _pow2 = reserved_false + 24u;
Packit Service b23acc
Packit Service b23acc
					/* reserved_false must always be a power of two minus 24. */
Packit Service b23acc
					g_assert_cmpuint (_pow2, >=, 64u);
Packit Service b23acc
					g_assert_cmpuint (_pow2, >, requested);
Packit Service b23acc
					g_assert (nm_utils_is_power_of_two (_pow2));
Packit Service b23acc
Packit Service b23acc
					/* but _pow2/2 must also be smaller than what we requested. */
Packit Service b23acc
					g_assert_cmpuint (_pow2 / 2u - 24u, <, requested);
Packit Service b23acc
				} else {
Packit Service b23acc
					/* smaller values are hard-coded. */
Packit Service b23acc
				}
Packit Service b23acc
			}
Packit Service b23acc
Packit Service b23acc
			/* reserved_true is generally the next 4k border - 24. */
Packit Service b23acc
			if (reserved_true == G_MAXSIZE)
Packit Service b23acc
				g_assert_cmpuint (requested, >, G_MAXSIZE - 0x1000u - 24u);
Packit Service b23acc
			else {
Packit Service b23acc
				g_assert_cmpuint (reserved_true, <=, G_MAXSIZE - 24u);
Packit Service b23acc
				if (reserved_true > 8168u) {
Packit Service b23acc
					const gsize page_border = reserved_true + 24u;
Packit Service b23acc
Packit Service b23acc
					/* reserved_true must always be aligned to 4k (minus 24). */
Packit Service b23acc
					g_assert_cmpuint (page_border % 0x1000u, ==, 0);
Packit Service b23acc
					if (requested > 0x1000u - 24u) {
Packit Service b23acc
						/* page_border not be more than 4k above requested. */
Packit Service b23acc
						g_assert_cmpuint (page_border, >=, 0x1000u - 24u);
Packit Service b23acc
						g_assert_cmpuint (page_border - 0x1000u - 24u, <, requested);
Packit Service b23acc
					}
Packit Service b23acc
				} else {
Packit Service b23acc
					/* for smaller sizes, reserved_true and reserved_false are the same. */
Packit Service b23acc
					g_assert_cmpuint (reserved_true, ==, reserved_false);
Packit Service b23acc
				}
Packit Service b23acc
			}
Packit Service b23acc
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
test_nm_str_buf (void)
Packit Service b23acc
{
Packit Service b23acc
	guint i_run;
Packit Service b23acc
Packit Service b23acc
	for (i_run = 0; TRUE; i_run++) {
Packit Service b23acc
		nm_auto_str_buf NMStrBuf strbuf = { };
Packit Service b23acc
		nm_auto_free_gstring GString *gstr = NULL;
Packit Service b23acc
		int i, j, k;
Packit Service b23acc
		int c;
Packit Service b23acc
Packit Service b23acc
		nm_str_buf_init (&strbuf,
Packit Service b23acc
		                 nmtst_get_rand_uint32 () % 200u + 1u,
Packit Service b23acc
		                 nmtst_get_rand_bool ());
Packit Service b23acc
Packit Service b23acc
		if (i_run < 1000) {
Packit Service b23acc
			c = nmtst_get_rand_word_length (NULL);
Packit Service b23acc
			for (i = 0; i < c; i++)
Packit Service b23acc
				nm_str_buf_append_c (&strbuf, '0' + (i % 10));
Packit Service b23acc
			gstr = g_string_new (nm_str_buf_get_str (&strbuf));
Packit Service b23acc
			j = nmtst_get_rand_uint32 () % (strbuf.len + 1);
Packit Service b23acc
			k = nmtst_get_rand_uint32 () % (strbuf.len - j + 2) - 1;
Packit Service b23acc
Packit Service b23acc
			nm_str_buf_erase (&strbuf, j, k, nmtst_get_rand_bool ());
Packit Service b23acc
			g_string_erase (gstr, j, k);
Packit Service b23acc
			g_assert_cmpstr (gstr->str, ==, nm_str_buf_get_str (&strbuf));
Packit Service b23acc
		} else
Packit Service b23acc
			return;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
NMTST_DEFINE ();
Packit Service b23acc
Packit Service b23acc
int main (int argc, char **argv)
Packit Service b23acc
{
Packit Service b23acc
	nmtst_init (&argc, &argv, TRUE);
Packit Service b23acc
Packit Service b23acc
	g_test_add_func ("/general/test_gpid", test_gpid);
Packit Service b23acc
	g_test_add_func ("/general/test_monotonic_timestamp", test_monotonic_timestamp);
Packit Service b23acc
	g_test_add_func ("/general/test_nmhash", test_nmhash);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_make_strv", test_make_strv);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_strdup_int", test_nm_strdup_int);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_strndup_a", test_nm_strndup_a);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_ip4_addr_is_localhost", test_nm_ip4_addr_is_localhost);
Packit Service b23acc
	g_test_add_func ("/general/test_unaligned", test_unaligned);
Packit Service b23acc
	g_test_add_func ("/general/test_strv_cmp", test_strv_cmp);
Packit Service b23acc
	g_test_add_func ("/general/test_strstrip_avoid_copy", test_strstrip_avoid_copy);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_utils_bin2hexstr", test_nm_utils_bin2hexstr);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_ref_string", test_nm_ref_string);
Packit Service b23acc
	g_test_add_func ("/general/test_string_table_lookup", test_string_table_lookup);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_utils_get_next_realloc_size", test_nm_utils_get_next_realloc_size);
Packit Service b23acc
	g_test_add_func ("/general/test_nm_str_buf", test_nm_str_buf);
Packit Service b23acc
Packit Service b23acc
	return g_test_run ();
Packit Service b23acc
}