Line |
Branch |
Exec |
Source |
1 |
|
|
#include <unistd.h> |
2 |
|
|
#include "test.h" |
3 |
|
|
#include "spawn.h" |
4 |
|
|
|
5 |
|
1 |
static void test_spawn(TestContext *ctx) |
6 |
|
|
{ |
7 |
|
1 |
static const char *args[] = { |
8 |
|
|
"sh", "-c", "cat; echo OUT; echo ERR >&2", |
9 |
|
|
NULL |
10 |
|
|
}; |
11 |
|
|
|
12 |
|
1 |
ErrorBuffer ebuf = {.print_to_stderr = false}; |
13 |
|
1 |
SpawnContext sc = { |
14 |
|
|
.argv = args, |
15 |
|
|
.input = STRING_VIEW("IN-"), |
16 |
|
|
.outputs = {STRING_INIT, STRING_INIT}, |
17 |
|
|
.ebuf = &ebuf, |
18 |
|
|
.quiet = true, |
19 |
|
|
.actions = { |
20 |
|
|
[STDIN_FILENO] = SPAWN_PIPE, |
21 |
|
|
[STDOUT_FILENO] = SPAWN_PIPE, |
22 |
|
|
[STDERR_FILENO] = SPAWN_PIPE, |
23 |
|
|
}, |
24 |
|
|
}; |
25 |
|
|
|
26 |
|
1 |
static_assert(ARRAYLEN(sc.actions) == 3); |
27 |
|
1 |
static_assert(ARRAYLEN(sc.outputs) == 2); |
28 |
|
|
|
29 |
|
1 |
String *out = &sc.outputs[0]; |
30 |
|
1 |
String *err = &sc.outputs[1]; |
31 |
|
1 |
EXPECT_EQ(spawn(&sc), 0); |
32 |
|
1 |
EXPECT_EQ(out->len, 7); |
33 |
|
1 |
EXPECT_EQ(err->len, 4); |
34 |
|
1 |
EXPECT_STREQ(string_borrow_cstring(out), "IN-OUT\n"); |
35 |
|
1 |
EXPECT_STREQ(string_borrow_cstring(err), "ERR\n"); |
36 |
|
1 |
EXPECT_EQ(string_clear(out), 7); |
37 |
|
1 |
EXPECT_EQ(string_clear(err), 4); |
38 |
|
|
|
39 |
|
1 |
sc.actions[STDIN_FILENO] = SPAWN_NULL; |
40 |
|
1 |
sc.actions[STDERR_FILENO] = SPAWN_NULL; |
41 |
|
1 |
EXPECT_EQ(spawn(&sc), 0); |
42 |
|
1 |
EXPECT_EQ(out->len, 4); |
43 |
|
1 |
EXPECT_EQ(err->len, 0); |
44 |
|
1 |
EXPECT_STREQ(string_borrow_cstring(out), "OUT\n"); |
45 |
|
1 |
EXPECT_EQ(string_clear(out), 4); |
46 |
|
1 |
EXPECT_EQ(string_clear(err), 0); |
47 |
|
|
|
48 |
|
1 |
args[2] = "printf 'xyz 123'; exit 37"; |
49 |
|
1 |
EXPECT_EQ(spawn(&sc), 37); |
50 |
|
1 |
EXPECT_EQ(out->len, 7); |
51 |
|
1 |
EXPECT_EQ(err->len, 0); |
52 |
|
1 |
EXPECT_STREQ(string_borrow_cstring(out), "xyz 123"); |
53 |
|
1 |
EXPECT_EQ(string_clear(out), 7); |
54 |
|
1 |
EXPECT_EQ(string_clear(err), 0); |
55 |
|
|
|
56 |
|
|
// Make sure zero-length input with one SPAWN_PIPE action |
57 |
|
|
// doesn't deadlock |
58 |
|
1 |
args[2] = "cat >/dev/null"; |
59 |
|
1 |
sc.input.length = 0; |
60 |
|
1 |
sc.actions[STDIN_FILENO] = SPAWN_PIPE; |
61 |
|
1 |
sc.actions[STDOUT_FILENO] = SPAWN_NULL; |
62 |
|
1 |
sc.actions[STDERR_FILENO] = SPAWN_NULL; |
63 |
|
1 |
EXPECT_EQ(spawn(&sc), 0); |
64 |
|
1 |
string_free(out); |
65 |
|
1 |
string_free(err); |
66 |
|
1 |
} |
67 |
|
|
|
68 |
|
|
static const TestEntry tests[] = { |
69 |
|
|
TEST(test_spawn), |
70 |
|
|
}; |
71 |
|
|
|
72 |
|
|
const TestGroup spawn_tests = TEST_GROUP(tests); |
73 |
|
|
|