test_child_common.c revision 57c5ea8825c7179fd93382dbcbb07e828e5aec19
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek Copyright (C) 2014 Red Hat
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek SSSD tests: Child handlers
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek This program is free software; you can redistribute it and/or modify
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek it under the terms of the GNU General Public License as published by
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek (at your option) any later version.
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek This program is distributed in the hope that it will be useful,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek GNU General Public License for more details.
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek You should have received a copy of the GNU General Public License
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx = talloc(global_talloc_context, struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->test_ctx = create_ev_test_ctx(child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "from_child: %d:%d\n",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "Failed to wait for children %d\n", child_pid);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_tctx->save_debug_timestamps = debug_timestamps;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekstatic int only_extra_args_teardown(void **state)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek debug_timestamps = child_tctx->save_debug_timestamps;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_test_teardown((void **) &child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic void extra_args_test(struct child_test_ctx *child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek const char *extra_args[] = { "--guitar=george",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "--drums=ringo",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "Failed to wait for children %d\n", child_pid);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Make sure extra arguments are passed correctly */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek setenv("TEST_CHILD_ACTION", "check_extra_args", 1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Make sure extra arguments are passed correctly */
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_exec_child_only_extra_args(void **state)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args", 1);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_exec_child_only_extra_args_neg(void **state)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args_neg", 1);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek const char *input);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekstatic void echo_child_write_done(struct tevent_req *subreq);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekstatic void echo_child_read_done(struct tevent_req *subreq);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek/* Test that writing to the pipes works as expected */
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Test that writing to the pipes works as expected */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Test that writing to the pipes works as expected */
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek DEBUG(SSSDBG_FUNC_DATA, "Forked into %d\n", child_pid);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek sss_fd_nonblocking(io_fds->read_from_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek req = echo_child_write_send(child_tctx, child_tctx, io_fds, ECHO_STR);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek req = tevent_req_create(mem_ctx, &echo_state, struct test_exec_echo_state);
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek echo_state->buf.data = (unsigned char *) talloc_strdup(echo_state, input);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek subreq = write_pipe_send(child_tctx, child_tctx->test_ctx->ev,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek tevent_req_set_callback(subreq, echo_child_write_done, req);
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozekstatic void echo_child_write_done(struct tevent_req *subreq)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek echo_state = tevent_req_data(req, struct test_exec_echo_state);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek tevent_req_set_callback(subreq, echo_child_read_done, req);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic void echo_child_read_done(struct tevent_req *subreq)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek req = tevent_req_callback_data(subreq, struct tevent_req);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state = tevent_req_data(req, struct test_exec_echo_state);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = read_pipe_recv(subreq, echo_state, &buf, &len);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek assert_string_equal(buf, echo_state->buf.data);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->child_test_ctx->test_ctx->done = true;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = sss_sigchld_init(child_tctx, child_tctx->test_ctx->ev, &sc_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_extra_args,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_io_destruct,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_handler,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_echo,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_sss_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args_neg,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek /* Set debug level to invalid value so we can decide if -d 0 was used. */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);