From 1f861441042380362345d8ce3f9e81151664c6c0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 21 Sep 2015 12:31:38 +0200
Subject: [PATCH 95/96] FO: Also reset the server common data in addition to
SRV
In a server that is expanded from a SRV query was reset, only it's
'meta-server' status was set to neutral, but the server->common
structure still retained its not_working status.
This patch also resets the status of the common structure so that both
the SRV query and resolving the server are retried next time.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 6ac6e8f83da241458742b7f8a3406ed66bded292)
---
src/providers/fail_over.c | 4 +-
src/tests/cmocka/test_fo_srv.c | 188 ++++++++++++++++++++++++++++++-----------
2 files changed, 142 insertions(+), 50 deletions(-)
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 562f0b3fd7870387a80c889b245cda0d39dea509..b076687ac6e571f7e27402fd11ac60183ea46951 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -1554,7 +1554,9 @@ void fo_reset_servers(struct fo_service *service)
DLIST_FOR_EACH(server, service->server_list) {
if (server->srv_data != NULL) {
set_srv_data_status(server->srv_data, SRV_NEUTRAL);
- } else {
+ }
+
+ if (server->common) {
fo_set_server_status(server, SERVER_NAME_NOT_RESOLVED);
}
diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c
index e5c5e4fe3b818ca2df0ab7bcd1a83719fefba191..e892bab0a261779363ea78a10038b15acefc49b7 100644
--- a/src/tests/cmocka/test_fo_srv.c
+++ b/src/tests/cmocka/test_fo_srv.c
@@ -194,7 +194,7 @@ errno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx,
}
/* The unit test */
-struct test_fo_srv_ctx {
+struct test_fo_ctx {
struct resolv_ctx *resolv;
struct fo_ctx *fo_ctx;
struct fo_resolve_srv_dns_ctx *srv_ctx;
@@ -208,19 +208,18 @@ int test_fo_srv_data_cmp(void *ud1, void *ud2)
return strcasecmp((char*) ud1, (char*) ud2);
}
-static int test_fo_srv_setup(void **state)
+static int test_fo_setup(void **state)
{
- struct test_fo_srv_ctx *test_ctx;
+ struct test_fo_ctx *test_ctx;
errno_t ret;
struct fo_options fopts;
- bool ok;
assert_true(leak_check_setup());
global_mock_context = talloc_new(global_talloc_context);
assert_non_null(global_mock_context);
test_ctx = talloc_zero(global_mock_context,
- struct test_fo_srv_ctx);
+ struct test_fo_ctx);
assert_non_null(test_ctx);
test_ctx->ctx = create_ev_test_ctx(test_ctx);
@@ -237,6 +236,34 @@ static int test_fo_srv_setup(void **state)
test_ctx->fo_ctx = fo_context_init(test_ctx, &fopts);
assert_non_null(test_ctx->fo_ctx);
+ ret = fo_new_service(test_ctx->fo_ctx, "ldap",
+ test_fo_srv_data_cmp,
+ &test_ctx->fo_svc);
+ assert_int_equal(ret, ERR_OK);
+
+ *state = test_ctx;
+ return 0;
+}
+
+static int test_fo_teardown(void **state)
+{
+ struct test_fo_ctx *test_ctx =
+ talloc_get_type(*state, struct test_fo_ctx);
+
+ talloc_free(test_ctx);
+ talloc_free(global_mock_context);
+ assert_true(leak_check_teardown());
+ return 0;
+}
+
+static int test_fo_srv_setup(void **state)
+{
+ struct test_fo_ctx *test_ctx;
+ bool ok;
+
+ test_fo_setup(state);
+ test_ctx = *state;
+
test_ctx->srv_ctx = fo_resolve_srv_dns_ctx_init(test_ctx, test_ctx->resolv,
IPV4_FIRST, default_host_dbs,
"client.sssd.com", "sssd.local");
@@ -248,23 +275,13 @@ static int test_fo_srv_setup(void **state)
test_ctx->srv_ctx);
assert_true(ok);
- ret = fo_new_service(test_ctx->fo_ctx, "ldap",
- test_fo_srv_data_cmp,
- &test_ctx->fo_svc);
- assert_int_equal(ret, ERR_OK);
-
*state = test_ctx;
return 0;
}
static int test_fo_srv_teardown(void **state)
{
- struct test_fo_srv_ctx *test_ctx =
- talloc_get_type(*state, struct test_fo_srv_ctx);
-
- talloc_free(test_ctx);
- talloc_free(global_mock_context);
- assert_true(leak_check_teardown());
+ test_fo_teardown(state);
return 0;
}
@@ -280,25 +297,30 @@ static void mock_srv_results(struct ares_srv_reply *reply_list,
will_return(resolv_discover_srv_recv, dns_domain);
}
-static void check_server(struct fo_server *srv, int port, const char *name)
+static void check_server(struct test_fo_ctx *ctx,
+ struct fo_server *srv,
+ int port,
+ const char *name)
{
assert_non_null(srv);
- assert_true(fo_is_srv_lookup(srv));
assert_int_equal(fo_get_server_port(srv), port);
assert_string_equal(fo_get_server_name(srv), name);
+
+
+ if (ctx->srv_ctx) {
+ assert_true(fo_is_srv_lookup(srv));
+ }
}
+static void test_fo_srv_step1(struct test_fo_ctx *test_ctx);
static 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);
-void test_fo_srv(void **state)
+static void test_fo_srv_mock_dns(struct test_fo_ctx *test_ctx)
{
- errno_t ret;
- struct tevent_req *req;
- struct test_fo_srv_ctx *test_ctx =
- talloc_get_type(*state, struct test_fo_srv_ctx);
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
@@ -325,25 +347,41 @@ void test_fo_srv(void **state)
assert_non_null(dns_domain);
mock_srv_results(s1, TEST_SRV_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);
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);
-
- ret = test_ev_loop(test_ctx->ctx);
- assert_int_equal(ret, ERR_OK);
}
static void test_fo_srv_done1(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
@@ -352,7 +390,7 @@ static void test_fo_srv_done1(struct tevent_req *req)
assert_int_equal(ret, ERR_OK);
/* ldap1.sssd.com has lower priority, it must always be first */
- check_server(srv, 389, "ldap1.sssd.com");
+ 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 */
@@ -367,8 +405,8 @@ static void test_fo_srv_done1(struct tevent_req *req)
static void test_fo_srv_done2(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
@@ -377,7 +415,7 @@ static void test_fo_srv_done2(struct tevent_req *req)
assert_int_equal(ret, ERR_OK);
/* Must be ldap1 again */
- check_server(srv, 389, "ldap1.sssd.com");
+ 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);
@@ -391,8 +429,8 @@ static void test_fo_srv_done2(struct tevent_req *req)
static void test_fo_srv_done3(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
@@ -401,7 +439,7 @@ static void test_fo_srv_done3(struct tevent_req *req)
assert_int_equal(ret, ERR_OK);
/* Must be ldap2 now */
- check_server(srv, 389, "ldap2.sssd.com");
+ 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);
@@ -415,8 +453,8 @@ static void test_fo_srv_done3(struct tevent_req *req)
static void test_fo_srv_done4(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
@@ -425,6 +463,35 @@ static void test_fo_srv_done4(struct tevent_req *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);
+ }
+
+ 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, &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;
}
@@ -432,20 +499,20 @@ static void test_fo_srv_done4(struct tevent_req *req)
/* 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_srv_ctx *test_ctx);
+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_srv_ctx *test_ctx =
- talloc_get_type(*state, struct test_fo_srv_ctx);
+ 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_srv_ctx *test_ctx)
+static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx)
{
errno_t ret;
struct tevent_req *req;
@@ -497,8 +564,8 @@ static void test_fo_srv_ttl_change_step(struct test_fo_srv_ctx *test_ctx)
static void test_fo_srv_before(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
@@ -511,7 +578,7 @@ static void test_fo_srv_before(struct tevent_req *req)
DEBUG(SSSDBG_TRACE_FUNC, "Before TTL change\n");
- check_server(srv, 389, "ldap1.sssd.com");
+ check_server(test_ctx, srv, 389, "ldap1.sssd.com");
fo_set_server_status(srv, SERVER_WORKING);
/* Simulate changing the DNS environment. Change the host names */
@@ -548,8 +615,8 @@ static void test_fo_srv_before(struct tevent_req *req)
static void test_fo_srv_after(struct tevent_req *req)
{
- struct test_fo_srv_ctx *test_ctx = \
- tevent_req_callback_data(req, struct test_fo_srv_ctx);
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
@@ -558,7 +625,7 @@ static void test_fo_srv_after(struct tevent_req *req)
assert_int_equal(ret, ERR_OK);
/* Must be a different server now */
- check_server(srv, 389, "ldap3.sssd.com");
+ check_server(test_ctx, srv, 389, "ldap3.sssd.com");
test_ctx->ctx->error = ERR_OK;
test_ctx->ctx->done = true;
@@ -566,13 +633,33 @@ static void test_fo_srv_after(struct tevent_req *req)
void test_fo_srv_ttl_zero(void **state)
{
- struct test_fo_srv_ctx *test_ctx =
- talloc_get_type(*state, struct test_fo_srv_ctx);
+ 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);
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -585,6 +672,9 @@ int main(int argc, const char *argv[])
};
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),
--
2.4.3