| 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 | .lines = 32, | ||
| 19 | .columns = 120, | ||
| 20 | .quiet = true, | ||
| 21 | .actions = { | ||
| 22 | [STDIN_FILENO] = SPAWN_PIPE, | ||
| 23 | [STDOUT_FILENO] = SPAWN_PIPE, | ||
| 24 | [STDERR_FILENO] = SPAWN_PIPE, | ||
| 25 | }, | ||
| 26 | }; | ||
| 27 | |||
| 28 | 1 | static_assert(ARRAYLEN(sc.actions) == 3); | |
| 29 | 1 | static_assert(ARRAYLEN(sc.outputs) == 2); | |
| 30 | |||
| 31 | 1 | String *out = &sc.outputs[0]; | |
| 32 | 1 | String *err = &sc.outputs[1]; | |
| 33 | 1 | EXPECT_EQ(spawn(&sc), 0); | |
| 34 | 1 | EXPECT_STRING_EQ_CSTRING(out, "IN-OUT\n"); | |
| 35 | 1 | EXPECT_STRING_EQ_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_STRING_EQ_CSTRING(out, "OUT\n"); | |
| 43 | 1 | EXPECT_STRING_EQ_CSTRING(err, ""); | |
| 44 | 1 | EXPECT_EQ(string_clear(out), 4); | |
| 45 | 1 | EXPECT_EQ(string_clear(err), 0); | |
| 46 | |||
| 47 | 1 | args[2] = "printf \"xyz $LINES $COLUMNS\"; exit 37"; | |
| 48 | 1 | EXPECT_EQ(spawn(&sc), 37); | |
| 49 | 1 | EXPECT_STRING_EQ_CSTRING(out, "xyz 32 120"); | |
| 50 | 1 | EXPECT_STRING_EQ_CSTRING(err, ""); | |
| 51 | 1 | EXPECT_EQ(string_clear(out), 10); | |
| 52 | 1 | EXPECT_EQ(string_clear(err), 0); | |
| 53 | |||
| 54 | // Make sure zero-length input with one SPAWN_PIPE action | ||
| 55 | // doesn't deadlock | ||
| 56 | 1 | args[2] = "cat >/dev/null"; | |
| 57 | 1 | sc.input.length = 0; | |
| 58 | 1 | sc.actions[STDIN_FILENO] = SPAWN_PIPE; | |
| 59 | 1 | sc.actions[STDOUT_FILENO] = SPAWN_NULL; | |
| 60 | 1 | sc.actions[STDERR_FILENO] = SPAWN_NULL; | |
| 61 | 1 | EXPECT_EQ(spawn(&sc), 0); | |
| 62 | 1 | string_free(out); | |
| 63 | 1 | string_free(err); | |
| 64 | 1 | } | |
| 65 | |||
| 66 | static const TestEntry tests[] = { | ||
| 67 | TEST(test_spawn), | ||
| 68 | }; | ||
| 69 | |||
| 70 | const TestGroup spawn_tests = TEST_GROUP(tests); | ||
| 71 |