On Tue, Jun 03, 2014 at 09:34:29AM +0200, Lukas Slebodnik wrote: > On (02/06/14 20:12), Jakub Hrozek wrote: > >Hi, > > > >this is another prerequisite to having the IFP responder in sssd-1-11. > >Only Makefile.am had to be changed. > > >From ae989d7793117078fa63e67c68eaade71ca38ad6 Mon Sep 17 00:00:00 2001 > >From: Jakub Hrozek <jhro...@redhat.com> > >Date: Fri, 18 Apr 2014 14:58:57 +0200 > >Subject: [PATCH 1/3] TESTS: Create a default sss_names_ctx in > > create_dom_test_ctx > >MIME-Version: 1.0 > >Content-Type: text/plain; charset=UTF-8 > >Content-Transfer-Encoding: 8bit > > > >This would allow to call create_dom_test_ctx from tests that expect to > >be able to parse input with a regular expression just like a responder > >would do with an input from a client. > > > >Reviewed-by: Pavel Březina <pbrez...@redhat.com> > > > >(cherry picked from commit e4b4b669e0c1ef5ec3be04768edf2565a7bac5a1) > > > >Conflicts: > > src/tests/common.h > >--- > > src/tests/common.h | 2 ++ > > src/tests/common_dom.c | 12 ++++++++++++ > > 2 files changed, 14 insertions(+) > > > >diff --git a/src/tests/common.h b/src/tests/common.h > >index > >ba3b3a7490ec5bd0e75c5f2f66c39542ca0c37ee..0b19168379b398e68b7acf9921d6d52f21fc55ec > > 100644 > >--- a/src/tests/common.h > >+++ b/src/tests/common.h > >@@ -62,6 +62,8 @@ struct sss_test_ctx { > > struct confdb_ctx *confdb; > > struct tevent_context *ev; > > struct sss_domain_info *dom; > >+ struct sss_names_ctx *nctx; > >+ char *confdb_path; > You added confdb_path to strunct sss_test_ctx, but you did not baackported > other changes from commit > > commit 5a22be7f84f85d6b25aa277ac78ee34fac95dd42 > Author: Pavel Březina <pbrez...@redhat.com> > Date: Tue Feb 18 13:34:32 2014 +0100 > > tests: add confdb_path to sss_test_ctx > > LS
OK, attached are patches with Pavel's patch included as well.
>From 76529d437a967ccc2255ed2c226eb0082225c9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Tue, 18 Feb 2014 13:34:32 +0100 Subject: [PATCH 1/4] tests: add confdb_path to sss_test_ctx Reviewed-by: Jakub Hrozek <jhro...@redhat.com> --- src/tests/common.h | 1 + src/tests/common_dom.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tests/common.h b/src/tests/common.h index ba3b3a7490ec5bd0e75c5f2f66c39542ca0c37ee..7cdecb92a937ff8899ab98c1c1fe8b8dfc7ca1a0 100644 --- a/src/tests/common.h +++ b/src/tests/common.h @@ -62,6 +62,7 @@ struct sss_test_ctx { struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *dom; + char *confdb_path; bool done; int error; diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c index c0b44456c819501b500ed87ffb3a6e089ef3b2dd..42bf358a3e13e9102fde0134762a76038dc3fcff 100644 --- a/src/tests/common_dom.c +++ b/src/tests/common_dom.c @@ -35,7 +35,6 @@ create_dom_test_ctx(TALLOC_CTX *mem_ctx, struct sss_test_conf_param *params) { struct sss_test_ctx *test_ctx; - char *conf_db; size_t i; const char *val[2]; val[1] = NULL; @@ -48,14 +47,15 @@ create_dom_test_ctx(TALLOC_CTX *mem_ctx, goto fail; } - conf_db = talloc_asprintf(test_ctx, "%s/%s", tests_path, confdb_path); - if (conf_db == NULL) { + test_ctx->confdb_path = talloc_asprintf(test_ctx, "%s/%s", + tests_path, confdb_path); + if (test_ctx->confdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); goto fail; } /* Connect to the conf db */ - ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); + ret = confdb_init(test_ctx, &test_ctx->confdb, test_ctx->confdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "confdb_init failed: %d\n", ret); goto fail; -- 1.9.0
>From 8ae906b5d47c441b1b0fbe408c87ca2ab7e3bd5b Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 18 Apr 2014 14:58:57 +0200 Subject: [PATCH 2/4] TESTS: Create a default sss_names_ctx in create_dom_test_ctx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This would allow to call create_dom_test_ctx from tests that expect to be able to parse input with a regular expression just like a responder would do with an input from a client. Reviewed-by: Pavel Březina <pbrez...@redhat.com> (cherry picked from commit e4b4b669e0c1ef5ec3be04768edf2565a7bac5a1) Conflicts: src/tests/common.h --- src/tests/common.h | 1 + src/tests/common_dom.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/tests/common.h b/src/tests/common.h index 7cdecb92a937ff8899ab98c1c1fe8b8dfc7ca1a0..0b19168379b398e68b7acf9921d6d52f21fc55ec 100644 --- a/src/tests/common.h +++ b/src/tests/common.h @@ -62,6 +62,7 @@ struct sss_test_ctx { struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *dom; + struct sss_names_ctx *nctx; char *confdb_path; bool done; diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c index 42bf358a3e13e9102fde0134762a76038dc3fcff..1e7de8f229eed54fb48beabd749d575c35debe0c 100644 --- a/src/tests/common_dom.c +++ b/src/tests/common_dom.c @@ -105,6 +105,18 @@ create_dom_test_ctx(TALLOC_CTX *mem_ctx, } test_ctx->sysdb = test_ctx->dom->sysdb; + /* Init with an AD-style regex to be able to test flat name */ + ret = sss_names_init_from_args(test_ctx, + "(((?P<domain>[^\\\\]+)\\\\(?P<name>.+$))|" \ + "((?P<name>[^@]+)@(?P<domain>.+$))|" \ + "(^(?P<name>[^@\\\\]+)$))", + "%1$s@%2$s", &test_ctx->nctx); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "cannot create names context\n"); + goto fail; + } + test_ctx->dom->names = test_ctx->nctx; + return test_ctx; fail: -- 1.9.0
>From 25ea38c05246c267a4e28815a557337c2c039e1a Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Fri, 18 Apr 2014 15:01:55 +0200 Subject: [PATCH 3/4] TESTS: Split a separate common_mock_resp_dp module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Splitting the module would allow responders that test the Data Provider requests to use the mock_rctx/mock_cctx functions without duplicate definitions. Reviewed-by: Pavel Březina <pbrez...@redhat.com> (cherry picked from commit c440c424443517b12afa8d56f989d92ca6ba56a3) --- Makefile.am | 1 + src/tests/cmocka/common_mock_resp.c | 71 ---------------------- .../{common_mock_resp.c => common_mock_resp_dp.c} | 52 +++------------- 3 files changed, 8 insertions(+), 116 deletions(-) copy src/tests/cmocka/{common_mock_resp.c => common_mock_resp_dp.c} (73%) diff --git a/Makefile.am b/Makefile.am index 329b0986192518414337a6d2dbbc4db172945925..3996a905431972b4df65600fb5b7e4879f6fe90a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1358,6 +1358,7 @@ if HAVE_CMOCKA TEST_MOCK_RESP_OBJ = \ src/tests/cmocka/common_mock_resp.c \ + src/tests/cmocka/common_mock_resp_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c \ src/responder/common/negcache.c \ diff --git a/src/tests/cmocka/common_mock_resp.c b/src/tests/cmocka/common_mock_resp.c index d74f6ffa7a76d2f80fc7cbcf46ecf9ac5bcc9878..767d4d7e1455d0998e6511cefa595ec6238ba07d 100644 --- a/src/tests/cmocka/common_mock_resp.c +++ b/src/tests/cmocka/common_mock_resp.c @@ -66,74 +66,3 @@ mock_cctx(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx) cctx->rctx = rctx; return cctx; } - -/* Mock DP requests that finish immediatelly and return - * mocked values as per previous set by mock_account_recv - */ -struct tevent_req * -sss_dp_get_account_send(TALLOC_CTX *mem_ctx, - struct resp_ctx *rctx, - struct sss_domain_info *dom, - bool fast_reply, - enum sss_dp_acct_type type, - const char *opt_name, - uint32_t opt_id, - const char *extra) -{ - return test_req_succeed_send(mem_ctx, rctx->ev); -} - - -errno_t -sss_dp_get_account_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - dbus_uint16_t *dp_err, - dbus_uint32_t *dp_ret, - char **err_msg) -{ - acct_cb_t cb; - - *dp_err = sss_mock_type(dbus_uint16_t); - *dp_ret = sss_mock_type(dbus_uint32_t); - *dp_ret = sss_mock_type(dbus_uint32_t); - - cb = sss_mock_ptr_type(acct_cb_t); - if (cb) { - (cb)(sss_mock_ptr_type(void *)); - } - - return test_request_recv(req); -} - -void mock_account_recv(uint16_t dp_err, uint32_t dp_ret, char *msg, - acct_cb_t acct_cb, void *pvt) -{ - will_return(sss_dp_get_account_recv, dp_err); - will_return(sss_dp_get_account_recv, dp_ret); - will_return(sss_dp_get_account_recv, msg); - - will_return(sss_dp_get_account_recv, acct_cb); - if (acct_cb) { - will_return(sss_dp_get_account_recv, pvt); - } -} - -void mock_account_recv_simple(void) -{ - return mock_account_recv(0, 0, NULL, NULL, NULL); -} - -/* Mock subdomain requests */ -struct tevent_req * -sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, - struct resp_ctx *rctx, - bool force, - const char *hint) -{ - return test_req_succeed_send(mem_ctx, rctx->ev); -} - -errno_t sss_dp_get_domains_recv(struct tevent_req *req) -{ - return test_request_recv(req); -} diff --git a/src/tests/cmocka/common_mock_resp.c b/src/tests/cmocka/common_mock_resp_dp.c similarity index 73% copy from src/tests/cmocka/common_mock_resp.c copy to src/tests/cmocka/common_mock_resp_dp.c index d74f6ffa7a76d2f80fc7cbcf46ecf9ac5bcc9878..40fa7c94f39047934900ae1245df1ef5203d94b9 100644 --- a/src/tests/cmocka/common_mock_resp.c +++ b/src/tests/cmocka/common_mock_resp_dp.c @@ -4,7 +4,7 @@ Copyright (C) 2013 Red Hat - SSSD tests: Common utilities for tests that exercise domains + SSSD tests: Fake Data Provider requests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,50 +23,6 @@ #include "util/util.h" #include "tests/cmocka/common_mock_resp.h" -/* Mock a responder context */ -struct resp_ctx * -mock_rctx(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sss_domain_info *domains, - void *pvt_ctx) -{ - struct resp_ctx *rctx; - errno_t ret; - - rctx = talloc_zero(mem_ctx, struct resp_ctx); - if (!rctx) return NULL; - - ret = sss_hash_create(rctx, 30, &rctx->dp_request_table); - if (ret != EOK) { - talloc_free(rctx); - return NULL; - } - - rctx->ev = ev; - rctx->domains = domains; - rctx->pvt_ctx = pvt_ctx; - return rctx; -} - -/* Mock a client context */ -struct cli_ctx * -mock_cctx(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx) -{ - struct cli_ctx *cctx; - - cctx = talloc_zero(mem_ctx, struct cli_ctx); - if (!cctx) return NULL; - - cctx->creq = talloc_zero(cctx, struct cli_request); - if (cctx->creq == NULL) { - talloc_free(cctx); - return NULL; - } - - cctx->rctx = rctx; - return cctx; -} - /* Mock DP requests that finish immediatelly and return * mocked values as per previous set by mock_account_recv */ @@ -123,6 +79,12 @@ void mock_account_recv_simple(void) return mock_account_recv(0, 0, NULL, NULL, NULL); } +void mock_parse_inp(const char *name, const char *domname) +{ + will_return(sss_parse_inp_recv, name); + will_return(sss_parse_inp_recv, domname); +} + /* Mock subdomain requests */ struct tevent_req * sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, -- 1.9.0
>From d1a88ab525de6ac63cbdb4879e7f142c19cc76e7 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Tue, 15 Apr 2014 17:24:55 +0200 Subject: [PATCH 4/4] RESPONDERS: Add a new request sss_parse_inp_send MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The responders were copying code to parse input and on encountering an uknown domain, send the discover subdomain request. This patch adds a reusable request that can always be called in responders and in case the name can be parsed, just shortcut. Reviewed-by: Pavel Březina <pbrez...@redhat.com> (cherry picked from commit 7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926) Conflicts: Makefile.am --- Makefile.am | 17 ++ src/responder/common/responder.h | 7 + src/responder/common/responder_get_domains.c | 121 ++++++++++ src/tests/cmocka/common_mock_resp_dp.c | 16 ++ src/tests/cmocka/test_nss_srv.c | 2 +- src/tests/cmocka/test_responder_common.c | 319 +++++++++++++++++++++++++++ src/util/util_errors.c | 1 + src/util/util_errors.h | 1 + 8 files changed, 483 insertions(+), 1 deletion(-) create mode 100644 src/tests/cmocka/test_responder_common.c diff --git a/Makefile.am b/Makefile.am index 3996a905431972b4df65600fb5b7e4879f6fe90a..1aef2647bd3a11dc4494fb38103b2aec45f5ccbf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -162,6 +162,7 @@ if HAVE_CMOCKA ad_access_filter_tests \ ad_common_tests \ dp_opt_tests \ + responder-get-domains-tests \ test_search_bases endif @@ -1388,6 +1389,22 @@ nss_srv_tests_LDADD = \ libsss_test_common.la \ libsss_idmap.la +EXTRA_responder_get_domains_tests_DEPENDENCIES = \ + $(ldblib_LTLIBRARIES) +responder_get_domains_tests_SOURCES = \ + src/responder/common/responder_get_domains.c \ + src/tests/cmocka/test_responder_common.c \ + src/tests/cmocka/common_mock_resp.c +responder_get_domains_tests_CFLAGS = \ + $(AM_CFLAGS) +responder_get_domains_tests_LDFLAGS = \ + -Wl,-wrap,sss_parse_name_for_domains +responder_get_domains_tests_LDADD = \ + $(CMOCKA_LIBS) \ + $(SSSD_LIBS) \ + $(SSSD_INTERNAL_LTLIBS) \ + libsss_test_common.la + test_find_uid_DEPENDENCIES = \ $(ldblib_LTLIBRARIES) test_find_uid_SOURCES = \ diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 44249b007d4e9ec52b6c13080fea8dfd5b8e565d..c2440b1325b4f74e5368d69fca2a288101aefaf2 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -311,4 +311,11 @@ errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string, errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, uid_t *allowed_uids); + +struct tevent_req * +sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *rawinp); +errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **_name, char **_domname); + #endif /* __SSS_RESPONDER_H__ */ diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c index 23b274b52a6e704afd41686f3bb2491698aea3eb..253728b260ac0b537d28a081aca5f1cc92797d35 100644 --- a/src/responder/common/responder_get_domains.c +++ b/src/responder/common/responder_get_domains.c @@ -421,3 +421,124 @@ errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, return EOK; } + +struct sss_parse_inp_state { + struct resp_ctx *rctx; + const char *rawinp; + + char *name; + char *domname; +}; + +static void sss_parse_inp_done(struct tevent_req *subreq); + +struct tevent_req * +sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *rawinp) +{ + errno_t ret; + struct tevent_req *req; + struct tevent_req *subreq; + struct sss_parse_inp_state *state; + + req = tevent_req_create(mem_ctx, &state, struct sss_parse_inp_state); + if (req == NULL) { + return NULL; + } + state->rawinp = rawinp; + state->rctx = rctx; + + /* If the subdomains haven't been checked yet, we need to always + * attach to the post-startup subdomain request and only then parse + * the input. Otherwise, we might not be able to parse input with a + * flat domain name specifier */ + if (rctx->get_domains_last_call.tv_sec > 0) { + ret = sss_parse_name_for_domains(state, rctx->domains, + rctx->default_domain, rawinp, + &state->domname, &state->name); + if (ret == EOK) { + /* Was able to use cached domains */ + goto done; + } else if (ret != EAGAIN) { + DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawinp); + ret = ERR_INPUT_PARSE; + goto done; + } + } + + /* EAGAIN - check the DP for subdomains */ + + DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s] from [%s]\n", + state->name, state->domname ? state->domname : "<ALL>"); + + /* We explicitly use force=false here. This request should decide itself + * if it's time to re-use the cached subdomain list or refresh. If the + * caller needs to specify the 'force' parameter, they should use the + * sss_dp_get_domains_send() request itself + */ + subreq = sss_dp_get_domains_send(state, rctx, false, state->domname); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + tevent_req_set_callback(subreq, sss_parse_inp_done, req); + return req; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, rctx->ev); + return req; +} + +static void sss_parse_inp_done(struct tevent_req *subreq) +{ + errno_t ret; + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sss_parse_inp_state *state = tevent_req_data(req, + struct sss_parse_inp_state); + + ret = sss_dp_get_domains_recv(subreq); + talloc_free(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = sss_parse_name_for_domains(state, state->rctx->domains, + state->rctx->default_domain, + state->rawinp, + &state->domname, &state->name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Invalid name received [%s]\n", state->rawinp); + tevent_req_error(req, ERR_INPUT_PARSE); + return; + } + + /* Was able to parse the name now */ + tevent_req_done(req); +} + +errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **_name, char **_domname) +{ + struct sss_parse_inp_state *state = tevent_req_data(req, + struct sss_parse_inp_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + if (_name) { + *_name = talloc_steal(mem_ctx, state->name); + } + + if (_domname) { + *_domname = talloc_steal(mem_ctx, state->domname); + } + + return EOK; +} diff --git a/src/tests/cmocka/common_mock_resp_dp.c b/src/tests/cmocka/common_mock_resp_dp.c index 40fa7c94f39047934900ae1245df1ef5203d94b9..08d74179d8e2dc0561ea3e2d1e9b5580762ee633 100644 --- a/src/tests/cmocka/common_mock_resp_dp.c +++ b/src/tests/cmocka/common_mock_resp_dp.c @@ -79,6 +79,22 @@ void mock_account_recv_simple(void) return mock_account_recv(0, 0, NULL, NULL, NULL); } +struct tevent_req * +sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *rawinp) +{ + return test_req_succeed_send(mem_ctx, rctx->ev); +} + +errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **_name, char **_domname) +{ + *_name = sss_mock_ptr_type(char *); + *_domname = sss_mock_ptr_type(char *); + + return test_request_recv(req); +} + void mock_parse_inp(const char *name, const char *domname) { will_return(sss_parse_inp_recv, name); diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index e2e81a65ffd71562ba328be6e5ecca6471ae68cb..3ef6da87cec166b57feca16d3f7ef36c49748e5e 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -4,7 +4,7 @@ Copyright (C) 2013 Red Hat - SSSD tests: Common utilities for tests that exercise domains + SSSD tests: NSS responder tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/tests/cmocka/test_responder_common.c b/src/tests/cmocka/test_responder_common.c new file mode 100644 index 0000000000000000000000000000000000000000..58aa32b5d0d56091b58c7ea256831ee3746b3935 --- /dev/null +++ b/src/tests/cmocka/test_responder_common.c @@ -0,0 +1,319 @@ +/* + Authors: + Jakub Hrozek <jhro...@redhat.com> + + Copyright (C) 2014 Red Hat + + SSSD tests: Common responder code tests + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> +#include <tevent.h> +#include <errno.h> +#include <popt.h> + +#include "tests/cmocka/common_mock.h" +#include "tests/cmocka/common_mock_resp.h" + +#define TESTS_PATH "tests_responder" +#define TEST_CONF_DB "test_responder_conf.ldb" +#define TEST_DOM_NAME "responder_test" +#define TEST_SYSDB_FILE "cache_"TEST_DOM_NAME".ldb" +#define TEST_ID_PROVIDER "ldap" + +#define NAME "username" + +static void +mock_sss_dp_done(struct tevent_context *ev, + struct tevent_immediate *imm, + void *pvt); + +errno_t +sss_dp_issue_request(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *strkey, struct sss_domain_info *dom, + dbus_msg_constructor msg_create, void *pvt, + struct tevent_req *nreq) +{ + struct tevent_immediate *imm; + + imm = tevent_create_immediate(rctx->ev); + if (imm == NULL) { + return ENOMEM; + } + tevent_schedule_immediate(imm, rctx->ev, mock_sss_dp_done, nreq); + return EOK; +} + +static void +mock_sss_dp_done(struct tevent_context *ev, + struct tevent_immediate *imm, + void *pvt) +{ + struct tevent_req *req; + + talloc_free(imm); + req = talloc_get_type(pvt, struct tevent_req); + tevent_req_done(req); +} + +errno_t +sss_dp_req_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *sidereq, + dbus_uint16_t *dp_err, + dbus_uint32_t *dp_ret, + char **err_msg) +{ + return EOK; +} + +struct parse_inp_test_ctx { + struct sss_test_ctx *tctx; + struct resp_ctx *rctx; +}; + +void parse_inp_test_setup(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx; + + check_leaks_push(global_talloc_context); + + parse_inp_ctx = talloc_zero(global_talloc_context, struct parse_inp_test_ctx); + assert_non_null(parse_inp_ctx); + + parse_inp_ctx->tctx = create_dom_test_ctx(parse_inp_ctx, TESTS_PATH, + TEST_CONF_DB, TEST_SYSDB_FILE, TEST_DOM_NAME, + TEST_ID_PROVIDER, NULL); + assert_non_null(parse_inp_ctx->tctx); + + parse_inp_ctx->rctx = mock_rctx(parse_inp_ctx, + parse_inp_ctx->tctx->ev, + parse_inp_ctx->tctx->dom, + parse_inp_ctx); + assert_non_null(parse_inp_ctx->rctx); + + /* Testing the request race condition should be a special case */ + gettimeofday(&parse_inp_ctx->rctx->get_domains_last_call, NULL); + + check_leaks_push(parse_inp_ctx); + *state = parse_inp_ctx; +} + +void parse_inp_test_teardown(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); + + assert_true(check_leaks_pop(parse_inp_ctx) == true); + + talloc_free(parse_inp_ctx); + assert_true(check_leaks_pop(global_talloc_context) == true); +} + +int __real_sss_parse_name_for_domains(TALLOC_CTX *memctx, + struct sss_domain_info *domains, + const char *default_domain, + const char *orig, char **domain, char **name); + +int __wrap_sss_parse_name_for_domains(TALLOC_CTX *memctx, + struct sss_domain_info *domains, + const char *default_domain, + const char *orig, char **domain, char **name) +{ + enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call); + errno_t ret; + + if (wtype == WRAP_CALL_REAL) { + return __real_sss_parse_name_for_domains(memctx, domains, + default_domain, orig, + domain, name); + } + + ret = sss_mock_type(errno_t); + return ret; +} + +void parse_inp_simple_done(struct tevent_req *req) +{ + errno_t ret; + struct parse_inp_test_ctx *parse_inp_ctx = + tevent_req_callback_data(req, struct parse_inp_test_ctx); + char *name = NULL; + char *domname = NULL; + + ret = sss_parse_inp_recv(req, parse_inp_ctx, &name, &domname); + parse_inp_ctx->tctx->done = true; + assert_int_equal(ret, EOK); + talloc_free(req); + + assert_string_equal(name, NAME); + assert_null(domname); + talloc_free(name); +} + +void parse_inp_simple(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); + struct tevent_req *req; + errno_t ret; + + will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); + + req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); + assert_non_null(req); + tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); + + ret = test_ev_loop(parse_inp_ctx->tctx); + assert_int_equal(ret, EOK); +} + +void parse_inp_call_dp(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); + struct tevent_req *req; + errno_t ret; + + /* First call will indicate we need to go to DP */ + will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_WRAPPER); + will_return(__wrap_sss_parse_name_for_domains, EAGAIN); + /* The second one will succeed as the domains are up-to-date */ + will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); + + req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); + assert_non_null(req); + tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); + + ret = test_ev_loop(parse_inp_ctx->tctx); + assert_int_equal(ret, EOK); +} + +void parse_inp_call_attach(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); + struct tevent_req *req; + errno_t ret; + + /* simulate responder startup */ + parse_inp_ctx->rctx->get_domains_last_call.tv_sec = 0; + + /* The first parse wouldn't be called, the second one will succeed + * as the domains are up-to-date */ + will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); + + req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); + assert_non_null(req); + tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); + + ret = test_ev_loop(parse_inp_ctx->tctx); + assert_int_equal(ret, EOK); +} + +void parse_inp_neg_done(struct tevent_req *req) +{ + errno_t ret; + struct parse_inp_test_ctx *parse_inp_ctx = + tevent_req_callback_data(req, struct parse_inp_test_ctx); + char *name = NULL; + char *domname = NULL; + + ret = sss_parse_inp_recv(req, parse_inp_ctx, &name, &domname); + parse_inp_ctx->tctx->done = true; + assert_int_equal(ret, ERR_INPUT_PARSE); + talloc_free(req); + + assert_null(name); + assert_null(domname); +} + +void parse_inp_call_neg(void **state) +{ + struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, + struct parse_inp_test_ctx); + struct tevent_req *req; + errno_t ret; + + /* Simulate an error */ + will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_WRAPPER); + will_return(__wrap_sss_parse_name_for_domains, EINVAL); + + req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); + assert_non_null(req); + tevent_req_set_callback(req, parse_inp_neg_done, parse_inp_ctx); + + ret = test_ev_loop(parse_inp_ctx->tctx); + assert_int_equal(ret, EOK); +} + +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 UnitTest tests[] = { + unit_test_setup_teardown(parse_inp_simple, + parse_inp_test_setup, + parse_inp_test_teardown), + unit_test_setup_teardown(parse_inp_call_dp, + parse_inp_test_setup, + parse_inp_test_teardown), + unit_test_setup_teardown(parse_inp_call_attach, + parse_inp_test_setup, + parse_inp_test_teardown), + unit_test_setup_teardown(parse_inp_call_neg, + parse_inp_test_setup, + parse_inp_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_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_SYSDB_FILE); + test_dom_suite_setup(TESTS_PATH); + + rv = run_tests(tests); + if (rv == 0 && !no_cleanup) { + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_SYSDB_FILE); + } + return rv; +} diff --git a/src/util/util_errors.c b/src/util/util_errors.c index c9b507557da07555c719bb0dd18145e6799a53eb..8dd4380b423ef75cd246933ec739e232094e9b37 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -48,6 +48,7 @@ struct err_string error_to_str[] = { { "Dynamic DNS update failed" }, /* ERR_DYNDNS_FAILED */ { "Dynamic DNS update timed out" }, /* ERR_DYNDNS_TIMEOUT */ { "Dynamic DNS update not possible while offline" }, /* ERR_DYNDNS_OFFLINE */ + { "Cannot parse input" }, /* ERR_INPUT_PARSE */ { "Entry not found" }, /* ERR_NOT_FOUND */ { "Domain not found" }, /* ERR_DOMAIN_NOT_FOUND */ { "Missing configuration file" }, /* ERR_MISSING_CONF */ diff --git a/src/util/util_errors.h b/src/util/util_errors.h index 3dd94af1f304d65e22515c859c6f69a021fa7e92..23048990da1e101397ae6bc9d5957133c1ea65af 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -70,6 +70,7 @@ enum sssd_errors { ERR_DYNDNS_FAILED, ERR_DYNDNS_TIMEOUT, ERR_DYNDNS_OFFLINE, + ERR_INPUT_PARSE, ERR_NOT_FOUND, ERR_DOMAIN_NOT_FOUND, ERR_MISSING_CONF, -- 1.9.0
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel