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