Tests as separate object implementations
[yazpp-moved-to-github.git] / zlint / zlint.cpp
1 /*
2  * Copyright (c) 2004, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: zlint.cpp,v 1.5 2004-03-25 23:14:07 adam Exp $
6  */
7
8 #include <stdio.h>
9 #include <stdarg.h>
10
11 #include <yaz/comstack.h>
12 #include <yaz/options.h>
13 #include <yaz/otherinfo.h>
14 #include <yaz/charneg.h>
15 #include <yaz/log.h>
16
17 #include <zlint.h>
18
19 class Zlint_t {
20 public:
21     friend class Zlint;
22     Zlint_t(Zlint_test *t);
23     ~Zlint_t();
24 private:
25     Zlint_test *m_t;
26     Zlint_t *m_next;
27     int m_test_number_sequence;
28     int m_test_ok;
29     int m_test_reported;
30 };
31
32 Zlint::Zlint(IYaz_PDU_Observable *the_PDU_Observable) : 
33     Yaz_Z_Assoc(the_PDU_Observable)
34     
35 {
36     m_PDU_Observable = the_PDU_Observable;
37     m_host = 0;
38     m_tests = 0;
39     m_cur_test = 0;
40     m_database = 0;
41 }
42
43 Zlint::~Zlint()
44 {
45     while (m_tests)
46     {
47         Zlint_t *t = m_tests;
48         m_tests = t->m_next;
49         delete t;
50     }
51     xfree(m_host);
52     xfree(m_database);
53 }
54
55 void Zlint::set_host(const char *cp)
56 {
57     xfree(m_host);
58     m_host = xstrdup(cp);
59     client(m_host);
60
61     const char *basep;
62     cs_get_host_args(m_host, &basep);
63     if (!basep || !*basep)
64         basep = "Default";
65     xfree(m_database);
66     m_database = xstrdup(basep);
67 }
68
69 void Zlint::timeoutNotify()
70 {
71     if (m_cur_test)
72     {
73         if (m_cur_test->m_t->recv_fail(this, 2) != TEST_FINISHED)
74         {
75             close();
76             client(m_host);
77             return;
78         }
79     }
80     close_goto_next();
81 }
82
83 void Zlint::failNotify()
84 {
85     if (m_cur_test)
86     {
87         if (m_cur_test->m_t->recv_fail(this, 1) != TEST_FINISHED)
88         {
89             close();
90             client(m_host);
91             return;
92         }
93     }
94     close_goto_next();
95 }
96
97 void Zlint::connectNotify()
98 {
99     if (m_cur_test)
100     {
101         if (m_cur_test->m_t->init(this) != TEST_FINISHED)
102             return;
103     }
104     close_goto_next();
105 }
106
107 void Zlint::recv_GDU(Z_GDU *gdu, int len)
108 {
109     if (m_cur_test)
110     {
111         int r = m_cur_test->m_t->recv_gdu(this, gdu);
112         if (r == TEST_CONTINUE)
113             return;
114         if (r == TEST_REOPEN)
115         {
116             close();
117             client(m_host);
118             return;
119         }
120     }
121     close_goto_next();
122 }
123
124 void Zlint::close_goto_next()
125 {
126     close();
127     if (m_cur_test)
128         m_cur_test = m_cur_test->m_next;
129     if (m_cur_test)
130         client(m_host);
131 }
132
133 IYaz_PDU_Observer *Zlint::sessionNotify(
134     IYaz_PDU_Observable *the_PDU_Observable, int fd)
135 {
136     return 0;
137 }
138
139 Z_ReferenceId *Zlint::mk_refid(const char *buf, int len)
140 {
141     Z_ReferenceId *id = 
142         (Z_ReferenceId *) odr_malloc(odr_encode(), sizeof(*id));
143     id->size = id->len = len;
144     id->buf = (unsigned char*) odr_malloc(odr_encode(), len);
145     memcpy(id->buf, buf, len);
146     return id;
147 }
148
149 int Zlint::initResponseGetVersion(Z_InitResponse *init)
150 {
151     int no = 0;
152     int off = 0;
153     int i;
154     for (i = 0; i<12; i++)
155         if (ODR_MASK_GET(init->protocolVersion, no))
156         {
157             no = i+1;
158             if (off)
159                 yaz_log(LOG_WARN, "%sbad formatted version");
160         }
161         else
162             off = 1;
163     return no;
164 }
165
166 void Zlint::add_test(Zlint_test *t)
167 {
168     Zlint_t **d = &m_tests;
169     while (*d)
170         d = &(*d)->m_next;
171     *d = new Zlint_t(t);
172     if (!m_cur_test)
173         m_cur_test = m_tests;
174 }
175
176 void Zlint::msg_check_for(const char *fmt, ...)
177 {
178     m_cur_test->m_test_ok = 0;
179     m_cur_test->m_test_number_sequence++;
180     m_cur_test->m_test_reported = 0;
181
182     va_list ap;
183     va_start(ap, fmt);
184     char buf[1024];
185     vsnprintf(buf, sizeof(buf), fmt, ap);
186     printf ("Checking %s .. ", buf);
187     va_end(ap);
188 }
189
190 void Zlint::msg_check_info(const char *fmt, ...)
191 {
192     va_list ap;
193     va_start(ap, fmt);
194     char buf[1024];
195     vsnprintf(buf, sizeof(buf), fmt, ap);
196     printf (" %s\n", buf);
197     va_end(ap);
198 }
199
200 void Zlint::msg_check_ok()
201 {
202     if (!m_cur_test->m_test_reported)
203     {
204         m_cur_test->m_test_ok = 1;
205         m_cur_test->m_test_reported = 1;
206         printf ("OK\n");
207     }
208 }
209
210 void Zlint::msg_check_fail(const char *fmt, ...)
211 {
212     if (!m_cur_test->m_test_reported)
213     {
214         m_cur_test->m_test_ok = 0;
215         m_cur_test->m_test_reported = 1;
216         printf ("Fail\n");
217     }
218     va_list ap;
219     va_start(ap, fmt);
220     char buf[1024];
221     vsnprintf(buf, sizeof(buf), fmt, ap);
222     printf (" %s\n", buf);
223     va_end(ap);
224 }
225
226 void Zlint::msg_check_notapp()
227 {
228     if (!m_cur_test->m_test_reported)
229     {
230         m_cur_test->m_test_ok = 2;
231         m_cur_test->m_test_reported = 1;
232         printf ("Unsupported\n");
233     }
234 }
235
236 void Zlint::getDatabase(char ***db, int *num)
237 {
238     *db = (char**) odr_malloc(odr_encode(), 2*sizeof(char *));
239     (*db)[0] = m_database;
240     (*db)[1] = 0;
241     *num = 1;
242 }
243
244 Zlint_t::Zlint_t(Zlint_test *t)
245 {
246     m_test_number_sequence = 0;
247     m_test_ok = 0;
248     m_test_reported = 0;
249     m_t = t;
250     m_next = 0;
251 }
252
253 Zlint_t::~Zlint_t()
254 {
255     delete m_t;
256 }
257
258 Zlint_code Zlint_test_simple::recv_fail(Zlint *z, int reason)
259 {
260     z->msg_check_fail("target closed connection");
261     return TEST_FINISHED;
262 }