pfix-srsd: add a -I option
[apps/pfixtools.git] / postlicyd / tst-qf.c
1 /******************************************************************************/
2 /*          pfixtools: a collection of postfix related tools                  */
3 /*          ~~~~~~~~~                                                         */
4 /*  ________________________________________________________________________  */
5 /*                                                                            */
6 /*  Redistribution and use in source and binary forms, with or without        */
7 /*  modification, are permitted provided that the following conditions        */
8 /*  are met:                                                                  */
9 /*                                                                            */
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 /*  3. The names of its contributors may not be used to endorse or promote    */
16 /*     products derived from this software without specific prior written     */
17 /*     permission.                                                            */
18 /*                                                                            */
19 /*  THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS   */
20 /*  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED         */
21 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE    */
22 /*  DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY         */
23 /*  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        */
24 /*  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS   */
25 /*  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)     */
26 /*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       */
27 /*  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  */
28 /*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           */
29 /*  POSSIBILITY OF SUCH DAMAGE.                                               */
30 /*                                                                            */
31 /*   Copyright (c) 2006-2008 the Authors                                      */
32 /*   see AUTHORS and source files for details                                 */
33 /******************************************************************************/
34
35 /*
36  * Copyright © 2008 Florent Bruneau
37  */
38
39 #include "common.h"
40 #include "file.h"
41 #include "query.h"
42
43 static bool read_query(const char *base, const char *file, query_t *query,
44                        char *buff)
45 {
46     char path[FILENAME_MAX];
47     snprintf(path, FILENAME_MAX, "%s%s", base, file);
48     {
49         file_map_t map;
50         if (!file_map_open(&map, path, false)) {
51             UNIXERR("open");
52             return false;
53         }
54         if (map.end - map.map >= BUFSIZ) {
55             err("File too large for a testcase: %s", path);
56             file_map_close(&map);
57             return false;
58         }
59         memcpy(buff, map.map, map.end - map.map);
60         buff[map.end - map.map] = '\0';
61         file_map_close(&map);
62     }
63
64     char *eoq = strstr(buff, "\n\n");
65     if (eoq == NULL) {
66         return false;
67     }
68     if (!query_parse(query, buff)) {
69         err("Cannot parse query from file %s", path);
70         return false;
71     }
72     return true;
73 }
74
75 int main(int argc, char *argv[])
76 {
77     char basepath[FILENAME_MAX];
78     char buff[BUFSIZ];
79     char *p;
80
81     p = strrchr(argv[0], '/');
82     if (p == NULL) {
83         p = argv[0];
84     } else {
85         ++p;
86     }
87     snprintf(basepath, FILENAME_MAX, "%.*sdata/", p - argv[0], argv[0]);
88
89     query_t q;
90     if (!read_query(basepath, "testcase_1", &q, buff)) {
91         return EXIT_FAILURE;
92     }
93
94     static const int iterations = 50000000;
95     {
96       static const char *format = "${sender} ${recipient} and ${client_name}[${client_address}] at ${protocol_state}";
97       time_t now = time(0);
98       char str[BUFSIZ];
99       for (int i = 0 ; i < iterations ; ++i) {
100           query_format(str, BUFSIZ, format, &q);
101       }
102       time_t ellapsed = time(0) - now;
103       printf("Done %d iterations in %us (%d format per second)\n", iterations,
104              (uint32_t)ellapsed, (int)(iterations / ellapsed));
105     }
106
107     {
108       time_t now = time(0);
109       char str[BUFSIZ];
110       for (int i = 0 ; i < iterations ; ++i) {
111           snprintf(str, BUFSIZ, "%s %s and %s[%s] at %s",
112                    q.sender.str, q.recipient.str, q.client_name.str, q.client_address.str,
113                    smtp_state_names[q.state].str);
114       }
115       time_t ellapsed = time(0) - now;
116       printf("Done %d iterations in %us (%d format per second)\n", iterations,
117              (uint32_t)ellapsed, (int)(iterations / ellapsed));
118     }
119     return 0;
120 }