Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115425509
D49975.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D49975.id.diff
View Options
diff --git a/tests/sys/sys/Makefile b/tests/sys/sys/Makefile
--- a/tests/sys/sys/Makefile
+++ b/tests/sys/sys/Makefile
@@ -7,6 +7,7 @@
bitstring_test \
buf_ring_test \
qmath_test \
+ queue_test \
rb_test \
splay_test \
time_test
diff --git a/tests/sys/sys/queue_test.c b/tests/sys/sys/queue_test.c
new file mode 100644
--- /dev/null
+++ b/tests/sys/sys/queue_test.c
@@ -0,0 +1,227 @@
+#include <sys/cdefs.h>
+#define QUEUE_MACRO_DEBUG_ASSERTIONS
+#include <sys/queue.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+/*
+ * General utilities.
+ */
+#define DIAG(fmt, ...) do { \
+ fprintf(stderr, "%s(): " fmt "\n", __func__, ##__VA_ARGS__); \
+} while (0)
+
+/*
+ * Common definitions and utilities.
+ *
+ * 'type' should be tailq, stailq, list or slist. 'TYPE' is 'type' in
+ * uppercase.
+ */
+
+#define QUEUE_TESTS_COMMON(type, TYPE) \
+/* \
+ * Definitions and utilities. \
+ */ \
+ \
+struct type ## _id_elem { \
+ TYPE ## _ENTRY(type ## _id_elem) ie_entry; \
+ unsigned ie_id; \
+}; \
+ \
+TYPE ## _HEAD(type ## _ids, type ## _id_elem); \
+ \
+static void \
+type ## _check(const struct type ## _ids *const type, \
+ const unsigned nb, const unsigned id_shift); \
+ \
+/* \
+ * Creates a tailq/list with 'nb' elements with contiguous IDs \
+ * in ascending order starting at 'id_shift'. \
+ */ \
+static struct type ## _ids * \
+type ## _create(const unsigned nb, const unsigned id_shift) \
+{ \
+ struct type ## _ids *const type = \
+ malloc(sizeof(*type)); \
+ \
+ ATF_REQUIRE_MSG(type != NULL, \
+ "Cannot malloc " #type " head"); \
+ \
+ TYPE ## _INIT(type); \
+ for (unsigned i = 0; i < nb; ++i) { \
+ struct type ## _id_elem *const e = \
+ malloc(sizeof(*e)); \
+ \
+ ATF_REQUIRE_MSG(e != NULL, \
+ "Cannot malloc " #type " element %u", i); \
+ e->ie_id = nb - 1 - i + id_shift; \
+ TYPE ## _INSERT_HEAD(type, e, ie_entry); \
+ } \
+ \
+ DIAG("Created " #type " %p with %u elements", \
+ type, nb); \
+ type ## _check(type, nb, id_shift); \
+ return (type); \
+} \
+ \
+/* Performs no check. */ \
+static void \
+type ## _destroy(struct type ## _ids *const type) \
+{ \
+ struct type ## _id_elem *e, *tmp_e; \
+ \
+ DIAG("Destroying " #type" %p", type); \
+ TYPE ## _FOREACH_SAFE(e, type, ie_entry, \
+ tmp_e) { \
+ free(e); \
+ } \
+ free(type); \
+} \
+ \
+ \
+/* Checks that some tailq/list is as produced by *_create(). */ \
+static void \
+type ## _check(const struct type ## _ids *const type, \
+ const unsigned nb, const unsigned id_shift) \
+{ \
+ struct type ## _id_elem *e; \
+ unsigned i = 0; \
+ \
+ TYPE ## _FOREACH(e, type, ie_entry) { \
+ ATF_REQUIRE_MSG(i + 1 <= nb, \
+ #type " %p has more than %u elements", \
+ type, nb); \
+ ATF_REQUIRE_MSG(e->ie_id == i + id_shift, \
+ #type " %p element %p: Found ID %u, " \
+ "expected %u", \
+ type, e, e->ie_id, i + id_shift); \
+ ++i; \
+ } \
+ ATF_REQUIRE_MSG(i == nb, \
+ #type " %p has only %u elements, expected %u", \
+ type, i, nb); \
+} \
+ \
+/* Returns NULL if not enough elements. */ \
+static struct type ## _id_elem * \
+type ## _nth(const struct type ## _ids *const type, \
+ const unsigned idx) \
+{ \
+ struct type ## _id_elem *e; \
+ unsigned i = 0; \
+ \
+ TYPE ## _FOREACH(e, type, ie_entry) { \
+ if (i == idx) { \
+ DIAG(#type " %p has element %p " \
+ "(ID %u) at index %u", \
+ type, e, e->ie_id, idx); \
+ return (e); \
+ } \
+ ++i; \
+ } \
+ DIAG(#type " %p: Only %u elements, no index %u", \
+ type, i, idx); \
+ return (NULL); \
+} \
+ \
+/* \
+ * Tests. \
+ */ \
+ \
+ATF_TC(type ## _split_after_and_concat); \
+ATF_TC_HEAD(type ## _split_after_and_concat, tc) \
+{ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Test " #TYPE "_SPLIT_AFTER() followed by " \
+ #TYPE "_CONCAT()"); \
+} \
+ATF_TC_BODY(type ## _split_after_and_concat, tc) \
+{ \
+ struct type ## _ids *const type = \
+ type ## _create(100, 0); \
+ struct type ## _ids rest; \
+ struct type ## _id_elem *e; \
+ \
+ e = type ## _nth(type, 49); \
+ TYPE ## _SPLIT_AFTER(type, e, &rest, ie_entry); \
+ type ## _check(type, 50, 0); \
+ type ## _check(&rest, 50, 50); \
+ QUEUE_TESTS_ ## TYPE ## _CONCAT(type, &rest); \
+ ATF_REQUIRE_MSG(TYPE ## _EMPTY(&rest), \
+ "'rest' not empty after concat"); \
+ type ## _check(type, 100, 0); \
+ type ## _destroy(type); \
+}
+
+/*
+ * Paper over the *_CONCAT() signature differences.
+ */
+
+#define QUEUE_TESTS_TAILQ_CONCAT(first, second) \
+ TAILQ_CONCAT(first, second, ie_entry)
+
+#define QUEUE_TESTS_LIST_CONCAT(first, second) \
+ LIST_CONCAT(first, second, list_id_elem, ie_entry)
+
+#define QUEUE_TESTS_STAILQ_CONCAT(first, second) \
+ STAILQ_CONCAT(first, second)
+
+#define QUEUE_TESTS_SLIST_CONCAT(first, second) \
+ SLIST_CONCAT(first, second, slist_id_elem, ie_entry)
+
+/*
+ * ATF test registration.
+ */
+
+#define QUEUE_TESTS_REGISTRATION(tp, type) \
+ ATF_TP_ADD_TC(tp, type ## _split_after_and_concat)
+
+/*
+ * Macros defining print functions.
+ *
+ * There are currently not used in the tests above, but are useful for
+ * debugging.
+ */
+
+#define QUEUE_TESTS_TQ_PRINT(type, hfp) \
+ static void \
+ type ## _print(const struct type ## _ids *const type) \
+ { \
+ printf(#type " %p: " __STRING(hfp ## _first) \
+ " = %p, " __STRING(hfp ## _last) " = %p\n", \
+ type, type->hfp ## _first, type->hfp ## _last); \
+ }
+
+#define QUEUE_TESTS_L_PRINT(type, hfp) \
+ static void \
+ type ## _print(const struct type ## _ids *const type) \
+ { \
+ printf(#type " %p: " __STRING(hfp ## _first) " = %p\n", \
+ type, type->hfp ## _first); \
+ }
+
+
+/*
+ * Meat.
+ */
+
+QUEUE_TESTS_COMMON(tailq, TAILQ);
+QUEUE_TESTS_COMMON(list, LIST);
+QUEUE_TESTS_COMMON(stailq, STAILQ);
+QUEUE_TESTS_COMMON(slist, SLIST);
+
+/*
+ * Main.
+ */
+ATF_TP_ADD_TCS(tp)
+{
+ QUEUE_TESTS_REGISTRATION(tp, tailq);
+ QUEUE_TESTS_REGISTRATION(tp, list);
+ QUEUE_TESTS_REGISTRATION(tp, stailq);
+ QUEUE_TESTS_REGISTRATION(tp, slist);
+
+ return (atf_no_error());
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 24, 4:45 PM (20 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17762091
Default Alt Text
D49975.id.diff (6 KB)
Attached To
Mode
D49975: queue(3): Add simple tests for some macros for all list/tailq types
Attached
Detach File
Event Timeline
Log In to Comment