]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test-dns-answer: fix misuse of ASSERT_TRUE/FALSE()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Aug 2025 19:42:33 +0000 (04:42 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 2 Aug 2025 10:02:31 +0000 (11:02 +0100)
E.g. dns_answer_match_key() may return negative errno, hence we should
use ASSERT_OK_POSITIVE/ZERO().

This also has bunch of cleanups:
- call functions in ASSERT_NOT_NULL(),
- add short comments for constant function arguments,
- merge several test cases,
- use memstream, rather than temporal files.

src/resolve/test-dns-answer.c

index 77775bffc9e782faa48df978a2353e55ee502e0b..06dec47ee095558734a159b1ba3fbee13173aae6 100644 (file)
@@ -1,12 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "dns-type.h"
-#include "fd-util.h"
-#include "fileio.h"
+#include "memstream-util.h"
 #include "resolved-dns-answer.h"
 #include "resolved-dns-rr.h"
+#include "strv.h"
 #include "tests.h"
-#include "tmpfile-util.h"
 
 /* ================================================================
  * dns_answer_add()
@@ -16,13 +15,11 @@ TEST(dns_answer_add_a) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
 
-        answer = dns_answer_new(0);
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
         ASSERT_TRUE(dns_answer_contains(answer, rr));
 }
@@ -33,94 +30,80 @@ TEST(dns_answer_add_a) {
 
 TEST(dns_answer_match_key_single) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
-        DnsResourceKey *key = NULL;
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
-        DnsAnswerFlags flags = 0;
+        DnsResourceKey *key;
+        DnsAnswerFlags flags;
 
-        answer = dns_answer_new(0);
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
         ASSERT_EQ(dns_answer_size(answer), 1u);
 
-        ASSERT_TRUE(dns_answer_match_key(answer, rr->key, NULL));
-
-        ASSERT_TRUE(dns_answer_match_key(answer, rr->key, &flags));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, rr->key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, rr->key, &flags));
         ASSERT_EQ((int)flags, DNS_ANSWER_CACHEABLE);
 
         /* ANY class matches */
-        key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
         /* ANY type matches */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_ANY, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_ANY, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
         /* non-matching type */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(answer, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com"));
+        ASSERT_OK_ZERO(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
         /* name is case-insensitive */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "WWW.EXAMPLE.COM");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "WWW.EXAMPLE.COM"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
         /* non-matching name */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(answer, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "example.com"));
+        ASSERT_OK_ZERO(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
         /* name containing an error */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.\\example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL) == -EINVAL);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.\\example.com"));
+        ASSERT_ERROR(dns_answer_match_key(answer, key, /* ret_flags = */ NULL), EINVAL);
         dns_resource_key_unref(key);
 }
 
 TEST(dns_answer_match_key_multiple) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
-        DnsAnswerFlags shared_flags = DNS_ANSWER_SECTION_ANSWER, ret_flags = 0;
+        DnsResourceRecord *rr;
+        DnsResourceKey *key;
+        DnsAnswerFlags flags;
 
-        answer = dns_answer_new(0);
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_TXT, "www.example.com");
-        ASSERT_NOT_NULL(rr);
-        dns_answer_add(answer, rr, 1, shared_flags | DNS_ANSWER_AUTHENTICATED, NULL);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_TXT, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_SECTION_ANSWER | DNS_ANSWER_AUTHENTICATED, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(answer, rr, 1, shared_flags | DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_SECTION_ANSWER | DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
         ASSERT_EQ(dns_answer_size(answer), 2u);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, &ret_flags));
-        ASSERT_EQ(ret_flags, shared_flags | DNS_ANSWER_CACHEABLE);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_SECTION_ANSWER | DNS_ANSWER_CACHEABLE);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_ANY, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, &ret_flags));
-        ASSERT_EQ(ret_flags, shared_flags);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_ANY, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_SECTION_ANSWER);
         dns_resource_key_unref(key);
 }
 
@@ -130,99 +113,97 @@ TEST(dns_answer_match_key_multiple) {
 
 TEST(dns_answer_find_soa) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
-        DnsResourceKey *key = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
-        DnsAnswerFlags flags = 0;
+        DnsResourceRecord *rr;
+        DnsResourceKey *key;
+        DnsAnswerFlags flags;
 
-        answer = dns_answer_new(0);
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
+        ASSERT_OK_ZERO(dns_answer_find_soa(answer, key, &rr, &flags));
         dns_resource_key_unref(key);
 
-        dns_answer_add_soa(answer, "example.com", 3600, 1);
+        ASSERT_OK_POSITIVE(dns_answer_add_soa(answer, "example.com", 3600, 1));
 
         /* does not find SOA keys */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com"));
+        ASSERT_OK_ZERO(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NULL(rr);
+        ASSERT_EQ((int) flags, 0);
         dns_resource_key_unref(key);
 
         /* finds matching A key */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_AUTHENTICATED);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_resource_key_equal(rr->key, key));
-        ASSERT_EQ((int)flags, DNS_ANSWER_AUTHENTICATED);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com"));
+        ASSERT_OK_POSITIVE(dns_resource_key_equal(rr->key, key));
         dns_resource_key_unref(key);
 
         /* finds matching A key suddomain */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "foo.www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "foo.www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_AUTHENTICATED);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_resource_key_equal(rr->key, key));
-        ASSERT_EQ((int)flags, DNS_ANSWER_AUTHENTICATED);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com"));
+        ASSERT_OK_POSITIVE(dns_resource_key_equal(rr->key, key));
         dns_resource_key_unref(key);
 
         /* does not match simple prefix */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "fooexample.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "fooexample.com"));
+        ASSERT_OK_ZERO(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NULL(rr);
+        ASSERT_EQ((int) flags, 0);
         dns_resource_key_unref(key);
 
         /* does not match parent domain */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "com"));
+        ASSERT_OK_ZERO(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NULL(rr);
+        ASSERT_EQ((int) flags, 0);
         dns_resource_key_unref(key);
 
         /* returns an error for bad escapes */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.\\example.com");
-        ASSERT_NOT_NULL(key);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.\\example.com"));
+        rr = POINTER_MAX;
+        flags = 4321;
         ASSERT_ERROR(dns_answer_find_soa(answer, key, &rr, &flags), EINVAL);
+        ASSERT_PTR_EQ(rr, POINTER_MAX);
+        ASSERT_EQ((int) flags, 4321);
         dns_resource_key_unref(key);
 }
 
 TEST(dns_answer_find_soa_multi) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
-        DnsAnswerFlags flags = 0;
+        DnsResourceKey *key;
+        DnsResourceRecord *rr;
+        DnsAnswerFlags flags;
 
-        answer = dns_answer_new(0);
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        dns_answer_add_soa(answer, "example.com", 3600, 1);
-        dns_answer_add_soa(answer, "example.org", 3600, 1);
+        ASSERT_OK_POSITIVE(dns_answer_add_soa(answer, "example.com", 3600, 1));
+        ASSERT_OK_POSITIVE(dns_answer_add_soa(answer, "example.org", 3600, 1));
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_AUTHENTICATED);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_resource_key_equal(rr->key, key));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.com"));
+        ASSERT_OK_POSITIVE(dns_resource_key_equal(rr->key, key));
+        ASSERT_EQ((int) flags, DNS_ANSWER_AUTHENTICATED);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.org");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "www.example.org"));
+        ASSERT_OK_POSITIVE(dns_answer_find_soa(answer, key, &rr, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_AUTHENTICATED);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.org");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_resource_key_equal(rr->key, key));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_SOA, "example.org"));
+        ASSERT_OK_POSITIVE(dns_resource_key_equal(rr->key, key));
         dns_resource_key_unref(key);
 }
 
@@ -230,114 +211,72 @@ TEST(dns_answer_find_soa_multi) {
  * dns_answer_merge()
  * ================================================================ */
 
-TEST(dns_answer_merge_same_object) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL, *ret = NULL;
-
-        a = dns_answer_new(0);
-        ASSERT_NOT_NULL(a);
-
-        ASSERT_OK(dns_answer_merge(a, a, &ret));
-        ASSERT_TRUE(ret == a);
-}
-
-TEST(dns_answer_merge_a_empty) {
+TEST(dns_answer_merge) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL, *b = NULL, *ret = NULL;
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr_a = NULL, *rr_b = NULL;
 
-        a = dns_answer_new(0);
-        ASSERT_NOT_NULL(a);
-
-        b = dns_answer_new(0);
-        ASSERT_NOT_NULL(b);
-
-        dns_answer_add_soa(b, "example.com", 3600, 1);
-
-        ASSERT_OK(dns_answer_merge(a, b, &ret));
-        ASSERT_TRUE(ret != a);
-        ASSERT_TRUE(ret == b);
-}
-
-TEST(dns_answer_merge_b_empty) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL, *b = NULL, *ret = NULL;
-
-        a = dns_answer_new(0);
-        ASSERT_NOT_NULL(a);
-
-        b = dns_answer_new(0);
-        ASSERT_NOT_NULL(b);
+        ASSERT_NOT_NULL(a = dns_answer_new(0));
+        ASSERT_OK(dns_answer_merge(a, a, &ret));
+        ASSERT_PTR_EQ(ret, a);
+        ret = dns_answer_unref(ret);
 
-        dns_answer_add_soa(a, "example.com", 3600, 1);
+        ASSERT_NOT_NULL(b = dns_answer_new(0));
+        ASSERT_OK_POSITIVE(dns_answer_add_soa(b, "example.com", 3600, 1));
 
         ASSERT_OK(dns_answer_merge(a, b, &ret));
-        ASSERT_TRUE(ret == a);
-        ASSERT_TRUE(ret != b);
-}
-
-TEST(dns_answer_merge_non_empty) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL, *b = NULL, *ret = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr_a = NULL, *rr_b = NULL;
+        ASSERT_PTR_EQ(ret, b);
+        ret = dns_answer_unref(ret);
 
-        a = dns_answer_new(0);
-        ASSERT_NOT_NULL(a);
+        ASSERT_OK(dns_answer_merge(b, a, &ret));
+        ASSERT_PTR_EQ(ret, b);
+        ret = dns_answer_unref(ret);
 
-        b = dns_answer_new(0);
-        ASSERT_NOT_NULL(b);
-
-        rr_a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr_a);
+        ASSERT_NOT_NULL(rr_a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr_a->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(a, rr_a, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(a, rr_a, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
-        rr_b = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr_b);
+        ASSERT_NOT_NULL(rr_b = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr_b->a.in_addr.s_addr = htobe32(0xc0a80180);
-        dns_answer_add(b, rr_b, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(b, rr_b, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
         ASSERT_OK(dns_answer_merge(a, b, &ret));
         ASSERT_TRUE(ret != a);
         ASSERT_TRUE(ret != b);
 
-        ASSERT_TRUE(dns_answer_match_key(a, rr_a->key, NULL));
-        ASSERT_FALSE(dns_answer_match_key(a, rr_b->key, NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(a, rr_a->key, /* ret_flags = */ NULL));
+        ASSERT_OK_ZERO(dns_answer_match_key(a, rr_b->key, /* ret_flags = */ NULL));
 
-        ASSERT_TRUE(dns_answer_match_key(b, rr_b->key, NULL));
-        ASSERT_FALSE(dns_answer_match_key(b, rr_a->key, NULL));
+        ASSERT_OK_ZERO(dns_answer_match_key(b, rr_a->key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(b, rr_b->key, /* ret_flags = */ NULL));
 
-        ASSERT_TRUE(dns_answer_match_key(ret, rr_a->key, NULL));
-        ASSERT_TRUE(dns_answer_match_key(ret, rr_b->key, NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(ret, rr_a->key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(ret, rr_b->key, /* ret_flags = */ NULL));
 }
 
 /* ================================================================
  * dns_answer_extend()
  * ================================================================ */
 
-TEST(dns_answer_replace_non_empty) {
+TEST(dns_answer_extend) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL, *b = NULL;
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr_a = NULL, *rr_b = NULL;
 
-        a = dns_answer_new(0);
-        ASSERT_NOT_NULL(a);
-
-        b = dns_answer_new(0);
-        ASSERT_NOT_NULL(b);
+        ASSERT_NOT_NULL(a = dns_answer_new(0));
+        ASSERT_NOT_NULL(b = dns_answer_new(0));
 
-        rr_a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr_a);
+        ASSERT_NOT_NULL(rr_a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr_a->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(a, rr_a, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(a, rr_a, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
-        rr_b = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr_b);
+        ASSERT_NOT_NULL(rr_b = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr_b->a.in_addr.s_addr = htobe32(0xc0a80180);
-        dns_answer_add(b, rr_b, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(b, rr_b, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
         ASSERT_OK(dns_answer_extend(&a, b));
         ASSERT_TRUE(a != b);
 
-        ASSERT_TRUE(dns_answer_match_key(a, rr_a->key, NULL));
-        ASSERT_TRUE(dns_answer_match_key(a, rr_b->key, NULL));
-
-        ASSERT_TRUE(dns_answer_match_key(b, rr_b->key, NULL));
-        ASSERT_FALSE(dns_answer_match_key(b, rr_a->key, NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(a, rr_a->key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(a, rr_b->key, /* ret_flags = */ NULL));
 }
 
 /* ================================================================
@@ -345,191 +284,124 @@ TEST(dns_answer_replace_non_empty) {
  * ================================================================ */
 
 static DnsAnswer* prepare_answer(void) {
-        DnsAnswer *answer = dns_answer_new(0);
-        DnsResourceRecord *rr = NULL;
-        int i;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
 
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        const char *hosts[] = {
-                "a.example.com",
-                "b.example.com",
-                "c.example.com"
-        };
+        char **hosts = STRV_MAKE("a.example.com", "b.example.com", "c.example.com");
+        STRV_FOREACH(h, hosts) {
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
 
-        for (i = 0; i < 3; i++) {
-                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, hosts[i]);
-                ASSERT_NOT_NULL(rr);
+                ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, *h));
                 rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-                dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-                dns_resource_record_unref(rr);
+                ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         }
 
-        return answer;
+        return TAKE_PTR(answer);
 }
 
-TEST(dns_answer_remove_by_key_single) {
+TEST(dns_answer_remove_by_key) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_answer();
-        DnsResourceKey *key = NULL;
+        DnsResourceKey *key;
 
         /* ignore non-matching class */
-        key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_remove_by_key(&answer, key));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "b.example.com"));
+        ASSERT_OK_ZERO(dns_answer_remove_by_key(&answer, key));
         ASSERT_EQ(dns_answer_size(answer), 3u);
         dns_resource_key_unref(key);
 
         /* ignore non-matching type */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_remove_by_key(&answer, key));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, "b.example.com"));
+        ASSERT_OK_ZERO(dns_answer_remove_by_key(&answer, key));
         ASSERT_EQ(dns_answer_size(answer), 3u);
         dns_resource_key_unref(key);
 
         /* ignore non-matching name */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "z.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_remove_by_key(&answer, key));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "z.example.com"));
+        ASSERT_OK_ZERO(dns_answer_remove_by_key(&answer, key));
         ASSERT_EQ(dns_answer_size(answer), 3u);
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL));
-        dns_resource_key_unref(key);
-
         /* remove matching key */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_remove_by_key(&answer, key));
-        ASSERT_EQ(dns_answer_size(answer), 2u);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(answer, key, NULL));
-        dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_remove_by_key_all) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_answer();
-        DnsResourceKey *key = NULL;
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        dns_answer_remove_by_key(&answer, key);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        dns_answer_remove_by_key(&answer, key);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com");
-        ASSERT_NOT_NULL(key);
-        dns_answer_remove_by_key(&answer, key);
-        dns_resource_key_unref(key);
+        char **hosts = STRV_MAKE("a.example.com", "b.example.com", "c.example.com");
+        unsigned n = strv_length(hosts);
+        STRV_FOREACH(h, hosts) {
+                n--;
+
+                ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, *h));
+                ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
+                ASSERT_OK_POSITIVE(dns_answer_remove_by_key(&answer, key));
+                ASSERT_EQ(dns_answer_size(answer), n);
+
+                ASSERT_OK_ZERO(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
+                ASSERT_OK_ZERO(dns_answer_remove_by_key(&answer, key));
+                ASSERT_EQ(dns_answer_size(answer), n);
+                dns_resource_key_unref(key);
+        }
 
         ASSERT_NULL(answer);
 }
 
-TEST(dns_answer_remove_by_rr_single) {
+TEST(dns_answer_remove_by_rr) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_answer();
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(answer, key, NULL));
-        dns_resource_key_unref(key);
-
-        /* remove nothing if the payload does not match */
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0x01020304);
-        ASSERT_FALSE(dns_answer_remove_by_rr(&answer, rr));
-        ASSERT_EQ(dns_answer_size(answer), 3u);
-        dns_resource_record_unref(rr);
 
-        /* remove matching payload */
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        ASSERT_TRUE(dns_answer_remove_by_rr(&answer, rr));
-        ASSERT_EQ(dns_answer_size(answer), 2u);
-        dns_resource_record_unref(rr);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(answer, key, NULL));
-        dns_resource_key_unref(key);
-}
+        char **hosts = STRV_MAKE("a.example.com", "b.example.com", "c.example.com");
+        unsigned n = strv_length(hosts);
+        STRV_FOREACH(h, hosts) {
+                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
 
-TEST(dns_answer_remove_by_rr_all) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_answer();
-        DnsResourceRecord *rr = NULL;
+                ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, *h));
+                ASSERT_OK_POSITIVE(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_remove_by_rr(&answer, rr);
-        dns_resource_record_unref(rr);
+                /* remove nothing if the payload does not match */
+                ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, *h));
+                rr->a.in_addr.s_addr = htobe32(0x01020304);
+                ASSERT_OK_ZERO(dns_answer_remove_by_rr(&answer, rr));
+                ASSERT_EQ(dns_answer_size(answer), n);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_remove_by_rr(&answer, rr);
-        dns_resource_record_unref(rr);
+                /* remove matching payload */
+                rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
+                ASSERT_OK_POSITIVE(dns_answer_remove_by_rr(&answer, rr));
+                ASSERT_EQ(dns_answer_size(answer), --n);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_remove_by_rr(&answer, rr);
-        dns_resource_record_unref(rr);
+                ASSERT_OK_ZERO(dns_answer_match_key(answer, key, /* ret_flags = */ NULL));
+        }
 
         ASSERT_NULL(answer);
 }
 
-TEST(dns_answer_remove_by_answer_keys_partial) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *a = prepare_answer();
-        _cleanup_(dns_answer_unrefp) DnsAnswer *b = prepare_answer();
-
-        dns_answer_remove_by_answer_keys(&a, b);
+TEST(dns_answer_remove_by_answer_keys) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *a = prepare_answer(), *b = prepare_answer();
+        DnsResourceKey *key;
 
+        ASSERT_OK(dns_answer_remove_by_answer_keys(&a, b));
         ASSERT_NULL(a);
-}
 
-TEST(dns_answer_remove_by_answer_keys_all) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *a = prepare_answer();
-        _cleanup_(dns_answer_unrefp) DnsAnswer *b = prepare_answer();
-        DnsResourceKey *key = NULL;
+        a = prepare_answer();
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        dns_answer_remove_by_key(&b, key);
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_remove_by_key(&b, key));
         dns_resource_key_unref(key);
 
         ASSERT_EQ(dns_answer_size(a), 3u);
         ASSERT_EQ(dns_answer_size(b), 2u);
 
-        dns_answer_remove_by_answer_keys(&a, b);
+        ASSERT_OK(dns_answer_remove_by_answer_keys(&a, b));
 
         ASSERT_EQ(dns_answer_size(a), 1u);
         ASSERT_EQ(dns_answer_size(b), 2u);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(a, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
+        ASSERT_OK_ZERO(dns_answer_match_key(a, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(a, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(a, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_match_key(a, key, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com"));
+        ASSERT_OK_ZERO(dns_answer_match_key(a, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
 }
 
@@ -537,145 +409,76 @@ TEST(dns_answer_remove_by_answer_keys_all) {
  * dns_answer_copy_by_key()
  * ================================================================ */
 
-TEST(dns_answer_copy_by_key_no_match) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+TEST(dns_answer_copy_by_key) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *source = NULL, *target = NULL;
+        DnsResourceRecord *rr;
+        DnsResourceKey *key;
+        DnsAnswerFlags flags;
 
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
+        ASSERT_NOT_NULL(source = dns_answer_new(0));
+        ASSERT_NOT_NULL(target = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */NULL));
+        rr = dns_resource_record_unref(rr);
 
         /* non-matching class */
-        key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
-        ASSERT_TRUE(dns_answer_isempty(target));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "a.example.com"));
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
 
         /* non-matching type */
         key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, "a.example.com");
         ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
-        ASSERT_TRUE(dns_answer_isempty(target));
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
 
         /* non-matching name */
         key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
         ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
-        ASSERT_TRUE(dns_answer_isempty(target));
-        dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_copy_by_key_single_match) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
-
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
 
+        /* matching key */
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(target), 1u);
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, NULL));
-        dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_copy_by_key_multi_match) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
 
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-        dns_resource_record_unref(rr);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        /* add one more record with the same key */
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->a.in_addr.s_addr = htobe32(0x7f000001);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
-        dns_resource_key_unref(key);
+        /* check if the two records are copied */
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(target), 2u);
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
 
+        /* try again with an empty target */
+        target = dns_answer_unref(target);
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(target), 2u);
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
         dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_copy_by_key_flags) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
-        DnsAnswerFlags ret_flags = 0;
-
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-        dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
+        /* add one more record */
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr->a.in_addr.s_addr = htobe32(0x7f000001);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, 0, NULL));
-        dns_resource_key_unref(key);
-
-        ASSERT_EQ(dns_answer_size(target), 1u);
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, &ret_flags));
-        ASSERT_EQ((int)ret_flags, DNS_ANSWER_CACHEABLE);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, DNS_ANSWER_SECTION_ANSWER, NULL));
-        dns_resource_key_unref(key);
-
-        ASSERT_EQ(dns_answer_size(target), 2u);
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, &ret_flags));
-        ASSERT_EQ((int)ret_flags, (DNS_ANSWER_CACHEABLE | DNS_ANSWER_SECTION_ANSWER));
+        /* copy with flags */
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
+        ASSERT_OK(dns_answer_copy_by_key(&target, source, key, DNS_ANSWER_SECTION_ANSWER, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(target), 3u);
+        ASSERT_TRUE(dns_answer_match_key(target, key, &flags));
+        ASSERT_EQ((int) flags, DNS_ANSWER_CACHEABLE | DNS_ANSWER_SECTION_ANSWER);
         dns_resource_key_unref(key);
 }
 
@@ -683,291 +486,167 @@ TEST(dns_answer_copy_by_key_flags) {
  * dns_answer_move_by_key()
  * ================================================================ */
 
-TEST(dns_answer_move_by_key_no_match) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+TEST(dns_answer_move_by_key) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *source = NULL, *target = NULL;
+        DnsResourceRecord *rr;
+        DnsResourceKey *key;
 
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
+        ASSERT_NOT_NULL(source = dns_answer_new(0));
+        ASSERT_NOT_NULL(target = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
+        dns_resource_record_unref(rr);
 
         /* non-matching class */
-        key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_ANY, DNS_TYPE_A, "a.example.com"));
+        ASSERT_OK_ZERO(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(source), 1u);
         ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
 
         /* non-matching type */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, "a.example.com"));
+        ASSERT_OK_ZERO(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(source), 1u);
         ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
 
         /* non-matching name */
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_FALSE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
+        ASSERT_OK_ZERO(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(source), 1u);
         ASSERT_EQ(dns_answer_size(target), 0u);
         dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_move_by_key_single_destroy_source) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
-
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        /* matching key */
+        ASSERT_NOT_NULL(key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_NULL(source);
         ASSERT_EQ(dns_answer_size(target), 1u);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, NULL));
-        dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_move_by_key_single_leave_source) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
-
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-        dns_resource_record_unref(rr);
+        /* move the record back to the source */
+        source = TAKE_PTR(target);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
+        /* add one more record */
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr->a.in_addr.s_addr = htobe32(0x7f000001);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        /* move only a.example.com */
+        ASSERT_OK_POSITIVE(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(source), 1u);
         ASSERT_EQ(dns_answer_size(target), 1u);
-        dns_resource_key_unref(key);
-
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_match_key(target, key, NULL));
-        dns_resource_key_unref(key);
-}
-
-TEST(dns_answer_move_by_key_multi_leave_source) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *source = dns_answer_new(0);
-        _cleanup_(dns_answer_unrefp) DnsAnswer *target = dns_answer_new(0);
-        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
-        DnsResourceRecord *rr = NULL;
+        ASSERT_OK_ZERO(dns_answer_match_key(source, key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
 
-        ASSERT_NOT_NULL(source);
-        ASSERT_NOT_NULL(target);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-        dns_resource_record_unref(rr);
-
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
-        rr->a.in_addr.s_addr = htobe32(0x7f000001);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
-        dns_resource_record_unref(rr);
+        /* move the record back to the source */
+        ASSERT_OK_POSITIVE(dns_answer_move_by_key(&source, &target, key, /* or_flags = */ 0, /* rrsig = */ NULL));
+        ASSERT_EQ(dns_answer_size(source), 2u);
+        ASSERT_EQ(dns_answer_size(target), 0u);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        /* add one more record */
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->a.in_addr.s_addr = htobe32(0xc0a80180);
-        dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(source, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(key);
-        ASSERT_TRUE(dns_answer_move_by_key(&target, &source, key, 0, NULL));
+        /* move two records for a.example.com */
+        ASSERT_OK_POSITIVE(dns_answer_move_by_key(&target, &source, key, /* or_flags = */ 0, /* rrsig = */ NULL));
         ASSERT_EQ(dns_answer_size(source), 1u);
         ASSERT_EQ(dns_answer_size(target), 2u);
+        ASSERT_OK_ZERO(dns_answer_match_key(source, key, /* ret_flags = */ NULL));
+        ASSERT_OK_POSITIVE(dns_answer_match_key(target, key, /* ret_flags = */ NULL));
+        dns_resource_key_unref(key);
 }
 
 /* ================================================================
  * dns_answer_has_dname_for_cname()
  * ================================================================ */
 
-TEST(dns_answer_has_dname_for_cname_pass) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL;
-
-        ASSERT_NOT_NULL(answer);
-
-        dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "example.com");
-        ASSERT_NOT_NULL(dname);
-        dname->dname.name = strdup("v2.example.com");
-        dns_answer_add(answer, dname, 1, DNS_ANSWER_CACHEABLE, NULL);
-
-        cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com");
-        ASSERT_NOT_NULL(cname);
-        cname->cname.name = strdup("www.v2.example.com");
-        ASSERT_TRUE(dns_answer_has_dname_for_cname(answer, cname));
-}
-
-TEST(dns_answer_has_dname_for_cname_no_dname) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL;
-
-        ASSERT_NOT_NULL(answer);
-
-        cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com");
-        ASSERT_NOT_NULL(cname);
-        cname->cname.name = strdup("www.v2.example.com");
-        ASSERT_FALSE(dns_answer_has_dname_for_cname(answer, cname));
-}
-
-TEST(dns_answer_has_dname_for_cname_no_match_old_suffix) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL;
-
-        dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "example.com");
-        ASSERT_NOT_NULL(dname);
-        dname->dname.name = strdup("v2.examples.com");
-        dns_answer_add(answer, dname, 1, DNS_ANSWER_CACHEABLE, NULL);
-
-        cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com");
-        ASSERT_NOT_NULL(cname);
-        cname->cname.name = strdup("www.v2.example.com");
-        ASSERT_FALSE(dns_answer_has_dname_for_cname(answer, cname));
-}
-
-TEST(dns_answer_has_dname_for_cname_no_match_new_suffix) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL;
-
-        ASSERT_NOT_NULL(answer);
+TEST(dns_answer_has_dname_for_cname) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL, *rr = NULL;
 
-        dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "example.com");
-        ASSERT_NOT_NULL(dname);
-        dname->dname.name = strdup("v2.example.com");
-        dns_answer_add(answer, dname, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com");
-        ASSERT_NOT_NULL(cname);
-        cname->cname.name = strdup("www.v3.example.com");
-        ASSERT_FALSE(dns_answer_has_dname_for_cname(answer, cname));
-}
+        /* no dname */
+        ASSERT_NOT_NULL(cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "www.example.com"));
+        ASSERT_NOT_NULL(cname->cname.name = strdup("www.v2.example.com"));
+        ASSERT_OK_ZERO(dns_answer_has_dname_for_cname(answer, cname));
 
-TEST(dns_answer_has_dname_for_cname_not_cname) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL;
+        /* has matching dname */
+        ASSERT_NOT_NULL(dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "example.com"));
+        ASSERT_NOT_NULL(dname->dname.name = strdup("v2.example.com"));
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, dname, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
 
-        ASSERT_NOT_NULL(answer);
+        /* no matching old suffix */
+        ASSERT_OK(free_and_strdup(&dname->dname.name, "www.v2.examples.com"));
+        ASSERT_OK_ZERO(dns_answer_has_dname_for_cname(answer, cname));
+        ASSERT_OK(free_and_strdup(&dname->dname.name, "www.v2.example.com"));
 
-        dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "example.com");
-        ASSERT_NOT_NULL(dname);
-        dname->dname.name = strdup("v2.example.com");
-        dns_answer_add(answer, dname, 1, DNS_ANSWER_CACHEABLE, NULL);
+        /* no matching new suffix */
+        ASSERT_OK(free_and_strdup(&cname->cname.name, "www.v3.example.com"));
+        ASSERT_OK_ZERO(dns_answer_has_dname_for_cname(answer, cname));
 
-        cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
-        ASSERT_NOT_NULL(cname);
-        cname->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        ASSERT_FALSE(dns_answer_has_dname_for_cname(answer, cname));
+        /* Not a cname */
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com"));
+        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
+        ASSERT_OK_ZERO(dns_answer_has_dname_for_cname(answer, rr));
 }
 
 /* ================================================================
  * dns_answer_dump()
  * ================================================================ */
 
-static void check_dump_contents(FILE *f, const char **expected, size_t n) {
-        char *actual[n];
-        size_t i, r;
-        rewind(f);
-
-        for (i = 0; i < n; i++) {
-                r = read_line(f, 1024, &actual[i]);
-                ASSERT_GT(r, 0u);
-        }
-
-        for (i = 0; i < n; i++)
-                ASSERT_STREQ(actual[i], expected[i]);
-
-        for (i = 0 ; i < n; i++)
-                free(actual[i]);
-}
-
 TEST(dns_answer_dump) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = dns_answer_new(0);
-        DnsResourceRecord *rr = NULL;
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        DnsResourceRecord *rr;
+        _cleanup_(memstream_done) MemStream ms = {};
+        _cleanup_free_ char *buf = NULL;
+        FILE *f;
 
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->ttl = 1200;
         rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
-        dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE | DNS_ANSWER_SECTION_ADDITIONAL, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE | DNS_ANSWER_SECTION_ADDITIONAL, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr->ttl = 2400;
         rr->a.in_addr.s_addr = htobe32(0xc0a80180);
-        dns_answer_add(answer, rr, 2, 0, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 2, 0, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com"));
         rr->ttl = 3600;
         rr->a.in_addr.s_addr = htobe32(0xc0a80181);
-        dns_answer_add(answer, rr, 3, DNS_ANSWER_AUTHENTICATED | DNS_ANSWER_SHARED_OWNER | DNS_ANSWER_SECTION_AUTHORITY | DNS_ANSWER_CACHE_FLUSH, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 3,
+                                          DNS_ANSWER_AUTHENTICATED | DNS_ANSWER_SHARED_OWNER | DNS_ANSWER_SECTION_AUTHORITY | DNS_ANSWER_CACHE_FLUSH,
+                                          /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "d.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "d.example.com"));
         rr->ttl = 4800;
         rr->cname.name = strdup("www.example.com");
-        dns_answer_add(answer, rr, 4, DNS_ANSWER_GOODBYE | DNS_ANSWER_SECTION_ANSWER, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 4, DNS_ANSWER_GOODBYE | DNS_ANSWER_SECTION_ANSWER, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
         ASSERT_EQ(dns_answer_size(answer), 4u);
 
-        _cleanup_(unlink_tempfilep) char p[] = "/tmp/dns-answer-dump-XXXXXX";
-        _cleanup_fclose_ FILE *f = NULL;
-        fmkostemp_safe(p, "r+", &f);
+        ASSERT_NOT_NULL(f = memstream_init(&ms));
         dns_answer_dump(answer, f);
-
-        const char *expected[] = {
-                "\ta.example.com IN A 192.168.1.127\t; ttl=1200 ifindex=1 cacheable section-additional",
-                "\tb.example.com IN A 192.168.1.128\t; ttl=2400 ifindex=2",
-                "\tc.example.com IN A 192.168.1.129\t; ttl=3600 ifindex=3 authenticated shared-owner cache-flush section-authority",
-                "\td.example.com IN CNAME www.example.com\t; ttl=4800 ifindex=4 goodbye section-answer"
-        };
-        check_dump_contents(f, expected, 4);
+        ASSERT_OK(memstream_finalize(&ms, &buf, /* ret_size = */ NULL));
+        ASSERT_STREQ(buf,
+                     "\ta.example.com IN A 192.168.1.127\t; ttl=1200 ifindex=1 cacheable section-additional\n"
+                     "\tb.example.com IN A 192.168.1.128\t; ttl=2400 ifindex=2\n"
+                     "\tc.example.com IN A 192.168.1.129\t; ttl=3600 ifindex=3 authenticated shared-owner cache-flush section-authority\n"
+                     "\td.example.com IN CNAME www.example.com\t; ttl=4800 ifindex=4 goodbye section-answer\n");
 }
 
 /* ================================================================
@@ -976,68 +655,54 @@ TEST(dns_answer_dump) {
 
 /* link-local addresses are a9fe0100 (169.254.1.0) to a9fefeff (169.254.254.255) */
 
-static DnsAnswer* prepare_link_local_answer(void) {
-        DnsAnswer *answer = dns_answer_new(0);
-        DnsResourceRecord *rr = NULL;
+TEST(dns_answer_order_by_scope) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        DnsResourceRecord *rr;
+        _cleanup_(memstream_done) MemStream ms = {};
+        _cleanup_free_ char *buf = NULL;
+        FILE *f;
 
-        ASSERT_NOT_NULL(answer);
+        ASSERT_NOT_NULL(answer = dns_answer_new(0));
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "a.example.com"));
         rr->ttl = 3600;
         rr->a.in_addr.s_addr = htobe32(0xa9fe0100);
-        dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 1, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "b.example.com"));
         rr->ttl = 3600;
         rr->a.in_addr.s_addr = htobe32(0xc0a80404);
-        dns_answer_add(answer, rr, 2, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 2, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com");
-        ASSERT_NOT_NULL(rr);
+        ASSERT_NOT_NULL(rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "c.example.com"));
         rr->ttl = 3600;
         rr->a.in_addr.s_addr = htobe32(0xa9fefeff);
-        dns_answer_add(answer, rr, 3, DNS_ANSWER_CACHEABLE, NULL);
+        ASSERT_OK_POSITIVE(dns_answer_add(answer, rr, 3, DNS_ANSWER_CACHEABLE, /* rrsig = */ NULL));
         dns_resource_record_unref(rr);
 
-        return answer;
-}
-
-TEST(dns_answer_order_by_scope_prefer_link_local) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_link_local_answer();
-        dns_answer_order_by_scope(answer, 1);
+        dns_answer_order_by_scope(answer, /* prefer_link_local = */ true);
 
-        _cleanup_(unlink_tempfilep) char p[] = "/tmp/dns-answer-order-by-scope-1-XXXXXX";
-        _cleanup_fclose_ FILE *f = NULL;
-        fmkostemp_safe(p, "r+", &f);
+        ASSERT_NOT_NULL(f = memstream_init(&ms));
         dns_answer_dump(answer, f);
+        ASSERT_OK(memstream_finalize(&ms, &buf, /* ret_size = */ NULL));
+        ASSERT_STREQ(buf,
+                     "\ta.example.com IN A 169.254.1.0\t; ttl=3600 ifindex=1 cacheable\n"
+                     "\tc.example.com IN A 169.254.254.255\t; ttl=3600 ifindex=3 cacheable\n"
+                     "\tb.example.com IN A 192.168.4.4\t; ttl=3600 ifindex=2 cacheable\n");
+        buf = mfree(buf);
+        memstream_done(&ms);
 
-        const char *expected[] = {
-                "\ta.example.com IN A 169.254.1.0\t; ttl=3600 ifindex=1 cacheable",
-                "\tc.example.com IN A 169.254.254.255\t; ttl=3600 ifindex=3 cacheable",
-                "\tb.example.com IN A 192.168.4.4\t; ttl=3600 ifindex=2 cacheable"
-        };
-        check_dump_contents(f, expected, 3);
-}
-
-TEST(dns_answer_order_by_scope_prefer_other) {
-        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = prepare_link_local_answer();
-        dns_answer_order_by_scope(answer, 0);
+        dns_answer_order_by_scope(answer, /* prefer_link_local = */ false);
 
-        _cleanup_(unlink_tempfilep) char p[] = "/tmp/dns-answer-order-by-scope-2-XXXXXX";
-        _cleanup_fclose_ FILE *f = NULL;
-        fmkostemp_safe(p, "r+", &f);
+        ASSERT_NOT_NULL(f = memstream_init(&ms));
         dns_answer_dump(answer, f);
-
-        const char *expected[] = {
-                "\tb.example.com IN A 192.168.4.4\t; ttl=3600 ifindex=2 cacheable",
-                "\ta.example.com IN A 169.254.1.0\t; ttl=3600 ifindex=1 cacheable",
-                "\tc.example.com IN A 169.254.254.255\t; ttl=3600 ifindex=3 cacheable"
-        };
-        check_dump_contents(f, expected, 3);
+        ASSERT_OK(memstream_finalize(&ms, &buf, /* ret_size = */ NULL));
+        ASSERT_STREQ(buf,
+                     "\tb.example.com IN A 192.168.4.4\t; ttl=3600 ifindex=2 cacheable\n"
+                     "\ta.example.com IN A 169.254.1.0\t; ttl=3600 ifindex=1 cacheable\n"
+                     "\tc.example.com IN A 169.254.254.255\t; ttl=3600 ifindex=3 cacheable\n");
 }
 
 DEFINE_TEST_MAIN(LOG_DEBUG);