Revert "pthreadpool: test cancelling and freeing jobs of a wrapped pthreadpool_tevent"
[samba.git] / lib / pthreadpool / tests_cmocka.c
index dc7b1150b5c0d90f052f6af63d4c4244695ffc41..5c7f6ab6904bad5e4608d2f55b4031d8386ea41e 100644 (file)
@@ -244,6 +244,147 @@ static void test_create(void **state)
        assert_false(in_main_thread);
 }
 
+static void test_per_thread_cwd_job(void *ptr)
+{
+       const bool *per_thread_cwd_ptr = ptr;
+       bool per_thread_cwd;
+       char cwdbuf[PATH_MAX] = {0,};
+       char *cwdstr = NULL;
+       int ret;
+
+       /*
+        * This needs to be consistent.
+        */
+       per_thread_cwd = pthreadpool_tevent_current_job_per_thread_cwd();
+       assert_int_equal(per_thread_cwd, *per_thread_cwd_ptr);
+
+       if (!per_thread_cwd) {
+               return;
+       }
+
+       /*
+        * Check we're not already in "/".
+        */
+       cwdstr = getcwd(cwdbuf, sizeof(cwdbuf));
+       assert_non_null(cwdstr);
+       assert_string_not_equal(cwdstr, "/");
+
+       ret = chdir("/");
+       assert_int_equal(ret, 0);
+
+       /*
+        * Check we're in "/" now.
+        */
+       cwdstr = getcwd(cwdbuf, sizeof(cwdbuf));
+       assert_non_null(cwdstr);
+       assert_string_equal(cwdstr, "/");
+}
+
+static int test_per_thread_cwd_do(struct tevent_context *ev,
+                                 struct pthreadpool_tevent *pool)
+{
+       struct tevent_req *req;
+       bool per_thread_cwd;
+       bool ok;
+       int ret;
+       per_thread_cwd = pthreadpool_tevent_per_thread_cwd(pool);
+
+       req = pthreadpool_tevent_job_send(
+               ev, ev, pool, test_per_thread_cwd_job, &per_thread_cwd);
+       if (req == NULL) {
+               fprintf(stderr, "pthreadpool_tevent_job_send failed\n");
+               return ENOMEM;
+       }
+
+       ok = tevent_req_poll(req, ev);
+       if (!ok) {
+               ret = errno;
+               fprintf(stderr, "tevent_req_poll failed: %s\n",
+                       strerror(ret));
+               return ret;
+       }
+
+       ret = pthreadpool_tevent_job_recv(req);
+       TALLOC_FREE(req);
+       if (ret != 0) {
+               fprintf(stderr, "tevent_req_recv failed: %s\n",
+                       strerror(ret));
+               return ret;
+       }
+
+       return 0;
+}
+
+static void test_per_thread_cwd(void **state)
+{
+       struct pthreadpool_tevent_test *t = *state;
+       int ret;
+       bool per_thread_cwd_u;
+       bool per_thread_cwd_o;
+       bool per_thread_cwd_s;
+       char cwdbuf1[PATH_MAX] = {0,};
+       char *cwdstr1 = NULL;
+       char cwdbuf2[PATH_MAX] = {0,};
+       char *cwdstr2 = NULL;
+
+       /*
+        * The unlimited and one pools
+        * should be consistent.
+        *
+        * We can't enforce this as some constraint
+        * container environments disable unshare()
+        * completely, even just with CLONE_FS.
+        */
+       per_thread_cwd_u = pthreadpool_tevent_per_thread_cwd(t->upool);
+       per_thread_cwd_o = pthreadpool_tevent_per_thread_cwd(t->opool);
+       assert_int_equal(per_thread_cwd_u, per_thread_cwd_o);
+
+       /*
+        * The sync pool should never support this.
+        */
+       per_thread_cwd_s = pthreadpool_tevent_per_thread_cwd(t->spool);
+       assert_false(per_thread_cwd_s);
+
+       /*
+        * Check we're not already in "/".
+        */
+       cwdstr1 = getcwd(cwdbuf1, sizeof(cwdbuf1));
+       assert_non_null(cwdstr1);
+       assert_string_not_equal(cwdstr1, "/");
+
+       will_return(__wrap_pthread_create, 0);
+       ret = test_per_thread_cwd_do(t->ev, t->upool);
+       assert_int_equal(ret, 0);
+
+       /*
+        * Check we're still in the same directory.
+        */
+       cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
+       assert_non_null(cwdstr2);
+       assert_string_equal(cwdstr2, cwdstr1);
+
+       will_return(__wrap_pthread_create, 0);
+       ret = test_per_thread_cwd_do(t->ev, t->opool);
+       assert_int_equal(ret, 0);
+
+       /*
+        * Check we're still in the same directory.
+        */
+       cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
+       assert_non_null(cwdstr2);
+       assert_string_equal(cwdstr2, cwdstr1);
+
+       ret = test_per_thread_cwd_do(t->ev, t->spool);
+       assert_int_equal(ret, 0);
+
+       /*
+        * Check we're still in the same directory.
+        */
+       cwdstr2 = getcwd(cwdbuf2, sizeof(cwdbuf2));
+       assert_non_null(cwdstr2);
+       assert_string_equal(cwdstr2, cwdstr1);
+}
+
 struct test_cancel_job {
        int fdm; /* the main end of socketpair */
        int fdj; /* the job end of socketpair */
@@ -670,6 +811,9 @@ int main(int argc, char **argv)
                cmocka_unit_test_setup_teardown(test_create,
                                                setup_pthreadpool_tevent,
                                                teardown_pthreadpool_tevent),
+               cmocka_unit_test_setup_teardown(test_per_thread_cwd,
+                                               setup_pthreadpool_tevent,
+                                               teardown_pthreadpool_tevent),
                cmocka_unit_test_setup_teardown(test_cancel_job,
                                                setup_pthreadpool_tevent,
                                                teardown_pthreadpool_tevent),