test_fo_srv.c revision a299f900981343904d7c9c5d148e30b8e0b2c460
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/*
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen Authors:
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen Jakub Hrozek <jhrozek@redhat.com>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen Copyright (C) 2014 Red Hat
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen SSSD tests: Resolver tests using a fake resolver library
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen This program is free software; you can redistribute it and/or modify
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen it under the terms of the GNU General Public License as published by
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen the Free Software Foundation; either version 3 of the License, or
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen (at your option) any later version.
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen This program is distributed in the hope that it will be useful,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen GNU General Public License for more details.
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen You should have received a copy of the GNU General Public License
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen*/
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen#include <talloc.h>
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen#include <tevent.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <errno.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <popt.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <arpa/inet.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <netinet/in.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <sys/types.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <stdarg.h>
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include <stdlib.h>
6307d76096764e66bddc63d4a3e5a1aa19cc528fJosef 'Jeff' Sipek
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include "providers/fail_over_srv.h"
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include "tests/cmocka/common_mock.h"
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#include "tests/cmocka/common_mock_resp.h"
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#define TEST_RESOLV_TIMEOUT 5
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#define TEST_FO_TIMEOUT 3000
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#define TEST_SRV_TTL 500
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen#define TEST_SRV_SHORT_TTL 2
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
d28179fd78550a58be44dcb1e3e830ab7d33172dTimo Sirainenstatic TALLOC_CTX *global_mock_context = NULL;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenenum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL };
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct resolv_ctx {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen int foo;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen};
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen/* mock resolver interface. The resolver test is separate */
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenint resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen int timeout, struct resolv_ctx **ctxp)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
573424407a2d3c1453638a643583a7cf10c129e1Phil Carmody *ctxp = talloc(mem_ctx, struct resolv_ctx);
573424407a2d3c1453638a643583a7cf10c129e1Phil Carmody return EOK;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct tevent_req *
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenresolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct resolv_ctx *ctx, const char *name,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen enum restrict_family family_order,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen enum host_database *db)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return test_req_succeed_send(mem_ctx, ev);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenint resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen int *status, int *timeouts,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct resolv_hostent **rhostent)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
b9e830a81455faf3c0dadfc9dbf0c7dc8aca955cJosef 'Jeff' Sipek return test_request_recv(req);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenconst char *resolv_strerror(int ares_code)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return NULL;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct tevent_req *resolv_discover_srv_send(TALLOC_CTX *mem_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct tevent_context *ev,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct resolv_ctx *resolv_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen const char *service,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen const char *protocol,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen const char **discovery_domains)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return test_req_succeed_send(mem_ctx, ev);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenerrno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct tevent_req *req,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply **_reply_list,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen uint32_t *_ttl,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen char **_dns_domain)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *reply_list;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen uint32_t ttl;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen char *dns_domain;
d868a04630bd7bfe9c1543a7c3f68703b3e276e4Timo Sirainen
d868a04630bd7bfe9c1543a7c3f68703b3e276e4Timo Sirainen /* Need to always consume all mocked values */
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen reply_list = sss_mock_ptr_type(struct ares_srv_reply *);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen ttl = sss_mock_ptr_type(uint32_t);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen dns_domain = sss_mock_ptr_type(char *);
131b0d222ad89b2c5d2b03b865b45cae9e290d68Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (_reply_list != NULL) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen *_reply_list = reply_list;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (_ttl != NULL) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen *_ttl = ttl;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (_dns_domain != NULL) {
b9e830a81455faf3c0dadfc9dbf0c7dc8aca955cJosef 'Jeff' Sipek *_dns_domain = dns_domain;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return test_request_recv(req);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct ares_srv_reply *pop_lowest_prio(struct ares_srv_reply **r)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *lowest;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *iter;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *prev;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen lowest = *r;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen iter = lowest;
9184983183ae28fb543695c54c85bc5396c07e42Phil Carmody while (iter != NULL) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (iter->priority < lowest->priority) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen lowest = iter;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen iter = iter->next;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen prev = NULL;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen iter = *r;
b7cabbb8fd1d662008faf20d2ec93e4be51f1e96Timo Sirainen while (iter != lowest) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen prev = iter;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen iter = iter->next;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen /* iter points to the lowest prio. Prev points to the item before */
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (prev) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen prev->next = lowest->next;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen } else {
0928812e725cd3a4debab2a93d0c9b0436a4de9fTimo Sirainen *r = lowest->next;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return lowest;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenint resolv_sort_srv_reply(struct ares_srv_reply **reply)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *r;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *lowest;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *sorted = NULL;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct ares_srv_reply *sorted_head = NULL;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen r = *reply;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (r == NULL || r->next == NULL) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return EOK;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen do {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen lowest = pop_lowest_prio(&r);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (sorted) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen sorted->next = lowest;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen sorted = sorted->next;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen } else {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen sorted = lowest;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen sorted_head = sorted;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen } while (r != NULL);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen *reply = sorted_head;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return EOK;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct tevent_req *resolv_get_domain_send(TALLOC_CTX *mem_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct tevent_context *ev,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct resolv_ctx *resolv_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen const char *hostname,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen enum host_database *host_dbs,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen enum restrict_family family_order)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return test_req_succeed_send(mem_ctx, ev);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenerrno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct tevent_req *req,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen char **_dns_domain)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return test_request_recv(req);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen/* The unit test */
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstruct test_fo_ctx {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct resolv_ctx *resolv;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_ctx *fo_ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_resolve_srv_dns_ctx *srv_ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_service *fo_svc;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct sss_test_ctx *ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen int ttl;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_server *srv;
9dadffcd2545eab4b251e83b60cee78ceb1e8362Anton Yuzhaninov
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen int num_done;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen};
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenint test_fo_srv_data_cmp(void *ud1, void *ud2)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return strcasecmp((char*) ud1, (char*) ud2);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
9dadffcd2545eab4b251e83b60cee78ceb1e8362Anton Yuzhaninovstatic int test_fo_setup(void **state)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct test_fo_ctx *test_ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen errno_t ret;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_options fopts;
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen assert_true(leak_check_setup());
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen global_mock_context = talloc_new(global_talloc_context);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(global_mock_context);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_ctx = talloc_zero(global_mock_context,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct test_fo_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(test_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_ctx->ctx = create_ev_test_ctx(test_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(test_ctx->ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen ret = resolv_init(test_ctx, test_ctx->ctx->ev,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen TEST_RESOLV_TIMEOUT, &test_ctx->resolv);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(test_ctx->resolv);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen memset(&fopts, 0, sizeof(fopts));
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen fopts.retry_timeout = TEST_FO_TIMEOUT;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen fopts.family_order = IPV4_FIRST;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_ctx->fo_ctx = fo_context_init(test_ctx, &fopts);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(test_ctx->fo_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen ret = fo_new_service(test_ctx->fo_ctx, "ldap",
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_fo_srv_data_cmp,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen &test_ctx->fo_svc);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_int_equal(ret, ERR_OK);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen *state = test_ctx;
2c0f1cb7a0564d48ec43c7315ea46ea38d2abd19Timo Sirainen return 0;
2c0f1cb7a0564d48ec43c7315ea46ea38d2abd19Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
2c0f1cb7a0564d48ec43c7315ea46ea38d2abd19Timo Sirainenstatic int test_fo_teardown(void **state)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct test_fo_ctx *test_ctx =
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen talloc_get_type(*state, struct test_fo_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen talloc_free(test_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen talloc_free(global_mock_context);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_true(leak_check_teardown());
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return 0;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic int test_fo_srv_setup(void **state)
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct test_fo_ctx *test_ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen bool ok;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_fo_setup(state);
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen test_ctx = *state;
7f74811b78f8915e73dffc88bb49009e98b6846dTimo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_ctx->srv_ctx = fo_resolve_srv_dns_ctx_init(test_ctx, test_ctx->resolv,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen IPV4_FIRST, default_host_dbs,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen "client.sssd.com", "sssd.local");
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(test_ctx->srv_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen ok = fo_set_srv_lookup_plugin(test_ctx->fo_ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen fo_resolve_srv_dns_send,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen fo_resolve_srv_dns_recv,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_ctx->srv_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_true(ok);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen *state = test_ctx;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return 0;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic int test_fo_srv_teardown(void **state)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen test_fo_teardown(state);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen return 0;
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen/* reply_list and dns_domain must be a talloc context so it can be used as
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen * talloc_steal argument later
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen */
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic void mock_srv_results(struct ares_srv_reply *reply_list,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen uint32_t ttl,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen char *dns_domain)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen will_return(resolv_discover_srv_recv, reply_list);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen will_return(resolv_discover_srv_recv, ttl);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen will_return(resolv_discover_srv_recv, dns_domain);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic void check_server(struct test_fo_ctx *ctx,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen struct fo_server *srv,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen int port,
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen const char *name)
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen{
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_non_null(srv);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_int_equal(fo_get_server_port(srv), port);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_string_equal(fo_get_server_name(srv), name);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen if (ctx->srv_ctx) {
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen assert_true(fo_is_srv_lookup(srv));
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen }
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen}
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainen
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic void test_fo_srv_step1(struct test_fo_ctx *test_ctx);
a49d1c2ca3c134c0c62b37a94936c78e9849e044Timo Sirainenstatic void test_fo_srv_done1(struct tevent_req *req);
static void test_fo_srv_done2(struct tevent_req *req);
static void test_fo_srv_done3(struct tevent_req *req);
static void test_fo_srv_done4(struct tevent_req *req);
static void test_fo_srv_done5(struct tevent_req *req);
struct ares_srv_reply *
mock_ares_reply(TALLOC_CTX *mem_ctx, const char *hostname,
int weight, int priority, int port)
{
struct ares_srv_reply *s;
s = talloc_zero(mem_ctx, struct ares_srv_reply);
if (s == NULL) {
return NULL;
}
s->host = talloc_strdup(s, hostname);
if (s->host == NULL) {
talloc_free(s);
return NULL;
}
s->weight = weight;
s->priority = priority;
s->port = port;
return s;
}
static void test_fo_srv_mock_dns(struct test_fo_ctx *test_ctx,
int ttl)
{
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389);
assert_non_null(s1);
s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
assert_non_null(s2);
s1->next = s2;
dns_domain = talloc_strdup(test_ctx, "sssd.com");
assert_non_null(dns_domain);
mock_srv_results(s1, ttl, dns_domain);
}
static void test_fo_srv(void **state)
{
errno_t ret;
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL);
ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com",
"sssd.local", "tcp", test_ctx);
assert_int_equal(ret, ERR_OK);
test_fo_srv_step1(test_ctx);
ret = test_ev_loop(test_ctx->ctx);
assert_int_equal(ret, ERR_OK);
}
static void test_fo_srv_step1(struct test_fo_ctx *test_ctx)
{
struct tevent_req *req;
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_done1, test_ctx);
}
static void test_fo_srv_done1(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* ldap1.sssd.com has lower priority, it must always be first */
check_server(test_ctx, srv, 389, "ldap1.sssd.com");
/* Mark the server as working and request the service again. The same server
* must be returned */
fo_set_server_status(srv, SERVER_WORKING);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_done2, test_ctx);
}
static void test_fo_srv_done2(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* Must be ldap1 again */
check_server(test_ctx, srv, 389, "ldap1.sssd.com");
/* Mark it at wrong, next lookup should yield ldap2 */
fo_set_server_status(srv, SERVER_NOT_WORKING);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_done3, test_ctx);
}
static void test_fo_srv_done3(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* Must be ldap2 now */
check_server(test_ctx, srv, 389, "ldap2.sssd.com");
/* Mark is at wrong, next lookup must reach the end of the server list */
fo_set_server_status(srv, SERVER_NOT_WORKING);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_done4, test_ctx);
}
static void test_fo_srv_done4(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
/* No servers are left..*/
assert_int_equal(ret, ENOENT);
/* reset the server status and try again.. */
fo_reset_servers(test_ctx->fo_svc);
if (test_ctx->srv_ctx) {
test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL);
}
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_done5, test_ctx);
}
static void test_fo_srv_done5(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* ldap1.sssd.com has lower priority, it must always be first */
check_server(test_ctx, srv, 389, "ldap1.sssd.com");
/* OK, we made a full circle with the test, done */
test_ctx->ctx->error = ERR_OK;
test_ctx->ctx->done = true;
}
/* Make sure that two queries more than TTL seconds apart resolve
* into two different lists
*/
static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx);
static void test_fo_srv_before(struct tevent_req *req);
static void test_fo_srv_after(struct tevent_req *req);
void test_fo_srv_ttl_change(void **state)
{
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
test_ctx->ttl = TEST_SRV_SHORT_TTL;
test_fo_srv_ttl_change_step(test_ctx);
}
static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx)
{
errno_t ret;
struct tevent_req *req;
test_fo_srv_mock_dns(test_ctx, test_ctx->ttl);
ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com",
"sssd.local", "tcp", test_ctx);
assert_int_equal(ret, ERR_OK);
ret = fo_add_server(test_ctx->fo_svc, "ldap1.sssd.com",
389, (void *) discard_const("ldap://ldap1.sssd.com"),
true);
assert_int_equal(ret, ERR_OK);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_before, test_ctx);
ret = test_ev_loop(test_ctx->ctx);
assert_int_equal(ret, ERR_OK);
}
static void test_fo_srv_before(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
errno_t ret;
ret = fo_resolve_service_recv(req, test_ctx, &test_ctx->srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
DEBUG(SSSDBG_TRACE_FUNC, "Before TTL change\n");
check_server(test_ctx, test_ctx->srv, 389, "ldap1.sssd.com");
fo_set_server_status(test_ctx->srv, SERVER_WORKING);
/* Simulate changing the DNS environment. Change the host names */
s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 2, 389);
assert_non_null(s1);
s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 1, 389);
assert_non_null(s2);
s1->next = s2;
dns_domain = talloc_strdup(test_ctx, "sssd.com");
assert_non_null(dns_domain);
mock_srv_results(s1, test_ctx->ttl, dns_domain);
sleep(test_ctx->ttl + 1);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_after, test_ctx);
}
static void test_fo_srv_after2(struct tevent_req *req);
static void test_fo_srv_after(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* Try accessing server from a previous iteration. The
* server should be collapsed, but at least we shouldn't crash
*/
fo_set_server_status(test_ctx->srv, SERVER_WORKING);
sleep(test_ctx->ttl + 1);
/* Must be a different server now */
check_server(test_ctx, srv, 389, "ldap2.sssd.com");
/* Simulate changing the DNS environment. Change the host names */
s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389);
assert_non_null(s1);
s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
assert_non_null(s2);
s1->next = s2;
dns_domain = talloc_strdup(test_ctx, "sssd.com");
assert_non_null(dns_domain);
mock_srv_results(s1, test_ctx->ttl, dns_domain);
sleep(test_ctx->ttl + 1);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_after2, test_ctx);
}
static void test_fo_srv_after2(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
/* Must be a different server now */
check_server(test_ctx, srv, 389, "ldap1.sssd.com");
test_ctx->ctx->error = ERR_OK;
test_ctx->ctx->done = true;
}
void test_fo_srv_ttl_zero(void **state)
{
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
test_ctx->ttl = 0;
test_fo_srv_ttl_change_step(test_ctx);
}
static void test_fo_hostlist(void **state)
{
errno_t ret;
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
ret = fo_add_server(test_ctx->fo_svc,
"ldap1.sssd.com", 389, test_ctx, true);
assert_int_equal(ret, ERR_OK);
ret = fo_add_server(test_ctx->fo_svc,
"ldap2.sssd.com", 389, test_ctx, true);
assert_int_equal(ret, ERR_OK);
test_fo_srv_step1(test_ctx);
ret = test_ev_loop(test_ctx->ctx);
assert_int_equal(ret, ERR_OK);
}
static void test_fo_srv_dup_done(struct tevent_req *req);
/* Test that running two parallel SRV queries doesn't return an error.
* This is a regression test for https://fedorahosted.org/sssd/ticket/3131
*/
void test_fo_srv_duplicates(void **state)
{
errno_t ret;
struct tevent_req *req;
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
test_fo_srv_mock_dns(test_ctx, test_ctx->ttl);
test_fo_srv_mock_dns(test_ctx, test_ctx->ttl);
ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com",
"sssd.local", "tcp", test_ctx);
assert_int_equal(ret, ERR_OK);
ret = fo_add_server(test_ctx->fo_svc, "ldap1.sssd.com",
389, (void *) discard_const("ldap://ldap1.sssd.com"),
true);
assert_int_equal(ret, ERR_OK);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_dup_done, test_ctx);
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
test_ctx->resolv, test_ctx->fo_ctx,
test_ctx->fo_svc);
assert_non_null(req);
tevent_req_set_callback(req, test_fo_srv_dup_done, test_ctx);
ret = test_ev_loop(test_ctx->ctx);
assert_int_equal(ret, ERR_OK);
}
static void test_fo_srv_dup_done(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
errno_t ret;
const char *name;
ret = fo_resolve_service_recv(req, test_ctx, &test_ctx->srv);
talloc_zfree(req);
assert_int_equal(ret, EOK);
name = fo_get_server_name(test_ctx->srv);
assert_string_equal(name, "ldap1.sssd.com");
test_ctx->num_done++;
if (test_ctx->num_done == 2) {
test_ctx->ctx->error = ERR_OK;
test_ctx->ctx->done = true;
}
}
int main(int argc, const char *argv[])
{
int rv;
poptContext pc;
int opt;
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_DEBUG_OPTS
POPT_TABLEEND
};
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(test_fo_hostlist,
test_fo_setup,
test_fo_teardown),
cmocka_unit_test_setup_teardown(test_fo_srv,
test_fo_srv_setup,
test_fo_srv_teardown),
cmocka_unit_test_setup_teardown(test_fo_srv_ttl_change,
test_fo_srv_setup,
test_fo_srv_teardown),
cmocka_unit_test_setup_teardown(test_fo_srv_ttl_zero,
test_fo_srv_setup,
test_fo_srv_teardown),
cmocka_unit_test_setup_teardown(test_fo_srv_duplicates,
test_fo_srv_setup,
test_fo_srv_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();
rv = cmocka_run_group_tests(tests, NULL, NULL);
return rv;
}