initial version
[vlendec/samba-autobuild/.git] / ctdb / ctdb_test.c
1 /* 
2    ctdb test harness
3
4    Copyright (C) Andrew Tridgell  2006
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10
11    This library 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 GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "replace.h"
22 #include "system/filesys.h"
23 #include "tdb.h"
24 #include "talloc.h"
25 #include "ctdb.h"
26 #include "popt.h"
27
28 enum my_functions {FUNC_SORT=1, FUNC_FETCH=2};
29
30 static int int_compare(int *i1, int *i2)
31 {
32         return *i1 - *i2;
33 }
34
35 /*
36   add an integer into a record in sorted order
37 */
38 static int sort_func(struct ctdb_call *call)
39 {
40         if (call->call_data == NULL ||
41             call->call_data->dsize != sizeof(int)) {
42                 return CTDB_ERR_INVALID;
43         }
44         call->new_data = talloc(call, TDB_DATA);
45         if (call->new_data == NULL) {
46                 return CTDB_ERR_NOMEM;
47         }
48         call->new_data->dptr = talloc_size(call, 
49                                            call->record_data.dsize + 
50                                            call->call_data->dsize);
51         if (call->new_data->dptr == NULL) {
52                 return CTDB_ERR_NOMEM;
53         }
54         call->new_data->dsize = call->record_data.dsize + call->call_data->dsize;
55         memcpy(call->new_data->dptr+call->record_data.dsize,
56                call->call_data->dptr, call->call_data->dsize);
57         qsort(call->new_data->dptr, call->new_data->dsize / sizeof(int),
58               sizeof(int), (comparison_fn_t)int_compare);
59         return 0;
60 }
61
62 /*
63   ctdb call function to fetch a record
64 */
65 static int fetch_func(struct ctdb_call *call)
66 {
67         call->reply_data = &call->record_data;
68         return 0;
69 }
70
71 /*
72   main program
73 */
74 int main(int argc, const char *argv[])
75 {
76         struct ctdb_context *ctdb;
77         const char *nlist = NULL;
78         struct poptOption popt_options[] = {
79                 POPT_AUTOHELP
80                 { "nlist", 0, POPT_ARG_STRING, &nlist, 0, "node list file", "filename" },
81         };
82         int opt;
83         const char **extra_argv;
84         int extra_argc = 0;
85         int i, ret;
86         TDB_DATA key, data;
87         poptContext pc;
88
89         pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
90
91         while ((opt = poptGetNextOpt(pc)) != -1) {
92                 switch (opt) {
93                 default:
94                         fprintf(stderr, "Invalid option %s: %s\n", 
95                                 poptBadOption(pc, 0), poptStrerror(opt));
96                         exit(1);
97                 }
98         }
99
100         /* setup the remaining options for the main program to use */
101         extra_argv = poptGetArgs(pc);
102         if (extra_argv) {
103                 extra_argv++;
104                 while (extra_argv[extra_argc]) extra_argc++;
105         }
106
107         if (nlist == NULL) {
108                 printf("You must provide a node list with --nlist\n");
109                 exit(1);
110         }
111
112         /* initialise ctdb */
113         ctdb = ctdb_init(NULL);
114         if (ctdb == NULL) {
115                 printf("Failed to init ctdb\n");
116                 exit(1);
117         }
118
119         /* tell ctdb what nodes are available */
120         ret = ctdb_set_nlist(ctdb, nlist);
121         if (ret == -1) {
122                 printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb));
123                 exit(1);
124         }
125
126         /* setup a ctdb call function */
127         ret = ctdb_set_call(ctdb, sort_func,  FUNC_SORT);
128         ret = ctdb_set_call(ctdb, fetch_func, FUNC_FETCH);
129         
130         /* attach to a specific database */
131         ret = ctdb_attach(ctdb, "test.tdb", TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0666);
132         if (ret == -1) {
133                 printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb));
134                 exit(1);
135         }
136
137         key.dptr = "test";
138         key.dsize = strlen("test")+1;
139
140         /* add some random data */
141         for (i=0;i<100;i++) {
142                 int v = random();
143                 data.dptr = (uint8_t *)&v;
144                 data.dsize = sizeof(v);
145                 ret = ctdb_call(ctdb, key, FUNC_SORT, &data, NULL);
146                 if (ret == -1) {
147                         printf("ctdb_call FUNC_SORT failed - %s\n", ctdb_errstr(ctdb));
148                         exit(1);
149                 }
150         }
151
152         /* fetch the record */
153         ret = ctdb_call(ctdb, key, FUNC_FETCH, NULL, &data);
154         if (ret == -1) {
155                 printf("ctdb_call FUNC_FETCH failed - %s\n", ctdb_errstr(ctdb));
156                 exit(1);
157         }
158
159         for (i=0;i<data.dsize/sizeof(int);i++) {
160                 printf("%3d\n", ((int *)data.dptr)[i]);
161         }
162         
163         /* shut it down */
164         talloc_free(ctdb);
165         return 0;
166 }