d056442318ceba1427188547cc5c07290b4cd094
[idzebra-moved-to-github.git] / test / api / test_zebra_fork.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 2004-2013 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #if HAVE_SYS_STAT_H
24 #include <sys/stat.h>
25 #endif
26 #if HAVE_SYS_TYPES_H
27 #include <sys/types.h>
28 #endif
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #if HAVE_SYS_WAIT_H
33 #include <sys/wait.h>
34 #endif
35 #if HAVE_SYS_UTSNAME_H
36 #include <sys/utsname.h>
37 #endif
38
39 #include <string.h>
40
41 #include "testlib.h"
42
43 static void update_process(ZebraService zs, int iter)
44 {
45     int i;
46     for (i = 0; i<iter; i++)
47     {
48         const char *rec = "<gils><title>some</title></gils>";
49         ZebraHandle zh = zebra_open(zs, 0);
50         zebra_add_record(zh, rec, strlen(rec));
51         if ((i % 30) == 0 || i == iter-1)
52             zebra_commit(zh);
53         zebra_close(zh);
54     }
55 }
56
57 static void search_process(ZebraService zs, int iter)
58 {
59     zint hits_max = 0;
60     int i;
61     for (i = 0; i<iter; i++)
62     {
63         ZebraHandle zh = zebra_open(zs, 0);
64         zint hits;
65         ZEBRA_RES res = zebra_search_PQF(zh, "@attr 1=4 some", "default",
66                                          &hits);
67         YAZ_CHECK(res == ZEBRA_OK);
68
69         YAZ_CHECK(hits >= hits_max);
70         if (hits < hits_max)
71             printf("i=%d hits=%lld hits_max=%lld\n", i, hits, hits_max);
72         hits_max = hits;
73         zebra_close(zh);
74     }
75 }
76
77 static pid_t fork_service(ZebraService zs, int iter,
78                            void (*f)(ZebraService zs, int iter))
79 {
80     pid_t pid = fork();
81
82     YAZ_CHECK(pid != -1);
83     if (pid)
84         return pid;
85
86     (*f)(zs, iter);
87     YAZ_CHECK_TERM;
88 }
89
90 static void tst(int argc, char **argv)
91 {
92     ZebraService zs;
93     ZebraHandle zh;
94
95     mkdir("register", 0775);
96     mkdir("shadow", 0775);
97
98     zs = tl_start_up("test_zebra_fork.cfg", argc, argv);
99     YAZ_CHECK(zs);
100
101     zh = zebra_open(zs, 0);
102     YAZ_CHECK(zh);
103
104     YAZ_CHECK(zebra_select_database(zh, "Default") == ZEBRA_OK);
105
106     zebra_init(zh);
107
108     YAZ_CHECK(zebra_create_database (zh, "Default") == ZEBRA_OK);
109     YAZ_CHECK(zebra_select_database(zh, "Default") == ZEBRA_OK);
110     zebra_close(zh);
111
112     update_process(zs, 1);
113
114 #if HAVE_SYS_WAIT_H
115 #if HAVE_UNISTD_H
116 #if HAVE_SYS_UTSNAME_H
117
118     if (1)
119     {
120         int tst_with_fork = 1;
121         int status[3];
122         pid_t pids[3];
123         struct utsname s;
124         uname(&s);
125         if (!strcmp(s.sysname, "FreeBSD"))
126             tst_with_fork = 0;
127
128         yaz_log(YLOG_LOG, "s.sysname=%s tst_with_fork=%d", s.sysname,
129             tst_with_fork);
130         if (tst_with_fork)
131         {
132             pids[0] = fork_service(zs, 200, search_process);
133             pids[1] = fork_service(zs, 20, update_process);
134             pids[2] = fork_service(zs, 20, update_process);
135             waitpid(pids[0], &status[0], 0);
136             YAZ_CHECK(status[0] == 0);
137             waitpid(pids[1], &status[1], 0);
138             YAZ_CHECK(status[1] == 0);
139             waitpid(pids[2], &status[2], 0);
140             YAZ_CHECK(status[2] == 0);
141         }
142     }
143 #endif
144 #endif
145 #endif
146     YAZ_CHECK(tl_close_down(0, zs));
147 }
148
149 TL_MAIN
150 /*
151  * Local variables:
152  * c-basic-offset: 4
153  * c-file-style: "Stroustrup"
154  * indent-tabs-mode: nil
155  * End:
156  * vim: shiftwidth=4 tabstop=8 expandtab
157  */
158