test: More tests

Include tests of internal functions, based on the value of the
CARES_SYMBOL_HIDING macro; need to configure the library with
--disable-symbol-hiding to enable these tests.
pull/34/head
David Drysdale 9 years ago
parent 3907b6dc68
commit 5da3201a05
  1. 6
      test/ares-test-init.cc
  2. 93
      test/ares-test-internal.cc
  3. 47
      test/ares-test-live.cc
  4. 121
      test/ares-test-misc.cc
  5. 15
      test/ares-test-parse.cc
  6. 2
      test/configure.ac
  7. 1
      test/dns-proto.cc

@ -19,6 +19,12 @@ TEST(LibraryInit, Basic) {
EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
}
TEST(LibraryInit, UnexpectedCleanup) {
EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
ares_library_cleanup();
EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
}
TEST(LibraryInit, DISABLED_InvalidParam) {
// TODO: police flags argument to ares_library_init()
EXPECT_EQ(ARES_EBADQUERY, ares_library_init(ARES_LIB_INIT_ALL << 2));

@ -2,9 +2,22 @@
#include "dns-proto.h"
extern "C" {
// Remove command-line defines of package variables for the test project...
#undef PACKAGE_NAME
#undef PACKAGE_BUGREPORT
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
// ... so we can include the library's config without symbol redefinitions.
#include "ares_config.h"
#include "ares_nowarn.h"
#include "ares_inet_net_pton.h"
#include "ares_data.h"
#include "bitncmp.h"
char *ares_strdup(const char*);
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
}
#include <string>
@ -16,13 +29,15 @@ namespace test {
TEST_F(LibraryTest, InetPtoN) {
struct in_addr a4;
struct in6_addr a6;
#ifdef DISABLED
EXPECT_EQ(1, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4)));
EXPECT_EQ(1, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
EXPECT_EQ(1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
EXPECT_EQ(0, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
#ifndef CARES_SYMBOL_HIDING
EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4)));
EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
EXPECT_EQ(-1, ares_inet_net_pton(AF_INET+AF_INET6, "1.2.3.4", &a4, sizeof(a4)));
#endif
EXPECT_EQ(1, ares_inet_pton(AF_INET, "1.2.3.4", &a4));
EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ff", &a6));
EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6));
@ -30,27 +45,87 @@ TEST_F(LibraryTest, InetPtoN) {
EXPECT_EQ(-1, ares_inet_pton(AF_INET+AF_INET6, "1.2.3.4", &a4));
}
#ifdef DISABLED
TEST_F(LibraryTest, FreeCorruptData) {
// ares_free_data(p) expects that there is a type field and a marker
// field in the memory before p. Feed it incorrect versions of each.
struct ares_data *data = (struct ares_data *)malloc(sizeof(struct ares_data));
void* p = &(data->data);
// Invalid type
data->type = (ares_datatype)99;
data->mark = ARES_DATATYPE_MARK;
ares_free_data(p);
// Invalid marker
data->type = (ares_datatype)ARES_DATATYPE_MX_REPLY;
data->mark = ARES_DATATYPE_MARK + 1;
ares_free_data(p);
// Null pointer
ares_free_data(nullptr);
free(data);
}
#ifndef CARES_SYMBOL_HIDING
TEST(LibraryInit, StrdupFailures) {
EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
char* copy = ares_strdup("string");
EXPECT_NE(nullptr, copy);
free(copy);
ares_library_cleanup();
}
TEST_F(LibraryTest, StrdupFailures) {
SetAllocFail(1);
char* copy = ares_strdup("string");
EXPECT_EQ(nullptr, copy);
}
TEST_F(LibraryTest, MallocDataFail) {
EXPECT_EQ(nullptr, ares_malloc_data((ares_datatype)99));
SetAllocSizeFail(sizeof(struct ares_data));
EXPECT_EQ(nullptr, ares_malloc_data(ARES_DATATYPE_MX_REPLY));
}
TEST(Misc, Bitncmp) {
byte a[4] = {0x80, 0x01, 0x02, 0x03};
byte b[4] = {0x80, 0x01, 0x02, 0x04};
EXPECT_EQ(-1, ares__bitncmp(a, b, sizeof(a)*8));
EXPECT_EQ(1, ares__bitncmp(b, a, sizeof(a)*8));
byte c[4] = {0x01, 0xFF, 0x80, 0x02};
EXPECT_GT(0, ares__bitncmp(a, b, sizeof(a)*8));
EXPECT_LT(0, ares__bitncmp(b, a, sizeof(a)*8));
EXPECT_EQ(0, ares__bitncmp(a, a, sizeof(a)*8));
for (int ii = 1; ii < (3*8+5); ii++) {
EXPECT_EQ(0, ares__bitncmp(a, b, ii));
EXPECT_EQ(0, ares__bitncmp(b, a, ii));
EXPECT_LT(0, ares__bitncmp(a, c, ii));
EXPECT_GT(0, ares__bitncmp(c, a, ii));
}
// Last byte differs at 5th bit
EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 3));
EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 4));
EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 5));
EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 6));
EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 7));
}
TEST_F(LibraryTest, Casts) {
ssize_t ssz = 100;
unsigned int u = 100;
int i = 100;
long l = 100;
unsigned int ru = aresx_sztoui(ssz);
EXPECT_EQ(u, ru);
int ri = aresx_sztosi(ssz);
EXPECT_EQ(i, ri);
ri = aresx_sltosi(l);
EXPECT_EQ(l, (long)ri);
}
#endif
} // namespace test
} // namespace ares

@ -13,6 +13,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByNameV4) {
ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET, result.host_.addrtype_);
}
@ -22,6 +23,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByNameV6) {
ares_gethostbyname(channel_, "www.google.com.", AF_INET6, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET6, result.host_.addrtype_);
}
@ -32,6 +34,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByAddrV4) {
ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET, result.host_.addrtype_);
}
@ -43,16 +46,46 @@ TEST_F(DefaultChannelTest, LiveGetHostByAddrV6) {
ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET6, HostCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
EXPECT_LT(0, (int)result.host_.addrs_.size());
EXPECT_EQ(AF_INET6, result.host_.addrtype_);
}
TEST_F(DefaultChannelTest, LiveGetHostByAddrFailFamily) {
HostResult result;
unsigned char addr[4] = {8, 8, 8, 8};
ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET6+AF_INET,
HostCallback, &result);
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_ENOTIMP, result.status_);
}
TEST_F(DefaultChannelTest, LiveGetHostByAddrFailAddrSize) {
HostResult result;
unsigned char addr[4] = {8, 8, 8, 8};
ares_gethostbyaddr(channel_, addr, sizeof(addr) - 1, AF_INET,
HostCallback, &result);
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_ENOTIMP, result.status_);
}
TEST_F(DefaultChannelTest, LiveGetHostByAddrFailAlloc) {
HostResult result;
unsigned char addr[4] = {8, 8, 8, 8};
SetAllocFail(1);
ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET,
HostCallback, &result);
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_ENOMEM, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchA) {
SearchResult result;
ares_search(channel_, "www.facebook.com.", ns_c_in, ns_t_a,
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchNS) {
@ -61,6 +94,7 @@ TEST_F(DefaultChannelTest, LiveSearchNS) {
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchMX) {
@ -69,6 +103,7 @@ TEST_F(DefaultChannelTest, LiveSearchMX) {
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchTXT) {
@ -77,6 +112,7 @@ TEST_F(DefaultChannelTest, LiveSearchTXT) {
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchSOA) {
@ -85,6 +121,7 @@ TEST_F(DefaultChannelTest, LiveSearchSOA) {
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveSearchANY) {
@ -93,6 +130,7 @@ TEST_F(DefaultChannelTest, LiveSearchANY) {
SearchCallback, &result);
Process();
EXPECT_TRUE(result.done_);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
TEST_F(DefaultChannelTest, LiveGetNameInfo) {
@ -107,14 +145,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfo) {
NameInfoCallback, &result);
Process();
EXPECT_TRUE(result.done_);
CARES_EXTERN void ares_getnameinfo(ares_channel channel,
const struct sockaddr *sa,
ares_socklen_t salen,
int flags,
ares_nameinfo_callback callback,
void *arg);
EXPECT_EQ(ARES_SUCCESS, result.status_);
}
} // namespace test

@ -26,7 +26,7 @@ std::vector<std::string> GetNameServers(ares_channel channel) {
}
server = server->next;
}
ares_free_data(servers);
if (servers) ares_free_data(servers);
return results;
}
@ -39,6 +39,17 @@ TEST_F(DefaultChannelTest, GetServers) {
}
}
TEST_F(DefaultChannelTest, GetServersFailures) {
EXPECT_EQ(ARES_SUCCESS,
ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
struct ares_addr_node* servers = nullptr;
SetAllocFail(1);
EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
SetAllocFail(2);
EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
EXPECT_EQ(ARES_ENODATA, ares_get_servers(nullptr, &servers));
}
TEST_F(DefaultChannelTest, SetServers) {
EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, nullptr));
std::vector<std::string> empty;
@ -79,6 +90,19 @@ TEST_F(DefaultChannelTest, SetServersCSV) {
EXPECT_EQ(ARES_SUCCESS,
ares_set_servers_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
EXPECT_EQ(expected, GetNameServers(channel_));
// Allocation failure cases
for (int fail = 1; fail <= 5; fail++) {
SetAllocFail(fail);
EXPECT_EQ(ARES_ENOMEM,
ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
}
// Blank servers
EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, ""));
std::vector<std::string> none;
EXPECT_EQ(none, GetNameServers(channel_));
}
TEST_F(DefaultChannelTest, TimeoutValue) {
@ -143,7 +167,9 @@ TEST_F(LibraryTest, Mkquery) {
TEST_F(LibraryTest, CreateQuery) {
byte* p;
int len;
ares_create_query("exam\\@le.com", ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0);
EXPECT_EQ(ARES_SUCCESS,
ares_create_query("exam\\@le.com", ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 0));
std::vector<byte> data(p, p + len);
ares_free_string(p);
@ -154,10 +180,95 @@ TEST_F(LibraryTest, CreateQuery) {
EXPECT_EQ(expected, actual);
}
TEST_F(LibraryTest, CreateQueryFailures) {
byte* p;
int len;
// RC1035 has a 255 byte limit on names.
std::string longname;
for (int ii = 0; ii < 17; ii++) {
longname += "fedcba9876543210";
}
EXPECT_EQ(ARES_EBADNAME,
ares_create_query(longname.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 0));
SetAllocFail(1);
EXPECT_EQ(ARES_ENOMEM,
ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 0));
// 63-char limit on a single label
std::string longlabel = "a.a123456789b123456789c123456789d123456789e123456789f123456789g123456789.org";
EXPECT_EQ(ARES_EBADNAME,
ares_create_query(longlabel.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 0));
// Empty non-terminal label
EXPECT_EQ(ARES_EBADNAME,
ares_create_query("example..com", ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 0));
}
TEST_F(LibraryTest, ExpandNameFailure) {
std::vector<byte> data1 = {0x03, 'c', 'o', 'm', 0x00};
char *name = nullptr;
long enclen;
SetAllocFail(1);
EXPECT_EQ(ARES_ENOMEM,
ares_expand_name(data1.data(), data1.data(), data1.size(),
&name, &enclen));
// Start beyond enclosing data
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data1.data() + data1.size(), data1.data(), data1.size(),
&name, &enclen));
// Length beyond size of enclosing data
std::vector<byte> data2 = {0x13, 'c', 'o', 'm', 0x00};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data2.data(), data2.data(), data2.size(),
&name, &enclen));
// Indirection beyond enclosing data
std::vector<byte> data3 = {0xCA, 'c', 'o', 'm', 0x00};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data3.data(), data3.data(), data3.size(),
&name, &enclen));
// Invalid top bits in label length
std::vector<byte> data4 = {0x03, 'c', 'o', 'm', 0x00, 0x80, 0x00};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data4.data() + 5, data4.data(), data4.size(),
&name, &enclen));
// Label too long: 64-byte label, with invalid top 2 bits of length (01).
std::vector<byte> data5 = {0x40,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
0x00};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data5.data(), data5.data(), data5.size(),
&name, &enclen)) << name;
// Incomplete indirect length
std::vector<byte> data6 = {0x03, 'c', 'o', 'm', 0x00, 0xC0};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data6.data() + 5, data6.data(), data6.size(),
&name, &enclen));
// Indirection loop
std::vector<byte> data7 = {0xC0, 0x02, 0xC0, 0x00};
EXPECT_EQ(ARES_EBADNAME,
ares_expand_name(data7.data(), data7.data(), data7.size(),
&name, &enclen));
}
TEST_F(LibraryTest, CreateEDNSQuery) {
byte* p;
int len;
ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 1280);
EXPECT_EQ(ARES_SUCCESS,
ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
&p, &len, 1280));
std::vector<byte> data(p, p + len);
ares_free_string(p);
@ -216,6 +327,10 @@ TEST_F(LibraryTest, ExpandString) {
EXPECT_EQ(ARES_EBADSTR,
ares_expand_string(s1.data() + 4, s1.data(), s1.size(),
(unsigned char**)&result, &len));
SetAllocSizeFail(3 + 1);
EXPECT_EQ(ARES_ENOMEM,
ares_expand_string(s1.data(), s1.data(), s1.size(),
(unsigned char**)&result, &len));
}
} // namespace test

@ -411,7 +411,9 @@ TEST_F(LibraryTest, ParseNaptrReplyOK) {
pkt.set_qid(0x1234).set_response().set_aa()
.add_question(new DNSQuestion("example.com", ns_t_soa))
.add_answer(new DNSNaptrRR("example.com", 0x01020304,
10, 20, "SP", "service", "regexp", "replace"));
10, 20, "SP", "service", "regexp", "replace"))
.add_answer(new DNSNaptrRR("example.com", 0x0010,
11, 21, "SP", "service2", "regexp2", "replace2"));
std::vector<byte> data = pkt.data();
struct ares_naptr_reply* naptr = nullptr;
@ -423,7 +425,16 @@ TEST_F(LibraryTest, ParseNaptrReplyOK) {
EXPECT_EQ("replace", std::string((char*)naptr->replacement));
EXPECT_EQ(10, naptr->order);
EXPECT_EQ(20, naptr->preference);
EXPECT_EQ(nullptr, naptr->next);
struct ares_naptr_reply* naptr2 = naptr->next;
ASSERT_NE(nullptr, naptr2);
EXPECT_EQ("SP", std::string((char*)naptr2->flags));
EXPECT_EQ("service2", std::string((char*)naptr2->service));
EXPECT_EQ("regexp2", std::string((char*)naptr2->regexp));
EXPECT_EQ("replace2", std::string((char*)naptr2->replacement));
EXPECT_EQ(11, naptr2->order);
EXPECT_EQ(21, naptr2->preference);
EXPECT_EQ(nullptr, naptr2->next);
ares_free_data(naptr);
}

@ -3,7 +3,7 @@ AC_INIT([c-ares-test],[-],[-])
AC_CONFIG_SRCDIR([ares-test.cc])
AC_CONFIG_MACRO_DIR([../m4])
AM_INIT_AUTOMAKE()
AM_INIT_AUTOMAKE([no-define])
dnl Checks for programs.
AC_PROG_CXX

@ -369,7 +369,6 @@ std::string RRToString(const std::vector<byte>& packet,
ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
ss << " '" << name << "'";
free(name);
p += enclen;
break;
}
default:

Loading…
Cancel
Save