5f69531dddc8bbcbc67ff78680b87b9ea0412f98
[yaz-moved-to-github.git] / test / test_solr.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdlib.h>
10 #include <yaz/srw.h>
11 #if YAZ_HAVE_XML2
12 #include <libxml/parser.h>
13 #endif
14 #include <yaz/test.h>
15 #include <yaz/yaz-version.h>
16 #include <yaz/pquery.h>
17
18 #if YAZ_HAVE_XML2
19 int compare_solr_req(ODR odr, Z_SRW_PDU *sr,
20                      const char *charset, const char *expect)
21 {
22     int r;
23     Z_GDU *gdu = 0;
24     YAZ_CHECK(sr);
25
26     if (!sr)
27         return 0;
28
29     gdu = z_get_HTTP_Request_host_path(odr, "localhost", "Default");
30     YAZ_CHECK(gdu);
31     if (!gdu)
32         return 0;
33
34     yaz_solr_encode_request(gdu->u.HTTP_Request, sr, odr, charset);
35
36     r = z_GDU(odr, &gdu, 0, 0);
37     YAZ_CHECK(r);
38     if (r)
39     {
40         int len = 0;
41         char *buf = odr_getbuf(odr, &len, 0);
42         
43         if (buf)
44         {
45             if (len == strlen(expect) && !memcmp(buf, expect, len))
46             {
47                 odr_reset(odr);
48                 return 1;
49             }
50             yaz_log(YLOG_WARN, "Expect:\n%s\n", expect);
51             yaz_log(YLOG_WARN, "Got:\n%.*s\n", len, buf);
52          }
53     }
54     odr_reset(odr);
55     return 0;
56 }
57 #endif
58
59 void tst_encoding(void)
60 {
61 #if YAZ_HAVE_XML2
62     ODR odr = odr_createmem(ODR_ENCODE);
63
64     {
65         Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request,
66                                         "1.2");
67         
68         YAZ_CHECK(compare_solr_req(
69                       odr, sr, 0,
70                       "GET Default/select? HTTP/1.1\r\n"
71                       "User-Agent: YAZ/" YAZ_VERSION "\r\n"
72                       "Host: localhost\r\n"
73                       "Content-Type: text/xml\r\n\r\n"));
74     }
75
76     {
77         Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request,
78                                         "1.2");
79         YAZ_CHECK(compare_solr_req(
80                       odr, sr, "utf-8",
81                       "GET Default/select? HTTP/1.1\r\n"
82                       "User-Agent: YAZ/" YAZ_VERSION "\r\n"
83                       "Host: localhost\r\n"
84                       "Content-Type: text/xml; charset=utf-8\r\n\r\n"));
85     }
86
87     {
88         Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request,
89                                         "1.2");
90         
91         sr->u.request->query_type = Z_SRW_query_type_cql;
92         sr->u.request->query.cql = "title:solr";
93         sr->u.request->startRecord = odr_intdup(odr, 3);
94         sr->u.request->maximumRecords = odr_intdup(odr, 10);
95
96         YAZ_CHECK(compare_solr_req(
97                       odr, sr, 0,
98                       "GET Default/select?q=title%3Asolr&start=2&rows=10"
99                       " HTTP/1.1\r\n"
100                       "User-Agent: YAZ/" YAZ_VERSION "\r\n"
101                       "Host: localhost\r\n"
102                       "Content-Type: text/xml\r\n\r\n"));
103     }
104
105     {
106         Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request,
107                                         "1.2");
108         
109         sr->u.request->query_type = Z_SRW_query_type_cql;
110         sr->u.request->query.cql = "title:solr";
111         sr->u.request->startRecord = odr_intdup(odr, 3);
112         sr->u.request->maximumRecords = odr_intdup(odr, 10);
113         sr->u.request->facetList = yaz_pqf_parse_facet_list(
114             odr, "@attr 1=date @attr 2=0, @attr 1=title_exact @attr 3=17");
115
116         YAZ_CHECK(compare_solr_req(
117                       odr, sr, 0,
118                       "GET Default/select?q=title%3Asolr&start=2&rows=10"
119                       "&facet=true&facet.mincount=1&facet.field=date"
120                       "&facet.field=title_exact&f.title_exact.facet.limit=17"
121                       " HTTP/1.1\r\n"
122                       "User-Agent: YAZ/" YAZ_VERSION "\r\n"
123                       "Host: localhost\r\n"
124                       "Content-Type: text/xml\r\n\r\n"));
125     }
126
127     odr_destroy(odr);
128 /* YAZ_HAVE_XML2 */
129 #endif
130 }
131
132
133 int check_response(ODR o, const char *content, Z_SRW_searchRetrieveResponse **p)
134 {
135     int r;
136     Z_GDU *gdu;
137     Z_SRW_PDU *sr_p;
138     char *http_response = odr_malloc(o, strlen(content) + 300);
139
140     strcpy(http_response, 
141            "HTTP/1.1 200 OK\r\n"
142            "Last-Modified: Wed, 13 Apr 2011 08:30:59 GMT\r\n"
143            "ETag: \"MjcyMWE5M2JiNDgwMDAwMFNvbHI=\"\r\n"
144            "Content-Type: text/xml; charset=utf-8\r\n");
145     sprintf(http_response + strlen(http_response),
146             "Content-Length: %d\r\n\r\n", (int) strlen(content));
147     strcat(http_response, content);
148
149     odr_setbuf(o, http_response, strlen(http_response), 0);
150
151     r = z_GDU(o, &gdu, 0, 0);
152     if (!r || gdu->which != Z_GDU_HTTP_Response)
153         return 0;
154     r = yaz_solr_decode_response(o, gdu->u.HTTP_Response, &sr_p);
155     if (r)
156         return 0;
157     if (sr_p->which != Z_SRW_searchRetrieve_response)
158         return 0;
159     *p = sr_p->u.response;
160     return 1;
161 }
162
163 void tst_decoding(void)
164 {
165 #if YAZ_HAVE_XML2
166     ODR odr = odr_createmem(ODR_DECODE);
167     Z_SRW_searchRetrieveResponse *response;
168
169     YAZ_CHECK(check_response(
170                   odr, 
171                   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
172                   "<response>\n"
173                   "<lst name=\"responseHeader\"><int name=\"status\">0</int>"
174                   "<int name=\"QTime\">1</int><lst name=\"params\">"
175                   "<str name=\"start\">0</str><str name=\"q\">@attr 1=title solr</str>"
176                   "<str name=\"rows\">0</str></lst>"
177                   "</lst><result name=\"response\" numFound=\"91\" start=\"0\"/>\n"
178                   "</response>\n", &response));
179     YAZ_CHECK_EQ(*response->numberOfRecords, 91);
180     YAZ_CHECK_EQ(response->num_records, 0);
181     YAZ_CHECK(response->records == 0);
182     YAZ_CHECK_EQ(response->num_diagnostics, 0);
183     YAZ_CHECK(response->diagnostics == 0);
184     YAZ_CHECK(response->nextRecordPosition == 0);
185     YAZ_CHECK(response->facetList == 0);
186
187     odr_reset(odr);
188
189     YAZ_CHECK(
190         check_response(
191             odr, 
192             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
193             "<response><lst name=\"responseHeader\">"
194             "<int name=\"status\">0</int><int name=\"QTime\">2</int>"
195             "<lst name=\"params\"><str name=\"facet\">true</str>"
196             "<str name=\"facet.mincount\">1</str><str name=\"start\">0</str>"
197             "<str name=\"q\">@attr 1=title solr</str>"
198             "<str name=\"f.date.facet.limit\">5</str>"
199             "<str name=\"facet.field\">date</str>"
200             "<str name=\"rows\">1</str></lst>"
201             "</lst><result name=\"response\" numFound=\"91000000000\" start=\"0\">"
202             "<doc><str name=\"author\">Alenius, Hans,</str>"
203             "<str name=\"author-date\">1937-</str>"
204             "<str name=\"author-title\"/>"
205             "<arr name=\"date\"><str>1969</str></arr>"
206             "<str name=\"id\">   73857731 </str>"
207             "<arr name=\"lccn\"><str>   73857731 </str></arr>"
208             "<arr name=\"medium\"><str>book</str></arr>"
209             "<arr name=\"medium_exact\"><str>book</str></arr>"
210             "<arr name=\"physical-accomp\"><str/></arr>"
211             "<arr name=\"physical-dimensions\"><str>20 cm.</str></arr>"
212             "<arr name=\"physical-extent\"><str>140, (1) p.</str></arr>"
213             "<arr name=\"physical-format\"><str>illus.</str></arr>"
214             "<arr name=\"physical-specified\"><str/></arr>"
215             "<arr name=\"physical-unitsize\"><str/></arr>"
216             "<arr name=\"physical-unittype\"><str/></arr>"
217             "<arr name=\"publication-date\"><str>1969.</str></arr>"
218             "<arr name=\"publication-name\"><str>Norstedt,</str></arr>"
219             "<arr name=\"publication-place\"><str>Stockholm,</str></arr>"
220             "<arr name=\"subject\"><str>Photography</str><str>Artistic</str></arr>"
221             "<arr name=\"subject-long\"><str>Photography, Artistic.</str></arr>"
222             "<arr name=\"subject_exact\"><str>Photography</str><str>Artistic</str></arr>"
223             "<arr name=\"system-control-nr\"><str>(OCoLC)36247690</str></arr>"
224             "<str name=\"title\">Solring.</str><str name=\"title-complete\">Solring.</str>"
225             "<str name=\"title-dates\"/><str name=\"title-medium\"/>"
226             "<str name=\"title-number-section\"/><str name=\"title-remainder\"/>"
227             "<str name=\"title-responsibility\"/><str name=\"title_exact\">Solring.</str>"
228             "</doc></result><lst name=\"facet_counts\">"
229             "<lst name=\"facet_queries\"/>"
230             "<lst name=\"facet_fields\">"
231             "<lst name=\"date\"><int name=\"1978\">5000000000</int><int name=\"1983\">4</int>"
232             "<int name=\"1987\">4</int><int name=\"1988\">4</int>"
233             "<int name=\"2003\">3</int></lst></lst><lst name=\"facet_dates\"/>"
234             "</lst></response>", &response));
235 #if HAVE_LONG_LONG
236     YAZ_CHECK(*response->numberOfRecords == 91000000000LL);
237 #endif
238     YAZ_CHECK_EQ(response->num_records, 1);
239     YAZ_CHECK(response->records);
240     if (response->records)
241     {
242         const char *doc =
243             "<doc><str name=\"author\">Alenius, Hans,</str>"
244             "<str name=\"author-date\">1937-</str>"
245             "<str name=\"author-title\"/>"
246             "<arr name=\"date\"><str>1969</str></arr>"
247             "<str name=\"id\">   73857731 </str>"
248             "<arr name=\"lccn\"><str>   73857731 </str></arr>"
249             "<arr name=\"medium\"><str>book</str></arr>"
250             "<arr name=\"medium_exact\"><str>book</str></arr>"
251             "<arr name=\"physical-accomp\"><str/></arr>"
252             "<arr name=\"physical-dimensions\"><str>20 cm.</str></arr>"
253             "<arr name=\"physical-extent\"><str>140, (1) p.</str></arr>"
254             "<arr name=\"physical-format\"><str>illus.</str></arr>"
255             "<arr name=\"physical-specified\"><str/></arr>"
256             "<arr name=\"physical-unitsize\"><str/></arr>"
257             "<arr name=\"physical-unittype\"><str/></arr>"
258             "<arr name=\"publication-date\"><str>1969.</str></arr>"
259             "<arr name=\"publication-name\"><str>Norstedt,</str></arr>"
260             "<arr name=\"publication-place\"><str>Stockholm,</str></arr>"
261             "<arr name=\"subject\"><str>Photography</str><str>Artistic</str></arr>"
262             "<arr name=\"subject-long\"><str>Photography, Artistic.</str></arr>"
263             "<arr name=\"subject_exact\"><str>Photography</str><str>Artistic</str></arr>"
264             "<arr name=\"system-control-nr\"><str>(OCoLC)36247690</str></arr>"
265             "<str name=\"title\">Solring.</str><str name=\"title-complete\">Solring.</str>"
266             "<str name=\"title-dates\"/><str name=\"title-medium\"/>"
267             "<str name=\"title-number-section\"/><str name=\"title-remainder\"/>"
268             "<str name=\"title-responsibility\"/><str name=\"title_exact\">Solring.</str>"
269             "</doc>";
270
271         Z_SRW_record *record = response->records;
272         
273         YAZ_CHECK(record->recordData_len == strlen(doc) &&
274                   !memcmp(record->recordData_buf, doc, record->recordData_len));
275     }
276     YAZ_CHECK_EQ(response->num_diagnostics, 0);
277     YAZ_CHECK(response->diagnostics == 0);
278     YAZ_CHECK(response->nextRecordPosition == 0);
279
280     YAZ_CHECK(response->facetList);
281     if (response->facetList)
282     {
283         Z_FacetList *facetList = response->facetList;
284
285         YAZ_CHECK(facetList->num == 1);
286         if (facetList->num == 1)
287         {
288             Z_FacetField *facetField = facetList->elements[0];
289             int i;
290
291             YAZ_CHECK(facetField->num_terms == 5);
292             if (facetField->num_terms == 5)
293             {
294                 for (i = 0; i < facetField->num_terms; i++)
295                 {
296                     YAZ_CHECK(
297                         facetField->terms[i] &&
298                         facetField->terms[i]->term &&
299                         facetField->terms[i]->term->which == Z_Term_general);
300                 }
301 #if HAVE_LONG_LONG
302                 YAZ_CHECK(*facetField->terms[0]->count == 5000000000LL);
303 #endif
304                 YAZ_CHECK(facetField->terms[0]->term->u.general->len == 4
305                           && !memcmp(facetField->terms[0]->term->u.general->buf,
306                                      "1978", 4));
307                 YAZ_CHECK(*facetField->terms[1]->count == 4);
308                 YAZ_CHECK(facetField->terms[1]->term->u.general->len == 4
309                           && !memcmp(facetField->terms[1]->term->u.general->buf,
310                                      "1983", 4));
311                 YAZ_CHECK(*facetField->terms[2]->count == 4);
312                 YAZ_CHECK(facetField->terms[2]->term->u.general->len == 4
313                           && !memcmp(facetField->terms[2]->term->u.general->buf,
314                                      "1987", 4));
315                 YAZ_CHECK(*facetField->terms[3]->count == 4);
316                 YAZ_CHECK(facetField->terms[3]->term->u.general->len == 4
317                           && !memcmp(facetField->terms[3]->term->u.general->buf,
318                                      "1988", 4));
319                 YAZ_CHECK(*facetField->terms[4]->count == 3);
320                 YAZ_CHECK(facetField->terms[4]->term->u.general->len == 4
321                           && !memcmp(facetField->terms[4]->term->u.general->buf,
322                                      "2003", 4));
323             }
324         }
325     }
326
327     odr_reset(odr);
328
329     odr_destroy(odr);
330 #endif
331 }
332 int main(int argc, char **argv)
333 {
334     YAZ_CHECK_INIT(argc, argv);
335 #if YAZ_HAVE_XML2
336     LIBXML_TEST_VERSION;
337 #endif
338     tst_encoding();
339     tst_decoding();
340     YAZ_CHECK_TERM;
341 }
342
343
344 /*
345  * Local variables:
346  * c-basic-offset: 4
347  * c-file-style: "Stroustrup"
348  * indent-tabs-mode: nil
349  * End:
350  * vim: shiftwidth=4 tabstop=8 expandtab
351  */
352