]> git.ipfire.org Git - people/ms/pakfire.git/blobdiff - tests/libpakfire/jail.c
jail: Implement sending data into standard input
[people/ms/pakfire.git] / tests / libpakfire / jail.c
index cd71f29b547b5d647c901492c59b0b63a83e8b93..d49795a94680604107d074265390b3f2ca5d5095 100644 (file)
@@ -45,7 +45,7 @@ static int test_create(const struct test* t) {
        struct pakfire_jail* jail = NULL;
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Destroy it
        ASSERT_NULL(pakfire_jail_unref(jail));
@@ -65,10 +65,10 @@ static int test_exit_code(const struct test* t) {
        };
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if we receive the correct exit code
-       ASSERT(pakfire_jail_exec(jail, argv, NULL, NULL, NULL) == 123);
+       ASSERT(pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0) == 123);
 
        // Success
        r = EXIT_SUCCESS;
@@ -89,10 +89,10 @@ static int test_segv(const struct test* t) {
        };
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if we receive the correct exit code
-       ASSERT(pakfire_jail_exec(jail, argv, NULL, NULL, NULL) == 139);
+       ASSERT(pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0) == 139);
 
        // Success
        r = EXIT_SUCCESS;
@@ -108,7 +108,7 @@ static int test_env(const struct test* t) {
        struct pakfire_jail* jail = NULL;
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if the default variables are set
        ASSERT(pakfire_jail_get_env(jail, "LANG"));
@@ -136,10 +136,10 @@ static int test_exec(const struct test* t) {
        struct pakfire_jail* jail = NULL;
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Try to execute something
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, cmd_hello_world, NULL, NULL, NULL));
+       ASSERT_SUCCESS(pakfire_jail_exec(jail, cmd_hello_world, NULL, NULL, NULL, 0));
 
        // Destroy it
        ASSERT_NULL(pakfire_jail_unref(jail));
@@ -156,16 +156,16 @@ static int test_launch_into_cgroup(const struct test* t) {
        int r = EXIT_FAILURE;
 
        // Create a new cgroup
-       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0));
+       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0));
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Connect jail to the cgroup
        ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail, cgroup));
 
        // Run command
-       ASSERT(pakfire_jail_exec(jail, cmd_hello_world, NULL, NULL, NULL) == 0);
+       ASSERT(pakfire_jail_exec(jail, cmd_hello_world, NULL, NULL, NULL, 0) == 0);
 
        r = EXIT_SUCCESS;
 
@@ -190,7 +190,7 @@ static int test_nice(const struct test* t) {
        };
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Set invalid nice levels
        ASSERT_ERRNO(pakfire_jail_nice(jail,  100), EINVAL);
@@ -201,7 +201,7 @@ static int test_nice(const struct test* t) {
 
        // Check if the nice level has been set
        ASSERT_SUCCESS(pakfire_jail_exec(jail, argv,
-               NULL, pakfire_jail_capture_stdout, &output));
+               NULL, pakfire_jail_capture_stdout, &output, 0));
        ASSERT_STRING_EQUALS(output, "5\n");
 
        // Success
@@ -223,10 +223,10 @@ static int test_memory_limit(const struct test* t) {
 
 
        // Create cgroup
-       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0));
+       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0));
 
        // Create jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Connect jail to the cgroup
        ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail, cgroup));
@@ -235,10 +235,10 @@ static int test_memory_limit(const struct test* t) {
        ASSERT_SUCCESS(pakfire_cgroup_set_memory_limit(cgroup, 100 * 1024 * 1024));
 
        // Try to exhaust all memory
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, NULL, NULL, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, NULL, NULL, NULL, 0));
 
        // A fork bomb should also exhaust all memory
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, NULL, NULL, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, NULL, NULL, NULL, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -260,10 +260,10 @@ static int test_pid_limit(const struct test* t) {
        int r = EXIT_FAILURE;
 
        // Create cgroup
-       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->pakfire, "pakfire-test", 0));
+       ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup, t->ctx, "pakfire-test", 0));
 
        // Create jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Connect jail to the cgroup
        ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail, cgroup));
@@ -272,7 +272,7 @@ static int test_pid_limit(const struct test* t) {
        ASSERT_SUCCESS(pakfire_cgroup_set_pid_limit(cgroup, 100));
 
        // Try to fork as many processes as possible
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, NULL, NULL, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, NULL, NULL, NULL, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -321,7 +321,7 @@ static int test_bind(const struct test* t) {
        };
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Bind-mount nonsense
        ASSERT_ERRNO(pakfire_jail_bind(jail, NULL, target, 0), EINVAL);
@@ -331,7 +331,7 @@ static int test_bind(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_bind(jail, source, target, MS_RDONLY));
 
        // Check if the mount actually works
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, NULL, NULL, NULL));
+       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -344,34 +344,45 @@ FAIL:
 }
 
 static int callback_stdin(struct pakfire* pakfire, void* data, int fd) {
-       const char* lines[] = { "a", "b", "c", NULL };
+       int* lines = (int*)data;
        int r;
 
-       for (const char** line = lines; *line; line++) {
-               r = dprintf(fd, "%s\n", *line);
+       while (*lines > 0) {
+               r = dprintf(fd, "LINE %d\n", *lines);
                if (r < 0) {
-                       LOG_ERROR("Could not write line (%s) to stdin: %m\n", *line);
-
-                       return 1;
+                       switch (errno) {
+                               case EAGAIN:
+                                       return 0;
+
+                               default:
+                                       LOG_ERROR("Could not write line (%u) to stdin: %m\n", *lines);
+                                       return -errno;
+                       }
                }
+
+               // Decrement the lines counter
+               (*lines)--;
        }
 
-       return 0;
+       return EOF;
 }
 
 static int test_communicate(const struct test* t) {
        struct pakfire_jail* jail = NULL;
        int r = EXIT_FAILURE;
 
+       // How many lines to send?
+       int lines = 65535;
+
        const char* argv[] = {
                "/command", "pipe", NULL,
        };
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if the mount actually works
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, callback_stdin, NULL, NULL));
+       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, callback_stdin, NULL, &lines, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -390,7 +401,7 @@ static int test_send_one_signal(const struct test* t,
        };
 
        // Perform the command
-       return pakfire_jail_exec(jail, argv, NULL, NULL, NULL);
+       return pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0);
 }
 
 static int test_send_signal(const struct test* t) {
@@ -398,7 +409,7 @@ static int test_send_signal(const struct test* t) {
        int r = EXIT_FAILURE;
 
        // Create a new jail
-       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Sending SIGTERM to ourselves
        ASSERT(test_send_one_signal(t, jail, "15") == 0);
@@ -419,20 +430,48 @@ FAIL:
        return r;
 }
 
+static int test_timeout(const struct test* t) {
+       struct pakfire_jail* jail = NULL;
+       int r = EXIT_FAILURE;
+
+       const char* argv[] = {
+               "/command", "sleep", "5", NULL,
+       };
+
+       // Create a new jail
+       ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
+
+       // Set a timeout of one second
+       ASSERT_SUCCESS(pakfire_jail_set_timeout(jail, 1));
+
+       // Check if we receive the correct exit code
+       ASSERT(pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0) == 139);
+
+       // Success
+       r = EXIT_SUCCESS;
+
+FAIL:
+       if (jail)
+               pakfire_jail_unref(jail);
+
+       return r;
+}
+
 int main(int argc, const char* argv[]) {
-       testsuite_add_test(test_create);
-       testsuite_add_test(test_exit_code);
-       testsuite_add_test(test_segv);
-       testsuite_add_test(test_env);
-       testsuite_add_test(test_exec);
-       testsuite_add_test(test_launch_into_cgroup);
-       testsuite_add_test(test_nice);
-       testsuite_add_test(test_memory_limit);
-       testsuite_add_test(test_pid_limit);
-       testsuite_add_test(test_file_ownership);
-       testsuite_add_test(test_bind);
-       testsuite_add_test(test_communicate);
-       testsuite_add_test(test_send_signal);
+       testsuite_add_test(test_create, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_exit_code, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_segv, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_env, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_exec, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_launch_into_cgroup, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_nice, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_memory_limit, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_pid_limit, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_file_ownership, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_bind, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_communicate, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_send_signal, TEST_WANTS_PAKFIRE);
+       testsuite_add_test(test_timeout, TEST_WANTS_PAKFIRE);
 
        return testsuite_run(argc, argv);
 }