test_child_common.c revision 57c5ea8825c7179fd93382dbcbb07e828e5aec19
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/*
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek Authors:
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek Copyright (C) 2014 Red Hat
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek SSSD tests: Child handlers
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek
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
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
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/>.
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek*/
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek#include <talloc.h>
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek#include <tevent.h>
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek#include <errno.h>
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek#include <popt.h>
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek#include "util/child_common.h"
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek#include "tests/cmocka/common_mock.h"
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek#define TEST_BIN "dummy-child"
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek#define ECHO_STR "Hello child"
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic int destructor_called;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstruct child_test_ctx {
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek int pipefd_to_child[2];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int pipefd_from_child[2];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek struct sss_test_ctx *test_ctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int save_debug_timestamps;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek};
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekstatic int child_test_setup(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno_t ret;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_true(leak_check_setup());
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx = talloc(global_talloc_context, struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->test_ctx = create_ev_test_ctx(child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(child_tctx->test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = pipe(child_tctx->pipefd_from_child);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(ret, -1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "from_child: %d:%d\n",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_from_child[0],
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_from_child[1]);
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek ret = pipe(child_tctx->pipefd_to_child);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek assert_int_not_equal(ret, -1);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "to_child: %d:%d\n",
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_tctx->pipefd_to_child[0],
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_tctx->pipefd_to_child[1]);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek *state = child_tctx;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek return 0;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek}
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic int child_test_teardown(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_free(child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_true(leak_check_teardown());
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid test_exec_child(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek errno_t ret;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek pid_t child_pid;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int status;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid = fork();
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(child_pid, -1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (child_pid == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek exec_child(child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_to_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_from_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } else {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek do {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = waitpid(child_pid, &status, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } while (ret == -1 && errno == EINTR);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (ret > 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = EIO;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (WIFEXITED(status)) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = WEXITSTATUS(status);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } else {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_FUNC_DATA,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "Failed to wait for children %d\n", child_pid);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = EIO;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic int only_extra_args_setup(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno_t ret;
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_test_setup((void **) &child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (ret != 0) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek return ret;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek }
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_tctx->save_debug_timestamps = debug_timestamps;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek *state = child_tctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek return 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekstatic int only_extra_args_teardown(void **state)
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek{
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek struct child_test_ctx);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek errno_t ret;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek debug_timestamps = child_tctx->save_debug_timestamps;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_test_teardown((void **) &child_tctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (ret != 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return ret;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic void extra_args_test(struct child_test_ctx *child_tctx,
f10ebaa51ecdcbbd10f171d19fe8e680e5bc74aaJakub Hrozek bool extra_args_only)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek pid_t child_pid;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno_t ret;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int status;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek const char *extra_args[] = { "--guitar=george",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "--drums=ringo",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek NULL };
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid = fork();
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(child_pid, -1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (child_pid == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek debug_timestamps = 1;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek exec_child_ex(child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_to_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_from_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2, extra_args,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek extra_args_only,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek STDIN_FILENO, STDOUT_FILENO);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } else {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek do {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = waitpid(child_pid, &status, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } while (ret == -1 && errno == EINTR);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (ret > 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = EIO;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (WIFEXITED(status)) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = WEXITSTATUS(status);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek } else {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_FUNC_DATA,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek "Failed to wait for children %d\n", child_pid);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = EIO;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Make sure extra arguments are passed correctly */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid test_exec_child_extra_args(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek setenv("TEST_CHILD_ACTION", "check_extra_args", 1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek extra_args_test(child_tctx, false);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Make sure extra arguments are passed correctly */
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_exec_child_only_extra_args(void **state)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek{
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args", 1);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek extra_args_test(child_tctx, true);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_exec_child_only_extra_args_neg(void **state)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek{
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek setenv("TEST_CHILD_ACTION", "check_only_extra_args_neg", 1);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek extra_args_test(child_tctx, false);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_io_fds *io_fds,
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
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekint __real_child_io_destructor(void *ptr);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekint __wrap_child_io_destructor(void *ptr)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek{
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek destructor_called = 1;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek return __real_child_io_destructor(ptr);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek/* Test that writing to the pipes works as expected */
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_exec_child_io_destruct(void **state)
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek{
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_test_ctx);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek struct child_io_fds *io_fds;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek io_fds->read_from_child_fd = -1;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek io_fds->write_to_child_fd = -1;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek assert_non_null(io_fds);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
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
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek destructor_called = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_free(io_fds);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(destructor_called, 1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek close(child_tctx->pipefd_from_child[0]);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(errno, EBADF);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(child_tctx->pipefd_from_child[1]);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek assert_int_equal(errno, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(child_tctx->pipefd_to_child[0]);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(errno, 0);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(child_tctx->pipefd_to_child[1]);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(errno, EBADF);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid test_child_cb(int child_status,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct tevent_signal *sige,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek void *pvt);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Test that writing to the pipes works as expected */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid test_exec_child_handler(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno_t ret;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek pid_t child_pid;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct sss_child_ctx_old *child_old_ctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek ret = unsetenv("TEST_CHILD_ACTION");
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid = fork();
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(child_pid, -1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (child_pid == 0) {
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek exec_child(child_tctx,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_tctx->pipefd_to_child,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_tctx->pipefd_from_child,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek test_child_cb, child_tctx, &child_old_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozekvoid test_child_cb(int child_status,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct tevent_signal *sige,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek void *pvt)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_ctx->test_ctx->error = EIO;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) {
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_ctx->test_ctx->error = 0;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek }
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_ctx->test_ctx->done = true;
4c9419d98b89a6161a3dde11f9f80be39d12e72aJakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Test that writing to the pipes works as expected */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid test_exec_child_echo(void **state)
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek{
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek errno_t ret;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek pid_t child_pid;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct tevent_req *req;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_io_fds *io_fds;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek setenv("TEST_CHILD_ACTION", "echo", 1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds = talloc(child_tctx, struct child_io_fds);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(io_fds);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->read_from_child_fd = -1;
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek io_fds->write_to_child_fd = -1;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_set_destructor((void *) io_fds, child_io_destructor);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid = fork();
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(child_pid, -1);
d25fa6f2608d5fe0617ada47f9d426f45deb96ffJakub Hrozek if (child_pid == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek exec_child_ex(child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_to_child,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_tctx->pipefd_from_child,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2, NULL, false,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek STDIN_FILENO, 3);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek DEBUG(SSSDBG_FUNC_DATA, "Forked into %d\n", child_pid);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(child_tctx->pipefd_from_child[1]);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1];
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(child_tctx->pipefd_to_child[0]);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek sss_fd_nonblocking(io_fds->write_to_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek sss_fd_nonblocking(io_fds->read_from_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek NULL, NULL, NULL);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek req = echo_child_write_send(child_tctx, child_tctx, io_fds, ECHO_STR);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(req);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_free(io_fds);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstruct test_exec_echo_state {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_io_fds *io_fds;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct io_buffer buf;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_test_ctx;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek};
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstruct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_io_fds *io_fds,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek const char *input)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek struct tevent_req *req;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct tevent_req *subreq;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct test_exec_echo_state *echo_state;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek req = tevent_req_create(mem_ctx, &echo_state, struct test_exec_echo_state);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek assert_non_null(req);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek echo_state->child_test_ctx = child_tctx;
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek echo_state->buf.data = (unsigned char *) talloc_strdup(echo_state, input);
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek assert_non_null(echo_state->buf.data);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->buf.size = strlen(input) + 1;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->io_fds = io_fds;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Writing..\n");
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek subreq = write_pipe_send(child_tctx, child_tctx->test_ctx->ev,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->buf.data, echo_state->buf.size,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->io_fds->write_to_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(subreq);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek tevent_req_set_callback(subreq, echo_child_write_done, req);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return req;
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek}
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozekstatic void echo_child_write_done(struct tevent_req *subreq)
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek{
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek struct tevent_req *req;
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek struct test_exec_echo_state *echo_state;
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek errno_t ret;
36b56482ca1e53d832accef0354124fd79711172Jakub Hrozek
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
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = write_pipe_recv(subreq);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Writing OK\n");
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_zfree(subreq);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(echo_state->io_fds->write_to_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->io_fds->write_to_child_fd = -1;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Reading..\n");
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek subreq = read_pipe_send(echo_state,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek echo_state->child_test_ctx->test_ctx->ev,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->io_fds->read_from_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_non_null(subreq);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek tevent_req_set_callback(subreq, echo_child_read_done, req);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekstatic void echo_child_read_done(struct tevent_req *subreq)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct tevent_req *req;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct test_exec_echo_state *echo_state;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek errno_t ret;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ssize_t len;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek uint8_t *buf;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
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
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = read_pipe_recv(subreq, echo_state, &buf, &len);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek talloc_zfree(subreq);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Reading OK\n");
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek close(echo_state->io_fds->read_from_child_fd);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->io_fds->read_from_child_fd = -1;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek assert_string_equal(buf, echo_state->buf.data);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek echo_state->child_test_ctx->test_ctx->done = true;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozekvoid test_sss_child(void **state)
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek errno_t ret;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek pid_t child_pid;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct sss_sigchild_ctx *sc_ctx;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct sss_child_ctx *sss_child;
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = unsetenv("TEST_CHILD_ACTION");
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = sss_sigchld_init(child_tctx, child_tctx->test_ctx->ev, &sc_ctx);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid = fork();
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_not_equal(child_pid, -1);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (child_pid == 0) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek exec_child(child_tctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_to_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx->pipefd_from_child,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = sss_child_register(child_tctx, sc_ctx,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_pid,
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek sss_child_cb,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_tctx, &sss_child);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek ret = test_ev_loop(child_tctx->test_ctx);
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek assert_int_equal(ret, EOK);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek assert_int_equal(child_tctx->test_ctx->error, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekvoid sss_child_cb(int pid, int wait_status, void *pvt)
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_ctx->test_ctx->error = EIO;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == 0) {
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek child_ctx->test_ctx->error = 0;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_ctx->test_ctx->done = true;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozekint main(int argc, const char *argv[])
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek{
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int rv;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek poptContext pc;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek int opt;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek struct poptOption long_options[] = {
9a839b29816c8906d4a6b074cf76df790cac9209Jakub Hrozek POPT_AUTOHELP
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek SSSD_DEBUG_OPTS
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek POPT_TABLEEND
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek };
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek const struct CMUnitTest tests[] = {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_test_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_extra_args,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_io_destruct,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_setup,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_handler,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_echo,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek child_test_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_sss_child,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek child_test_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek only_extra_args_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek only_extra_args_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek cmocka_unit_test_setup_teardown(test_exec_child_only_extra_args_neg,
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek only_extra_args_setup,
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek only_extra_args_teardown),
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek };
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek /* Set debug level to invalid value so we can decide if -d 0 was used. */
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek debug_level = SSSDBG_INVALID;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek while((opt = poptGetNextOpt(pc)) != -1) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek switch(opt) {
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek default:
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek fprintf(stderr, "\nInvalid option %s: %s\n\n",
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek poptBadOption(pc, 0), poptStrerror(opt));
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek poptPrintUsage(pc, stderr, 0);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek return 1;
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek }
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek poptFreeContext(pc);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek DEBUG_CLI_INIT(debug_level);
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek rv = cmocka_run_group_tests(tests, NULL, NULL);
b47fd11a259c50e63cd674c7cba0da3f2549cae0Jakub Hrozek return rv;
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek}
f45a20d6ba9e8d695ec3ab707f0cc082999aa4a3Jakub Hrozek