summaryrefslogtreecommitdiff
path: root/tests/subprocess_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/subprocess_tests.c')
-rw-r--r--tests/subprocess_tests.c111
1 files changed, 110 insertions, 1 deletions
diff --git a/tests/subprocess_tests.c b/tests/subprocess_tests.c
index 58c8f235..75d6e493 100644
--- a/tests/subprocess_tests.c
+++ b/tests/subprocess_tests.c
@@ -164,12 +164,119 @@ static void test_subprocess_small_output_buffer(void)
static void test_subprocess_return_code_failure(void)
{
- const char *const argv[] = {"false"};
+ const char *const argv[] = {"false", NULL};
TEST_NEQ(subprocess_run(argv, NULL, NULL, NULL), 0,
"Return value of \"false\" is nonzero");
}
+struct cb_ctx {
+ char buffer[49 * 1024];
+ char *ptr;
+};
+
+static ssize_t input_cb(char *buf, size_t buf_sz, void *data)
+{
+ struct cb_ctx *ctx = (struct cb_ctx *)data;
+ size_t len = (ctx->buffer + sizeof(ctx->buffer)) - ctx->ptr;
+ if (len > buf_sz)
+ len = buf_sz;
+ memcpy(buf, ctx->ptr, len);
+ ctx->ptr += len;
+ return len;
+}
+
+static void test_subprocess_input_from_cb(void)
+{
+ struct cb_ctx ctx;
+ char output_buffer[sizeof(ctx.buffer)];
+ const char *const argv[] = {"cat", NULL};
+
+ /* Initialize the input buffer with some data */
+ for (size_t i = 0; i < sizeof(ctx.buffer); i++)
+ ctx.buffer[i] = (char)i;
+ ctx.ptr = ctx.buffer;
+
+ struct subprocess_target output = {
+ .type = TARGET_BUFFER,
+ .buffer = {
+ .buf = output_buffer,
+ .size = sizeof(output_buffer),
+ },
+ };
+
+ struct subprocess_target input = {
+ .type = TARGET_CALLBACK,
+ .callback = {
+ .cb = input_cb,
+ .data = &ctx,
+ },
+ };
+ TEST_EQ(subprocess_run(argv, &input, &output, NULL), 0,
+ "Return value of \"cat\" is zero.");
+ TEST_EQ(memcmp(ctx.buffer, output_buffer, sizeof(output_buffer)), 0,
+ "The input buffer is equal to the output buffer.");
+ TEST_EQ(output.buffer.bytes_consumed, sizeof(output_buffer),
+ "The entire output buffer should have been used.");
+}
+
+static ssize_t output_cb(char *buf, size_t buf_sz, void *data)
+{
+ struct cb_ctx *ctx = (struct cb_ctx *)data;
+ if (ctx->ptr + buf_sz > ctx->buffer + sizeof(ctx->buffer)) {
+ TEST_TRUE(0, "Test failed as there is not enough space in the "
+ "output buffer.");
+ return -1;
+ }
+ memcpy(ctx->ptr, buf, buf_sz);
+ ctx->ptr += buf_sz;
+ return 0;
+}
+
+static void test_subprocess_output_to_cb(void)
+{
+ struct cb_ctx ctx;
+ char output_buffer[sizeof(ctx.buffer)];
+ const char *const argv[] = {
+ "bc", "-l", NULL
+ };
+
+ ctx.ptr = ctx.buffer;
+
+ struct subprocess_target input = {
+ .type = TARGET_BUFFER_NULL_TERMINATED,
+ .buffer = {
+ .buf = (char *)"for (i = 0; i <= 10000; i += 1) i\n",
+ },
+ };
+
+ struct subprocess_target target_via_buffer = {
+ .type = TARGET_BUFFER,
+ .buffer = {
+ .buf = output_buffer,
+ .size = sizeof(output_buffer),
+ },
+ };
+
+ struct subprocess_target target_via_cb = {
+ .type = TARGET_CALLBACK,
+ .callback = {
+ .cb = output_cb,
+ .data = &ctx,
+ },
+ };
+
+ TEST_EQ(subprocess_run(argv, &input, &target_via_buffer, NULL), 0,
+ "Return value is zero when using buffer.");
+ TEST_EQ(subprocess_run(argv, &input, &target_via_cb, NULL), 0,
+ "Return value is zero when using callback.");
+ TEST_EQ(ctx.ptr - ctx.buffer, target_via_buffer.buffer.bytes_consumed,
+ "Both commmand invocations used the same number of bytes.");
+ TEST_EQ(memcmp(output_buffer, ctx.buffer,
+ target_via_buffer.buffer.bytes_consumed),
+ 0, "Both output buffers are equivalent.");
+}
+
int main(int argc, char *argv[])
{
test_subprocess_output_to_buffer();
@@ -178,6 +285,8 @@ int main(int argc, char *argv[])
test_subprocess_input_null_terminated();
test_subprocess_small_output_buffer();
test_subprocess_return_code_failure();
+ test_subprocess_input_from_cb();
+ test_subprocess_output_to_cb();
return gTestSuccess ? 0 : 255;
}