* Copyright (c) 2004, Index Data.
* See the file LICENSE for details.
*
- * $Id: zlint.cpp,v 1.4 2004-03-20 15:06:53 adam Exp $
+ * $Id: zlint.cpp,v 1.12 2005-09-22 12:40:45 adam Exp $
*/
-#include <yaz/pquery.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <yaz/comstack.h>
#include <yaz/options.h>
#include <yaz/otherinfo.h>
#include <yaz/charneg.h>
-#include <yaz/sortspec.h>
#include <yaz/log.h>
-#include <yaz++/pdu-assoc.h>
-#include <yaz++/socket-manager.h>
-#include <yaz++/z-assoc.h>
-
-#define REFID_BUF1 "zlint\000check1"
-#define REFID_LEN1 12
-#define REFID_BUF2 "zlint\000check2"
-#define REFID_LEN2 12
-enum Zlint_code {
- TEST_FINISHED,
- TEST_CONTINUE,
-};
+#include <zlint.h>
-class Zlint;
-
-class Zlint_test {
-public:
- virtual Zlint_code init(Zlint *z) = 0;
- virtual Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu) = 0;
- virtual Zlint_code recv_fail(Zlint *z, int reason) = 0;
-};
-
-const char *try_syntax [] = {
- "usmarc",
- "unimarc",
- "danmarc",
- "sutrs",
- "grs1",
- "xml",
- "normarc",
- 0
-};
-const char *try_query[] = {
- "@attr 1=4 petersson",
- "@attr 1=1016 petersson",
- "@attr 1=4 kingdom",
- "@attr 1=1016 kingdom",
- "@attr 1=62 sword",
- "sword"
- "seven",
- "@attr 1=4 water",
- "@attr 1=1016 water",
- "computer",
- "@attr 1=4 computer",
- "@attr 1=1016 computer",
- "water",
- "join",
- "about",
- "map",
- 0,
-};
-
-const char *try_sort [] = {
- "1=4 <",
- "1=4 >",
- "1=62 >",
- "1=62 <",
- 0
-};
-const char *try_scan [] = {
- "@attr 1=4 ab",
- "@attr 1=1003 ab",
- "@attr 1=1016 ab",
- 0
-};
-
-#define TEST_STATE_FAIL 0
-#define TEST_STATE_UNKNOWN 1
-#define TEST_STATE_OK 2
-#define TEST_STATE_NOT_APPLIC 3
-
-class Zlint : public Yaz_Z_Assoc {
- int m_tst_no;
-
- int m_subtst_no;
-
- int m_test_state;
- int m_query_no;
- int m_scan_no;
- int m_sort_no;
- int m_record_syntax_no;
- int m_got_result_set;
- IYaz_PDU_Observable *m_PDU_Observable;
- char *m_host;
- char *m_database;
- int m_timeout_init;
- int m_timeout_connect;
- int m_protocol_version;
- char m_session_str[20];
-public:
- int initResponseGetVersion(Z_InitResponse *init);
- void prepare();
- void recv_GDU(Z_GDU *apdu, int len);
- Zlint(IYaz_PDU_Observable *the_PDU_Observable);
- void args(int argc, char **argv);
- void connectNotify();
- void failNotify();
- void closeNextTest();
- void sendTest();
- int nextTest();
- void testContinue();
- void timeoutNotify();
- IYaz_PDU_Observer *sessionNotify(
- IYaz_PDU_Observable *the_PDU_Observable, int fd);
- void connect();
- Z_ReferenceId *mk_refid(const char *buf, int len);
-};
-
-int Zlint::initResponseGetVersion(Z_InitResponse *init)
+Zlint_test::~Zlint_test()
{
- int no = 0;
- int off = 0;
- int i;
- for (i = 0; i<12; i++)
- if (ODR_MASK_GET(init->protocolVersion, no))
- {
- no = i+1;
- if (off)
- yaz_log(LOG_WARN, "%sbad formatted version");
- }
- else
- off = 1;
- return no;
-}
-Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
-{
- Z_ReferenceId *id =
- (Z_ReferenceId *) odr_malloc(odr_encode(), sizeof(*id));
- id->size = id->len = len;
- id->buf = (unsigned char*) odr_malloc(odr_encode(), len);
- memcpy(id->buf, buf, len);
- return id;
}
-void Zlint::recv_GDU(Z_GDU *gdu, int len)
-{
- if (gdu->which != Z_GDU_Z3950)
- {
- yaz_log(LOG_LOG, "%sreceived non-Z39.50 response", m_session_str);
- closeNextTest();
- }
- if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_initResponse)
- {
- int i;
- Z_InitResponse *init = gdu->u.z3950->u.initResponse;
- int ver = initResponseGetVersion(init);
- int result = init->result ? *init->result : 0;
- if (!result)
- yaz_log(LOG_WARN, "%sinit rejected");
- switch(m_tst_no)
- {
- case 0:
- if (ver > 3 || ver < 2)
- yaz_log(LOG_WARN, "%sgot version %d, expected 2 or 3",
- m_session_str, ver);
- else
- m_test_state = TEST_STATE_OK;
- m_protocol_version = ver;
- if (!result)
- closeNextTest();
- else
- {
- close();
- nextTest();
- }
- break;
- case 1:
- if (ver != 2)
- yaz_log(LOG_WARN, "%sgot version %d, expected 2",
- m_session_str, ver);
- else
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- break;
- case 2:
- if (ver < 2 || ver > 5)
- yaz_log(LOG_WARN, "%sgot version %d, expected 2-5",
- m_session_str,ver);
- else
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- break;
- case 3:
- if (!init->referenceId)
- yaz_log(LOG_WARN, "%smissing referenceID from init response",
- m_session_str);
- else if (init->referenceId->len != REFID_LEN1
- || memcmp(init->referenceId->buf, REFID_BUF1, REFID_LEN1))
- yaz_log(LOG_WARN, "%sreference ID does not match");
- else
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- break;
- case 4:
- if (m_subtst_no == 0)
- {
- if (!init->referenceId)
- yaz_log(LOG_WARN, "%smissing referenceID from first init response",
- m_session_str);
- else if (init->referenceId->len != REFID_LEN1
- || memcmp(init->referenceId->buf, REFID_BUF1, REFID_LEN1))
- yaz_log(LOG_WARN, "%sreference ID does not match");
- m_subtst_no++;
- }
- else
- {
- if (!init->referenceId)
- yaz_log(LOG_WARN, "%smissing referenceID from second init response",
- m_session_str);
- else if (init->referenceId->len != REFID_LEN2
- || memcmp(init->referenceId->buf, REFID_BUF2, REFID_LEN2))
- yaz_log(LOG_WARN, "%sreference ID does not match");
- else
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- }
- break;
- case 5:
- if (init->options)
- {
- int i;
- int no_set = 0;
- int no_reset = 0;
- for (i = 0; i <= 24; i++)
- if (ODR_MASK_GET(init->options, i))
- no_set++;
- else
- no_reset++;
- if (no_set < 2)
- yaz_log(LOG_WARN, "%ssuspicuously few option bits set",
- m_session_str);
- if (no_reset == 0)
- yaz_log(LOG_WARN, "%ssuspicuously many option bits set",
- m_session_str);
- if (no_set >= 2 && no_reset)
- m_test_state = TEST_STATE_OK;
- }
- closeNextTest();
- break;
- case 6:
- if (ODR_MASK_GET(init->options, Z_Options_negotiationModel))
- {
- Z_CharSetandLanguageNegotiation *p =
- yaz_get_charneg_record(init->otherInfo);
-
- if (p) {
-
- char *charset=NULL, *lang=NULL;
- int selected;
- NMEM m = nmem_create();
-
- yaz_get_response_charneg(m, p, &charset, &lang,
- &selected);
- yaz_log(LOG_DEBUG, "%sAccepted character set : %s",
- m_session_str, charset);
- yaz_log(LOG_DEBUG, "%sAccepted code language : %s",
- m_session_str, lang ? lang : "none");
- yaz_log(LOG_DEBUG, "%sAccepted records in ...: %d",
- m_session_str, selected );
- nmem_destroy(m);
- m_test_state = TEST_STATE_OK;
- }
- }
- else
- m_test_state = TEST_STATE_NOT_APPLIC;
- closeNextTest();
- break;
- case 7:
- if (m_subtst_no * m_subtst_no * 100000 + 2000 < *init->maximumRecordSize)
- {
- yaz_log(LOG_WARN, "%smaximumRecordSize bigger than proposed size");
- closeNextTest();
- }
- else if (m_subtst_no * m_subtst_no * 100000 + 2000 < *init->preferredMessageSize)
- {
- yaz_log(LOG_WARN, "%smaximumRecordSize bigger than proposed size");
- closeNextTest();
- }
- else if (m_subtst_no < 3)
- {
- close();
- m_subtst_no++;
- connect();
- }
- else
- {
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- }
- break;
- case 9:
- if (result && ODR_MASK_GET(init->options, Z_Options_scan))
- sendTest();
- else
- {
- m_test_state = TEST_STATE_NOT_APPLIC;
- closeNextTest();
- }
- break;
- case 10:
- if (result && ODR_MASK_GET(init->options, Z_Options_sort))
- sendTest();
- else
- {
- m_test_state = TEST_STATE_NOT_APPLIC;
- closeNextTest();
- }
- break;
- default:
- if (result)
- sendTest();
- else
- {
- m_test_state = TEST_STATE_NOT_APPLIC;
- closeNextTest();
- }
- }
- }
- else if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_searchResponse)
- {
- Z_SearchResponse *sr = gdu->u.z3950->u.searchResponse;
- switch(m_tst_no)
- {
- case 8:
- if (sr->records && (sr->records->which == Z_Records_NSD
- ||
- sr->records->which == Z_Records_multipleNSD))
- {
- yaz_log(LOG_WARN, "%sSearch Error", m_session_str);
- m_query_no++;
- sendTest();
- }
- else if (!sr->resultCount || *sr->resultCount == 0)
- {
- m_query_no++;
- sendTest();
- }
- else
- {
- yaz_log(LOG_DEBUG, "%sgot %d result count with %s",
- m_session_str, *sr->resultCount,
- try_query[m_query_no]);
- m_got_result_set = 1;
- sendTest();
- }
- break;
- case 10:
- if (sr->resultCount && *sr->resultCount > 0)
- {
- m_got_result_set = 1;
- sendTest();
- }
- else
- {
- closeNextTest();
- }
- break;
- default:
- closeNextTest();
- }
- }
- else if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_presentResponse)
- {
- Z_PresentResponse *sr = gdu->u.z3950->u.presentResponse;
- switch(m_tst_no)
- {
- case 8:
- if (sr->records && (sr->records->which == Z_Records_NSD
- ||
- sr->records->which == Z_Records_multipleNSD))
- {
- yaz_log(LOG_LOG, "%spresent returned NSD for %s",
- m_session_str, try_syntax[m_record_syntax_no]);
- }
- else if (sr->records && sr->records->which == Z_Records_DBOSD
- && sr->records->u.databaseOrSurDiagnostics->num_records>0
- && sr->records->u.databaseOrSurDiagnostics->records[0])
- {
- if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_databaseRecord)
- {
- Z_External *ext = sr->records->u.databaseOrSurDiagnostics->records[0]->u.databaseRecord;
- Odr_oid *expectRecordSyntax =
- yaz_str_to_z3950oid(odr_decode(), CLASS_RECSYN,
- try_syntax[m_record_syntax_no]);
- if (oid_oidcmp(expectRecordSyntax,
- ext->direct_reference))
- yaz_log(LOG_WARN, "%sGot Record in different syntax from that required %s",
- m_session_str,
- try_syntax[m_record_syntax_no]);
- else
- {
- yaz_log(LOG_DEBUG, "%spresent OK for %s", m_session_str,
- try_syntax[m_record_syntax_no]);
- m_test_state = TEST_STATE_OK;
- }
- }
- else if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_surrogateDiagnostic)
- yaz_log(LOG_DEBUG, "%spresent returned SD %s", m_session_str,
- try_syntax[m_record_syntax_no]);
- else
- yaz_log(LOG_WARN, "%spresent returned fragment %s",
- m_session_str,
- try_syntax[m_record_syntax_no]);
- }
- else
- {
- yaz_log(LOG_WARN, "%spresent returned no records or diagnostics", m_session_str);
-
- }
- m_record_syntax_no++;
- sendTest();
- }
- }
- else if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_scanResponse)
- {
- Z_ScanResponse *sr = gdu->u.z3950->u.scanResponse;
- switch(m_tst_no)
- {
- case 9:
- if (sr->entries->nonsurrogateDiagnostics)
- {
- yaz_log(LOG_LOG, "%sscan NSD for %s", m_session_str,
- try_scan[m_scan_no]);
- m_scan_no++;
- sendTest();
- }
- else if (sr->entries->entries && sr->entries->num_entries > 0)
- {
- yaz_log(LOG_DEBUG, "%sscan OK for %s", m_session_str,
- try_scan[m_scan_no]);
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- }
- else
- {
- yaz_log(LOG_WARN, "%sscan no entries/diagnostics for %s",
- m_session_str,
- try_scan[m_scan_no]);
- m_scan_no++;
- sendTest();
- }
- break;
- default:
- closeNextTest();
- }
- }
- else if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_sortResponse)
- {
- Z_SortResponse *sr = gdu->u.z3950->u.sortResponse;
- switch(m_tst_no)
- {
- case 10:
- if (sr->diagnostics)
- {
- yaz_log(LOG_LOG, "%ssort NSD for %s", m_session_str,
- try_sort[m_sort_no]);
- m_sort_no++;
- sendTest();
- }
- else
- {
- yaz_log(LOG_DEBUG, "%ssort OK for %s", m_session_str,
- try_sort[m_sort_no]);
- m_test_state = TEST_STATE_OK;
- closeNextTest();
- }
- break;
- default:
- closeNextTest();
- }
- }
- else
- closeNextTest();
-}
+class Zlint_t {
+public:
+ friend class Zlint;
+ Zlint_t(Zlint_test *t);
+ ~Zlint_t();
+private:
+ Zlint_test *m_t;
+ Zlint_t *m_next;
+ int m_test_number_sequence;
+ int m_test_ok;
+ int m_test_reported;
+};
-Zlint::Zlint(IYaz_PDU_Observable *the_PDU_Observable) :
- Yaz_Z_Assoc(the_PDU_Observable)
+Zlint::Zlint(IPDU_Observable *the_PDU_Observable) :
+ Z_Assoc(the_PDU_Observable)
+
{
m_PDU_Observable = the_PDU_Observable;
m_host = 0;
+ m_tests = 0;
+ m_cur_test = 0;
m_database = 0;
- m_timeout_connect = 30;
- m_timeout_init = 30;
- m_tst_no = -1;
- m_subtst_no = 0;
- m_protocol_version = 0;
- sprintf(m_session_str, "%d ", m_tst_no);
}
-void Zlint::connectNotify()
+Zlint::~Zlint()
{
- Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
- Z_InitRequest *init = apdu->u.initRequest;
- int len;
- Z_OtherInformation **oi;
-
- timeout(m_timeout_init);
-
- switch(m_tst_no)
+ while (m_tests)
{
- case 0:
- /* check if target properly negotiates to v3 .. */
- ODR_MASK_ZERO(init->protocolVersion);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_1);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_2);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- break;
- case 1:
- /* check if target properly negotiates to v2 .. */
- ODR_MASK_ZERO(init->protocolVersion);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_1);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_2);
- break;
- case 2:
- /* check latest version of target - up to v9 */
- ODR_MASK_ZERO(init->protocolVersion);
- int i;
- for (i = 0; i< 9; i++)
- ODR_MASK_SET(init->protocolVersion, i);
- break;
- case 3:
- /* send refID in init request */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- init->referenceId = mk_refid(REFID_BUF1, REFID_LEN1);
- break;
- case 4:
- /* send double init with differnet refID's */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_SET(init->options, Z_Options_concurrentOperations);
- init->referenceId = mk_refid(REFID_BUF1, REFID_LEN1);
- send_Z_PDU(apdu, &len);
-
- apdu = create_Z_PDU(Z_APDU_initRequest);
- init = apdu->u.initRequest;
-
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_SET(init->options, Z_Options_concurrentOperations);
-
- init->referenceId = mk_refid(REFID_BUF2, REFID_LEN2);
- break;
- case 5:
- /* set all options.. see what target really supports .. */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_ZERO(init->options);
- for (i = 0; i <= 24; i++)
- ODR_MASK_SET(init->options, i);
- break;
- case 6:
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- yaz_oi_APDU(apdu, &oi);
- if (oi)
- {
- Z_OtherInformationUnit *p0;
- const char *negotiationCharset[] = {
- "UTF-8",
- "UTF-16",
- "UCS-2",
- "UCS-4",
- "ISO-8859-1"
- };
- char *yazLang = 0;
-
- if ((p0=yaz_oi_update(oi, odr_encode(), NULL, 0, 0))) {
- ODR_MASK_SET(init->options, Z_Options_negotiationModel);
-
- p0->which = Z_OtherInfo_externallyDefinedInfo;
- p0->information.externallyDefinedInfo =
-
- yaz_set_proposal_charneg(
- odr_encode(),
- negotiationCharset, 5,
- (const char**)&yazLang, yazLang ? 1 : 0, 1);
- }
- }
- break;
- case 7:
- *init->maximumRecordSize = m_subtst_no * m_subtst_no* 100000 + 2000;
- *init->preferredMessageSize = m_subtst_no * m_subtst_no *100000 + 2000;
- break;
- case 8:
- /* search */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_SET(init->options, Z_Options_namedResultSets);
- break;
- case 9:
- /* scan */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_SET(init->options, Z_Options_namedResultSets);
- ODR_MASK_SET(init->options, Z_Options_scan);
- break;
- case 10:
- /* sort */
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
- ODR_MASK_SET(init->options, Z_Options_namedResultSets);
- ODR_MASK_SET(init->options, Z_Options_sort);
- break;
- }
- int r = send_Z_PDU(apdu, &len);
-}
-
-int Zlint::nextTest()
-{
- if (m_tst_no >= 0)
- {
- switch(m_test_state)
- {
- case TEST_STATE_FAIL:
- yaz_log(LOG_LOG, "%sTest Failed", m_session_str);
- break;
- case TEST_STATE_OK:
- yaz_log(LOG_LOG, "%sTest Passed", m_session_str);
- break;
- case TEST_STATE_NOT_APPLIC:
- yaz_log(LOG_LOG, "%sTest Not Applicable", m_session_str);
- break;
- case TEST_STATE_UNKNOWN:
- yaz_log(LOG_LOG, "%sTest Could not be performed", m_session_str);
- }
- }
- m_test_state = TEST_STATE_FAIL;
- m_subtst_no = 0;
- connect();
- while(1)
- {
- m_tst_no++;
- sprintf(m_session_str, "%d ", m_tst_no);
- switch(m_tst_no)
- {
- case 0:
- yaz_log(LOG_LOG, "%sCheck for init v3",
- m_session_str);
- return 1;
- case 1:
- yaz_log(LOG_LOG, "%sCheck for init v2",
- m_session_str);
- return 1;
- case 2:
- yaz_log(LOG_LOG, "%sCheck for init protocol version negotiation",
- m_session_str);
- return 1;
- case 3:
- yaz_log(LOG_LOG, "%sCheck for init reference ID",
- m_session_str);
- return 1;
- case 4:
- yaz_log(LOG_LOG, "%sCheck for double init request",
- m_session_str);
- return 1;
- case 5:
- yaz_log(LOG_LOG, "%sCheck for init options",
- m_session_str);
- return 1;
- case 6:
- yaz_log(LOG_LOG, "%sCheck for character set negotiation",
- m_session_str);
- return 1;
- case 7:
- yaz_log(LOG_LOG, "%sCheck for messages size negotiation",
- m_session_str);
- return 1;
- case 8:
- yaz_log(LOG_LOG, "%sCheck for basic search and retrieve",
- m_session_str);
- m_query_no = 0;
- m_record_syntax_no = 0;
- m_got_result_set = 0;
- return 1;
- case 9:
- yaz_log(LOG_LOG, "%sCheck for scan", m_session_str);
- m_scan_no = 0;
- return 1;
- case 10:
- yaz_log(LOG_LOG, "%sCheck for sort", m_session_str);
- m_got_result_set = 0;
- m_sort_no = 0;
- return 1;
- default:
- close();
- return 0;
- }
- }
- return 0;
-}
-
-// current test failed badly - goto next or stop..
-void Zlint::closeNextTest()
-{
- close();
- if (m_tst_no != 0)
- {
- nextTest();
+ Zlint_t *t = m_tests;
+ m_tests = t->m_next;
+ delete t;
}
+ xfree(m_host);
+ xfree(m_database);
}
-void Zlint::failNotify()
+void Zlint::set_host(const char *cp)
{
- yaz_log(LOG_WARN, "%sconnection closed by foreign host", m_session_str);
- testContinue();
+ xfree(m_host);
+ m_host = xstrdup(cp);
+ client(m_host);
+ timeout(30);
+
+ const char *basep;
+ cs_get_host_args(m_host, &basep);
+ if (!basep || !*basep)
+ basep = "Default";
+ xfree(m_database);
+ m_database = xstrdup(basep);
}
void Zlint::timeoutNotify()
{
- yaz_log(LOG_WARN, "%sconnection timed out", m_session_str);
- testContinue();
-}
-
-void Zlint::testContinue()
-{
- close();
- switch(m_tst_no)
+ if (m_cur_test)
{
- case 8:
- if (m_got_result_set)
- {
- // must search again to establish.. keep query
- m_got_result_set = 0;
- m_record_syntax_no++;
- }
- else
- {
- // try new search ..
- m_query_no++;
- }
- connect();
- return;
- case 9:
- m_scan_no++;
- connect();
- return;
- case 10:
- if (m_got_result_set)
- {
- // if sort test fails during sort, we'll continue to next
- m_got_result_set = 0;
- m_sort_no++;
- connect();
- return;
- }
+ if (m_cur_test->m_t->recv_fail(this, 2) != TEST_FINISHED)
+ {
+ close();
+ client(m_host);
+ timeout(30);
+ return;
+ }
}
- nextTest();
+ close_goto_next();
}
-void Zlint::sendTest()
+void Zlint::failNotify()
{
- Z_APDU *apdu;
- switch(m_tst_no)
+ if (m_cur_test)
{
- case 8:
- if (!m_got_result_set)
- {
- apdu = zget_APDU(odr_encode(), Z_APDU_searchRequest);
- Z_SearchRequest *sr;
- sr = apdu->u.searchRequest;
- sr->query = (Z_Query *) odr_malloc(odr_encode(), sizeof(*sr->query));
- if (try_query[m_query_no] && sr)
- {
- sr->query->which = Z_Query_type_1;
- Z_RPNQuery *rpn;
- YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
-
- sr->databaseNames = &m_database;
- sr->num_databaseNames = 1;
-
- rpn = yaz_pqf_parse(pqf_parser, odr_encode(), try_query[m_query_no]);
-
- yaz_pqf_destroy (pqf_parser);
-
- if (rpn)
- {
- int len;
- yaz_log(LOG_DEBUG, "%spqf: %s",
- m_session_str, try_query[m_query_no]);
-
- sr->query->u.type_1 = rpn;
- send_Z_PDU(apdu, &len);
- }
- else
- closeNextTest();
- }
- else
- {
- yaz_log(LOG_WARN, "%sunable to get any hit count",
- m_session_str);
- closeNextTest();
- }
- }
- else if (m_got_result_set && try_syntax[m_record_syntax_no])
- {
- int len;
- apdu = zget_APDU(odr_encode(), Z_APDU_presentRequest);
- Z_PresentRequest *pr = apdu->u.presentRequest;
- *pr->numberOfRecordsRequested = 1;
- *pr->resultSetStartPoint = 1;
-
- pr->preferredRecordSyntax =
- yaz_str_to_z3950oid(odr_encode(), CLASS_RECSYN,
- try_syntax[m_record_syntax_no]);
- send_Z_PDU(apdu, &len);
- }
- else
- closeNextTest();
- break;
- case 9:
- apdu = zget_APDU(odr_encode(), Z_APDU_scanRequest);
- if (apdu && try_scan[m_scan_no])
- {
- int len;
- YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
- Z_ScanRequest *sr = apdu->u.scanRequest;
- sr->termListAndStartPoint = yaz_pqf_scan(pqf_parser,
- odr_encode(),
- &sr->attributeSet,
- try_scan[m_scan_no]);
-
- sr->databaseNames = &m_database;
- sr->num_databaseNames = 1;
-
- yaz_pqf_destroy (pqf_parser);
- send_Z_PDU(apdu, &len);
- }
- else
- closeNextTest();
- break;
- case 10:
- if (!m_got_result_set)
- {
- apdu = zget_APDU(odr_encode(), Z_APDU_searchRequest);
- Z_SearchRequest *sr;
- sr = apdu->u.searchRequest;
- sr->query = (Z_Query *) odr_malloc(odr_encode(), sizeof(*sr->query));
- if (try_query[m_query_no] && sr)
- {
- sr->query->which = Z_Query_type_1;
- Z_RPNQuery *rpn;
- YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
-
- sr->databaseNames = &m_database;
- sr->num_databaseNames = 1;
-
- rpn = yaz_pqf_parse(pqf_parser, odr_encode(), try_query[m_query_no]);
-
- yaz_pqf_destroy (pqf_parser);
-
- if (rpn)
- {
- int len;
- yaz_log(LOG_DEBUG, "%spqf: %s",
- m_session_str, try_query[m_query_no]);
-
- sr->query->u.type_1 = rpn;
- send_Z_PDU(apdu, &len);
- }
- else
- closeNextTest();
- }
- else
- {
- yaz_log(LOG_WARN, "%sunable to get any hit count",
- m_session_str);
- closeNextTest();
- }
- }
- else
- {
- apdu = zget_APDU(odr_encode(), Z_APDU_sortRequest);
- if (apdu && try_sort[m_sort_no])
- {
- char *setstring = "default";
- int len;
- Z_SortRequest *sr = apdu->u.sortRequest;
-
- sr->num_inputResultSetNames = 1;
- sr->num_inputResultSetNames = 1;
- sr->inputResultSetNames = (Z_InternationalString **)
- odr_malloc (odr_encode(), sizeof(*sr->inputResultSetNames));
- sr->inputResultSetNames[0] = odr_strdup (odr_encode(), setstring);
- sr->sortedResultSetName = odr_strdup(odr_encode(), setstring);
- sr->sortSequence = yaz_sort_spec(odr_encode(), try_sort[m_sort_no]);
- send_Z_PDU(apdu, &len);
- }
- else
- closeNextTest();
- }
- break;
- default:
- closeNextTest();
+ if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
+ {
+ close();
+ client(m_host);
+ timeout(30);
+ return;
+ }
}
+ close_goto_next();
}
-IYaz_PDU_Observer *Zlint::sessionNotify(
- IYaz_PDU_Observable *the_PDU_Observable, int fd)
-{
- return 0;
-}
-
-void Zlint::connect()
+void Zlint::connectNotify()
{
- if (m_host)
+ if (m_cur_test)
{
- yaz_log(LOG_DEBUG, "%sconnecting to %s", m_session_str, m_host);
- timeout(m_timeout_connect);
- client(m_host);
+ if (m_cur_test->m_t->init(this) != TEST_FINISHED)
+ return;
}
+ close_goto_next();
}
-void Zlint::args(int argc, char **argv)
+void Zlint::recv_GDU(Z_GDU *gdu, int len)
{
- char *arg;
- int ret;
- while ((ret = options("a:v:", argv, argc, &arg)) != -2)
+ if (m_cur_test)
{
- switch (ret)
- {
- case 'v':
- yaz_log_init(yaz_log_mask_str(arg), "", 0);
- break;
- case 'a':
- set_APDU_log(arg);
- break;
- case 0:
- if (arg)
- {
- const char *basep;
- m_host = xstrdup(arg);
- cs_get_host_args(m_host, &basep);
- if (!basep || !*basep)
- basep = "Default";
- m_database = xstrdup(basep);
- }
- break;
- }
+ int r = m_cur_test->m_t->recv_gdu(this, gdu);
+ if (r == TEST_CONTINUE)
+ return;
+ if (r == TEST_REOPEN)
+ {
+ close();
+ client(m_host);
+ timeout(30);
+ return;
+ }
}
+ close_goto_next();
}
-class Zlint_driver_t;
-class Zlint_driver : public Yaz_Z_Assoc {
-public:
- Zlint_driver(IYaz_PDU_Observable *the_PDU_Observable);
- ~Zlint_driver();
- void add_test(Zlint_test *i);
- void set_host(const char *cp);
-private:
- void connectNotify();
- void timeoutNotify();
- void failNotify();
- void recv_GDU(Z_GDU *apdu, int len);
- IYaz_PDU_Observable *m_PDU_Observable;
- IYaz_PDU_Observer *sessionNotify(
- IYaz_PDU_Observable *the_PDU_Observable, int fd);
- Zlint_driver_t *m_tests;
- char *m_host;
-};
-
-class Zlint_driver_t {
-public:
- friend class Zlint_driver;
- Zlint_driver_t(Zlint_test *t);
-private:
- Zlint_test *m_t;
- Zlint_driver_t *m_next;
-};
-
-void Zlint_driver::set_host(const char *cp)
-{
- xfree(m_host);
- m_host = xstrdup(cp);
-}
-
-Zlint_driver::Zlint_driver(IYaz_PDU_Observable *the_PDU_Observable) :
- Yaz_Z_Assoc(the_PDU_Observable)
-
+void Zlint::close_goto_next()
{
- m_PDU_Observable = the_PDU_Observable;
- m_host = 0;
- m_tests = 0;
+ close();
+ if (m_cur_test)
+ m_cur_test = m_cur_test->m_next;
+ if (m_cur_test)
+ client(m_host);
+ timeout(30);
}
-
-Zlint_driver::~Zlint_driver()
+IPDU_Observer *Zlint::sessionNotify(
+ IPDU_Observable *the_PDU_Observable, int fd)
{
- xfree(m_host);
+ return 0;
}
-void Zlint_driver::timeoutNotify()
+Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
{
+ Z_ReferenceId *id =
+ (Z_ReferenceId *) odr_malloc(odr_encode(), sizeof(*id));
+ id->size = id->len = len;
+ id->buf = (unsigned char*) odr_malloc(odr_encode(), len);
+ memcpy(id->buf, buf, len);
+ return id;
}
-void Zlint_driver::failNotify()
+int Zlint::initResponseGetVersion(Z_InitResponse *init)
{
+ int no = 0;
+ int off = 0;
+ int i;
+ for (i = 0; i<12; i++)
+ if (ODR_MASK_GET(init->protocolVersion, no))
+ {
+ no = i+1;
+ }
+ else
+ off = 1;
+ return no;
}
-void Zlint_driver::connectNotify()
+void Zlint::add_test(Zlint_test *t)
{
+ Zlint_t **d = &m_tests;
+ while (*d)
+ d = &(*d)->m_next;
+ *d = new Zlint_t(t);
+ if (!m_cur_test)
+ m_cur_test = m_tests;
}
-void Zlint_driver::recv_GDU(Z_GDU *gdu, int len)
+void Zlint::msg_check_for(const char *fmt, ...)
{
-
+ m_cur_test->m_test_ok = 0;
+ m_cur_test->m_test_number_sequence++;
+ m_cur_test->m_test_reported = 0;
+
+ va_list ap;
+ va_start(ap, fmt);
+ char buf[1024];
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ printf ("Checking %s .. ", buf);
+ va_end(ap);
}
-IYaz_PDU_Observer *Zlint_driver::sessionNotify(
- IYaz_PDU_Observable *the_PDU_Observable, int fd)
+void Zlint::msg_check_info(const char *fmt, ...)
{
- return 0;
+ va_list ap;
+ va_start(ap, fmt);
+ char buf[1024];
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ printf (" %s\n", buf);
+ va_end(ap);
}
-void Zlint_driver::add_test(Zlint_test *t)
+void Zlint::msg_check_ok()
{
- Zlint_driver_t **d = &m_tests;
- while (*d)
- d = &(*d)->m_next;
- *d = new Zlint_driver_t(t);
+ if (!m_cur_test->m_test_reported)
+ {
+ m_cur_test->m_test_ok = 1;
+ m_cur_test->m_test_reported = 1;
+ printf ("OK\n");
+ }
}
-Zlint_driver_t::Zlint_driver_t(Zlint_test *t)
+void Zlint::msg_check_fail(const char *fmt, ...)
{
- m_t = t;
- m_next = 0;
+ if (!m_cur_test->m_test_reported)
+ {
+ m_cur_test->m_test_ok = 0;
+ m_cur_test->m_test_reported = 1;
+ printf ("Fail\n");
+ }
+ va_list ap;
+ va_start(ap, fmt);
+ char buf[1024];
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ printf (" %s\n", buf);
+ va_end(ap);
}
-class Zlint_test_01 : public Zlint_test {
-public:
- Zlint_test_01();
- virtual ~Zlint_test_01();
- Zlint_code init(Zlint *z);
- Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
- Zlint_code recv_fail(Zlint *z, int reason);
-};
-
-Zlint_test_01::Zlint_test_01()
+void Zlint::msg_check_notapp()
{
+ if (!m_cur_test->m_test_reported)
+ {
+ m_cur_test->m_test_ok = 2;
+ m_cur_test->m_test_reported = 1;
+ printf ("Unsupported\n");
+ }
}
-Zlint_test_01::~Zlint_test_01()
+void Zlint::getDatabase(char ***db, int *num)
{
+ *db = (char**) odr_malloc(odr_encode(), 2*sizeof(char *));
+ (*db)[0] = m_database;
+ (*db)[1] = 0;
+ *num = 1;
}
-Zlint_code Zlint_test_01::init(Zlint *z)
+Zlint_t::Zlint_t(Zlint_test *t)
{
- int len;
- Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
- Z_InitRequest *init = apdu->u.initRequest;
-
- ODR_MASK_ZERO(init->protocolVersion);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_1);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_2);
- ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
-
- int r = z->send_Z_PDU(apdu, &len);
- if (r < 0)
- return TEST_FINISHED;
- return TEST_CONTINUE;
+ m_test_number_sequence = 0;
+ m_test_ok = 0;
+ m_test_reported = 0;
+ m_t = t;
+ m_next = 0;
}
-Zlint_code Zlint_test_01::recv_gdu(Zlint *z, Z_GDU *gdu)
+Zlint_t::~Zlint_t()
{
- if (gdu->which == Z_GDU_Z3950 &&
- gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_initResponse)
- {
- Z_InitResponse *init = gdu->u.z3950->u.initResponse;
- int ver = z->initResponseGetVersion(init);
- int result = init->result ? *init->result : 0;
- if (ver > 3 || ver < 2)
- yaz_log(LOG_WARN, "got version %d, expected 2 or 3", ver);
- if (!result)
- return TEST_FINISHED;
- }
- return TEST_FINISHED;
+ delete m_t;
}
-Zlint_code Zlint_test_01::recv_fail(Zlint *z, int reason)
+Zlint_code Zlint_test_simple::recv_fail(Zlint *z, int reason)
{
+ z->msg_check_fail("target closed connection");
return TEST_FINISHED;
}
-
-int main(int argc, char **argv)
-{
- Yaz_SocketManager mySocketManager;
- Zlint z(new Yaz_PDU_Assoc(&mySocketManager));
-
- z.args(argc, argv);
-
- z.nextTest();
-
- while (mySocketManager.processEvent() > 0)
- ;
- exit (0);
-}
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */