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