From 8d5292227a8d1ab9c6aa5b88d8ac8655cd1223e5 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Dec 19 2016 22:28:55 +0000 Subject: nss: make nss responder tests work with new code There were few type of changes that were require for tests to work: 1) When calling "get by name" commands, a name is parsed with sss_parse_inp. Returned value is now mocked. 2) When calling "get by upn" commands, a name is parsed with sss_parse_inp and negative cache is not hit in the first run since cache_req knows it may be upn since it is not equal to any known domain. Returned value of sss_parse_inp is now mocked to return ERR_DOMAIN_NOT_FOUND and negative cache hits are checked to be 0. 3) Lookups by certificate or sid do not require name parsing so those have separate mock functions. 4) Sometime the test fail since different number of mocked functions is called due to changes in the code. Where possible, will_return_always() is used, otherwise number of mocked values was fixed. 5) In SID by name lookups, we set nss_test_ctx->tctx->done to false on the beggining of for cycle, since the code now contains tevent calls and withough it only a first request proceed into tevent_loop in test_ev_loop() because the first finished request sets it to true. Resolves: https://fedorahosted.org/sssd/ticket/3151 Reviewed-by: Lukáš Slebodník --- diff --git a/Makefile.am b/Makefile.am index 3484736..b60c6a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2115,9 +2115,16 @@ EXTRA_nss_srv_tests_DEPENDENCIES = \ nss_srv_tests_SOURCES = \ $(TEST_MOCK_RESP_OBJ) \ src/tests/cmocka/test_nss_srv.c \ - src/responder/nss/nsssrv_cmd.c \ - src/responder/nss/nsssrv_netgroup.c \ - src/responder/nss/nsssrv_services.c \ + src/responder/nss/nss_cmd.c \ + src/responder/nss/nss_enum.c \ + src/responder/nss/nss_get_object.c \ + src/responder/nss/nss_protocol.c \ + src/responder/nss/nss_protocol_pwent.c \ + src/responder/nss/nss_protocol_grent.c \ + src/responder/nss/nss_protocol_netgr.c \ + src/responder/nss/nss_protocol_svcent.c \ + src/responder/nss/nss_protocol_sid.c \ + src/responder/nss/nss_utils.c \ src/responder/nss/nsssrv_mmap_cache.c nss_srv_tests_CFLAGS = \ $(AM_CFLAGS) diff --git a/src/tests/cmocka/common_mock_resp.c b/src/tests/cmocka/common_mock_resp.c index dc03d39..88808b1 100644 --- a/src/tests/cmocka/common_mock_resp.c +++ b/src/tests/cmocka/common_mock_resp.c @@ -64,6 +64,7 @@ mock_cctx(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx) if (!cctx) return NULL; cctx->rctx = rctx; + cctx->ev = rctx->ev; return cctx; } diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c index 2e35757..14e4fa6 100644 --- a/src/tests/cmocka/test_negcache.c +++ b/src/tests/cmocka/test_negcache.c @@ -33,8 +33,7 @@ #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" -#include "responder/nss/nsssrv.h" -#include "responder/nss/nsssrv_private.h" +#include "responder/nss/nss_private.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/util_sss_idmap.h" #include "lib/idmap/sss_idmap.h" diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c index 1e64a0b..715a61e 100644 --- a/src/tests/cmocka/test_nss_srv.c +++ b/src/tests/cmocka/test_nss_srv.c @@ -28,8 +28,8 @@ #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "responder/common/negcache.h" -#include "responder/nss/nsssrv.h" -#include "responder/nss/nsssrv_private.h" +#include "responder/nss/nss_private.h" +#include "responder/nss/nss_protocol.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/util_sss_idmap.h" #include "util/crypto/sss_crypto.h" @@ -213,10 +213,53 @@ int __wrap_sss_ncache_check_cert(struct sss_nc_ctx *ctx, const char *cert) } /* Mock input from the client library */ -static void mock_input_user_or_group(const char *username) +static void mock_input_user_or_group(const char *input) +{ + const char *copy; + const char *shortname; + const char *domname; + char *separator; + + copy = talloc_strdup(nss_test_ctx, input); + assert_non_null(copy); + + separator = strrchr(copy, '@'); + if (separator == NULL) { + shortname = input; + domname = NULL; + } else { + *separator = '\0'; + shortname = copy; + domname = separator + 1; + } + + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); + will_return(__wrap_sss_packet_get_body, input); + will_return(__wrap_sss_packet_get_body, 0); + + mock_parse_inp(shortname, domname, EOK); +} + +static void mock_input_upn(const char *upn) +{ + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); + will_return(__wrap_sss_packet_get_body, upn); + will_return(__wrap_sss_packet_get_body, 0); + + mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); +} + +static void mock_input_sid(const char *sid) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); - will_return(__wrap_sss_packet_get_body, username); + will_return(__wrap_sss_packet_get_body, sid); + will_return(__wrap_sss_packet_get_body, 0); +} + +static void mock_input_cert(const char *cert) +{ + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); + will_return(__wrap_sss_packet_get_body, cert); will_return(__wrap_sss_packet_get_body, 0); } @@ -246,30 +289,6 @@ static void mock_fill_bysid(void) will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); } -static void mock_fill_initgr_user(void) -{ - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -} - -static void mock_fill_group_with_members(unsigned members) -{ - unsigned i; - - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); - - if (members == 0) return; - - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); - - /* Member header , one per member */ - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); - for (i=0; itctx->done = false; + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); @@ -2054,6 +2075,8 @@ void test_nss_well_known_getsidbyname_nonexisting(void **state) size_t c; for (c = 0; names[c] != NULL; c++) { + nss_test_ctx->tctx->done = false; + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); @@ -2079,6 +2102,8 @@ void test_nss_well_known_getsidbyname_special(void **state) size_t c; for (c = 0; names[c] != NULL; c++) { + nss_test_ctx->tctx->done = false; + will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); @@ -2207,7 +2232,7 @@ void test_nss_getorigbyname(void **state) /* Also test looking up the same stuff with UPN */ nss_test_ctx->tctx->done = false; - mock_input_user_or_group(test_upn); + mock_input_upn(test_upn); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); @@ -2518,7 +2543,7 @@ void test_nss_getpwnam_upn(void **state) &upn_user, attrs, 0); assert_int_equal(ret, EOK); - mock_input_user_or_group("upnuser@upndomain.test"); + mock_input_upn("upnuser@upndomain.test"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); @@ -2540,7 +2565,7 @@ void test_nss_getpwnam_upn_neg(void **state) { errno_t ret; - mock_input_user_or_group("nosuchupnuser@upndomain.test"); + mock_input_upn("nosuchupnuser@upndomain.test"); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); @@ -2553,7 +2578,7 @@ void test_nss_getpwnam_upn_neg(void **state) /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); - assert_int_equal(nss_test_ctx->ncache_hits, 1); + assert_int_equal(nss_test_ctx->ncache_hits, 0); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand @@ -2562,7 +2587,7 @@ void test_nss_getpwnam_upn_neg(void **state) nss_test_ctx->tctx->done = false; nss_test_ctx->ncache_hits = 0; - mock_input_user_or_group("nosuchupnuser@upndomain.test"); + mock_input_upn("nosuchupnuser@upndomain.test"); set_cmd_cb(NULL); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); @@ -2653,7 +2678,7 @@ void test_nss_initgroups(void **state) mock_input_user_or_group("testinitgr"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); - mock_fill_initgr_user(); + will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_initgr_check); @@ -2673,7 +2698,11 @@ void test_initgr_neg_by_name(const char *name, bool is_upn) { errno_t ret; - mock_input_user_or_group(name); + if (is_upn) { + mock_input_upn(name); + } else { + mock_input_user_or_group(name); + } mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); @@ -2686,8 +2715,7 @@ void test_initgr_neg_by_name(const char *name, bool is_upn) /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); - /* UPN lookup will first hit negcache with the username */ - assert_int_equal(nss_test_ctx->ncache_hits, is_upn ? 1 : 0); + assert_int_equal(nss_test_ctx->ncache_hits, 0); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand @@ -2696,7 +2724,11 @@ void test_initgr_neg_by_name(const char *name, bool is_upn) nss_test_ctx->tctx->done = false; nss_test_ctx->ncache_hits = 0; - mock_input_user_or_group(name); + if (is_upn) { + mock_input_upn(name); + } else { + mock_input_user_or_group(name); + } set_cmd_cb(NULL); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); @@ -2799,7 +2831,7 @@ void test_nss_initgr_search(void **state) mock_input_user_or_group("testinitgr_srch"); mock_account_recv(0, 0, NULL, test_nss_initgr_search_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); - mock_fill_initgr_user(); + will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_nss_initgr_search_check); ret = get_user(nss_test_ctx, nss_test_ctx->tctx->dom, @@ -2919,7 +2951,7 @@ void test_nss_initgr_update(void **state) mock_input_user_or_group("testinitgr_update"); mock_account_recv(0, 0, NULL, test_nss_initgr_update_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); - mock_fill_initgr_user(); + will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_nss_initgr_update_check); /* Query for that user, call a callback when command finishes */ @@ -3041,7 +3073,7 @@ void test_nss_initgr_update_two_expire_attributes(void **state) test_nss_initgr_update_acct_2expire_attributes_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); - mock_fill_initgr_user(); + will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_nss_initgr_update_2expire_attributes_check); /* Query for that user, call a callback when command finishes */ @@ -3058,9 +3090,9 @@ void test_nss_initgroups_upn(void **state) { errno_t ret; - mock_input_user_or_group("upninitgr@upndomain.test"); + mock_input_upn("upninitgr@upndomain.test"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); - mock_fill_initgr_user(); + will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_initgr_check); @@ -3207,7 +3239,7 @@ static void test_nss_getnamebysid(void **state) &testbysid, attrs, 0); assert_int_equal(ret, EOK); - mock_input_user_or_group(user_sid); + mock_input_sid(user_sid); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); mock_fill_bysid(); @@ -3235,7 +3267,7 @@ void test_nss_getnamebysid_neg(void **state) nss_test_ctx->tctx->dom->domain_id); assert_non_null(user_sid); - mock_input_user_or_group(user_sid); + mock_input_sid(user_sid); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); @@ -3256,7 +3288,7 @@ void test_nss_getnamebysid_neg(void **state) */ nss_test_ctx->tctx->done = false; - mock_input_user_or_group(user_sid); + mock_input_sid(user_sid); set_cmd_cb(NULL); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); @@ -3335,7 +3367,7 @@ void test_nss_getnamebysid_update(void **state) assert_int_equal(ret, EOK); /* Mock client input */ - mock_input_user_or_group(user_sid); + mock_input_sid(user_sid); /* Mock client command */ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); /* Call this function when user is updated by the mock DP request */ @@ -3439,7 +3471,7 @@ static void test_nss_getnamebycert(void **state) assert_int_equal(ret, EOK); talloc_free(attrs); - mock_input_user_or_group(TEST_TOKEN_CERT); + mock_input_cert(TEST_TOKEN_CERT); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYCERT); mock_fill_bysid(); @@ -3459,7 +3491,7 @@ void test_nss_getnamebycert_neg(void **state) { errno_t ret; - mock_input_user_or_group(TEST_TOKEN_CERT); + mock_input_cert(TEST_TOKEN_CERT); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); @@ -3480,7 +3512,7 @@ void test_nss_getnamebycert_neg(void **state) */ nss_test_ctx->tctx->done = false; - mock_input_user_or_group(TEST_TOKEN_CERT); + mock_input_cert(TEST_TOKEN_CERT); set_cmd_cb(NULL); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYCERT, nss_test_ctx->nss_cmds); @@ -3582,7 +3614,7 @@ void test_nss_getsidbyupn(void **state) &sid_user, attrs, 0); assert_int_equal(ret, EOK); - mock_input_user_or_group(testuser_upn); + mock_input_upn(testuser_upn); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);