test_dyndns.c revision 6fd5306145d98ea3bab7f32aa66475f610f388ce
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder/*
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder Authors:
d53747c386354ff7db8629dfdf20f44a7c4d715dEugen Kuksa Jakub Hrozek <jhrozek@redhat.com>
cacbb5e3100fb85d23d1614cace3a8662801f2e6Eugen Kuksa
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu Copyright (C) 2013 Red Hat
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
cacbb5e3100fb85d23d1614cace3a8662801f2e6Eugen Kuksa SSSD tests: Dynamic DNS tests
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
6d81916b9004f8d9b6032113c5987ab07da47015Karl Luc This program is free software; you can redistribute it and/or modify
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder it under the terms of the GNU General Public License as published by
d53747c386354ff7db8629dfdf20f44a7c4d715dEugen Kuksa the Free Software Foundation; either version 3 of the License, or
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder (at your option) any later version.
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder This program is distributed in the hope that it will be useful,
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc but WITHOUT ANY WARRANTY; without even the implied warranty of
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder GNU General Public License for more details.
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder You should have received a copy of the GNU General Public License
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc along with this program. If not, see <http://www.gnu.org/licenses/>.
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc*/
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder#include <talloc.h>
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder#include <tevent.h>
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc#include <errno.h>
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa#include <popt.h>
b3138d7e20d2d6dd26a325b844a8b21b0ecbb602Eugen Kuksa#include <unistd.h>
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa#include <sys/types.h>
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa#include <ifaddrs.h>
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc#include <arpa/inet.h>
f6eb05386b068f5968180b21cc225ef0d7d836e7Eugen Kuksa
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa/* In order to access opaque types */
f6eb05386b068f5968180b21cc225ef0d7d836e7Eugen Kuksa#include "providers/dp_dyndns.c"
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder#include "tests/cmocka/common_mock.h"
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder#include "tests/cmocka/common_mock_be.h"
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa#include "src/providers/dp_dyndns.h"
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc#define TESTS_PATH "tests_dyndns"
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc#define TEST_CONF_DB "test_dyndns_conf.ldb"
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa#define TEST_DOM_NAME "dyndns_test"
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc#define TEST_ID_PROVIDER "ldap"
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksaenum mock_nsupdate_states {
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa MOCK_NSUPDATE_OK,
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa MOCK_NSUPDATE_ERR,
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa MOCK_NSUPDATE_TIMEOUT,
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa};
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucstatic TALLOC_CTX *global_mock_context = NULL;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucstruct dyndns_test_ctx {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct sss_test_ctx *tctx;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct be_ctx *be_ctx;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct be_nsupdate_ctx *update_ctx;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc enum mock_nsupdate_states state;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc int child_status;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc int child_retval;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc};
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucstatic struct dyndns_test_ctx *dyndns_test_ctx;
18741eef977546e24fce1fde1b8a8f817aedc6d0Christian Maeder
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucvoid __wrap_execv(const char *path, char *const argv[])
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc{
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc int err;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc switch (dyndns_test_ctx->state) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc case MOCK_NSUPDATE_OK:
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc DEBUG(SSSDBG_FUNC_DATA, "nsupdate success test case\n");
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa err = 0;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc break;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc case MOCK_NSUPDATE_ERR:
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa DEBUG(SSSDBG_FUNC_DATA, "nsupdate error test case\n");
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc err = 1;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc break;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa case MOCK_NSUPDATE_TIMEOUT:
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa DEBUG(SSSDBG_FUNC_DATA, "nsupdate timeout test case\n");
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc err = 2;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc sleep(3);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa break;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc default:
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc DEBUG(SSSDBG_CRIT_FAILURE, "unknown test case\n");
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa err = 255;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa break;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc }
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa DEBUG(SSSDBG_TRACE_LIBS, "Child exiting with status %d\n", err);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa _exit(err);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa}
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksaint __wrap_getifaddrs(struct ifaddrs **_ifap)
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa{
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa struct ifaddrs *ifap = NULL;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa struct ifaddrs *ifap_prev = NULL;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct ifaddrs *ifap_head = NULL;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa char *name;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa char *straddr;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa int ad_family;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa struct sockaddr_in *sa;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa void *dst;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa while ((name = sss_mock_ptr_type(char *)) != NULL) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc straddr = sss_mock_ptr_type(char *);
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa if (straddr == NULL) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc errno = EINVAL;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa goto fail;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa }
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa ad_family = sss_mock_type(int);
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa ifap = talloc_zero(global_mock_context, struct ifaddrs);
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa if (ifap == NULL) {
18741eef977546e24fce1fde1b8a8f817aedc6d0Christian Maeder errno = ENOMEM; /* getifaddrs sets errno, too */
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa goto fail;
18741eef977546e24fce1fde1b8a8f817aedc6d0Christian Maeder }
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa if (ifap_prev) {
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa ifap_prev->ifa_next = ifap;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa } else {
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa ifap_head = ifap;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa }
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa ifap_prev = ifap;
ead7fb0fe5492f65c8e47eaa9d5105bffde163f2Eugen Kuksa
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc ifap->ifa_name = talloc_strdup(ifap, name);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc if (ifap->ifa_name == NULL) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc errno = ENOMEM;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc goto fail;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc }
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc /* Do not alocate directly on ifap->ifa_addr to
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc * avoid alignment warnings */
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa if (ad_family == AF_INET) {
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc sa = talloc(ifap, struct sockaddr_in);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa } else if (ad_family == AF_INET6) {
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa sa = (struct sockaddr_in *) talloc(ifap, struct sockaddr_in6);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa } else {
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa errno = EINVAL;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa goto fail;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa }
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa if (sa == NULL) {
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa errno = ENOMEM;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa goto fail;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa }
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa sa->sin_family = ad_family;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa if (ad_family == AF_INET) {
18741eef977546e24fce1fde1b8a8f817aedc6d0Christian Maeder dst = &sa->sin_addr;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc } else if (ad_family == AF_INET6) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc dst = &((struct sockaddr_in6 *)sa)->sin6_addr;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc } else {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc errno = EINVAL;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc goto fail;
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc }
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc /* convert straddr into ifa_addr */
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc if (inet_pton(ad_family, straddr, dst) != 1) {
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc goto fail;
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc }
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc ifap->ifa_addr = (struct sockaddr *) sa;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc }
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa *_ifap = ifap_head;
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder return 0;
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucfail:
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc talloc_free(ifap);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc return -1;
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc}
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maedervoid __wrap_freeifaddrs(struct ifaddrs *ifap)
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc{
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc talloc_free(ifap);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc}
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksastatic void dyndns_test_done(struct tevent_req *req)
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc{
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc struct dyndns_test_ctx *ctx =
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa tevent_req_callback_data(req, struct dyndns_test_ctx);
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa ctx->child_retval = -1;
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa ctx->tctx->error = be_nsupdate_recv(req, &ctx->child_status);
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa talloc_zfree(req);
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa ctx->tctx->done = true;
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa}
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksavoid will_return_getifaddrs(const char *ifname, const char *straddr,
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa int af_family)
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa{
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc will_return(__wrap_getifaddrs, ifname);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa if (ifname) {
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa will_return(__wrap_getifaddrs, straddr);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa }
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa if (straddr) {
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa will_return(__wrap_getifaddrs, af_family);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa }
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa}
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksavoid dyndns_test_get_ifaddr(void **state)
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa{
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa errno_t ret;
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa struct sss_iface_addr *addrlist;
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa char straddr[128];
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa check_leaks_push(dyndns_test_ctx);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_int_equal(ret, EOK);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa /* There must be only one address with the correct value */
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_non_null(addrlist);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_non_null(addrlist->addr);
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa assert_null(addrlist->next);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_null(addrlist->prev);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_non_null(inet_ntop(AF_INET,
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa &((struct sockaddr_in *) addrlist->addr)->sin_addr,
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa straddr, INET_ADDRSTRLEN));
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_string_equal(straddr, "192.168.0.1");
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
dabf0263008e0b55440c4e3fa0b61261af8c28ceEugen Kuksa talloc_free(addrlist);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa assert_true(check_leaks_pop(dyndns_test_ctx) == true);
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa}
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksavoid dyndns_test_get_multi_ifaddr(void **state)
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa{
ff41d94839a36ce86291af5d83abe2bd39cce1d0Eugen Kuksa errno_t ret;
f6eb05386b068f5968180b21cc225ef0d7d836e7Eugen Kuksa struct sss_iface_addr *addrlist;
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder struct sss_iface_addr *sss_if_addr;
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder char straddr[128];
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc check_leaks_push(dyndns_test_ctx);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder assert_int_equal(ret, EOK);
d53747c386354ff7db8629dfdf20f44a7c4d715dEugen Kuksa
fe1d1e27d7199f3ae7be6406d0ab01b29afbacb0Karl Luc sss_if_addr = addrlist;
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder assert_non_null(sss_if_addr);
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder assert_non_null(sss_if_addr->addr);
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder assert_non_null(sss_if_addr->next);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc assert_null(sss_if_addr->prev);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc assert_non_null(inet_ntop(AF_INET,
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr,
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa straddr, INET_ADDRSTRLEN));
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa /* ip addresses are returned in different order */
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_string_equal(straddr, "192.168.0.1");
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa sss_if_addr = addrlist->next;
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_non_null(sss_if_addr);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_non_null(sss_if_addr->addr);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_null(sss_if_addr->next);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_non_null(sss_if_addr->prev);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_non_null(inet_ntop(AF_INET,
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr,
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa straddr, INET_ADDRSTRLEN));
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa /* ip addresses are returned in different order */
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_string_equal(straddr, "192.168.0.2");
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa talloc_free(addrlist);
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa
8b42604fc9e948093bde658f32b8446e9c6a3576Eugen Kuksa assert_true(check_leaks_pop(dyndns_test_ctx) == true);
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder}
b062631d2f72f0b2b2b6140bc5b0fccb66d1802bChristian Maeder
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Lucvoid dyndns_test_get_ifaddr_enoent(void **state)
b696e806e85f1c07f2f5ea07f2b5babcd656e0d6Karl Luc{
b696e806e85f1c07f2f5ea07f2b5babcd656e0d6Karl Luc errno_t ret;
b696e806e85f1c07f2f5ea07f2b5babcd656e0d6Karl Luc struct sss_iface_addr *addrlist = NULL;
b696e806e85f1c07f2f5ea07f2b5babcd656e0d6Karl Luc
b696e806e85f1c07f2f5ea07f2b5babcd656e0d6Karl Luc check_leaks_push(dyndns_test_ctx);
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa ret = sss_iface_addr_list_get(dyndns_test_ctx, "non_existing_interface",
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa &addrlist);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa assert_int_equal(ret, ENOENT);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa talloc_free(addrlist);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa assert_true(check_leaks_pop(dyndns_test_ctx) == true);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa}
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksavoid dyndns_test_addr_list_as_str_list(void **state)
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa{
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa int i;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa char **output;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa errno_t ret;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa struct sss_iface_addr *addrlist;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa struct {
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa const char* addr;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa int af;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa } input[] = {
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa {"2001:cdba::555", AF_INET6},
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa {"192.168.0.1", AF_INET},
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa {"192.168.0.2", AF_INET},
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa {"2001:cdba::444", AF_INET6}
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa };
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa int size = 4;
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa check_leaks_push(dyndns_test_ctx);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa for (i = 0; i < size; i++) {
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa will_return_getifaddrs("eth0", input[i].addr, input[i].af);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa }
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa assert_int_equal(ret, EOK);
d5c6ddb570942f686319dcaf6c4b513a033e00ceEugen Kuksa
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc ret = sss_iface_addr_list_as_str_list(dyndns_test_ctx, addrlist, &output);
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc assert_int_equal(ret, EOK);
f2bb6f4c9f075b94e7f83a6589f457bc8b7fb30cEugen Kuksa for (i = 0; i < size; i++) {
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa /* addresses are returned in reversed order */
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_int_equal(strcmp(input[i].addr, output[size - 1 - i]), 0);
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa }
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa talloc_free(addrlist);
f2bb6f4c9f075b94e7f83a6589f457bc8b7fb30cEugen Kuksa talloc_free(output);
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc assert_true(check_leaks_pop(dyndns_test_ctx) == true);
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc}
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Lucvoid dyndns_test_dualstack(void **state)
2aa433939988fc34e3968ae0363fe628374fb3d2Karl Luc{
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa errno_t ret;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct sss_iface_addr *addrlist;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc struct sss_iface_addr *sss_if_addrs;
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc char straddr[128];
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc int i;
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa check_leaks_push(dyndns_test_ctx);
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc /* getifaddrs is called twice in sss_get_dualstack_addresses() */
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc for (i = 0; i < 2; i++) {
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
18741eef977546e24fce1fde1b8a8f817aedc6d0Christian Maeder will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa }
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa
823ce7a568b0f653ebe83af7ab6ac9ec70f2cf8eKarl Luc struct sockaddr_in sin;
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc memset (&sin, 0, sizeof (sin));
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa sin.sin_family = AF_INET;
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc ret = sss_get_dualstack_addresses(dyndns_test_ctx,
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa (struct sockaddr *) &sin,
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc &addrlist);
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc assert_int_equal(ret, EOK);
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa sss_if_addrs = addrlist;
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_non_null(sss_if_addrs);
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_non_null(sss_if_addrs->addr);
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_non_null(sss_if_addrs->next);
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_null(sss_if_addrs->prev);
cba0aeea95db26960d4d2e5a1dd571f17a5b7ae4Eugen Kuksa
08e520eb8e9947de926d733c48a13249c857f570Eugen Kuksa assert_non_null(inet_ntop(AF_INET6,
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
c51d1f5ff88cce030fe543e271ca6b85625b70d8Karl Luc straddr, INET6_ADDRSTRLEN));
1ea7fb6b0f66210bc0d3cb995f1b655277b33884Eugen Kuksa /* ip addresses are returned in different order */
07f731e693fe433a238b5cc0aab6c5c99c1da798Karl Luc assert_string_equal(straddr, "2001:cdba::555");
2c10bceb28a74fc291959697e023f22a66753655Eugen Kuksa
sss_if_addrs = addrlist->next;
assert_non_null(sss_if_addrs);
assert_non_null(sss_if_addrs->addr);
assert_null(sss_if_addrs->next);
assert_non_null(sss_if_addrs->prev);
assert_non_null(inet_ntop(AF_INET,
&((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
straddr, INET_ADDRSTRLEN));
/* ip addresses are returned in different order */
assert_string_equal(straddr, "192.168.0.2");
talloc_free(addrlist);
assert_true(check_leaks_pop(dyndns_test_ctx) == true);
}
void dyndns_test_dualstack_multiple_addresses(void **state)
{
errno_t ret;
struct sss_iface_addr *addrlist;
struct sss_iface_addr *sss_if_addrs;
char straddr[128];
int i;
check_leaks_push(dyndns_test_ctx);
/* getifaddrs is called twice in sss_get_dualstack_addresses() */
for (i = 0; i < 2; i++) {
will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
/* loopback - invalid for dns (should be skipped) */
will_return_getifaddrs("eth0", "::1", AF_INET6);
/* linklocal - invalid for dns (should be skipped) */
will_return_getifaddrs("eth0", "fe80::5054:ff:fe4a:65ae", AF_INET6);
will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6);
will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
}
struct sockaddr_in sin;
memset (&sin, 0, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
ret = sss_get_dualstack_addresses(dyndns_test_ctx,
(struct sockaddr *) &sin,
&addrlist);
assert_int_equal(ret, EOK);
sss_if_addrs = addrlist;
assert_non_null(sss_if_addrs);
assert_non_null(sss_if_addrs->addr);
assert_non_null(sss_if_addrs->next);
assert_null(sss_if_addrs->prev);
assert_non_null(inet_ntop(AF_INET6,
&((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
straddr, INET6_ADDRSTRLEN));
/* ip addresses are returned in different order */
assert_string_equal(straddr, "2001:cdba::444");
sss_if_addrs = sss_if_addrs->next;
assert_non_null(sss_if_addrs);
assert_non_null(sss_if_addrs->addr);
assert_non_null(sss_if_addrs->prev);
assert_non_null(sss_if_addrs->next);
assert_non_null(inet_ntop(AF_INET6,
&((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
straddr, INET6_ADDRSTRLEN));
/* ip addresses are returned in different order */
assert_string_equal(straddr, "2001:cdba::555");
sss_if_addrs = sss_if_addrs->next;
assert_non_null(sss_if_addrs);
assert_non_null(sss_if_addrs->addr);
assert_non_null(sss_if_addrs->next);
assert_non_null(sss_if_addrs->prev);
assert_non_null(inet_ntop(AF_INET,
&((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
straddr, INET_ADDRSTRLEN));
/* ip addresses are returned in different order */
assert_string_equal(straddr, "192.168.0.1");
sss_if_addrs = sss_if_addrs->next;
assert_non_null(sss_if_addrs);
assert_non_null(sss_if_addrs->addr);
assert_null(sss_if_addrs->next);
assert_non_null(sss_if_addrs->prev);
assert_non_null(inet_ntop(AF_INET,
&((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
straddr, INET_ADDRSTRLEN));
/* ip addresses are returned in different order */
assert_string_equal(straddr, "192.168.0.2");
talloc_free(addrlist);
assert_true(check_leaks_pop(dyndns_test_ctx) == true);
}
void dyndns_test_dualstack_no_iface(void **state)
{
errno_t ret;
struct sss_iface_addr *addrlist;
check_leaks_push(dyndns_test_ctx);
will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
struct sockaddr_in sin;
memset (&sin, 0, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr ("192.168.0.3");
ret = sss_get_dualstack_addresses(dyndns_test_ctx,
(struct sockaddr *) &sin,
&addrlist);
assert_int_equal(ret, ENOENT);
assert_true(check_leaks_pop(dyndns_test_ctx) == true);
}
void dyndns_test_ok(void **state)
{
struct tevent_req *req;
errno_t ret;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(global_talloc_context);
assert_non_null(tmp_ctx);
check_leaks_push(tmp_ctx);
dyndns_test_ctx->state = MOCK_NSUPDATE_OK;
req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
/* Wait until the test finishes with EOK */
ret = test_ev_loop(dyndns_test_ctx->tctx);
DEBUG(SSSDBG_TRACE_LIBS,
"Child request returned [%d]: %s\n", ret, strerror(ret));
assert_int_equal(ret, EOK);
assert_true(WIFEXITED(dyndns_test_ctx->child_status));
assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 0);
assert_true(check_leaks_pop(tmp_ctx) == true);
talloc_free(tmp_ctx);
}
void dyndns_test_error(void **state)
{
struct tevent_req *req;
errno_t ret;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(global_talloc_context);
assert_non_null(tmp_ctx);
check_leaks_push(tmp_ctx);
dyndns_test_ctx->state = MOCK_NSUPDATE_ERR;
req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
/* Wait until the test finishes with EIO (child error) */
ret = test_ev_loop(dyndns_test_ctx->tctx);
DEBUG(SSSDBG_TRACE_LIBS,
"Child request returned [%d]: %s\n", ret, strerror(ret));
assert_int_equal(ret, ERR_DYNDNS_FAILED);
assert_true(WIFEXITED(dyndns_test_ctx->child_status));
assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 1);
assert_true(check_leaks_pop(tmp_ctx) == true);
talloc_free(tmp_ctx);
}
void dyndns_test_timeout(void **state)
{
struct tevent_req *req;
errno_t ret;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(global_talloc_context);
assert_non_null(tmp_ctx);
check_leaks_push(tmp_ctx);
dyndns_test_ctx->state = MOCK_NSUPDATE_TIMEOUT;
req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
/* Wait until the test finishes with EIO (child error) */
ret = test_ev_loop(dyndns_test_ctx->tctx);
/* The event queue may not be empty. We need to make sure that all events
* are processed. Unfortunately, tevent_loop_wait() contains a bug that
* prevents exiting the loop even if there are no remaining events, thus
* we have to use tevent_loop_once().
*
* FIXME: use tevent_loop_wait() when the bug is fixed
* https://bugzilla.samba.org/show_bug.cgi?id=10012
*/
tevent_loop_once(dyndns_test_ctx->tctx->ev); /* SIGCHLD handler */
tevent_loop_once(dyndns_test_ctx->tctx->ev); /* nsupdate_child_handler */
DEBUG(SSSDBG_TRACE_LIBS,
"Child request returned [%d]: %s\n", ret, strerror(ret));
assert_int_equal(ret, ERR_DYNDNS_TIMEOUT);
assert_true(check_leaks_pop(tmp_ctx) == true);
talloc_free(tmp_ctx);
}
void dyndns_test_timer(void *pvt)
{
struct dyndns_test_ctx *ctx = talloc_get_type(pvt, struct dyndns_test_ctx);
static int ncalls = 0;
ncalls++;
if (ncalls == 1) {
be_nsupdate_timer_schedule(ctx->tctx->ev, ctx->update_ctx);
} else if (ncalls == 2) {
ctx->tctx->done = true;
}
ctx->tctx->error = ERR_OK;
}
void dyndns_test_interval(void **state)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(global_talloc_context);
assert_non_null(tmp_ctx);
check_leaks_push(tmp_ctx);
ret = be_nsupdate_init(tmp_ctx, dyndns_test_ctx->be_ctx, NULL,
&dyndns_test_ctx->update_ctx);
assert_int_equal(ret, EOK);
ret = be_nsupdate_init_timer(dyndns_test_ctx->update_ctx,
dyndns_test_ctx->be_ctx->ev,
dyndns_test_timer, dyndns_test_ctx);
assert_int_equal(ret, EOK);
/* Wait until the timer hits */
ret = test_ev_loop(dyndns_test_ctx->tctx);
DEBUG(SSSDBG_TRACE_LIBS,
"Child request returned [%d]: %s\n", ret, strerror(ret));
assert_int_equal(ret, ERR_OK);
talloc_free(dyndns_test_ctx->update_ctx);
assert_true(check_leaks_pop(tmp_ctx) == true);
talloc_free(tmp_ctx);
}
/* Testsuite setup and teardown */
static int dyndns_test_setup(void **state)
{
struct sss_test_conf_param params[] = {
{ "dyndns_update", "true" },
{ "dyndns_refresh_interval", "2" },
{ NULL, NULL }, /* Sentinel */
};
assert_true(leak_check_setup());
global_mock_context = talloc_new(global_talloc_context);
assert_non_null(global_mock_context);
dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx);
assert_non_null(dyndns_test_ctx);
dyndns_test_ctx->tctx = create_dom_test_ctx(dyndns_test_ctx, TESTS_PATH,
TEST_CONF_DB, TEST_DOM_NAME,
TEST_ID_PROVIDER, params);
assert_non_null(dyndns_test_ctx->tctx);
dyndns_test_ctx->be_ctx = mock_be_ctx(dyndns_test_ctx, dyndns_test_ctx->tctx);
assert_non_null(dyndns_test_ctx->be_ctx);
return 0;
}
static int dyndns_test_simple_setup(void **state)
{
assert_true(leak_check_setup());
global_mock_context = talloc_new(global_talloc_context);
assert_non_null(global_mock_context);
dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx);
assert_non_null(dyndns_test_ctx);
return 0;
}
static int dyndns_test_teardown(void **state)
{
talloc_free(dyndns_test_ctx);
talloc_free(global_mock_context);
assert_true(leak_check_teardown());
return 0;
}
int main(int argc, const char *argv[])
{
int rv;
int no_cleanup = 0;
poptContext pc;
int opt;
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_DEBUG_OPTS
{"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
_("Do not delete the test database after a test run"), NULL },
POPT_TABLEEND
};
const struct CMUnitTest tests[] = {
/* Utility functions unit test */
cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr,
dyndns_test_simple_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_get_multi_ifaddr,
dyndns_test_simple_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr_enoent,
dyndns_test_simple_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_addr_list_as_str_list,
dyndns_test_simple_setup,
dyndns_test_teardown),
/* Dynamic DNS update unit tests*/
cmocka_unit_test_setup_teardown(dyndns_test_ok,
dyndns_test_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_error,
dyndns_test_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_timeout,
dyndns_test_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_interval,
dyndns_test_setup,
dyndns_test_teardown),
/* Dynamic DNS dualstack unit tests*/
cmocka_unit_test_setup_teardown(dyndns_test_dualstack,
dyndns_test_simple_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_dualstack_multiple_addresses,
dyndns_test_simple_setup,
dyndns_test_teardown),
cmocka_unit_test_setup_teardown(dyndns_test_dualstack_no_iface,
dyndns_test_simple_setup,
dyndns_test_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
debug_level = SSSDBG_INVALID;
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
while((opt = poptGetNextOpt(pc)) != -1) {
switch(opt) {
default:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
poptPrintUsage(pc, stderr, 0);
return 1;
}
}
poptFreeContext(pc);
DEBUG_CLI_INIT(debug_level);
/* Even though normally the tests should clean up after themselves
* they might not after a failed run. Remove the old db to be sure */
tests_set_cwd();
test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
test_dom_suite_setup(TESTS_PATH);
rv = cmocka_run_group_tests(tests, NULL, NULL);
if (rv == 0 && !no_cleanup) {
test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
}
return rv;
}