summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2018-12-03 14:14:44 +0100
committerMax <msuraev@sysmocom.de>2018-12-12 09:34:12 +0000
commitdb038255eb1a2ff1a026b6c1ecd7328c22242985 (patch)
treea3c77ec1b6142959fe2526057964ad308695e718 /src
parent48b2de097216d5fb86d3e03fbccc39a7a83e8228 (diff)
msgb: add test helpers
It's often handy to compare certain msgb layer to a given array and print the position where they differ. Add simple pretty-printer and corresponding L* wrappers. Change-Id: I3bc95f2f5ab6e3f4b502647fb3e0aaaf1f7c4cf5
Diffstat (limited to 'src')
-rw-r--r--src/msgb.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/msgb.c b/src/msgb.c
index 844cfc61..9cd59c67 100644
--- a/src/msgb.c
+++ b/src/msgb.c
@@ -173,6 +173,98 @@ uint8_t *msgb_data(const struct msgb *msg)
return msg->data;
}
+/*! Compare and print: check data in msgb against given data and print errors if any
+ * \param[in] file text prefix, usually __FILE__, ignored if print == false
+ * \param[in] line numeric prefix, usually __LINE__, ignored if print == false
+ * \param[in] func text prefix, usually __func__, ignored if print == false
+ * \param[in] level while layer (L1, L2 etc) data should be compared against
+ * \param[in] msg message buffer
+ * \param[in] data expected data
+ * \param[in] len length of data
+ * \param[in] print boolean indicating whether we should print anything to stdout
+ * \returns boolean indicating whether msgb content is equal to a given data
+ *
+ * This function is not intended to be called directly but rather used through corresponding macro wrappers.
+ */
+bool _msgb_eq(const char *file, size_t line, const char *func, uint8_t level,
+ const struct msgb *msg, const uint8_t *data, size_t len, bool print)
+{
+ const char *m_dump;
+ unsigned int m_len, i;
+ uint8_t *m_data;
+
+ if (!msg) {
+ if (print)
+ LOGPSRC(DLGLOBAL, LOGL_FATAL, file, line, "%s() NULL msg comparison\n", func);
+ return false;
+ }
+
+ if (!data) {
+ if (print)
+ LOGPSRC(DLGLOBAL, LOGL_FATAL, file, line, "%s() NULL comparison data\n", func);
+ return false;
+ }
+
+ switch (level) {
+ case 0:
+ m_len = msgb_length(msg);
+ m_data = msgb_data(msg);
+ m_dump = print ? msgb_hexdump(msg) : NULL;
+ break;
+ case 1:
+ m_len = msgb_l1len(msg);
+ m_data = msgb_l1(msg);
+ m_dump = print ? msgb_hexdump_l1(msg) : NULL;
+ break;
+ case 2:
+ m_len = msgb_l2len(msg);
+ m_data = msgb_l2(msg);
+ m_dump = print ? msgb_hexdump_l2(msg) : NULL;
+ break;
+ case 3:
+ m_len = msgb_l3len(msg);
+ m_data = msgb_l3(msg);
+ m_dump = print ? msgb_hexdump_l3(msg) : NULL;
+ break;
+ case 4:
+ m_len = msgb_l4len(msg);
+ m_data = msgb_l4(msg);
+ m_dump = print ? msgb_hexdump_l4(msg) : NULL;
+ break;
+ default:
+ LOGPSRC(DLGLOBAL, LOGL_FATAL, file, line,
+ "%s() FIXME: unexpected comparison level %u\n", func, level);
+ return false;
+ }
+
+ if (m_len != len) {
+ if (print)
+ LOGPSRC(DLGLOBAL, LOGL_FATAL, file, line,
+ "%s() Length mismatch: %d != %zu, %s\n", func, m_len, len, m_dump);
+ return false;
+ }
+
+ if (memcmp(m_data, data, len) == 0)
+ return true;
+
+ if (!print)
+ return false;
+
+ LOGPSRC(DLGLOBAL, LOGL_FATAL, file, line,
+ "%s() L%u data mismatch:\nexpected %s\n ", func, level, osmo_hexdump(data, len));
+
+ for(i = 0; i < len; i++)
+ if (data[i] != m_data[i]) {
+ LOGPC(DLGLOBAL, LOGL_FATAL, "!!\n");
+ break;
+ } else
+ LOGPC(DLGLOBAL, LOGL_FATAL, ".. ");
+
+ LOGPC(DLGLOBAL, LOGL_FATAL, " msgb %s\n", m_dump);
+
+ return false;
+}
+
/*! get length of message buffer
* \param[in] msg message buffer
* \returns length of data section in message buffer