test_child_common.c revision e00c2b5ac4963de9521599c88597b7fb97339d0e
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek/*
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Authors:
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek Copyright (C) 2014 Red Hat
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek SSSD tests: Child handlers
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
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
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
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*/
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <talloc.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <tevent.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <errno.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include <popt.h>
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include "util/child_common.h"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#include "tests/cmocka/common_mock.h"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#define TEST_BIN "test-child"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek#define ECHO_STR "Hello child"
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekstruct child_test_ctx {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int pipefd_to_child[2];
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int pipefd_from_child[2];
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct sss_test_ctx *test_ctx;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek};
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekvoid child_test_setup(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno_t ret;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek check_leaks_push(global_talloc_context);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx = talloc(global_talloc_context, struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_non_null(child_tctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->test_ctx = create_ev_test_ctx(child_tctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_non_null(child_tctx->test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = pipe(child_tctx->pipefd_from_child);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(ret, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "from_child: %d:%d\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_from_child[0],
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_from_child[1]);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = pipe(child_tctx->pipefd_to_child);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(ret, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "to_child: %d:%d\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_to_child[0],
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_to_child[1]);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek *state = child_tctx;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekvoid child_test_teardown(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek talloc_free(child_tctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek check_leaks_pop(global_talloc_context);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek/* Just make sure the exec works. The child does nothing but exits */
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekvoid test_exec_child(void **state)
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno_t ret;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek pid_t child_pid;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int status;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx *child_tctx = talloc_get_type(*state,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct child_test_ctx);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_pid = fork();
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_not_equal(child_pid, -1);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (child_pid == 0) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = exec_child(child_tctx,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_to_child,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_tctx->pipefd_from_child,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek CHILD_DIR"/"TEST_BIN, 2);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_equal(ret, EOK);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } else {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek do {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek errno = 0;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = waitpid(child_pid, &status, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } while (ret == -1 && errno == EINTR);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (ret > 0) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = EIO;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek if (WIFEXITED(status)) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = WEXITSTATUS(status);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek assert_int_equal(ret, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek } else {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG(SSSDBG_FUNC_DATA,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek "Failed to wait for children %d\n", child_pid);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek ret = EIO;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozekint main(int argc, const char *argv[])
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek{
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int rv;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptContext pc;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek int opt;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek struct poptOption long_options[] = {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek POPT_AUTOHELP
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek SSSD_DEBUG_OPTS
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek POPT_TABLEEND
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek };
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek const UnitTest tests[] = {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek unit_test_setup_teardown(test_exec_child,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_test_setup,
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek child_test_teardown),
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek };
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek /* Set debug level to invalid value so we can deside if -d 0 was used. */
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek debug_level = SSSDBG_INVALID;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek while((opt = poptGetNextOpt(pc)) != -1) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek switch(opt) {
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek default:
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek fprintf(stderr, "\nInvalid option %s: %s\n\n",
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptBadOption(pc, 0), poptStrerror(opt));
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptPrintUsage(pc, stderr, 0);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek return 1;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek }
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek poptFreeContext(pc);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek DEBUG_CLI_INIT(debug_level);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek rv = run_tests(tests);
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek return rv;
e00c2b5ac4963de9521599c88597b7fb97339d0eJakub Hrozek}