Location | Tool | Test ID | Function | Issue |
---|---|---|---|---|
tracker-ontology-test.c:143:23 | clang-analyzer | Access to field 'str' results in a dereference of a null pointer (loaded from variable 'test_results') |
1 /*
2 * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #include <string.h>
23 #include <locale.h>
24
25 #include <glib.h>
26 #include <gio/gio.h>
27 #include <glib/gstdio.h>
28
29 #include <libtracker-data/tracker-data-manager.h>
30 #include <libtracker-data/tracker-data-query.h>
31 #include <libtracker-data/tracker-data-update.h>
32 #include <libtracker-data/tracker-data.h>
33 #include <libtracker-data/tracker-sparql-query.h>
34
35 typedef struct _TestInfo TestInfo;
36
37 struct _TestInfo {
38 const gchar *test_name;
39 const gchar *data;
40 };
41
42 typedef struct _ChangeInfo ChangeInfo;
43
44 struct _ChangeInfo {
45 const gchar *ontology;
46 const gchar *update;
47 const gchar *test_name;
48 const gchar *ptr;
49 };
50
51 const TestInfo nie_tests[] = {
52 { "nie/filter-subject-1", "nie/data-1" },
53 { "nie/filter-characterset-1", "nie/data-1" },
54 { "nie/filter-comment-1", "nie/data-1" },
55 { "nie/filter-description-1", "nie/data-1" },
56 { "nie/filter-generator-1", "nie/data-1" },
57 { "nie/filter-identifier-1", "nie/data-1" },
58 { "nie/filter-keyword-1", "nie/data-1" },
59 { "nie/filter-language-1", "nie/data-1" },
60 { "nie/filter-legal-1", "nie/data-1" },
61 { "nie/filter-title-1", "nie/data-1" },
62 { "nie/filter-version-1", "nie/data-1" },
63 { NULL }
64 };
65
66 const TestInfo nmo_tests[] = {
67 { "nmo/filter-charset-1", "nmo/data-1" },
68 { "nmo/filter-contentdescription-1", "nmo/data-1" },
69 { "nmo/filter-contentid-1", "nmo/data-1" },
70 { "nmo/filter-contenttransferencoding-1", "nmo/data-1" },
71 { "nmo/filter-headername-1", "nmo/data-1" },
72 { "nmo/filter-headervalue-1", "nmo/data-1" },
73 { "nmo/filter-isanswered-1", "nmo/data-1" },
74 { "nmo/filter-isdeleted-1", "nmo/data-1" },
75 { "nmo/filter-isdraft-1", "nmo/data-1" },
76 { "nmo/filter-isflagged-1", "nmo/data-1" },
77 { "nmo/filter-isread-1", "nmo/data-1" },
78 { "nmo/filter-isrecent-1", "nmo/data-1" },
79 { "nmo/filter-messageid-1", "nmo/data-1" },
80 { "nmo/filter-messagesubject-1", "nmo/data-1" },
81 { NULL }
82 };
83
84 static void
85 query_helper (const gchar *query_filename, const gchar *results_filename)
86 {
87 GError *error = NULL;
88 gchar *queries = NULL, *query;
89 gchar *results = NULL;
90 GString *test_results = NULL;
91
92 g_file_get_contents (query_filename, &queries, NULL, &error);
93 g_assert_no_error (error);
94
95 g_file_get_contents (results_filename, &results, NULL, &error);
96 g_assert_no_error (error);
97
98 /* perform actual query */
99
100 query = strtok (queries, "~");
101
102 while (query) {
103 TrackerDBCursor *cursor;
104
105 cursor = tracker_data_query_sparql_cursor (query, &error);
106 g_assert_no_error (error);
107
108 /* compare results with reference output */
109
110 if (!test_results) {
111 test_results = g_string_new ("");
112 } else {
113 g_string_append (test_results, "~\n");
114 }
115
116 if (cursor) {
117 gint col;
118
119 while (tracker_db_cursor_iter_next (cursor, NULL, &error)) {
120 for (col = 0; col < tracker_db_cursor_get_n_columns (cursor); col++) {
121 const gchar *str;
122
123 if (col > 0) {
124 g_string_append (test_results, "\t");
125 }
126
127 str = tracker_db_cursor_get_string (cursor, col, NULL);
128 if (str != NULL) {
129 /* bound variable */
130 g_string_append_printf (test_results, "\"%s\"", str);
131 }
132 }
133
134 g_string_append (test_results, "\n");
135 }
136
137 g_object_unref (cursor);
138 }
139
140 query = strtok (NULL, "~");
141 }
142
143 if (strcmp (results, test_results->str)) {
(emitted by clang-analyzer)TODO: a detailed trace is available in the data model (not yet rendered in this report)
144 /* print result difference */
145 gchar *quoted_results;
146 gchar *command_line;
147 gchar *quoted_command_line;
148 gchar *shell;
149 gchar *diff;
150
151 quoted_results = g_shell_quote (test_results->str);
152 command_line = g_strdup_printf ("echo -n %s | diff -u %s -", quoted_results, results_filename);
153 quoted_command_line = g_shell_quote (command_line);
154 shell = g_strdup_printf ("sh -c %s", quoted_command_line);
155 g_spawn_command_line_sync (shell, &diff, NULL, NULL, &error);
156 g_assert_no_error (error);
157
158 g_error ("%s", diff);
159
160 g_free (quoted_results);
161 g_free (command_line);
162 g_free (quoted_command_line);
163 g_free (shell);
164 g_free (diff);
165 }
166
167 g_string_free (test_results, TRUE);
168 g_free (results);
169 g_free (queries);
170 }
171
172 static void
173 test_ontology_init (void)
174 {
175 GError *error = NULL;
176
177 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
178
179 /* first-time initialization */
180 tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
181 NULL,
182 NULL,
183 FALSE,
184 FALSE,
185 100,
186 100,
187 NULL,
188 NULL,
189 NULL,
190 &error);
191
192 g_assert_no_error (error);
193
194 tracker_data_manager_shutdown ();
195
196 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
197
198 /* initialization from existing database */
199 tracker_data_manager_init (0,
200 NULL,
201 NULL,
202 FALSE,
203 FALSE,
204 100,
205 100,
206 NULL,
207 NULL,
208 NULL,
209 &error);
210
211 g_assert_no_error (error);
212
213 tracker_data_manager_shutdown ();
214 }
215
216 static void
217 test_query (gconstpointer test_data)
218 {
219 const TestInfo *test_info;
220 GError *error;
221 gchar *data_filename;
222 gchar *query_filename;
223 gchar *results_filename;
224 gchar *prefix, *data_prefix, *test_prefix;
225
226 error = NULL;
227 test_info = test_data;
228
229 prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL);
230
231 data_prefix = g_build_filename (prefix, test_info->data, NULL);
232 test_prefix = g_build_filename (prefix, test_info->test_name, NULL);
233 g_free (prefix);
234
235 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL);
236
237 /* initialization */
238 tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX,
239 NULL,
240 NULL,
241 FALSE,
242 FALSE,
243 100,
244 100,
245 NULL,
246 NULL,
247 NULL,
248 NULL);
249
250 /* load data set */
251 data_filename = g_strconcat (data_prefix, ".ttl", NULL);
252 tracker_turtle_reader_load (data_filename, &error);
253 g_assert_no_error (error);
254
255 query_filename = g_strconcat (test_prefix, ".rq", NULL);
256 results_filename = g_strconcat (test_prefix, ".out", NULL);
257
258 g_free (data_prefix);
259 g_free (test_prefix);
260
261 query_helper (query_filename, results_filename);
262
263 /* cleanup */
264
265 g_free (data_filename);
266 g_free (query_filename);
267 g_free (results_filename);
268
269 tracker_data_manager_shutdown ();
270 }
271
272 int
273 main (int argc, char **argv)
274 {
275 gint result;
276 gint i;
277 gchar *data_dir;
278
279 g_test_init (&argc, &argv, NULL);
280
281 data_dir = g_build_filename (g_get_current_dir (), "test-cache", NULL);
282
283 /* Warning warning!!! We need to impose a proper LC_COLLATE here, so
284 * that the expected order in the test results is always the same! */
285 setlocale (LC_COLLATE, "en_US.utf8");
286
287 g_setenv ("XDG_DATA_HOME", data_dir, TRUE);
288 g_setenv ("XDG_CACHE_HOME", data_dir, TRUE);
289 g_setenv ("TRACKER_DB_ONTOLOGIES_DIR", TOP_SRCDIR "/data/ontologies/", TRUE);
290
291 /* add test cases */
292
293 g_test_add_func ("/libtracker-data/ontology-init", test_ontology_init);
294
295 for (i = 0; nie_tests[i].test_name; i++) {
296 gchar *testpath;
297
298 g_message ("%d", i);
299
300 testpath = g_strconcat ("/libtracker-data/nie/", nie_tests[i].test_name, NULL);
301 g_test_add_data_func (testpath, &nie_tests[i], test_query);
302 g_free (testpath);
303 }
304
305 for (i = 0; nmo_tests[i].test_name; i++) {
306 gchar *testpath;
307
308 g_message ("%d", i);
309
310 testpath = g_strconcat ("/libtracker-data/nmo/", nmo_tests[i].test_name, NULL);
311 g_test_add_data_func (testpath, &nmo_tests[i], test_query);
312 g_free (testpath);
313 }
314
315 /* run tests */
316
317 result = g_test_run ();
318
319 /* clean up */
320 g_print ("Removing temporary data\n");
321 g_spawn_command_line_sync ("rm -R tracker/", NULL, NULL, NULL, NULL);
322 g_spawn_command_line_sync ("rm -R test-cache/", NULL, NULL, NULL, NULL);
323
324 g_free (data_dir);
325
326 return result;
327 }