ntprinting: mark the final 4 byte null pointer for printer data in ndr_pull_ntprintin...
[Samba.git] / source3 / torture / test_ctdbconn.c
blob539e224899d7969fbe6dc6e84aa80975f221c92d
1 /*
2 Unix SMB/CIFS implementation.
3 Test new ctdb API
4 Copyright (C) Volker Lendecke 2012
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.
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.
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/>.
20 #include "includes.h"
21 #include "torture/proto.h"
23 #ifdef CLUSTER_SUPPORT
25 #include "ctdb_conn.h"
26 #include "lib/util/tevent_unix.h"
27 #include "tdb.h"
28 #include "ctdb_protocol.h"
29 #include "messages.h"
31 struct ctdb_conn_test_state {
32 struct tevent_context *ev;
33 struct ctdb_conn *conn;
34 struct ctdb_msg_channel *channel;
35 int msgno;
38 static void ctdb_conn_test_got_conn(struct tevent_req *subreq);
39 static void ctdb_conn_test_got_pnn(struct tevent_req *subreq);
40 static void ctdb_conn_test_got_channel(struct tevent_req *subreq);
41 static void ctdb_conn_test_got_msg(struct tevent_req *subreq);
42 static void ctdb_conn_test_msg_sent(struct tevent_req *subreq);
44 static struct tevent_req *ctdb_conn_test_send(TALLOC_CTX *mem_ctx,
45 struct tevent_context *ev)
47 struct tevent_req *req, *subreq;
48 struct ctdb_conn_test_state *state;
50 req = tevent_req_create(mem_ctx, &state, struct ctdb_conn_test_state);
51 if (req == NULL) {
52 return NULL;
54 state->ev = ev;
56 subreq = ctdb_conn_init_send(mem_ctx, ev, lp_ctdbd_socket());
57 if (tevent_req_nomem(subreq, req)) {
58 return tevent_req_post(req, ev);
60 tevent_req_set_callback(subreq, ctdb_conn_test_got_conn, req);
61 return req;
64 static void ctdb_conn_test_got_conn(struct tevent_req *subreq)
66 struct tevent_req *req = tevent_req_callback_data(
67 subreq, struct tevent_req);
68 struct ctdb_conn_test_state *state = tevent_req_data(
69 req, struct ctdb_conn_test_state);
70 uint64_t ret;
72 ret = ctdb_conn_init_recv(subreq, state, &state->conn);
73 TALLOC_FREE(subreq);
74 if (tevent_req_error(req, ret)) {
75 return;
77 subreq = ctdb_conn_control_send(state, state->ev, state->conn,
78 CTDB_CURRENT_NODE,
79 CTDB_CONTROL_GET_PNN, 0, 0, NULL, 0);
80 if (tevent_req_nomem(subreq, req)) {
81 return;
83 tevent_req_set_callback(subreq, ctdb_conn_test_got_pnn, req);
86 static void ctdb_conn_test_got_pnn(struct tevent_req *subreq)
88 struct tevent_req *req = tevent_req_callback_data(
89 subreq, struct tevent_req);
90 struct ctdb_conn_test_state *state = tevent_req_data(
91 req, struct ctdb_conn_test_state);
92 int ret;
93 struct ctdb_reply_control *reply;
95 ret = ctdb_conn_control_recv(subreq, talloc_tos(), &reply);
96 TALLOC_FREE(subreq);
97 if (tevent_req_error(req, ret)) {
98 return;
100 printf("vnn=%d\n", (int)reply->status);
102 subreq = ctdb_msg_channel_init_send(
103 state, state->ev, lp_ctdbd_socket(), 999999);
104 if (tevent_req_nomem(subreq, req)) {
105 return;
107 tevent_req_set_callback(subreq, ctdb_conn_test_got_channel, req);
110 static void ctdb_conn_test_got_channel(struct tevent_req *subreq)
112 struct tevent_req *req = tevent_req_callback_data(
113 subreq, struct tevent_req);
114 struct ctdb_conn_test_state *state = tevent_req_data(
115 req, struct ctdb_conn_test_state);
116 int ret;
118 ret = ctdb_msg_channel_init_recv(subreq, state, &state->channel);
119 TALLOC_FREE(subreq);
120 if (tevent_req_error(req, ret)) {
121 return;
124 subreq = ctdb_msg_read_send(state, state->ev, state->channel);
125 if (tevent_req_nomem(subreq, req)) {
126 return;
128 tevent_req_set_callback(subreq, ctdb_conn_test_got_msg, req);
130 state->msgno += 1;
132 subreq = ctdb_conn_msg_write_send(
133 state, state->ev, state->conn, CTDB_CURRENT_NODE, 999999,
134 (uint8_t *)&state->msgno, sizeof(state->msgno));
135 if (tevent_req_nomem(subreq, req)) {
136 return;
138 tevent_req_set_callback(subreq, ctdb_conn_test_msg_sent, req);
141 static void ctdb_conn_test_got_msg(struct tevent_req *subreq)
143 struct tevent_req *req = tevent_req_callback_data(
144 subreq, struct tevent_req);
145 struct ctdb_conn_test_state *state = tevent_req_data(
146 req, struct ctdb_conn_test_state);
147 uint8_t *buf;
148 size_t buf_len;
149 int ret;
151 ret = ctdb_msg_read_recv(subreq, talloc_tos(), &buf, &buf_len);
152 TALLOC_FREE(subreq);
153 if (tevent_req_error(req, ret)) {
154 return;
156 if (buf_len != sizeof(int)) {
157 printf("got invalid msg\n");
158 tevent_req_error(req, EINVAL);
159 return;
161 memcpy(&ret, buf, buf_len);
162 printf("got msg %d\n", ret);
163 if (ret == 5) {
164 tevent_req_done(req);
165 return;
168 subreq = ctdb_msg_read_send(state, state->ev, state->channel);
169 if (tevent_req_nomem(subreq, req)) {
170 return;
172 tevent_req_set_callback(subreq, ctdb_conn_test_got_msg, req);
175 static void ctdb_conn_test_msg_sent(struct tevent_req *subreq)
177 struct tevent_req *req = tevent_req_callback_data(
178 subreq, struct tevent_req);
179 struct ctdb_conn_test_state *state = tevent_req_data(
180 req, struct ctdb_conn_test_state);
181 int ret;
183 ret = ctdb_conn_msg_write_recv(subreq);
184 TALLOC_FREE(subreq);
185 if (tevent_req_error(req, ret)) {
186 return;
188 state->msgno += 1;
190 if (state->msgno >= 10) {
191 return;
194 subreq = ctdb_conn_msg_write_send(
195 state, state->ev, state->conn, CTDB_CURRENT_NODE, 999999,
196 (uint8_t *)&state->msgno, sizeof(state->msgno));
197 if (tevent_req_nomem(subreq, req)) {
198 return;
200 tevent_req_set_callback(subreq, ctdb_conn_test_msg_sent, req);
203 static int ctdb_conn_test_recv(struct tevent_req *req)
205 int err;
206 if (tevent_req_is_unix_error(req, &err)) {
207 return err;
209 return 0;
212 bool run_ctdb_conn(int dummy)
214 struct tevent_context *ev;
215 struct tevent_req *req;
216 int ret;
218 ev = tevent_context_init(talloc_tos());
219 if (ev == NULL) {
220 fprintf(stderr, "tevent_context_init failed\n");
221 return false;
223 req = ctdb_conn_test_send(ev, ev);
224 if (req == NULL) {
225 fprintf(stderr, "ctdb_conn_test_send failed\n");
226 return false;
228 if (!tevent_req_poll(req, ev)) {
229 fprintf(stderr, "tevent_req_poll failed\n");
230 return false;
232 ret = ctdb_conn_test_recv(req);
233 TALLOC_FREE(req);
234 printf("ctdb_conn_test returned %s\n",
235 ret ? strerror(ret) : "success");
236 TALLOC_FREE(ev);
237 return (ret == 0);
240 #else /* CLUSTER_SUPPORT */
242 bool run_ctdb_conn(int dummy)
244 return true;
247 #endif