tests/libknot/test_probe.c
tests/libknot/test_rdata.c
tests/libknot/test_rdataset.c
+tests/libknot/test_rrset-dump.c
tests/libknot/test_rrset-wire.c
tests/libknot/test_rrset.c
tests/libknot/test_tsig.c
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
- if (in_len > MAX_B32_BIN_DATA_LEN || out_len < ((in_len + 4) / 5) * 8) {
+ if (in_len > MAX_B32_BIN_DATA_LEN) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 4) / 5) * 8) {
+ return KNOT_ESPACE; // NOTE it is essential to return KNOT_ESPACE when output buffer overflows because this is directly called in rrset_dump and there is a realloc/retry mechanism in KNOT_ESPACE case.
+ }
uint8_t rest_len = in_len % 5;
const uint8_t *stop = in + in_len - rest_len;
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
- if (in_len > INT32_MAX || out_len < ((in_len + 7) / 8) * 5) {
+ if (in_len > INT32_MAX) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 7) / 8) * 5) {
+ return KNOT_ESPACE;
+ }
if ((in_len % 8) != 0) {
return KNOT_BASE32HEX_ESIZE;
}
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base32hex_encode(const uint8_t *in,
const uint32_t in_len,
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base32hex_decode(const uint8_t *in,
const uint32_t in_len,
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
- if (in_len > MAX_B64_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
+ if (in_len > MAX_B64_BIN_DATA_LEN) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 2) / 3) * 4) {
+ return KNOT_ESPACE; // NOTE it is essential to return KNOT_ESPACE when output buffer overflows because this is directly called in rrset_dump and there is a realloc/retry mechanism in KNOT_ESPACE case.
+ }
uint8_t rest_len = in_len % 3;
const uint8_t *stop = in + in_len - rest_len;
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
- if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
+ if (in_len > INT32_MAX) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 3) / 4) * 3) {
+ return KNOT_ESPACE;
+ }
if ((in_len % 4) != 0) {
return KNOT_BASE64_ESIZE;
}
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base64_encode(const uint8_t *in,
const uint32_t in_len,
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base64_decode(const uint8_t *in,
const uint32_t in_len,
if (in == NULL || out == NULL) {
return KNOT_EINVAL;
}
- if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) {
+ if (in_len > MAX_BIN_DATA_LEN) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 2) / 3) * 4) {
+ return KNOT_ESPACE;
+ }
uint8_t rest_len = in_len % 3;
const uint8_t *stop = in + in_len - rest_len;
}
}
- if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) {
+ if (in_len > INT32_MAX) {
return KNOT_ERANGE;
}
+ if (out_len < ((in_len + 3) / 4) * 3) {
+ return KNOT_ESPACE;
+ }
const uint8_t *stop = in + in_len;
uint8_t *bin = out;
* \param out_len Size of output buffer.
*
* \retval >=0 length of output string.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base64url_encode(const uint8_t *in,
const uint32_t in_len,
* \param out_len Size of output buffer.
*
* \retval >=0 length of output data.
- * \retval KNOT_E* if error.
+ * \retval KNOT_ESPACE if output buffer is not large enough.
+ * \return KNOT_E* if other error.
*/
int32_t knot_base64url_decode(const uint8_t *in,
uint32_t in_len,
#include "libknot/attribute.h"
#include "libknot/descriptor.h"
+#include "libknot/errcode.h"
/*!
* \brief Table with supported DNS classes.
const size_t out_len)
{
if (out == NULL) {
- return -1;
+ return KNOT_EINVAL;
}
int ret;
}
if (ret <= 0 || (size_t)ret >= out_len) {
- return -1;
+ return KNOT_ESPACE; // NOTE it is essential to return KNOT_ESPACE when output buffer overflows because this is directly called in rrset_dump and there is a realloc/retry mechanism in KNOT_ESPACE case.
} else {
return ret;
}
int knot_rrtype_from_string(const char *name, uint16_t *num)
{
if (name == NULL || num == NULL) {
- return -1;
+ return KNOT_EINVAL;
}
int i;
if (rdata_descriptors[i].type_name != NULL &&
strcasecmp(rdata_descriptors[i].type_name, name) == 0) {
*num = i;
- return 0;
+ return KNOT_EOK;
}
}
// Type name must begin with TYPE.
if (strncasecmp(name, "TYPE", 4) != 0) {
- return -1;
+ return KNOT_ENOTYPE;
} else {
name += 4;
}
// The rest must be a number.
n = strtoul(name, &end, 10);
if (end == name || *end != '\0' || n > UINT16_MAX) {
- return -1;
+ return KNOT_ENOTYPE;
}
*num = n;
- return 0;
+ return KNOT_EOK;
}
_public_
const size_t out_len)
{
if (out == NULL) {
- return -1;
+ return KNOT_EINVAL;
}
int ret;
}
if (ret <= 0 || (size_t)ret >= out_len) {
- return -1;
+ return KNOT_ESPACE;
} else {
return ret;
}
int knot_rrclass_from_string(const char *name, uint16_t *num)
{
if (name == NULL || num == NULL) {
- return -1;
+ return KNOT_EINVAL;
}
int i;
if ((row[0] != NULL && strcasecmp(row[0], name) == 0) ||
(row[1] != NULL && strcasecmp(row[1], name) == 0)) {
*num = i;
- return 0;
+ return KNOT_EOK;
}
}
// Class name must begin with CLASS.
if (strncasecmp(name, "CLASS", 5) != 0) {
- return -1;
+ return KNOT_ENOCLASS;
} else {
name += 5;
}
// The rest must be a number.
n = strtoul(name, &end, 10);
if (end == name || *end != '\0' || n > UINT16_MAX) {
- return -1;
+ return KNOT_ENOCLASS;
}
*num = n;
- return 0;
+ return KNOT_EOK;
}
_public_
int knot_opt_code_to_string(const uint16_t code, char *out, const size_t out_len)
{
if (out == NULL) {
- return -1;
+ return KNOT_EINVAL;
}
const char *name = NULL;
}
if (ret <= 0 || (size_t)ret >= out_len) {
- return -1;
+ return KNOT_ESPACE;
} else {
return ret;
}
* \param out_len Length of the output buffer.
*
* \retval Length of output string.
- * \retval -1 if error.
+ * \retval KNOT_ESPACE if output buffer not large enough.
+ * \return KNOT_E* if other error.
*/
int knot_rrtype_to_string(const uint16_t rrtype,
char *out,
* \param name Mnemonic string to be converted.
* \param num Output variable.
*
- * \retval 0 if OK.
- * \retval -1 if error.
+ * \return KNOT_E*
*/
int knot_rrtype_from_string(const char *name, uint16_t *num);
* \param out_len Length of the output buffer.
*
* \retval Length of output string.
- * \retval -1 if error.
+ * \retval KNOT_ESPACE if output buffer not large enough.
+ * \return KNOT_E* if other error.
*/
int knot_rrclass_to_string(const uint16_t rrclass,
char *out,
* \param name Mnemonic string to be converted.
* \param num Output variable.
*
- * \retval 0 if OK.
- * \retval -1 if error.
+ * \return KNOT_E*
*/
int knot_rrclass_from_string(const char *name, uint16_t *num);
* \param out_len The available size of the buffer.
*
* \retval Length of output string.
- * \retval -1 if error.
+ * \retval KNOT_ESPACE if output buffer not large enough.
+ * \return KNOT_E* if other error.
*/
int knot_opt_code_to_string(const uint16_t code, char *out, const size_t out_len);
KNOT_EMODINVAL,
KNOT_EEXTERNAL,
KNOT_ERDB,
+ KNOT_ENOTYPE,
+ KNOT_ENOCLASS,
KNOT_GENERAL_ERROR = -900,
{ KNOT_EMODINVAL, "invalid module" },
{ KNOT_EEXTERNAL, "external validation failed" },
{ KNOT_ERDB, "zone database error" },
+ { KNOT_ENOTYPE, "no such RR type" },
+ { KNOT_ENOCLASS, "no such CLASS" },
{ KNOT_GENERAL_ERROR, "unknown general error" },
/libknot/test_rdata
/libknot/test_rdataset
/libknot/test_rrset
+/libknot/test_rrset-dump
/libknot/test_rrset-wire
/libknot/test_tsig
/libknot/test_xdp_tcp
libknot/test_rdata \
libknot/test_rdataset \
libknot/test_rrset \
+ libknot/test_rrset-dump \
libknot/test_rrset-wire \
libknot/test_tsig \
libknot/test_yparser \
ret = knot_base32hex_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN);
is_int(KNOT_ERANGE, ret, "knot_base32hex_encode: input buffer too large");
ret = knot_base32hex_encode(in, BUF_LEN, out, BUF_LEN);
- is_int(KNOT_ERANGE, ret, "knot_base32hex_encode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base32hex_encode: output buffer too small");
ret = knot_base32hex_encode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base32hex_encode_alloc: NULL input buffer");
ret = knot_base32hex_decode(in, UINT32_MAX, out, BUF_LEN);
is_int(KNOT_ERANGE, ret, "knot_base32hex_decode: input buffer too large");
ret = knot_base32hex_decode(in, BUF_LEN, out, 0);
- is_int(KNOT_ERANGE, ret, "knot_base32hex_decode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base32hex_decode: output buffer too small");
ret = knot_base32hex_decode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base32hex_decode_alloc: NULL input buffer");
ret = knot_base64_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN);
is_int(KNOT_ERANGE, ret, "knot_base64_encode: input buffer too large");
ret = knot_base64_encode(in, BUF_LEN, out, BUF_LEN);
- is_int(KNOT_ERANGE, ret, "knot_base64_encode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base64_encode: output buffer too small");
ret = knot_base64_encode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base64_encode_alloc: NULL input buffer");
ret = knot_base64_decode(in, UINT32_MAX, out, BUF_LEN);
is_int(KNOT_ERANGE, ret, "knot_base64_decode: input buffer too large");
ret = knot_base64_decode(in, BUF_LEN, out, 0);
- is_int(KNOT_ERANGE, ret, "knot_base64_decode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base64_decode: output buffer too small");
ret = knot_base64_decode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base64_decode_alloc: NULL input buffer");
ret = knot_base64url_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN);
is_int(KNOT_ERANGE, ret, "knot_base64ulr_encode: input buffer too large");
ret = knot_base64url_encode(in, BUF_LEN, out, BUF_LEN);
- is_int(KNOT_ERANGE, ret, "knot_base64ulr_encode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base64ulr_encode: output buffer too small");
ret = knot_base64url_encode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base64ulr_encode_alloc: NULL input buffer");
ret = knot_base64url_decode(in, BUF_LEN, NULL, 0);
is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode: NULL output buffer");
ret = knot_base64url_decode(in, BUF_LEN, out, 0);
- is_int(KNOT_ERANGE, ret, "knot_base64ulr_decode: output buffer too small");
+ is_int(KNOT_ESPACE, ret, "knot_base64ulr_decode: output buffer too small");
ret = knot_base64url_decode_alloc(NULL, 0, &out3);
is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode_alloc: NULL input buffer");
#include <tap/basic.h>
#include "libknot/descriptor.h"
+#include "libknot/errcode.h"
#define BUF_LEN 256
"get TYPE0 descriptor 2. item type");
ret = knot_rrtype_to_string(0, name, BUF_LEN);
- ok(ret != -1, "get TYPE0 ret");
+ ok(ret > 0, "get TYPE0 ret");
ok(strcmp(name, "TYPE0") == 0, "get TYPE0 name");
// 2. A
"get A descriptor 2. item type");
ret = knot_rrtype_to_string(1, name, BUF_LEN);
- ok(ret != -1, "get A ret");
+ ok(ret > 0, "get A ret");
ok(strcmp(name, "A") == 0, "get A name");
// 3. CNAME
"get CNAME descriptor 2. item type");
ret = knot_rrtype_to_string(5, name, BUF_LEN);
- ok(ret != -1, "get CNAME ret");
+ ok(ret > 0, "get CNAME ret");
ok(strcmp(name, "CNAME") == 0, "get CNAME name");
// 4. TYPE38 (A6)
"get TYPE38 descriptor 2. item type");
ret = knot_rrtype_to_string(38, name, BUF_LEN);
- ok(ret != -1, "get TYPE38 ret");
+ ok(ret > 0, "get TYPE38 ret");
ok(strcmp(name, "TYPE38") == 0, "get TYPE38 name");
// 5. ANY
"get ANY descriptor 2. item type");
ret = knot_rrtype_to_string(255, name, BUF_LEN);
- ok(ret != -1, "get ANY ret");
+ ok(ret > 0, "get ANY ret");
ok(strcmp(name, "ANY") == 0, "get ANY name");
// 6. TYPE65535
"get TYPE65535 descriptor 2. item type");
ret = knot_rrtype_to_string(65535, name, BUF_LEN);
- ok(ret != -1, "get TYPE65535 ret");
+ ok(ret > 0, "get TYPE65535 ret");
ok(strcmp(name, "TYPE65535") == 0, "get TYPE65535 name");
// Class num to string:
// 7. CLASS0
ret = knot_rrclass_to_string(0, name, BUF_LEN);
- ok(ret != -1, "get CLASS0 ret");
+ ok(ret > 0, "get CLASS0 ret");
ok(strcmp(name, "CLASS0") == 0, "get CLASS0 name");
// 8. IN
ret = knot_rrclass_to_string(1, name, BUF_LEN);
- ok(ret != -1, "get IN ret");
+ ok(ret > 0, "get IN ret");
ok(strcmp(name, "IN") == 0, "get IN name");
// 9. ANY
ret = knot_rrclass_to_string(255, name, BUF_LEN);
- ok(ret != -1, "get ANY ret");
+ ok(ret > 0, "get ANY ret");
ok(strcmp(name, "ANY") == 0, "get ANY name");
// 10. CLASS65535
ret = knot_rrclass_to_string(65535, name, BUF_LEN);
- ok(ret != -1, "get CLASS65535 ret");
+ ok(ret > 0, "get CLASS65535 ret");
ok(strcmp(name, "CLASS65535") == 0, "get CLASS65535 name");
// String to type num:
// 11. A
ret = knot_rrtype_from_string("A", &num);
- ok(ret != -1, "get A num ret");
+ ok(ret == KNOT_EOK, "get A num ret");
ok(num == 1, "get A num");
// 12. a
ret = knot_rrtype_from_string("a", &num);
- ok(ret != -1, "get a num ret");
+ ok(ret == KNOT_EOK, "get a num ret");
ok(num == 1, "get a num");
// 13. AaAa
ret = knot_rrtype_from_string("AaAa", &num);
- ok(ret != -1, "get AaAa num ret");
+ ok(ret == KNOT_EOK, "get AaAa num ret");
ok(num == 28, "get AaAa num");
// 14. ""
ret = knot_rrtype_from_string("", &num);
- ok(ret == -1, "get "" num ret");
+ ok(ret == KNOT_ENOTYPE, "get "" num ret");
// 15. DUMMY
ret = knot_rrtype_from_string("DUMMY", &num);
- ok(ret == -1, "get DUMMY num ret");
+ ok(ret == KNOT_ENOTYPE, "get DUMMY num ret");
// 16. TypE33
ret = knot_rrtype_from_string("TypE33", &num);
- ok(ret != -1, "get TypE33 num ret");
+ ok(ret == KNOT_EOK, "get TypE33 num ret");
ok(num == 33, "get TypE33 num");
// 17. TYPE
ret = knot_rrtype_from_string("TYPE", &num);
- ok(ret == -1, "get TYPE num ret");
+ ok(ret == KNOT_ENOTYPE, "get TYPE num ret");
// 18. TYPE0
ret = knot_rrtype_from_string("TYPE0", &num);
- ok(ret != -1, "get TYPE0 num ret");
+ ok(ret == KNOT_EOK, "get TYPE0 num ret");
ok(num == 0, "get TYPE0 num");
// 19. TYPE65535
ret = knot_rrtype_from_string("TYPE65535", &num);
- ok(ret != -1, "get TYPE65535 num ret");
+ ok(ret == KNOT_EOK, "get TYPE65535 num ret");
ok(num == 65535, "get TYPE65535 num");
// 20. TYPE65536
ret = knot_rrtype_from_string("TYPE65536", &num);
- ok(ret == -1, "get TYPE65536 num ret");
+ ok(ret == KNOT_ENOTYPE, "get TYPE65536 num ret");
// String to class num:
// 21. In
ret = knot_rrclass_from_string("In", &num);
- ok(ret != -1, "get In num ret");
+ ok(ret == KNOT_EOK, "get In num ret");
ok(num == 1, "get In num");
ret = knot_rrclass_from_string("Internet", &num);
- ok(ret != -1, "get In num ret");
+ ok(ret == KNOT_EOK, "get In num ret");
ok(num == 1, "get In num");
// 22. ANY
ret = knot_rrclass_from_string("ANY", &num);
- ok(ret != -1, "get ANY num ret");
+ ok(ret == KNOT_EOK, "get ANY num ret");
ok(num == 255, "get ANY num");
// 23. ""
ret = knot_rrclass_from_string("", &num);
- ok(ret == -1, "get "" num ret");
+ ok(ret == KNOT_ENOCLASS, "get "" num ret");
// 24. DUMMY
ret = knot_rrclass_from_string("DUMMY", &num);
- ok(ret == -1, "get DUMMY num ret");
+ ok(ret == KNOT_ENOCLASS, "get DUMMY num ret");
// 25. CLass33
ret = knot_rrclass_from_string("CLass33", &num);
- ok(ret != -1, "get CLass33 num ret");
+ ok(ret == KNOT_EOK, "get CLass33 num ret");
ok(num == 33, "get CLass33 num");
// 26. CLASS
ret = knot_rrclass_from_string("CLASS", &num);
- ok(ret == -1, "get CLASS num ret");
+ ok(ret == KNOT_ENOCLASS, "get CLASS num ret");
// 27. CLASS0
ret = knot_rrclass_from_string("CLASS0", &num);
- ok(ret != -1, "get CLASS0 num ret");
+ ok(ret == KNOT_EOK, "get CLASS0 num ret");
ok(num == 0, "get CLASS0 num");
// 28. CLASS65535
ret = knot_rrclass_from_string("CLASS65535", &num);
- ok(ret != -1, "get CLASS65535 num ret");
+ ok(ret == KNOT_EOK, "get CLASS65535 num ret");
ok(num == 65535, "get CLASS65535 num");
// 29. CLASS65536
ret = knot_rrclass_from_string("CLASS65536", &num);
- ok(ret == -1, "get CLASS65536 num ret");
+ ok(ret == KNOT_ENOCLASS, "get CLASS65536 num ret");
// Get obsolete descriptor:
// 30. TYPE0
ok(descr->block_types[1] == KNOT_RDATA_WF_END,
"get TYPE38 descriptor 2. item type");
- // knot_rrtype_to_string invalid output buffer size
+ // knot_rrtype_to_string NULL output buffer
ret = knot_rrtype_to_string(1, NULL, 0);
- ok(ret == -1, "knot_rrtype_to_string: invalid output buffer size");
+ ok(ret == KNOT_EINVAL, "knot_rrtype_to_string: NULL output buffer");
- // knot_rrclass_to_string invalid output buffer size
+ // knot_rrclass_to_string NULL output buffer
ret = knot_rrclass_to_string(1, NULL, 0);
- ok(ret == -1, "knot_rrclass_to_string: invalid output buffer size");
+ ok(ret == KNOT_EINVAL, "knot_rrclass_to_string: NULL output buffer");
+
+ char dummy_buf[1] = { 0 };
+ // knot_rrtype_to_string invalid output buffer size
+ ret = knot_rrtype_to_string(1, dummy_buf, 1);
+ ok(ret == KNOT_ESPACE, "knot_rrtype_to_string: invalid output buffer size");
+
+ // knot_rrclass_to_string invalid output buffer size
+ ret = knot_rrclass_to_string(1, dummy_buf, 1);
+ ok(ret == KNOT_ESPACE, "knot_rrclass_to_string: invalid output buffer size");
// knot_rrtype_is_metatype
ok(knot_rrtype_is_metatype(0) == 0,
--- /dev/null
+/* Copyright (C) CZ.NIC, z.s.p.o. and contributors
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * For more information, see <https://www.knot-dns.cz/>
+ */
+
+#include <tap/basic.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libknot/rrset-dump.h"
+
+/* BACKGROUND:
+ *
+ * This unit test could be used for testing rrset-dump with newly implemented RR types.
+ * But so far, the functional test records/load is used for this purpose.
+ * This unit test ought to catch different quirks of knot_rrset_txt_dump,
+ * like re-allocating the given output buffer based on errcode (KNOT_ESPACE).
+ */
+
+const knot_dump_style_t *dump_style = &KNOT_DUMP_STYLE_DEFAULT;
+
+typedef struct {
+ const char *description;
+ knot_rrset_t rrset;
+ const char *expect_out;
+ int expect_ret;
+ size_t buf_sizes[8];
+} rrset_dump_test_case_t;
+
+const char * const rrsig_case_text = "test. \t1234567890\tRRSIG\tDNSKEY 13 1 1234567890 20251015085855 20251015063355 33658 test. uj40mBZYSg21VqhF7AcU6CTp3dM2k8G/Br8ZP902OCrsDjRq3qPZySxYwmcnbNYeAdVyT1m2zLmKZbYa8cCqRA==\n";
+
+knot_rdata_t rrsig_case_rdata = {
+ 88, { 0x00, 0x30, 0x0d, 0x01, 0x49, 0x96, 0x02, 0xd2, 0x68, 0xef, 0x62, 0x4f, 0x68, 0xef, 0x40, 0x53, 0x83, 0x7a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x00,
+ 0xba, 0x3e, 0x34, 0x98, 0x16, 0x58, 0x4a, 0x0d, 0xb5, 0x56, 0xa8, 0x45, 0xec, 0x07, 0x14, 0xe8, 0x24, 0xe9, 0xdd, 0xd3, 0x36, 0x93, 0xc1, 0xbf, 0x06, 0xbf, 0x19, 0x3f, 0xdd, 0x36, 0x38, 0x2a,
+ 0xec, 0x0e, 0x34, 0x6a, 0xde, 0xa3, 0xd9, 0xc9, 0x2c, 0x58, 0xc2, 0x67, 0x27, 0x6c, 0xd6, 0x1e, 0x01, 0xd5, 0x72, 0x4f, 0x59, 0xb6, 0xcc, 0xb9, 0x8a, 0x65, 0xb6, 0x1a, 0xf1, 0xc0, 0xaa, 0x44
+ }
+};
+
+rrset_dump_test_case_t rrset_dump_test_cases[] = {
+ { "some RRSIG", { (knot_dname_t *)"\x04""test", 1234567890U, KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN, { 1, 90, &rrsig_case_rdata }, NULL }, rrsig_case_text, KNOT_EOK, { 1, 3, 5, 7, 9, 11 } },
+};
+
+void test_rrset_dump(const char *description, const knot_rrset_t *rrset, const char *expect_out, int expect_ret, size_t initial_buf)
+{
+ size_t bufsize = initial_buf;
+ char *buf = calloc(1, initial_buf);
+ assert(buf != NULL);
+
+ if (expect_ret == KNOT_EOK) {
+ expect_ret = strlen(expect_out);
+ }
+
+ int ret = knot_rrset_txt_dump(rrset, &buf, &bufsize, dump_style);
+ ok(ret == expect_ret, "%s (init buf %zu): return code %d found %d", description, initial_buf, expect_ret, ret);
+
+ if (expect_out != NULL) {
+ ok(strcmp(buf, expect_out) == 0, "%s (init buf %zu): output string '%s' found '%s'", description, initial_buf, expect_out, buf);
+ }
+
+ free(buf);
+}
+
+int main(int argc, char *argv[])
+{
+ plan_lazy();
+
+ for (size_t i = 0; i < sizeof(rrset_dump_test_cases) / sizeof(*rrset_dump_test_cases); i++) {
+ rrset_dump_test_case_t *c = &rrset_dump_test_cases[i];
+ for (size_t j = 0; j < sizeof(c->buf_sizes) / sizeof(*c->buf_sizes); j++) {
+ if (c->buf_sizes[j] > 0) {
+ test_rrset_dump(c->description, &c->rrset, c->expect_out, c->expect_ret, c->buf_sizes[j]);
+ }
+ }
+ }
+
+ return 0;
+}