1//
2// Automated Testing Framework (atf)
3//
4// Copyright (c) 2010 The NetBSD Foundation, Inc.
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions
9// are met:
10// 1. Redistributions of source code must retain the above copyright
11//    notice, this list of conditions and the following disclaimer.
12// 2. Redistributions in binary form must reproduce the above copyright
13//    notice, this list of conditions and the following disclaimer in the
14//    documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
30#include <iostream>
31#include <sstream>
32#include <string>
33#include <utility>
34#include <vector>
35
36#include "atf-c++/macros.hpp"
37
38#include "atf-c++/detail/parser.hpp"
39#include "atf-c++/detail/sanity.hpp"
40#include "atf-c++/detail/test_helpers.hpp"
41#include "atf-c++/detail/text.hpp"
42
43#include "reader.hpp"
44
45namespace impl = atf::atf_report;
46
47class tps_reader : protected impl::atf_tps_reader {
48    void
49    got_info(const std::string& what, const std::string& val)
50    {
51        m_calls.push_back("got_info(" + what + ", " + val + ")");
52    }
53
54    void
55    got_ntps(size_t ntps)
56    {
57        m_calls.push_back("got_ntps(" + atf::text::to_string(ntps) + ")");
58    }
59
60    void
61    got_tp_start(const std::string& tpname, size_t ntcs)
62    {
63        m_calls.push_back("got_tp_start(" + tpname + ", " +
64                          atf::text::to_string(ntcs) + ")");
65    }
66
67    void
68    got_tp_end(struct timeval* tv ATF_DEFS_ATTRIBUTE_UNUSED,
69               const std::string& reason)
70    {
71        m_calls.push_back("got_tp_end(" + reason + ")");
72    }
73
74    void
75    got_tc_start(const std::string& tcname)
76    {
77        m_calls.push_back("got_tc_start(" + tcname + ")");
78    }
79
80    void
81    got_tc_end(const std::string& state,
82               struct timeval* tv ATF_DEFS_ATTRIBUTE_UNUSED,
83               const std::string& reason)
84    {
85        const std::string r = state + (reason.empty() ? "" : ", " + reason);
86        m_calls.push_back("got_tc_end(" + r + ")");
87    }
88
89    void
90    got_tc_stdout_line(const std::string& line)
91    {
92        m_calls.push_back("got_tc_stdout_line(" + line + ")");
93    }
94
95    void
96    got_tc_stderr_line(const std::string& line)
97    {
98        m_calls.push_back("got_tc_stderr_line(" + line + ")");
99    }
100
101    void
102    got_eof(void)
103    {
104        m_calls.push_back("got_eof()");
105    }
106
107public:
108    tps_reader(std::istream& is) :
109        impl::atf_tps_reader(is)
110    {
111    }
112
113    void
114    read(void)
115    {
116        atf_tps_reader::read();
117    }
118
119    std::vector< std::string > m_calls;
120};
121
122ATF_TEST_CASE_WITHOUT_HEAD(tps_1);
123ATF_TEST_CASE_BODY(tps_1)
124{
125    const char* input =
126        "Content-Type: application/X-atf-tps; version=\"3\"\n"
127        "\n"
128        "tps-count: 0\n"
129    ;
130
131    const char* exp_calls[] = {
132        "got_ntps(0)",
133        "got_eof()",
134        NULL
135    };
136
137    const char* exp_errors[] = {
138        NULL
139    };
140
141    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
142}
143
144ATF_TEST_CASE_WITHOUT_HEAD(tps_2);
145ATF_TEST_CASE_BODY(tps_2)
146{
147    const char* input =
148        "Content-Type: application/X-atf-tps; version=\"3\"\n"
149        "\n"
150        "tps-count: 2\n"
151        "tp-start: 123.456, first-prog, 0\n"
152        "tp-end: 123.567, first-prog\n"
153        "tp-start: 123.678, second-prog, 0\n"
154        "tp-end: 123.789, second-prog, This program failed\n"
155    ;
156
157    const char* exp_calls[] = {
158        "got_ntps(2)",
159        "got_tp_start(first-prog, 0)",
160        "got_tp_end()",
161        "got_tp_start(second-prog, 0)",
162        "got_tp_end(This program failed)",
163        "got_eof()",
164        NULL
165    };
166
167    const char* exp_errors[] = {
168        NULL
169    };
170
171    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
172}
173
174ATF_TEST_CASE_WITHOUT_HEAD(tps_3);
175ATF_TEST_CASE_BODY(tps_3)
176{
177    const char* input =
178        "Content-Type: application/X-atf-tps; version=\"3\"\n"
179        "\n"
180        "tps-count: 2\n"
181        "tp-start: 123.123, first-prog, 3\n"
182        "tc-start: 123.234, first-test\n"
183        "tc-end: 123.345, first-test, passed\n"
184        "tc-start: 123.456, second-test\n"
185        "tc-end: 123.567, second-test, skipped, Testing skipped reason\n"
186        "tc-start: 123.678, third.test\n"
187        "tc-end: 123.789, third.test, failed, Testing failed reason\n"
188        "tp-end: 123.890, first-prog\n"
189        "tp-start: 124.901, second-prog, 3\n"
190        "tc-start: 124.1012, first-test\n"
191        "tc-so:first stdout line for 1st test\n"
192        "tc-se:first stderr line for 1st test\n"
193        "tc-so:second stdout line for 1st test\n"
194        "tc-se:second stderr line for 1st test\n"
195        "tc-end: 124.1123, first-test, passed\n"
196        "tc-start: 124.1234, second-test\n"
197        "tc-so:first stdout line for 2nd test\n"
198        "tc-se:first stderr line for 2nd test\n"
199        "tc-so:second stdout line for 2nd test\n"
200        "tc-se:second stderr line for 2nd test\n"
201        "tc-end: 124.1345, second-test, skipped, Testing skipped reason\n"
202        "tc-start: 124.1456, third.test\n"
203        "tc-so:first stdout line for 3rd test\n"
204        "tc-se:first stderr line for 3rd test\n"
205        "tc-so:second stdout line for 3rd test\n"
206        "tc-se:second stderr line for 3rd test\n"
207        "tc-end: 124.1567, third.test, failed, Testing failed reason\n"
208        "tp-end: 124.1678, second-prog, This program failed\n"
209    ;
210
211    const char* exp_calls[] = {
212        "got_ntps(2)",
213        "got_tp_start(first-prog, 3)",
214        "got_tc_start(first-test)",
215        "got_tc_end(passed)",
216        "got_tc_start(second-test)",
217        "got_tc_end(skipped, Testing skipped reason)",
218        "got_tc_start(third.test)",
219        "got_tc_end(failed, Testing failed reason)",
220        "got_tp_end()",
221        "got_tp_start(second-prog, 3)",
222        "got_tc_start(first-test)",
223        "got_tc_stdout_line(first stdout line for 1st test)",
224        "got_tc_stderr_line(first stderr line for 1st test)",
225        "got_tc_stdout_line(second stdout line for 1st test)",
226        "got_tc_stderr_line(second stderr line for 1st test)",
227        "got_tc_end(passed)",
228        "got_tc_start(second-test)",
229        "got_tc_stdout_line(first stdout line for 2nd test)",
230        "got_tc_stderr_line(first stderr line for 2nd test)",
231        "got_tc_stdout_line(second stdout line for 2nd test)",
232        "got_tc_stderr_line(second stderr line for 2nd test)",
233        "got_tc_end(skipped, Testing skipped reason)",
234        "got_tc_start(third.test)",
235        "got_tc_stdout_line(first stdout line for 3rd test)",
236        "got_tc_stderr_line(first stderr line for 3rd test)",
237        "got_tc_stdout_line(second stdout line for 3rd test)",
238        "got_tc_stderr_line(second stderr line for 3rd test)",
239        "got_tc_end(failed, Testing failed reason)",
240        "got_tp_end(This program failed)",
241        "got_eof()",
242        NULL
243    };
244
245    const char* exp_errors[] = {
246        NULL
247    };
248
249    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
250}
251
252ATF_TEST_CASE_WITHOUT_HEAD(tps_4);
253ATF_TEST_CASE_BODY(tps_4)
254{
255    const char* input =
256        "Content-Type: application/X-atf-tps; version=\"3\"\n"
257        "\n"
258        "info: a, foo\n"
259        "info: b, bar\n"
260        "info: c, baz\n"
261        "tps-count: 2\n"
262        "tp-start: 234.1, first-prog, 3\n"
263        "tc-start: 234.12, first-test\n"
264        "tc-end: 234.23, first-test, passed\n"
265        "tc-start: 234.34, second-test\n"
266        "tc-end: 234.45, second-test, skipped, Testing skipped reason\n"
267        "tc-start: 234.56, third-test\n"
268        "tc-end: 234.67, third-test, failed, Testing failed reason\n"
269        "tp-end: 234.78, first-prog\n"
270        "tp-start: 234.89, second-prog, 3\n"
271        "tc-start: 234.90, first-test\n"
272        "tc-so:first stdout line for 1st test\n"
273        "tc-se:first stderr line for 1st test\n"
274        "tc-so:second stdout line for 1st test\n"
275        "tc-se:second stderr line for 1st test\n"
276        "tc-end: 234.101, first-test, passed\n"
277        "tc-start: 234.112, second-test\n"
278        "tc-so:first stdout line for 2nd test\n"
279        "tc-se:first stderr line for 2nd test\n"
280        "tc-so:second stdout line for 2nd test\n"
281        "tc-se:second stderr line for 2nd test\n"
282        "tc-end: 234.123, second-test, skipped, Testing skipped reason\n"
283        "tc-start: 234.134, third-test\n"
284        "tc-so:first stdout line for 3rd test\n"
285        "tc-se:first stderr line for 3rd test\n"
286        "tc-so:second stdout line for 3rd test\n"
287        "tc-se:second stderr line for 3rd test\n"
288        "tc-end: 234.145, third-test, failed, Testing failed reason\n"
289        "tp-end: 234.156, second-prog, This program failed\n"
290        "info: d, foo\n"
291        "info: e, bar\n"
292        "info: f, baz\n"
293    ;
294
295    const char* exp_calls[] = {
296        "got_info(a, foo)",
297        "got_info(b, bar)",
298        "got_info(c, baz)",
299        "got_ntps(2)",
300        "got_tp_start(first-prog, 3)",
301        "got_tc_start(first-test)",
302        "got_tc_end(passed)",
303        "got_tc_start(second-test)",
304        "got_tc_end(skipped, Testing skipped reason)",
305        "got_tc_start(third-test)",
306        "got_tc_end(failed, Testing failed reason)",
307        "got_tp_end()",
308        "got_tp_start(second-prog, 3)",
309        "got_tc_start(first-test)",
310        "got_tc_stdout_line(first stdout line for 1st test)",
311        "got_tc_stderr_line(first stderr line for 1st test)",
312        "got_tc_stdout_line(second stdout line for 1st test)",
313        "got_tc_stderr_line(second stderr line for 1st test)",
314        "got_tc_end(passed)",
315        "got_tc_start(second-test)",
316        "got_tc_stdout_line(first stdout line for 2nd test)",
317        "got_tc_stderr_line(first stderr line for 2nd test)",
318        "got_tc_stdout_line(second stdout line for 2nd test)",
319        "got_tc_stderr_line(second stderr line for 2nd test)",
320        "got_tc_end(skipped, Testing skipped reason)",
321        "got_tc_start(third-test)",
322        "got_tc_stdout_line(first stdout line for 3rd test)",
323        "got_tc_stderr_line(first stderr line for 3rd test)",
324        "got_tc_stdout_line(second stdout line for 3rd test)",
325        "got_tc_stderr_line(second stderr line for 3rd test)",
326        "got_tc_end(failed, Testing failed reason)",
327        "got_tp_end(This program failed)",
328        "got_info(d, foo)",
329        "got_info(e, bar)",
330        "got_info(f, baz)",
331        "got_eof()",
332        NULL
333    };
334
335    const char* exp_errors[] = {
336        NULL
337    };
338
339    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
340}
341
342ATF_TEST_CASE_WITHOUT_HEAD(tps_5);
343ATF_TEST_CASE_BODY(tps_5)
344{
345    const char* input =
346        "Content-Type: application/X-atf-tps; version=\"3\"\n"
347        "\n"
348        "tps-count: 1\n"
349        "tp-start: 345.123, the-prog, 1\n"
350        "tc-start: 345.134, the-test\n"
351        "tc-so:--- a	2007-11-04 14:00:41.000000000 +0100\n"
352        "tc-so:+++ b	2007-11-04 14:00:48.000000000 +0100\n"
353        "tc-so:@@ -1,7 +1,7 @@\n"
354        "tc-so: This test is meant to simulate a diff.\n"
355        "tc-so: Blank space at beginning of context lines must be preserved.\n"
356        "tc-so: \n"
357        "tc-so:-First original line.\n"
358        "tc-so:-Second original line.\n"
359        "tc-so:+First modified line.\n"
360        "tc-so:+Second modified line.\n"
361        "tc-so: \n"
362        "tc-so: EOF\n"
363        "tc-end: 345.145, the-test, passed\n"
364        "tp-end: 345.156, the-prog\n"
365    ;
366
367    // NO_CHECK_STYLE_BEGIN
368    const char* exp_calls[] = {
369        "got_ntps(1)",
370        "got_tp_start(the-prog, 1)",
371        "got_tc_start(the-test)",
372        "got_tc_stdout_line(--- a	2007-11-04 14:00:41.000000000 +0100)",
373        "got_tc_stdout_line(+++ b	2007-11-04 14:00:48.000000000 +0100)",
374        "got_tc_stdout_line(@@ -1,7 +1,7 @@)",
375        "got_tc_stdout_line( This test is meant to simulate a diff.)",
376        "got_tc_stdout_line( Blank space at beginning of context lines must be preserved.)",
377        "got_tc_stdout_line( )",
378        "got_tc_stdout_line(-First original line.)",
379        "got_tc_stdout_line(-Second original line.)",
380        "got_tc_stdout_line(+First modified line.)",
381        "got_tc_stdout_line(+Second modified line.)",
382        "got_tc_stdout_line( )",
383        "got_tc_stdout_line( EOF)",
384        "got_tc_end(passed)",
385        "got_tp_end()",
386        "got_eof()",
387        NULL
388    };
389    // NO_CHECK_STYLE_END
390
391    const char* exp_errors[] = {
392        NULL
393    };
394
395    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
396}
397
398ATF_TEST_CASE_WITHOUT_HEAD(tps_6);
399ATF_TEST_CASE_BODY(tps_6)
400{
401    const char* input =
402        "Content-Type: application/X-atf-tps; version=\"3\"\n"
403        "\n"
404        "tps-count: 1\n"
405        "tp-start: 321.1, the-prog, 8\n"
406        "tc-start: 321.12, one\n"
407        "tc-end: 321.23, one, expected_death, The reason\n"
408        "tc-start: 321.34, two\n"
409        "tc-end: 321.45, two, expected_exit, This would be an exit\n"
410        "tc-start: 321.56, three\n"
411        "tc-end: 321.67, three, expected_failure, And this a failure\n"
412        "tc-start: 321.78, four\n"
413        "tc-end: 321.89, four, expected_signal, And this a signal\n"
414        "tc-start: 321.90, five\n"
415        "tc-end: 321.101, five, failed, Another reason\n"
416        "tc-start: 321.112, six\n"
417        "tc-end: 321.123, six, passed\n"
418        "tc-start: 321.134, seven\n"
419        "tc-end: 321.145, seven, skipped, Skipping it\n"
420        "tc-start: 321.156, eight\n"
421        "tc-end: 321.167, eight, expected_timeout, Some hang reason\n"
422        "tp-end: 321.178, the-prog\n"
423    ;
424
425    // NO_CHECK_STYLE_BEGIN
426    const char* exp_calls[] = {
427        "got_ntps(1)",
428        "got_tp_start(the-prog, 8)",
429        "got_tc_start(one)",
430        "got_tc_end(expected_death, The reason)",
431        "got_tc_start(two)",
432        "got_tc_end(expected_exit, This would be an exit)",
433        "got_tc_start(three)",
434        "got_tc_end(expected_failure, And this a failure)",
435        "got_tc_start(four)",
436        "got_tc_end(expected_signal, And this a signal)",
437        "got_tc_start(five)",
438        "got_tc_end(failed, Another reason)",
439        "got_tc_start(six)",
440        "got_tc_end(passed)",
441        "got_tc_start(seven)",
442        "got_tc_end(skipped, Skipping it)",
443        "got_tc_start(eight)",
444        "got_tc_end(expected_timeout, Some hang reason)",
445        "got_tp_end()",
446        "got_eof()",
447        NULL
448    };
449    // NO_CHECK_STYLE_END
450
451    const char* exp_errors[] = {
452        NULL
453    };
454
455    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
456}
457
458
459ATF_TEST_CASE_WITHOUT_HEAD(tps_50);
460ATF_TEST_CASE_BODY(tps_50)
461{
462    const char* input =
463        "Content-Type: application/X-atf-tps; version=\"3\"\n"
464        "\n"
465        "foo\n"
466    ;
467
468    const char* exp_calls[] = {
469        NULL
470    };
471
472    const char* exp_errors[] = {
473        "3: Unexpected token `foo'; expected tps-count or info field",
474        NULL
475    };
476
477    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
478}
479
480ATF_TEST_CASE_WITHOUT_HEAD(tps_51);
481ATF_TEST_CASE_BODY(tps_51)
482{
483    const char* input =
484        "Content-Type: application/X-atf-tps; version=\"3\"\n"
485        "\n"
486        "tps-count\n"
487    ;
488
489    const char* exp_calls[] = {
490        NULL
491    };
492
493    const char* exp_errors[] = {
494        "3: Unexpected token `<<NEWLINE>>'; expected `:'",
495        NULL
496    };
497
498    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
499}
500
501ATF_TEST_CASE_WITHOUT_HEAD(tps_52);
502ATF_TEST_CASE_BODY(tps_52)
503{
504    const char* input =
505        "Content-Type: application/X-atf-tps; version=\"3\"\n"
506        "\n"
507        "tps-count:\n"
508    ;
509
510    const char* exp_calls[] = {
511        NULL
512    };
513
514    const char* exp_errors[] = {
515        "3: Unexpected token `<<NEWLINE>>'; expected number of test programs",
516        NULL
517    };
518
519    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
520}
521
522ATF_TEST_CASE_WITHOUT_HEAD(tps_53);
523ATF_TEST_CASE_BODY(tps_53)
524{
525    const char* input =
526        "Content-Type: application/X-atf-tps; version=\"3\"\n"
527        "\n"
528        "tps-count: 1\n"
529        "foo\n"
530    ;
531
532    const char* exp_calls[] = {
533        "got_ntps(1)",
534        NULL
535    };
536
537    const char* exp_errors[] = {
538        "4: Unexpected token `foo'; expected start of test program",
539        NULL
540    };
541
542    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
543}
544
545ATF_TEST_CASE_WITHOUT_HEAD(tps_54);
546ATF_TEST_CASE_BODY(tps_54)
547{
548    const char* input =
549        "Content-Type: application/X-atf-tps; version=\"3\"\n"
550        "\n"
551        "tps-count: 1\n"
552        "foo\n"
553        "tp-start\n"
554        "tp-start:\n"
555        "tp-start: 123\n"
556        "tp-start: 123.\n"
557        "tp-start: 123.456\n"
558        "tp-start: 123.456,\n"
559        "tp-start: 123.456, foo\n"
560        "tp-start: 123.456, foo,\n"
561        "tp-start: 123.456, foo, 0\n"
562        "bar\n"
563        "tp-start: 456.789, foo, 0\n"
564        "tp-end\n"
565        "tp-start: 777.777, foo, 0\n"
566        "tp-end:\n"
567        "tp-start: 777.777, foo, 0\n"
568        "tp-end: 777\n"
569        "tp-start: 777.777, foo, 0\n"
570        "tp-end: 777.\n"
571        "tp-start: 777.777, foo, 0\n"
572        "tp-end: 777.888\n"
573        "tp-start: 777.777, foo, 0\n"
574        "tp-end: 777.888, \n"
575        "tp-start: 777.777, foo, 0\n"
576        "tp-end: 777.888, bar\n"
577        "tp-start: 777.777, foo, 0\n"
578        "tp-end: 777.888, foo,\n"
579    ;
580
581    const char* exp_calls[] = {
582        "got_ntps(1)",
583        NULL
584    };
585
586    const char* exp_errors[] = {
587        "4: Unexpected token `foo'; expected start of test program",
588        "5: Unexpected token `<<NEWLINE>>'; expected `:'",
589        "6: Unexpected token `<<NEWLINE>>'; expected timestamp",
590        "7: Malformed timestamp value 123",
591        "8: Malformed timestamp value 123.",
592        "9: Unexpected token `<<NEWLINE>>'; expected `,'",
593        "10: Unexpected token `<<NEWLINE>>'; expected test program name",
594        "11: Unexpected token `<<NEWLINE>>'; expected `,'",
595        "12: Unexpected token `<<NEWLINE>>'; expected number of test programs",
596        "14: Unexpected token `bar'; expected end of test program",
597        "16: Unexpected token `<<NEWLINE>>'; expected `:'",
598        "18: Unexpected token `<<NEWLINE>>'; expected timestamp",
599        "20: Malformed timestamp value 777",
600        "22: Malformed timestamp value 777.",
601        "24: Unexpected token `<<NEWLINE>>'; expected `,'",
602
603        "26: Unexpected token `<<NEWLINE>>'; expected test program name",
604        "28: Test program name used in terminator does not match opening",
605        "30: Empty reason for failed test program",
606        NULL
607    };
608
609    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
610}
611
612ATF_TEST_CASE_WITHOUT_HEAD(tps_55);
613ATF_TEST_CASE_BODY(tps_55)
614{
615    const char* input =
616        "Content-Type: application/X-atf-tps; version=\"3\"\n"
617        "\n"
618        "tps-count: 1\n"
619        "tp-start: 100.200, foo, 1\n"
620        "foo\n"
621        "tc-start\n"
622        "tc-start:\n"
623        "tc-start: 111\n"
624        "tc-start: 111.\n"
625        "tc-start: 111.222\n"
626        "tc-start: 111.222,\n"
627        "tc-start: 111.222, foo\n"
628        "bar\n"
629        "tc-start: 111.333, foo\n"
630        "tc-end\n"
631        "tc-start: 111.444, foo\n"
632        "tc-end:\n"
633        "tc-start: 111.444, foo\n"
634        "tc-end: 111\n"
635        "tc-start: 111.444, foo\n"
636        "tc-end: 111.\n"
637        "tc-start: 111.444, foo\n"
638        "tc-end: 111.555\n"
639        "tc-start: 111.444, foo\n"
640        "tc-end: 111.555, \n"
641        "tc-start: 111.444, foo\n"
642        "tc-end: 111.555, bar\n"
643        "tc-start: 111.444, foo\n"
644        "tc-end: 111.555, foo\n"
645        "tc-start: 111.444, foo\n"
646        "tc-end: 111.555, foo,\n"
647        "tp-end: 111.666, foo\n"
648    ;
649
650    const char* exp_calls[] = {
651        "got_ntps(1)",
652        "got_tp_start(foo, 1)",
653        NULL
654    };
655
656    // NO_CHECK_STYLE_BEGIN
657    const char* exp_errors[] = {
658        "5: Unexpected token `foo'; expected start of test case",
659        "6: Unexpected token `<<NEWLINE>>'; expected `:'",
660        "7: Unexpected token `<<NEWLINE>>'; expected timestamp",
661        "8: Malformed timestamp value 111",
662        "9: Malformed timestamp value 111.",
663        "10: Unexpected token `<<NEWLINE>>'; expected `,'",
664        "11: Unexpected token `<<NEWLINE>>'; expected test case name",
665        "13: Unexpected token `bar'; expected end of test case or test case's stdout/stderr line",
666        "15: Unexpected token `<<NEWLINE>>'; expected `:'",
667        "17: Unexpected token `<<NEWLINE>>'; expected timestamp",
668        "19: Malformed timestamp value 111",
669        "21: Malformed timestamp value 111.",
670        "23: Unexpected token `<<NEWLINE>>'; expected `,'",
671        "25: Unexpected token `<<NEWLINE>>'; expected test case name",
672        "27: Test case name used in terminator does not match opening",
673        "29: Unexpected token `<<NEWLINE>>'; expected `,'",
674        "31: Unexpected token `<<NEWLINE>>'; expected expected_{death,exit,failure,signal,timeout}, failed, passed or skipped",
675        "32: Unexpected token `tp-end'; expected start of test case",
676        NULL
677    };
678    // NO_CHECK_STYLE_END
679
680    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
681}
682
683ATF_TEST_CASE_WITHOUT_HEAD(tps_56);
684ATF_TEST_CASE_BODY(tps_56)
685{
686    const char* input =
687        "Content-Type: application/X-atf-tps; version=\"3\"\n"
688        "\n"
689        "tps-count: 1\n"
690        "tp-start: 111.222, foo, 1\n"
691        "tc-start: 111.333, foo\n"
692        "tc-end: 111.444, foo, passe\n"
693        "tc-start: 111.333, foo\n"
694        "tc-end: 111.444, foo, passed,\n"
695        "tc-start: 111.555, bar\n"
696        "tc-end: 111.666, bar, failed\n"
697        "tc-start: 111.555, bar\n"
698        "tc-end: 111.666, bar, failed,\n"
699        "tc-start: 111.555, baz\n"
700        "tc-end: 111.666, baz, skipped\n"
701        "tc-start: 111.555, baz\n"
702        "tc-end: 111.666, baz, skipped,\n"
703        "tp-end: 111.777, foo\n"
704    ;
705
706    const char* exp_calls[] = {
707        "got_ntps(1)",
708        "got_tp_start(foo, 1)",
709        "got_tc_start(foo)",
710        NULL
711    };
712
713    // NO_CHECK_STYLE_BEGIN
714    const char* exp_errors[] = {
715        "6: Unexpected token `passe'; expected expected_{death,exit,failure,signal,timeout}, failed, passed or skipped",
716        "8: Unexpected token `,'; expected new line",
717        "10: Unexpected token `<<NEWLINE>>'; expected `,'",
718        "12: Empty reason for failed test case result",
719        "14: Unexpected token `<<NEWLINE>>'; expected `,'",
720        "16: Empty reason for skipped test case result",
721        "17: Unexpected token `tp-end'; expected start of test case",
722        NULL
723    };
724    // NO_CHECK_STYLE_END
725
726    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
727}
728
729ATF_TEST_CASE_WITHOUT_HEAD(tps_57);
730ATF_TEST_CASE_BODY(tps_57)
731{
732    const char* input =
733        "Content-Type: application/X-atf-tps; version=\"3\"\n"
734        "\n"
735        "tps-count: 2\n"
736        "tp-start: 111.222, foo, 0\n"
737        "tp-end: 111.333, foo\n"
738    ;
739
740    const char* exp_calls[] = {
741        "got_ntps(2)",
742        "got_tp_start(foo, 0)",
743        "got_tp_end()",
744        NULL
745    };
746
747    const char* exp_errors[] = {
748        "6: Unexpected token `<<EOF>>'; expected start of test program",
749        NULL
750    };
751
752    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
753}
754
755ATF_TEST_CASE_WITHOUT_HEAD(tps_58);
756ATF_TEST_CASE_BODY(tps_58)
757{
758    const char* input =
759        "Content-Type: application/X-atf-tps; version=\"3\"\n"
760        "\n"
761        "tps-count: 1\n"
762        "tp-start: 111.222, foo, 0\n"
763        "tp-end: 111.333, foo\n"
764        "tp-start: 111.444, bar, 0\n"
765        "tp-end: 111.555, bar\n"
766    ;
767
768    const char* exp_calls[] = {
769        "got_ntps(1)",
770        "got_tp_start(foo, 0)",
771        "got_tp_end()",
772        NULL
773    };
774
775    const char* exp_errors[] = {
776        "6: Unexpected token `tp-start'; expected end of stream or info field",
777        NULL
778    };
779
780    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
781}
782
783ATF_TEST_CASE_WITHOUT_HEAD(tps_59);
784ATF_TEST_CASE_BODY(tps_59)
785{
786    const char* input =
787        "Content-Type: application/X-atf-tps; version=\"3\"\n"
788        "\n"
789        "info\n"
790    ;
791
792    const char* exp_calls[] = {
793        NULL
794    };
795
796    const char* exp_errors[] = {
797        "3: Unexpected token `<<NEWLINE>>'; expected `:'",
798        NULL
799    };
800
801    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
802}
803
804ATF_TEST_CASE_WITHOUT_HEAD(tps_60);
805ATF_TEST_CASE_BODY(tps_60)
806{
807    const char* input =
808        "Content-Type: application/X-atf-tps; version=\"3\"\n"
809        "\n"
810        "info:\n"
811    ;
812
813    const char* exp_calls[] = {
814        NULL
815    };
816
817    const char* exp_errors[] = {
818        "3: Unexpected token `<<NEWLINE>>'; expected info property name",
819        NULL
820    };
821
822    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
823}
824
825ATF_TEST_CASE_WITHOUT_HEAD(tps_61);
826ATF_TEST_CASE_BODY(tps_61)
827{
828    const char* input =
829        "Content-Type: application/X-atf-tps; version=\"3\"\n"
830        "\n"
831        "info: a\n"
832    ;
833
834    const char* exp_calls[] = {
835        NULL
836    };
837
838    const char* exp_errors[] = {
839        "3: Unexpected token `<<NEWLINE>>'; expected `,'",
840        NULL
841    };
842
843    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
844}
845
846ATF_TEST_CASE_WITHOUT_HEAD(tps_62);
847ATF_TEST_CASE_BODY(tps_62)
848{
849    const char* input =
850        "Content-Type: application/X-atf-tps; version=\"3\"\n"
851        "\n"
852        "info: a,\n"
853    ;
854
855    const char* exp_calls[] = {
856        "got_info(a, )",
857        NULL
858    };
859
860    const char* exp_errors[] = {
861        "4: Unexpected token `<<EOF>>'; expected tps-count or info field",
862        NULL
863    };
864
865    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
866}
867
868ATF_TEST_CASE_WITHOUT_HEAD(tps_63);
869ATF_TEST_CASE_BODY(tps_63)
870{
871    const char* input =
872        "Content-Type: application/X-atf-tps; version=\"3\"\n"
873        "\n"
874        "info: a, b\n"
875    ;
876
877    const char* exp_calls[] = {
878        "got_info(a, b)",
879        NULL
880    };
881
882    const char* exp_errors[] = {
883        "4: Unexpected token `<<EOF>>'; expected tps-count or info field",
884        NULL
885    };
886
887    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
888}
889
890ATF_TEST_CASE_WITHOUT_HEAD(tps_64);
891ATF_TEST_CASE_BODY(tps_64)
892{
893    const char* input =
894        "Content-Type: application/X-atf-tps; version=\"3\"\n"
895        "\n"
896        "info: a, b\n"
897        "info: a.b.c.def, g\n"
898        "tps-count\n"
899    ;
900
901    const char* exp_calls[] = {
902        "got_info(a, b)",
903        "got_info(a.b.c.def, g)",
904        NULL
905    };
906
907    const char* exp_errors[] = {
908        "5: Unexpected token `<<NEWLINE>>'; expected `:'",
909        NULL
910    };
911
912    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
913}
914
915ATF_TEST_CASE_WITHOUT_HEAD(tps_65);
916ATF_TEST_CASE_BODY(tps_65)
917{
918    const char* input =
919        "Content-Type: application/X-atf-tps; version=\"3\"\n"
920        "\n"
921        "info: a, b\n"
922        "tps-count:\n"
923    ;
924
925    const char* exp_calls[] = {
926        "got_info(a, b)",
927        NULL
928    };
929
930    const char* exp_errors[] = {
931        "4: Unexpected token `<<NEWLINE>>'; expected number of test programs",
932        NULL
933    };
934
935    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
936}
937
938ATF_TEST_CASE_WITHOUT_HEAD(tps_66);
939ATF_TEST_CASE_BODY(tps_66)
940{
941    const char* input =
942        "Content-Type: application/X-atf-tps; version=\"3\"\n"
943        "\n"
944        "info: a, b\n"
945        "tps-count: 0\n"
946        "info\n"
947    ;
948
949    const char* exp_calls[] = {
950        "got_info(a, b)",
951        "got_ntps(0)",
952        NULL
953    };
954
955    const char* exp_errors[] = {
956        "5: Unexpected token `<<NEWLINE>>'; expected `:'",
957        NULL
958    };
959
960    do_parser_test< tps_reader >(input, exp_calls, exp_errors);
961}
962
963ATF_INIT_TEST_CASES(tcs)
964{
965    ATF_ADD_TEST_CASE(tcs, tps_1);
966    ATF_ADD_TEST_CASE(tcs, tps_2);
967    ATF_ADD_TEST_CASE(tcs, tps_3);
968    ATF_ADD_TEST_CASE(tcs, tps_4);
969    ATF_ADD_TEST_CASE(tcs, tps_5);
970    ATF_ADD_TEST_CASE(tcs, tps_6);
971    ATF_ADD_TEST_CASE(tcs, tps_50);
972    ATF_ADD_TEST_CASE(tcs, tps_51);
973    ATF_ADD_TEST_CASE(tcs, tps_52);
974    ATF_ADD_TEST_CASE(tcs, tps_53);
975    ATF_ADD_TEST_CASE(tcs, tps_54);
976    ATF_ADD_TEST_CASE(tcs, tps_55);
977    ATF_ADD_TEST_CASE(tcs, tps_56);
978    ATF_ADD_TEST_CASE(tcs, tps_57);
979    ATF_ADD_TEST_CASE(tcs, tps_58);
980    ATF_ADD_TEST_CASE(tcs, tps_59);
981    ATF_ADD_TEST_CASE(tcs, tps_60);
982    ATF_ADD_TEST_CASE(tcs, tps_61);
983    ATF_ADD_TEST_CASE(tcs, tps_62);
984    ATF_ADD_TEST_CASE(tcs, tps_63);
985    ATF_ADD_TEST_CASE(tcs, tps_64);
986    ATF_ADD_TEST_CASE(tcs, tps_65);
987    ATF_ADD_TEST_CASE(tcs, tps_66);
988}
989
990