process: Provide an abstraction to spawn child processes with redirected I/O
This commit is contained in:
@@ -30,6 +30,7 @@ tests_SOURCES = tests.h tests.c \
|
||||
suites/test_hashtable.c \
|
||||
suites/test_identification.c \
|
||||
suites/test_threading.c \
|
||||
suites/test_process.c \
|
||||
suites/test_watcher.c \
|
||||
suites/test_stream.c \
|
||||
suites/test_fetch_http.c \
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Willi
|
||||
* Copyright (C) 2014 revosec AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <utils/process.h>
|
||||
|
||||
START_TEST(test_retval_true)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/true",
|
||||
NULL
|
||||
};
|
||||
int retval;
|
||||
|
||||
process = process_start(argv, NULL, NULL, NULL, NULL, TRUE);
|
||||
ck_assert(process != NULL);
|
||||
ck_assert(process->wait(process, &retval));
|
||||
ck_assert_int_eq(retval, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_retval_false)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/false",
|
||||
NULL
|
||||
};
|
||||
int retval;
|
||||
|
||||
process = process_start(argv, NULL, NULL, NULL, NULL, TRUE);
|
||||
ck_assert(process != NULL);
|
||||
ck_assert(process->wait(process, &retval));
|
||||
ck_assert(retval != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_not_found)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/does-not-exist",
|
||||
NULL
|
||||
};
|
||||
|
||||
process = process_start(argv, NULL, NULL, NULL, NULL, TRUE);
|
||||
/* both is acceptable behavior */
|
||||
ck_assert(process == NULL || !process->wait(process, NULL));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_echo)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/cat",
|
||||
NULL
|
||||
};
|
||||
int retval, in, out;
|
||||
char *msg = "test";
|
||||
char buf[strlen(msg) + 1];
|
||||
|
||||
memset(buf, 0, strlen(msg) + 1);
|
||||
|
||||
process = process_start(argv, NULL, &in, &out, NULL, TRUE);
|
||||
ck_assert(process != NULL);
|
||||
ck_assert_int_eq(write(in, msg, strlen(msg)), strlen(msg));
|
||||
ck_assert(close(in) == 0);
|
||||
ck_assert_int_eq(read(out, buf, strlen(msg) + 1), strlen(msg));
|
||||
ck_assert_str_eq(buf, msg);
|
||||
ck_assert(close(out) == 0);
|
||||
ck_assert(process->wait(process, &retval));
|
||||
ck_assert_int_eq(retval, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_echo_err)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"1>&2 /bin/cat",
|
||||
NULL
|
||||
};
|
||||
int retval, in, err;
|
||||
char *msg = "a longer test message";
|
||||
char buf[strlen(msg) + 1];
|
||||
|
||||
memset(buf, 0, strlen(msg) + 1);
|
||||
|
||||
process = process_start(argv, NULL, &in, NULL, &err, TRUE);
|
||||
ck_assert(process != NULL);
|
||||
ck_assert_int_eq(write(in, msg, strlen(msg)), strlen(msg));
|
||||
ck_assert(close(in) == 0);
|
||||
ck_assert_int_eq(read(err, buf, strlen(msg) + 1), strlen(msg));
|
||||
ck_assert_str_eq(buf, msg);
|
||||
ck_assert(close(err) == 0);
|
||||
ck_assert(process->wait(process, &retval));
|
||||
ck_assert_int_eq(retval, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_env)
|
||||
{
|
||||
process_t *process;
|
||||
char *argv[] = {
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"echo -n $A $B",
|
||||
NULL
|
||||
};
|
||||
char *envp[] = {
|
||||
"A=atest",
|
||||
"B=bstring",
|
||||
NULL
|
||||
};
|
||||
int retval, out;
|
||||
char buf[64] = {};
|
||||
|
||||
process = process_start(argv, envp, NULL, &out, NULL, TRUE);
|
||||
ck_assert(process != NULL);
|
||||
ck_assert(read(out, buf, sizeof(buf)) > 0);
|
||||
ck_assert_str_eq(buf, "atest bstring");
|
||||
ck_assert(close(out) == 0);
|
||||
ck_assert(process->wait(process, &retval));
|
||||
ck_assert_int_eq(retval, 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *process_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("process");
|
||||
|
||||
tc = tcase_create("return values");
|
||||
tcase_add_test(tc, test_retval_true);
|
||||
tcase_add_test(tc, test_retval_false);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("not found");
|
||||
tcase_add_test(tc, test_not_found);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("echo");
|
||||
tcase_add_test(tc, test_echo);
|
||||
tcase_add_test(tc, test_echo_err);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("env");
|
||||
tcase_add_test(tc, test_env);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ TEST_SUITE(hashtable_suite_create)
|
||||
TEST_SUITE(array_suite_create)
|
||||
TEST_SUITE(identification_suite_create)
|
||||
TEST_SUITE(threading_suite_create)
|
||||
TEST_SUITE(process_suite_create)
|
||||
TEST_SUITE(watcher_suite_create)
|
||||
TEST_SUITE(stream_suite_create)
|
||||
TEST_SUITE(utils_suite_create)
|
||||
|
||||
Reference in New Issue
Block a user