ctdb-test: Modify ctdb_io_test test_setup to provide queue reference
[gd/samba-autobuild/.git] / ctdb / tests / src / ctdb_io_test.c
1 /*
2    ctdb_io tests
3
4    Copyright (C) Christof Schmitt 2019
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 "system/filesys.h"
22
23 #include <assert.h>
24
25 #include "common/ctdb_io.c"
26
27 void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...)
28 {
29         va_list ap;
30         va_start(ap, fmt);
31         vprintf(fmt, ap);
32         assert(false);
33 }
34
35 static void test_setup(ctdb_queue_cb_fn_t cb,
36                        int *pfd,
37                        struct ctdb_context **pctdb,
38                        struct ctdb_queue **pqueue)
39 {
40         int pipefd[2], ret;
41         struct ctdb_context *ctdb;
42         struct ctdb_queue *queue;
43
44         ret = pipe(pipefd);
45         assert(ret == 0);
46
47         ctdb = talloc_zero(NULL, struct ctdb_context);
48         assert(ctdb != NULL);
49
50         ctdb->ev = tevent_context_init(NULL);
51
52         queue = ctdb_queue_setup(ctdb, ctdb, pipefd[0], 0, cb,
53                                  NULL, "test queue");
54         assert(queue != NULL);
55
56         *pctdb = ctdb;
57         *pfd = pipefd[1];
58         if (pqueue != NULL) {
59                 *pqueue = queue;
60         }
61 }
62
63 static const size_t test1_req_len = 8;
64 static const char *test1_req = "abcdefgh";
65
66 static void test1_callback(uint8_t *data, size_t length, void *private_data)
67 {
68         uint32_t len;
69
70         len = *(uint32_t *)data;
71         assert(len == sizeof(uint32_t) + test1_req_len);
72
73         assert(length == sizeof(uint32_t) + test1_req_len);
74         assert(memcmp(data  + sizeof(len), test1_req, test1_req_len) == 0);
75 }
76
77 static void test1(void)
78 {
79         struct ctdb_context *ctdb;
80         int fd, ret;
81         uint32_t pkt_size;
82
83         test_setup(test1_callback, &fd, &ctdb, NULL);
84
85         pkt_size = sizeof(uint32_t) + test1_req_len;
86         ret = write(fd, &pkt_size, sizeof(pkt_size));
87         assert(ret == sizeof(pkt_size));
88
89         ret = write(fd, test1_req, test1_req_len);
90         assert(ret == test1_req_len);
91
92         tevent_loop_once(ctdb->ev);
93
94         TALLOC_FREE(ctdb);
95 }
96
97 static const size_t test2_req_len[] = { 900, 24, 600 };
98
99 static int test2_cb_num = 0;
100
101 static void test2_callback(uint8_t *data, size_t length, void *private_data)
102 {
103         uint32_t len;
104
105         len = *(uint32_t *)data;
106         assert(len == sizeof(uint32_t) + test2_req_len[test2_cb_num]);
107         assert(length == sizeof(uint32_t) + test2_req_len[test2_cb_num]);
108
109         test2_cb_num++;
110 }
111
112 static void test2(void)
113 {
114         struct ctdb_context *ctdb;
115         int fd, ret, i;
116         uint32_t pkt_size;
117         char req[1024] = { 0 };
118
119         for (i = 0; i < sizeof(req); i++) {
120                 req[i] = i % CHAR_MAX;
121         }
122
123         test_setup(test2_callback, &fd, &ctdb, NULL);
124
125         /*
126          * request 0
127          */
128
129         pkt_size = sizeof(uint32_t) + test2_req_len[0];
130         ret = write(fd, &pkt_size, sizeof(pkt_size));
131         assert(ret == sizeof(pkt_size));
132
133         ret = write(fd, req, test2_req_len[0]);
134         assert(ret == test2_req_len[0]);
135
136         /*
137          * request 1
138          */
139         pkt_size = sizeof(uint32_t) + test2_req_len[1];
140         ret = write(fd, &pkt_size, sizeof(pkt_size));
141         assert(ret == sizeof(pkt_size));
142
143         /*
144          * Omit the last byte to avoid buffer processing.
145          */
146         ret = write(fd, req, test2_req_len[1] - 1);
147         assert(ret == test2_req_len[1] - 1);
148
149         tevent_loop_once(ctdb->ev);
150
151         /*
152          * Write the missing byte now.
153          */
154         ret = write(fd, &req[test2_req_len[1] - 1], 1);
155         assert(ret == 1);
156
157         /*
158          * request 2
159          */
160         pkt_size = sizeof(uint32_t) + test2_req_len[2];
161         ret = write(fd, &pkt_size, sizeof(pkt_size));
162         assert(ret == sizeof(pkt_size));
163
164         ret = write(fd, req, test2_req_len[2]);
165         assert(ret == test2_req_len[2]);
166
167         tevent_loop_once(ctdb->ev);
168         tevent_loop_once(ctdb->ev);
169
170         assert(test2_cb_num == 2);
171
172         TALLOC_FREE(ctdb);
173 }
174
175 int main(int argc, const char **argv)
176 {
177         int num;
178
179         if (argc != 2) {
180                 fprintf(stderr, "%s <testnum>\n", argv[0]);
181                 exit(1);
182         }
183
184
185         num = atoi(argv[1]);
186         switch (num) {
187         case 1:
188                 test1();
189                 break;
190
191         case 2:
192                 test2();
193                 break;
194
195         default:
196                 fprintf(stderr, "Unknown test number %s\n", argv[1]);
197         }
198
199         return 0;
200 }