lib/util: adjust loglevel in tfork test with samba_runcmd_send()
[samba.git] / lib / util / tests / tfork.c
1 /*
2  * Tests for tfork
3  *
4  * Copyright Ralph Boehme <slow@samba.org> 2017
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "replace.h"
21 #include <talloc.h>
22 #include <tevent.h>
23 #include "system/filesys.h"
24 #include "system/wait.h"
25 #include "libcli/util/ntstatus.h"
26 #include "torture/torture.h"
27 #include "lib/util/data_blob.h"
28 #include "torture/local/proto.h"
29 #include "lib/util/tfork.h"
30 #include "lib/util/samba_util.h"
31 #include "lib/util/sys_rw.h"
32
33 static bool test_tfork_simple(struct torture_context *tctx)
34 {
35         pid_t parent = getpid();
36         struct tfork *t = NULL;
37         pid_t child;
38         int ret;
39
40         t = tfork_create();
41         if (t == NULL) {
42                 torture_fail(tctx, "tfork failed\n");
43                 return false;
44         }
45         child = tfork_child_pid(t);
46         if (child == 0) {
47                 torture_comment(tctx, "my parent pid is %d\n", parent);
48                 torture_assert(tctx, getpid() != parent, "tfork failed\n");
49                 _exit(0);
50         }
51
52         ret = tfork_destroy(&t);
53         torture_assert(tctx, ret == 0, "tfork_destroy failed\n");
54
55         return true;
56 }
57
58 static bool test_tfork_status(struct torture_context *tctx)
59 {
60         struct tfork *t = NULL;
61         int status;
62         pid_t child;
63         bool ok = true;
64
65         t = tfork_create();
66         if (t == NULL) {
67                 torture_fail(tctx, "tfork failed\n");
68                 return false;
69         }
70         child = tfork_child_pid(t);
71         if (child == 0) {
72                 _exit(123);
73         }
74
75         status = tfork_status(&t, true);
76         if (status == -1) {
77                 torture_fail(tctx, "tfork_status failed\n");
78         }
79
80         torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
81                             "tfork failed\n");
82         torture_assert_goto(tctx, WEXITSTATUS(status) == 123, ok, done,
83                             "tfork failed\n");
84
85         torture_comment(tctx, "exit status [%d]\n", WEXITSTATUS(status));
86
87 done:
88         return ok;
89 }
90
91 static bool test_tfork_cmd_send(struct torture_context *tctx)
92 {
93         struct tevent_context *ev = NULL;
94         struct tevent_req *req = NULL;
95         const char *cmd[2] = { NULL, NULL };
96         bool ok = true;
97
98         ev = tevent_context_init(tctx);
99         torture_assert_goto(tctx, ev != NULL, ok, done,
100                             "tevent_context_init failed\n");
101
102         cmd[0] = talloc_asprintf(tctx, "%s/testprogs/blackbox/tfork.sh", SRCDIR);
103         torture_assert_goto(tctx, cmd[0] != NULL, ok, done,
104                             "talloc_asprintf failed\n");
105
106         req = samba_runcmd_send(tctx, ev, timeval_zero(), 0, 0,
107                                 cmd, "foo", NULL);
108         torture_assert_goto(tctx, req != NULL, ok, done,
109                             "samba_runcmd_send failed\n");
110
111         ok = tevent_req_poll(req, ev);
112         torture_assert_goto(tctx, ok, ok, done, "tevent_req_poll failed\n");
113
114         torture_comment(tctx, "samba_runcmd_send test finished\n");
115
116 done:
117         TALLOC_FREE(ev);
118
119         return ok;
120 }
121
122 struct torture_suite *torture_local_tfork(TALLOC_CTX *mem_ctx)
123 {
124         struct torture_suite *suite =
125                 torture_suite_create(mem_ctx, "tfork");
126
127         torture_suite_add_simple_test(suite,
128                                       "tfork_simple",
129                                       test_tfork_simple);
130
131         torture_suite_add_simple_test(suite,
132                                       "tfork_status",
133                                       test_tfork_status);
134
135         torture_suite_add_simple_test(suite,
136                                       "tfork_cmd_send",
137                                       test_tfork_cmd_send);
138
139         return suite;
140 }