1 /*
2 * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include <stdio.h>
20 #include <glib.h>
21 #include <glib-object.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <gmodule.h>
26 #include <libgda/libgda.h>
27 #include <sql-parser/gda-sql-parser.h>
28
29 #include <libxml/parser.h>
30 #include <libxml/tree.h>
31
32 static GdaSqlParser *create_parser_for_provider (const gchar *prov_name);
33 static gint do_test (GdaSqlParser *parser, const xmlChar *id, const xmlChar *file, xmlNodePtr test_node);
34
35 int
main(int argc,char ** argv)36 main (int argc, char** argv)
37 {
38 xmlDocPtr doc;
39 xmlNodePtr root, node;
40 GdaSqlParser *parser;
41 gint failures = 0;
42 gint ntests = 0;
43 gchar *fname;
44 GHashTable *parsers_hash;
45 GdaDataModel *providers_model;
46 gint i;
47
48 gda_init ();
49
50 /* load file */
51 fname = g_build_filename (ROOT_DIR, "tests", "parser", "testscripts.xml", NULL);
52 if (! g_file_test (fname, G_FILE_TEST_EXISTS)) {
53 g_print ("File '%s' does not exist\n", fname);
54 exit (1);
55 }
56
57 /* create parsers */
58 parsers_hash = g_hash_table_new (g_str_hash, g_str_equal);
59 providers_model = gda_config_list_providers ();
60 for (i = 0; i < gda_data_model_get_n_rows (providers_model); i++) {
61 const GValue *pname;
62 GError *lerror = NULL;
63 pname = gda_data_model_get_value_at (providers_model, 0, i, &lerror);
64 if (!pname) {
65 g_print ("Can't get data model's value: %s",
66 lerror && lerror->message ? lerror->message : "No detail");
67 exit (1);
68 }
69 parser = create_parser_for_provider (g_value_get_string (pname));
70 g_hash_table_insert (parsers_hash, g_strdup (g_value_get_string (pname)), parser);
71 g_print ("Created parser for provider %s\n", g_value_get_string (pname));
72 }
73 g_object_unref (providers_model);
74 g_hash_table_insert (parsers_hash, "", gda_sql_parser_new ());
75
76 /* use test data */
77 doc = xmlParseFile (fname);
78 g_free (fname);
79 g_assert (doc);
80 root = xmlDocGetRootElement (doc);
81 g_assert (!strcmp ((gchar*) root->name, "testdata"));
82 for (node = root->children; node; node = node->next) {
83 if (strcmp ((gchar*) node->name, "test"))
84 continue;
85 xmlChar *id;
86 xmlChar *file;
87 xmlChar *prov_name;
88
89 prov_name = xmlGetProp (node, BAD_CAST "provider");
90 if (prov_name) {
91 parser = g_hash_table_lookup (parsers_hash, (gchar *) prov_name);
92 xmlFree (prov_name);
93 }
94 else
95 parser = g_hash_table_lookup (parsers_hash, "");
96 if (!parser)
97 continue;
98
99 id = xmlGetProp (node, BAD_CAST "id");
100 file = xmlGetProp (node, BAD_CAST "file");
101
102 if (id && file) {
103 failures += do_test (parser, id, file, node);
104 ntests++;
105 }
106
107 /* mem free */
108 if (id) xmlFree (id);
109 if (file) xmlFree (file);
110 }
111 xmlFreeDoc (doc);
112
113 g_print ("TESTS COUNT: %d\n", ntests);
114 g_print ("FAILURES: %d\n", failures);
115
116 return failures != 0 ? 1 : 0;
117 }
118
119 /*
120 * Returns: the number of failures
121 */
122 static gint
do_test(GdaSqlParser * parser,const xmlChar * id,const xmlChar * file,xmlNodePtr test_node)123 do_test (GdaSqlParser *parser, const xmlChar *id, const xmlChar *file, xmlNodePtr test_node)
124 {
125 gboolean failures = 0;
126 GdaBatch *batch;
127 GError *error = NULL;
128 gchar *full_file;
129
130 full_file = g_build_filename (ROOT_DIR, "tests", "parser", "scripts", file, NULL);
131
132 #ifdef GDA_DEBUG
133 g_print ("===== TEST %s FILE: %s\n", id, full_file);
134 #endif
135
136 batch = gda_sql_parser_parse_file_as_batch (parser, full_file, &error);
137 g_free (full_file);
138
139 if (!batch) {
140 g_print ("ERROR for test '%s':\n *got error while parsing: %s\n", id,
141 error && error->message ? error->message: "No detail");
142 if (error)
143 g_error_free (error);
144 failures ++;
145 }
146 else {
147 const GSList *stmt_list;
148 xmlNodePtr snode;
149 guint nb_stmt = 0;
150
151 stmt_list = gda_batch_get_statements (batch);
152
153 /* number of statements */
154 for (snode = test_node->children; snode; snode = snode->next) {
155 if (!strcmp ((gchar*) snode->name, "stmt"))
156 nb_stmt++;
157 }
158 if (nb_stmt != g_slist_length ((GSList*) stmt_list)) {
159 g_print ("ERROR for test '%s':\n *expected %d statements and got %d\n", id,
160 nb_stmt, g_slist_length ((GSList*) stmt_list));
161 failures ++;
162 }
163
164 /* each statement */
165 GSList *list;
166 for (snode = test_node->children, list = (GSList*) stmt_list;
167 list;
168 list = list->next) {
169 gchar *sql;
170 sql = gda_statement_to_sql (GDA_STATEMENT (list->data), NULL, &error);
171 if (!sql) {
172 g_print ("ERROR for test '%s':\n *can't convert statement at position %d to SQL: %s\n", id,
173 g_slist_position ((GSList*) stmt_list, list),
174 error && error->message ? error->message: "No detail");
175 if (error)
176 g_error_free (error);
177 failures ++;
178 }
179 else {
180 /* find the next <stmt> node */
181 xmlChar *expected = NULL;
182 for (; snode; snode = snode->next) {
183 if (strcmp ((gchar*) snode->name, "stmt"))
184 continue;
185 expected = xmlNodeGetContent (snode);
186 snode = snode->next;
187 break;
188 }
189 if (!expected) {
190 g_print ("ERROR for test '%s':\n *missing <stmt> tag for statement at position %d\n", id,
191 g_slist_position ((GSList*) stmt_list, list));
192 failures ++;
193 }
194
195 gchar *ptr;
196 for (ptr = sql; *ptr; ptr++) {
197 if ((*ptr == '\n') || (*ptr == '\t') || (*ptr == '\r'))
198 *ptr = ' ';
199 }
200 g_strstrip (sql);
201 if (expected) {
202 if (strcmp (sql, expected)) {
203 g_print ("ERROR for test '%s', statement at position %d:\n *exp:%s\n *got:%s\n", id,
204 g_slist_position ((GSList*) stmt_list, list), expected, sql);
205 failures ++;
206 break;
207 }
208 }
209 else
210 g_print ("% 2d: %s\n", g_slist_position ((GSList*) stmt_list, list), sql);
211 g_free (sql);
212 }
213 }
214 g_object_unref (batch);
215 }
216
217 return failures;
218 }
219
220 static GdaSqlParser *
create_parser_for_provider(const gchar * prov_name)221 create_parser_for_provider (const gchar *prov_name)
222 {
223 GdaServerProvider *prov;
224 GdaSqlParser *parser;
225 GError *error = NULL;
226
227 prov = gda_config_get_provider (prov_name, &error);
228 if (!prov)
229 g_error ("Could not create provider for '%s': %s\n", prov_name,
230 error && error->message ? error->message : "No detail");
231
232 parser = gda_server_provider_create_parser (prov, NULL);
233 if (!parser)
234 parser = gda_sql_parser_new ();
235
236 return parser;
237 }
238