Tests as separate object implementations
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Mar 2004 23:14:07 +0000 (23:14 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Mar 2004 23:14:07 +0000 (23:14 +0000)
14 files changed:
zlint/Makefile.am
zlint/main.cpp [new file with mode: 0644]
zlint/test-init-01.cpp [new file with mode: 0644]
zlint/test-init-02.cpp [new file with mode: 0644]
zlint/test-init-03.cpp [new file with mode: 0644]
zlint/test-init-04.cpp [new file with mode: 0644]
zlint/test-init-05.cpp [new file with mode: 0644]
zlint/test-init-06.cpp [new file with mode: 0644]
zlint/test-init-07.cpp [new file with mode: 0644]
zlint/test-init-08.cpp [new file with mode: 0644]
zlint/test-scan-01.cpp [new file with mode: 0644]
zlint/test-search-01.cpp [new file with mode: 0644]
zlint/zlint.cpp
zlint/zlint.h [new file with mode: 0644]

index 976ea4b..3bb7ea0 100644 (file)
@@ -1,8 +1,19 @@
-## $Id: Makefile.am,v 1.3 2004-02-25 08:17:52 adam Exp $
+## $Id: Makefile.am,v 1.4 2004-03-25 23:14:07 adam Exp $
 
 AM_CXXFLAGS = $(YAZINC) -I$(srcdir)/../include $(XSLT_CFLAGS)
 
-zlint_SOURCES=zlint.cpp
+zlint_SOURCES=zlint.cpp zlint.h \
+ test-init-01.cpp \
+ test-init-02.cpp \
+ test-init-03.cpp \
+ test-init-04.cpp \
+ test-init-05.cpp \
+ test-init-06.cpp \
+ test-init-07.cpp \
+ test-init-08.cpp \
+ test-search-01.cpp \
+ test-scan-01.cpp \
+ main.cpp 
 
 bin_PROGRAMS = zlint
 
diff --git a/zlint/main.cpp b/zlint/main.cpp
new file mode 100644 (file)
index 0000000..038e6f7
--- /dev/null
@@ -0,0 +1,50 @@
+#include <yaz++/pdu-assoc.h>
+#include <yaz++/socket-manager.h>
+
+#include <zlint.h>
+
+int main(int argc, char **argv)
+{
+    Yaz_SocketManager mySocketManager;
+    Zlint z(new Yaz_PDU_Assoc(&mySocketManager));
+    if (argc > 1)
+       z.set_host(argv[1]);
+    else
+       z.set_host("localhost:9999");
+
+    Zlint_test_init_01 t01;
+    z.add_test(&t01);
+
+    Zlint_test_init_02 t02;
+    z.add_test(&t02);
+
+    Zlint_test_init_03 t03;
+    z.add_test(&t03);
+
+    Zlint_test_init_04 t04;
+    z.add_test(&t04);
+
+    Zlint_test_init_05 t05;
+    z.add_test(&t05);
+
+    Zlint_test_init_06 t06;
+    z.add_test(&t06);
+
+    Zlint_test_init_07 t07;
+    z.add_test(&t07);
+
+    Zlint_test_init_08 t08;
+    z.add_test(&t08);
+
+    Zlint_test_search_01 s01;
+    z.add_test(&s01);
+
+    Zlint_test_scan_01 scan01;
+    z.add_test(&scan01);
+
+    while (mySocketManager.processEvent() > 0)
+       ;
+    exit (0);
+}
+
diff --git a/zlint/test-init-01.cpp b/zlint/test-init-01.cpp
new file mode 100644 (file)
index 0000000..7323cc9
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-01.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+Zlint_test_init_01::Zlint_test_init_01()
+{
+}
+
+Zlint_test_init_01::~Zlint_test_init_01()
+{
+}
+
+Zlint_code Zlint_test_init_01::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for V3 init");
+
+    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)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_01::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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)
+           z->msg_check_fail("got version %d, expected 2 or 3", ver);
+       if (!result)
+       {
+           z->msg_check_fail("init rejected (result false)");
+           return TEST_FINISHED;
+       }
+       else
+           z->msg_check_ok();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
diff --git a/zlint/test-init-02.cpp b/zlint/test-init-02.cpp
new file mode 100644 (file)
index 0000000..bd258a8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-02.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+Zlint_test_init_02::Zlint_test_init_02()
+{
+}
+
+Zlint_test_init_02::~Zlint_test_init_02()
+{
+}
+
+Zlint_code Zlint_test_init_02::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for V2 init");
+
+    ODR_MASK_ZERO(init->protocolVersion);
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_1);
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_2);
+    
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_02::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 != 2)
+           z->msg_check_fail("got version %d, expected 2", ver);
+       z->msg_check_ok();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
+
diff --git a/zlint/test-init-03.cpp b/zlint/test-init-03.cpp
new file mode 100644 (file)
index 0000000..66f0775
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-03.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+Zlint_test_init_03::Zlint_test_init_03()
+{
+}
+
+Zlint_test_init_03::~Zlint_test_init_03()
+{
+}
+
+Zlint_code Zlint_test_init_03::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for V9 init");
+
+    ODR_MASK_ZERO(init->protocolVersion);
+    int i;
+    for (i = 0; i< 9; i++)
+       ODR_MASK_SET(init->protocolVersion, i);
+    
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_03::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 < 2 || ver > 5)
+           z->msg_check_fail("%sgot version %d, expected 2-5", ver);
+       z->msg_check_ok();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
diff --git a/zlint/test-init-04.cpp b/zlint/test-init-04.cpp
new file mode 100644 (file)
index 0000000..4d436f5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-04.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+#define REFID_BUF1 "zlint\000check1"
+#define REFID_LEN1 12
+
+Zlint_test_init_04::Zlint_test_init_04()
+{
+}
+
+Zlint_test_init_04::~Zlint_test_init_04()
+{
+}
+
+Zlint_code Zlint_test_init_04::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for referenceID for init");
+
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+    init->referenceId = z->mk_refid(REFID_BUF1, REFID_LEN1);
+
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_04::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (!init->referenceId)
+           z->msg_check_fail("missing referenceID from init response");
+       else if (init->referenceId->len != REFID_LEN1
+                || memcmp(init->referenceId->buf, REFID_BUF1, REFID_LEN1))
+           z->msg_check_fail("reference ID does not match");
+       z->msg_check_ok();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
diff --git a/zlint/test-init-05.cpp b/zlint/test-init-05.cpp
new file mode 100644 (file)
index 0000000..cd7fbb7
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-05.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+#define REFID_BUF1 "zlint\000check1"
+#define REFID_LEN1 12
+#define REFID_BUF2 "zlint\000check2"
+#define REFID_LEN2 12
+
+Zlint_test_init_05::Zlint_test_init_05()
+{
+    m_init_response_no = 0;
+}
+
+Zlint_test_init_05::~Zlint_test_init_05()
+{
+}
+
+Zlint_code Zlint_test_init_05::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for double init");
+    
+    /* 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 = z->mk_refid(REFID_BUF1, REFID_LEN1);
+
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+       
+    apdu = z->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 = z->mk_refid(REFID_BUF2, REFID_LEN2);
+
+    r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_05::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (m_init_response_no == 0)
+       {
+           if (!init->referenceId)
+           {
+               z->msg_check_fail("missing referenceID from "
+                                 "first init response");
+               return TEST_FINISHED;
+           }
+           else if (init->referenceId->len != REFID_LEN1
+                    || memcmp(init->referenceId->buf, REFID_BUF1, REFID_LEN1))
+           {
+               z->msg_check_fail("reference ID does not match from "
+                                 "first init response");
+               return TEST_FINISHED;
+           }
+       }
+       else
+       {
+           if (!init->referenceId)
+               z->msg_check_fail("missing referenceID from "
+                                 "second init response");
+           else if (init->referenceId->len != REFID_LEN2
+                    || memcmp(init->referenceId->buf, REFID_BUF2, REFID_LEN2))
+               z->msg_check_fail("reference ID does not match from "
+                                 "second init response");
+       }
+       
+       if (!result)
+       {
+           z->msg_check_fail("init rejected (result false)");
+           return TEST_FINISHED;
+       }
+       else
+       {
+           if (m_init_response_no == 0)
+           {
+               m_init_response_no++;
+               return TEST_CONTINUE;
+           }
+           else
+               z->msg_check_ok();
+       }
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
diff --git a/zlint/test-init-06.cpp b/zlint/test-init-06.cpp
new file mode 100644 (file)
index 0000000..8d4e596
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-06.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+
+#include <zlint.h>
+
+Zlint_test_init_06::Zlint_test_init_06()
+{
+}
+
+Zlint_test_init_06::~Zlint_test_init_06()
+{
+}
+
+Zlint_code Zlint_test_init_06::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for init options");
+    
+    /* set all options.. see what target really supports .. */
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+    ODR_MASK_ZERO(init->options);
+    int i;
+    for (i = 0; i <= 24; i++)
+       ODR_MASK_SET(init->options, i);
+
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_06::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (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)
+           {
+               z->msg_check_fail("suspicuously few option bits set");
+               return TEST_FINISHED;
+           }
+           if (no_reset == 0)
+           {
+               z->msg_check_fail("suspicuously many option bits set");
+               return TEST_FINISHED;
+           }
+       }
+       z->msg_check_ok();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
diff --git a/zlint/test-init-07.cpp b/zlint/test-init-07.cpp
new file mode 100644 (file)
index 0000000..fb55cd2
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-07.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+#include <yaz/charneg.h>
+#include <yaz/otherinfo.h>
+
+#include <zlint.h>
+
+Zlint_test_init_07::Zlint_test_init_07()
+{
+}
+
+Zlint_test_init_07::~Zlint_test_init_07()
+{
+}
+
+Zlint_code Zlint_test_init_07::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+    Z_OtherInformation **oi;
+
+    z->msg_check_for("for character set negotiation");
+    
+    /* set all options.. see what target really supports .. */
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+    yaz_oi_APDU(apdu, &oi);
+    if (!oi)
+    {
+       z->msg_check_fail("encoding failure");
+       return TEST_FINISHED;
+    }
+    else
+    {
+       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, z->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(
+                   z->odr_encode(),
+                   negotiationCharset, 5,
+                   (const char**)&yazLang, yazLang ? 1 : 0, 1);
+       }
+    }
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_07::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (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);
+               z->msg_check_ok();
+               z->msg_check_info("Accepted character set : %s", charset);
+               z->msg_check_info("Accepted code language : %s", lang ? lang : "none");
+               z->msg_check_info("Accepted records in ...: %d", selected );
+               nmem_destroy(m);
+               return TEST_FINISHED;
+           }
+       }
+       z->msg_check_notapp();
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+
diff --git a/zlint/test-init-08.cpp b/zlint/test-init-08.cpp
new file mode 100644 (file)
index 0000000..5269900
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-init-08.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+#include <yaz/charneg.h>
+#include <yaz/otherinfo.h>
+
+#include <zlint.h>
+
+Zlint_test_init_08::Zlint_test_init_08()
+{
+    m_no = 0;
+}
+
+Zlint_test_init_08::~Zlint_test_init_08()
+{
+}
+
+Zlint_code Zlint_test_init_08::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("for init message sizes %d", m_no);
+    
+    /* set all options.. see what target really supports .. */
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+
+    *init->maximumRecordSize = m_no * m_no * 100000 + 2000;
+    *init->preferredMessageSize = m_no * m_no *100000 + 2000;
+
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_init_08::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (m_no * m_no * 100000 + 2000 < *init->maximumRecordSize)
+           z->msg_check_fail("maximumRecordSize bigger than proposed size");
+       if (m_no * m_no * 100000 + 2000 < *init->preferredMessageSize)
+           z->msg_check_fail("preferredMessage bigger than proposed size");
+       z->msg_check_ok();
+       if (m_no < 2)
+       {
+           m_no++;
+           return TEST_REOPEN;
+       }
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+Zlint_code Zlint_test_init_08::recv_fail(Zlint *z, int reason)
+{
+    z->msg_check_fail("target closed connection");
+    if (m_no < 2)
+    {
+       m_no++;
+       return TEST_REOPEN;
+    }
+    return TEST_FINISHED;
+}
+
diff --git a/zlint/test-scan-01.cpp b/zlint/test-scan-01.cpp
new file mode 100644 (file)
index 0000000..119d9bb
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-scan-01.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+#include <yaz/pquery.h>
+
+#include <zlint.h>
+
+static const char *try_scan [] = {
+    "@attr 1=4 ab",
+    "@attr 1=1003 ab",
+    "@attr 1=1016 ab",
+    0
+};
+
+Zlint_test_scan_01::Zlint_test_scan_01()
+{
+    m_scan_no = 0;
+}
+
+Zlint_test_scan_01::~Zlint_test_scan_01()
+{
+}
+
+Zlint_code Zlint_test_scan_01::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+    ODR_MASK_SET(init->options, Z_Options_namedResultSets);
+    ODR_MASK_SET(init->options, Z_Options_scan);
+    
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_scan_01::sendTest(Zlint *z)
+{
+    if (try_scan[m_scan_no])
+    {
+       int len;
+       z->msg_check_for("scan support %s", try_scan[m_scan_no]);
+
+       Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_scanRequest);
+       YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
+       Z_ScanRequest *sr = apdu->u.scanRequest;
+       sr->termListAndStartPoint = yaz_pqf_scan(pqf_parser,
+                                                z->odr_encode(),
+                                                &sr->attributeSet,
+                                                try_scan[m_scan_no]);
+       
+       z->getDatabase(&sr->databaseNames, &sr->num_databaseNames);
+       
+       yaz_pqf_destroy (pqf_parser);
+       z->send_Z_PDU(apdu, &len);
+       return TEST_CONTINUE;
+    }
+    else
+       return TEST_FINISHED;
+}
+
+Zlint_code Zlint_test_scan_01::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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)
+           z->msg_check_fail("got version %d, expected 2 or 3", ver);
+       if (!result)
+       {
+           z->msg_check_fail("init rejected (result false)");
+           return TEST_FINISHED;
+       }
+       else if (!ODR_MASK_GET(init->options, Z_Options_scan))
+       {
+           z->msg_check_notapp();
+           z->msg_check_info("scan unsupported");
+           return TEST_FINISHED;
+       }
+       else
+       {
+           sendTest(z);
+           return TEST_CONTINUE;
+       }
+    }
+    else if (gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_scanResponse)
+    {
+       Z_ScanResponse *sr =  gdu->u.z3950->u.scanResponse;
+       if (sr->entries->nonsurrogateDiagnostics)
+       {
+           z->msg_check_ok();
+           z->msg_check_info("scan NSD for %s", try_scan[m_scan_no]);
+       }
+       else if (sr->entries->entries && sr->entries->num_entries > 0)
+       {
+           z->msg_check_ok();
+       }
+       else
+       {
+           z->msg_check_fail("scan no entries/diagnostics for %s",
+                             try_scan[m_scan_no]);
+       }
+       m_scan_no++;
+       return sendTest(z);
+    }
+    else
+       z->msg_check_fail("did not receive init response as expected");
+    return TEST_FINISHED;
+}
+
+Zlint_code Zlint_test_scan_01::recv_fail(Zlint *z, int reason)
+{
+    m_scan_no++;
+    z->msg_check_fail("target closed connection");
+    return TEST_FINISHED;
+}
diff --git a/zlint/test-search-01.cpp b/zlint/test-search-01.cpp
new file mode 100644 (file)
index 0000000..a292f3a
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: test-search-01.cpp,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz/log.h>
+#include <yaz/pquery.h>
+#include <yaz/sortspec.h>
+
+#include <zlint.h>
+
+static 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,
+};
+
+static const char *try_syntax [] = {
+    "usmarc",
+    "unimarc",
+    "danmarc",
+    "sutrs",
+    "grs1",
+    "xml",
+    "normarc",
+    0
+};
+
+static const char *try_sort [] = {
+    "1=4 <",
+    "1=4 >",
+    "1=62 >",
+    "1=62 <",
+    0
+};
+
+Zlint_test_search_01::Zlint_test_search_01()
+{
+    m_query_no = 0;
+    m_record_syntax_no = 0;
+    m_got_result_set = 0;
+    m_sort_no = 0;
+}
+
+Zlint_test_search_01::~Zlint_test_search_01()
+{
+}
+
+Zlint_code Zlint_test_search_01::init(Zlint *z)
+{
+    int len;
+    Z_APDU *apdu = z->create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *init = apdu->u.initRequest;
+
+    z->msg_check_for("search and retrieve");
+
+    ODR_MASK_SET(init->protocolVersion, Z_ProtocolVersion_3);
+
+    ODR_MASK_SET(init->options, Z_Options_namedResultSets);
+    ODR_MASK_SET(init->options, Z_Options_sort);
+
+    int r = z->send_Z_PDU(apdu, &len);
+    if (r < 0)
+    {
+       z->msg_check_fail("unable to send init request");
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_search_01::sendTest(Zlint *z)
+{
+    if (!m_got_result_set)
+    {
+       Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_searchRequest);
+       Z_SearchRequest *sr;
+       sr = apdu->u.searchRequest;
+       sr->query = (Z_Query *) odr_malloc(z->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 ();
+           
+           z->getDatabase(&sr->databaseNames, &sr->num_databaseNames);
+           
+           rpn = yaz_pqf_parse(pqf_parser, z->odr_encode(),
+                               try_query[m_query_no]);
+           
+           yaz_pqf_destroy (pqf_parser);
+           
+           if (!rpn)
+           {
+               z->msg_check_fail("Query %s invalid", try_query[m_query_no]);
+               return TEST_FINISHED;
+           }
+           int len;
+           sr->query->u.type_1 = rpn;
+           z->send_Z_PDU(apdu, &len);
+       }
+       else
+       {
+           z->msg_check_notapp();
+           z->msg_check_info("unable to get any hit count");
+           return TEST_FINISHED;
+       }
+    }
+    else if (m_got_result_set && try_syntax[m_record_syntax_no])
+    {
+       int len;
+       Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_presentRequest);
+       Z_PresentRequest *pr = apdu->u.presentRequest;
+       *pr->numberOfRecordsRequested = 1;
+       *pr->resultSetStartPoint = 1;
+
+       z->msg_check_for("record syntax %s", try_syntax[m_record_syntax_no]);
+       pr->preferredRecordSyntax =
+           yaz_str_to_z3950oid(z->odr_encode(), CLASS_RECSYN,
+                               try_syntax[m_record_syntax_no]);
+       z->send_Z_PDU(apdu, &len);
+       return TEST_CONTINUE;
+    }
+    else if(m_got_result_set && !try_syntax[m_record_syntax_no])
+    {
+       Z_APDU *apdu = zget_APDU(z->odr_encode(), Z_APDU_sortRequest);
+       if (apdu && try_sort[m_sort_no])
+       {
+           z->msg_check_for("sort %s", 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 (z->odr_encode(), sizeof(*sr->inputResultSetNames));
+           sr->inputResultSetNames[0] = odr_strdup (z->odr_encode(), setstring);
+           sr->sortedResultSetName = odr_strdup(z->odr_encode(), setstring);
+           sr->sortSequence = yaz_sort_spec(z->odr_encode(), try_sort[m_sort_no]);
+           z->send_Z_PDU(apdu, &len);
+       }
+       else
+           return TEST_FINISHED;
+    }
+    else
+    {
+       return TEST_FINISHED;
+    }
+    return TEST_CONTINUE;
+}
+
+Zlint_code Zlint_test_search_01::recv_gdu(Zlint *z, Z_GDU *gdu)
+{
+    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 (!result)
+       {
+           z->msg_check_notapp();
+           z->msg_check_info ("init rejected (result false)");
+           return TEST_FINISHED;
+       }
+       return sendTest(z);
+    }
+    else if (gdu->which == Z_GDU_Z3950 &&
+            gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_searchResponse)
+    {
+       Z_SearchResponse *sr = gdu->u.z3950->u.searchResponse;
+       if (sr->records && (sr->records->which == Z_Records_NSD 
+                           || 
+                           sr->records->which == Z_Records_multipleNSD))
+           m_query_no++;
+       else if (!sr->resultCount || *sr->resultCount == 0)
+           m_query_no++;
+       else
+       {
+           z->msg_check_ok();
+           z->msg_check_info("got %d result count with %s", *sr->resultCount,
+                             try_query[m_query_no]);
+           m_got_result_set = 1;
+       }
+       return sendTest(z);
+    }
+    else if (gdu->which == Z_GDU_Z3950 && 
+            gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_presentResponse)
+    {
+       Z_PresentResponse *sr = gdu->u.z3950->u.presentResponse;
+       if (sr->records && (sr->records->which == Z_Records_NSD 
+                           || 
+                           sr->records->which == Z_Records_multipleNSD))
+       {
+           z->msg_check_ok();
+           z->msg_check_info("present returned NSD for %s",
+                             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(z->odr_decode(), CLASS_RECSYN,
+                                       try_syntax[m_record_syntax_no]);
+               if (oid_oidcmp(expectRecordSyntax,
+                              ext->direct_reference))
+               {
+                   z->msg_check_fail("Got Record in different syntax "
+                                     "from that requested %s",
+                                     try_syntax[m_record_syntax_no]);
+               }
+               else
+                   z->msg_check_ok();
+           }
+           else if (sr->records->u.databaseOrSurDiagnostics->records[0]->which == Z_NamePlusRecord_surrogateDiagnostic)
+           {
+               z->msg_check_ok();
+               z->msg_check_info("present returned SD %s",
+                                 try_syntax[m_record_syntax_no]);
+           }
+           else
+           {
+               z->msg_check_ok();
+               z->msg_check_info("present returned fragment %s",
+                                 try_syntax[m_record_syntax_no]);
+           }
+       }
+       else
+       {
+           z->msg_check_fail("present returned no records or diagnostics");
+       }
+       m_record_syntax_no++;
+       return sendTest(z);
+    }
+    else if (gdu->which == Z_GDU_Z3950 && 
+            gdu->u.z3950 && gdu->u.z3950->which == Z_APDU_sortResponse)
+    {
+       Z_SortResponse *sr =  gdu->u.z3950->u.sortResponse;
+       z->msg_check_ok();
+       if (sr->diagnostics)
+           z->msg_check_info( "sort NSD for %s", try_sort[m_sort_no]);
+       m_sort_no++;
+       return sendTest(z);
+    }
+    else
+       z->msg_check_fail("did not receive init/search/present response "
+                         "as expected");
+    return TEST_FINISHED;
+}
+
+Zlint_code Zlint_test_search_01::recv_fail(Zlint *z, int reason)
+{
+    z->msg_check_fail("target closed connection");
+    return TEST_FINISHED;
+}
index 3093d0b..028e6d6 100644 (file)
  * 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.5 2004-03-25 23:14:07 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 {
+class Zlint_t {
 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);
+    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;
 };
 
-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;
-           if (off)
-               yaz_log(LOG_WARN, "%sbad formatted version");
-       }
-       else
-           off = 1;
-    return no;
-}
-
-Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
+Zlint::Zlint(IYaz_PDU_Observable *the_PDU_Observable) : 
+    Yaz_Z_Assoc(the_PDU_Observable)
+    
 {
-    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;
+    m_PDU_Observable = the_PDU_Observable;
+    m_host = 0;
+    m_tests = 0;
+    m_cur_test = 0;
+    m_database = 0;
 }
 
-void Zlint::recv_GDU(Z_GDU *gdu, int len)
+Zlint::~Zlint()
 {
-    if (gdu->which != Z_GDU_Z3950)
+    while (m_tests)
     {
-       yaz_log(LOG_LOG, "%sreceived non-Z39.50 response", m_session_str);
-       closeNextTest();
+       Zlint_t *t = m_tests;
+       m_tests = t->m_next;
+       delete t;
     }
-    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();
+    xfree(m_host);
+    xfree(m_database);
 }
 
-Zlint::Zlint(IYaz_PDU_Observable *the_PDU_Observable) : 
-    Yaz_Z_Assoc(the_PDU_Observable)
+void Zlint::set_host(const char *cp)
 {
-    m_PDU_Observable = the_PDU_Observable;
-    m_host = 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);
+    xfree(m_host);
+    m_host = xstrdup(cp);
+    client(m_host);
+
+    const char *basep;
+    cs_get_host_args(m_host, &basep);
+    if (!basep || !*basep)
+       basep = "Default";
+    xfree(m_database);
+    m_database = xstrdup(basep);
 }
 
-void Zlint::connectNotify()
+void Zlint::timeoutNotify()
 {
-    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)
+    if (m_cur_test)
     {
-    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)
+       if (m_cur_test->m_t->recv_fail(this, 2) != TEST_FINISHED)
        {
-           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);
-           }
+           close();
+           client(m_host);
+           return;
        }
-       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);
+    close_goto_next();
 }
 
-int Zlint::nextTest()
+void Zlint::failNotify()
 {
-    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)
+    if (m_cur_test)
     {
-       m_tst_no++;
-       sprintf(m_session_str, "%d ", m_tst_no);
-       switch(m_tst_no)
+       if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
        {
-       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;
+           client(m_host);
+           return;
        }
     }
-    return 0;
+    close_goto_next();
 }
 
-// current test failed badly - goto next or stop..
-void Zlint::closeNextTest()
+void Zlint::connectNotify()
 {
-    close();
-    if (m_tst_no != 0)
+    if (m_cur_test)
     {
-       nextTest();
+       if (m_cur_test->m_t->init(this) != TEST_FINISHED)
+           return;
     }
+    close_goto_next();
 }
 
-void Zlint::failNotify()
-{
-    yaz_log(LOG_WARN, "%sconnection closed by foreign host", m_session_str);
-    testContinue();
-}
-
-void Zlint::timeoutNotify()
-{
-    yaz_log(LOG_WARN, "%sconnection timed out", m_session_str);
-    testContinue();
-}
-
-void Zlint::testContinue()
+void Zlint::recv_GDU(Z_GDU *gdu, int len)
 {
-    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)
+       int r = m_cur_test->m_t->recv_gdu(this, gdu);
+       if (r == TEST_CONTINUE)
+           return;
+       if (r == TEST_REOPEN)
        {
-           // if sort test fails during sort, we'll continue to next
-           m_got_result_set = 0;
-           m_sort_no++;
-           connect();
+           close();
+           client(m_host);
            return;
        }
     }
-    nextTest();
+    close_goto_next();
 }
 
-void Zlint::sendTest()
+void Zlint::close_goto_next()
 {
-    Z_APDU *apdu;
-    switch(m_tst_no)
-    {
-    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();
-    }
+    close();
+    if (m_cur_test)
+       m_cur_test = m_cur_test->m_next;
+    if (m_cur_test)
+       client(m_host);
 }
 
 IYaz_PDU_Observer *Zlint::sessionNotify(
@@ -908,197 +136,127 @@ IYaz_PDU_Observer *Zlint::sessionNotify(
     return 0;
 }
 
-void Zlint::connect()
+Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
 {
-    if (m_host)
-    {
-       yaz_log(LOG_DEBUG, "%sconnecting to %s", m_session_str, m_host);
-       timeout(m_timeout_connect);
-       client(m_host);
-    }
+    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::args(int argc, char **argv)
+int Zlint::initResponseGetVersion(Z_InitResponse *init)
 {
-    char *arg;
-    int ret;
-    while ((ret = options("a:v:", argv, argc, &arg)) != -2)
-    {
-        switch (ret)
+    int no = 0;
+    int off = 0;
+    int i;
+    for (i = 0; i<12; i++)
+       if (ODR_MASK_GET(init->protocolVersion, no))
        {
-       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;
+           no = i+1;
+           if (off)
+               yaz_log(LOG_WARN, "%sbad formatted version");
        }
-    }
-}
-
-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)
-    
-{
-    m_PDU_Observable = the_PDU_Observable;
-    m_host = 0;
-    m_tests = 0;
+       else
+           off = 1;
+    return no;
 }
 
-
-Zlint_driver::~Zlint_driver()
+void Zlint::add_test(Zlint_test *t)
 {
-    xfree(m_host);
+    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::timeoutNotify()
+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);
 }
 
-void Zlint_driver::failNotify()
+void Zlint::msg_check_info(const char *fmt, ...)
 {
+    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::connectNotify()
+void Zlint::msg_check_ok()
 {
+    if (!m_cur_test->m_test_reported)
+    {
+       m_cur_test->m_test_ok = 1;
+       m_cur_test->m_test_reported = 1;
+       printf ("OK\n");
+    }
 }
 
-void Zlint_driver::recv_GDU(Z_GDU *gdu, int len)
+void Zlint::msg_check_fail(const char *fmt, ...)
 {
-
+    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);
 }
 
-IYaz_PDU_Observer *Zlint_driver::sessionNotify(
-    IYaz_PDU_Observable *the_PDU_Observable, int fd)
+void Zlint::msg_check_notapp()
 {
-    return 0;
+    if (!m_cur_test->m_test_reported)
+    {
+       m_cur_test->m_test_ok = 2;
+       m_cur_test->m_test_reported = 1;
+       printf ("Unsupported\n");
+    }
 }
 
-void Zlint_driver::add_test(Zlint_test *t)
+void Zlint::getDatabase(char ***db, int *num)
 {
-    Zlint_driver_t **d = &m_tests;
-    while (*d)
-       d = &(*d)->m_next;
-    *d = new Zlint_driver_t(t);
+    *db = (char**) odr_malloc(odr_encode(), 2*sizeof(char *));
+    (*db)[0] = m_database;
+    (*db)[1] = 0;
+    *num = 1;
 }
 
-Zlint_driver_t::Zlint_driver_t(Zlint_test *t)
+Zlint_t::Zlint_t(Zlint_test *t)
 {
+    m_test_number_sequence = 0;
+    m_test_ok = 0;
+    m_test_reported = 0;
     m_t = t;
     m_next = 0;
 }
 
-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()
-{
-}
-
-Zlint_test_01::~Zlint_test_01()
-{
-}
-
-Zlint_code Zlint_test_01::init(Zlint *z)
-{
-    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;
-}
-
-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);
-}
-
diff --git a/zlint/zlint.h b/zlint/zlint.h
new file mode 100644 (file)
index 0000000..694e0e5
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2004, Index Data.
+ * See the file LICENSE for details.
+ * 
+ * $Id: zlint.h,v 1.1 2004-03-25 23:14:07 adam Exp $
+ */
+
+#include <yaz++/z-assoc.h>
+
+enum Zlint_code {
+    TEST_FINISHED,
+    TEST_CONTINUE,
+    TEST_REOPEN,
+};
+
+class Zlint_test;
+class Zlint_t;
+
+class Zlint : public Yaz_Z_Assoc {
+public:
+    Zlint(IYaz_PDU_Observable *the_PDU_Observable);
+    ~Zlint();
+    void add_test(Zlint_test *i);
+    void set_host(const char *cp);
+    int initResponseGetVersion(Z_InitResponse *init);
+    Z_ReferenceId *mk_refid(const char *buf, int len);
+    void msg_check_for(const char *fmt, ...);
+    void msg_check_ok();
+    void msg_check_fail(const char *fmt, ...);
+    void msg_check_info(const char *fmt, ...);
+    void msg_check_notapp();
+    void getDatabase(char ***db, int *num);
+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_t *m_tests;
+    Zlint_t *m_cur_test;
+    char *m_host;
+    char *m_database;
+    void close_goto_next();
+};
+
+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;
+};
+
+class Zlint_test_simple : public 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);
+};
+
+class Zlint_test_init_01 : public Zlint_test_simple {
+public:
+    Zlint_test_init_01();
+    virtual ~Zlint_test_init_01();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_02 : public Zlint_test_simple {
+public:
+    Zlint_test_init_02();
+    virtual ~Zlint_test_init_02();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_03 : public Zlint_test_simple {
+public:
+    Zlint_test_init_03();
+    virtual ~Zlint_test_init_03();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_04 : public Zlint_test_simple {
+public:
+    Zlint_test_init_04();
+    virtual ~Zlint_test_init_04();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_05 : public Zlint_test_simple {
+    int m_init_response_no;
+public:
+    Zlint_test_init_05();
+    virtual ~Zlint_test_init_05();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_06 : public Zlint_test_simple {
+public:
+    Zlint_test_init_06();
+    virtual ~Zlint_test_init_06();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_07 : public Zlint_test_simple {
+public:
+    Zlint_test_init_07();
+    virtual ~Zlint_test_init_07();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+};
+
+class Zlint_test_init_08 : public Zlint_test {
+    int m_no;
+public:
+    Zlint_test_init_08();
+    virtual ~Zlint_test_init_08();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+    Zlint_code recv_fail(Zlint *z, int reason);
+};
+
+class Zlint_test_search_01 : public Zlint_test {
+    int m_query_no;
+    int m_got_result_set;
+    int m_record_syntax_no;
+    int m_sort_no;
+    Zlint_code sendTest(Zlint *z);
+public:
+    Zlint_test_search_01();
+    virtual ~Zlint_test_search_01();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+    Zlint_code recv_fail(Zlint *z, int reason);
+};
+
+class Zlint_test_scan_01 : public Zlint_test {
+    int m_scan_no;
+    Zlint_code sendTest(Zlint *z);
+public:
+    Zlint_test_scan_01();
+    virtual ~Zlint_test_scan_01();
+    Zlint_code init(Zlint *z);
+    Zlint_code recv_gdu(Zlint *z, Z_GDU *gdu);
+    Zlint_code recv_fail(Zlint *z, int reason);
+};