Location | Tool | Test ID | Function | Issue |
---|---|---|---|---|
tracker-ontology-change-test.c:151: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 * Author:
20 * Philip Van Hoof <philip@codeminded.be>
21 */
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include <glib.h>
28 #include <gio/gio.h>
29 #include <glib/gstdio.h>
30
31 #include <libtracker-data/tracker-data.h>
32
33 typedef struct _TestInfo TestInfo;
34
35 struct _TestInfo {
36 const gchar *test_name;
37 const gchar *data;
38 };
39
40 typedef struct _ChangeInfo ChangeInfo;
41
42 struct _ChangeInfo {
43 const gchar *ontology;
44 const gchar *update;
45 const gchar *test_name;
46 const gchar *ptr;
47 };
48
49 const TestInfo change_tests[] = {
50 { "change/test-1", "change/data-1" },
51 { "change/test-2", "change/data-2" },
52 { "change/test-3", "change/data-3" },
53 { "change/test-4", "change/data-4" },
54 { "change/test-5", "change/data-5" },
55 { NULL }
56 };
57
58 const ChangeInfo changes[] = {
59 { "99-example.ontology.v1", "99-example.queries.v1", NULL, NULL },
60 { "99-example.ontology.v2", "99-example.queries.v2", NULL, NULL },
61 { "99-example.ontology.v3", "99-example.queries.v3", NULL, NULL },
62 { "99-example.ontology.v4", "99-example.queries.v4", NULL, NULL },
63 { "99-example.ontology.v5", "99-example.queries.v5", "change/change-test-1", NULL },
64 { "99-example.ontology.v6", "99-example.queries.v6", "change/change-test-2", NULL },
65 { "99-example.ontology.v7", "99-example.queries.v7", "change/change-test-3", NULL },
66 { NULL }
67 };
68
69 static void
70 delete_db (gboolean del_journal)
71 {
72 gchar *meta_db, *db_location;
73
74 db_location = g_build_path (G_DIR_SEPARATOR_S, g_get_current_dir (), "tracker", NULL);
75 meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "meta.db", NULL);
76 g_unlink (meta_db);
77 g_free (meta_db);
78
79 if (del_journal) {
80 meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", "tracker-store.journal", NULL);
81 g_unlink (meta_db);
82 g_free (meta_db);
83 }
84
85 meta_db = g_build_path (G_DIR_SEPARATOR_S, db_location, "data", ".meta.isrunning", NULL);
86 g_unlink (meta_db);
87 g_free (meta_db);
88
89 g_free (db_location);
90 }
91
92 static void
93 query_helper (const gchar *query_filename, const gchar *results_filename)
94 {
95 GError *error = NULL;
96 gchar *queries = NULL, *query;
97 gchar *results = NULL;
98 GString *test_results = NULL;
99
100 g_file_get_contents (query_filename, &queries, NULL, &error);
101 g_assert_no_error (error);
102
103 g_file_get_contents (results_filename, &results, NULL, &error);
104 g_assert_no_error (error);
105
106 /* perform actual query */
107
108 query = strtok (queries, "~");
109
110 while (query) {
111 TrackerDBCursor *cursor;
112
113 cursor = tracker_data_query_sparql_cursor (query, &error);
114 g_assert_no_error (error);
115
116 /* compare results with reference output */
117
118 if (!test_results) {
119 test_results = g_string_new ("");
120 } else {
121 g_string_append (test_results, "~\n");
122 }
123
124 if (cursor) {
125 gint col;
126
127 while (tracker_db_cursor_iter_next (cursor, NULL, &error)) {
128 for (col = 0; col < tracker_db_cursor_get_n_columns (cursor); col++) {
129 const gchar *str;
130
131 if (col > 0) {
132 g_string_append (test_results, "\t");
133 }
134
135 str = tracker_db_cursor_get_string (cursor, col, NULL);
136 if (str != NULL) {
137 /* bound variable */
138 g_string_append_printf (test_results, "\"%s\"", str);
139 }
140 }
141
142 g_string_append (test_results, "\n");
143 }
144
145 g_object_unref (cursor);
146 }
147
148 query = strtok (NULL, "~");
149 }
150
151 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)
152 /* print result difference */
153 gchar *quoted_results;
154 gchar *command_line;
155 gchar *quoted_command_line;
156 gchar *shell;
157 gchar *diff;
158
159 quoted_results = g_shell_quote (test_results->str);
160 command_line = g_strdup_printf ("echo -n %s | diff -u %s -", quoted_results, results_filename);
161 quoted_command_line = g_shell_quote (command_line);
162 shell = g_strdup_printf ("sh -c %s", quoted_command_line);
163 g_spawn_command_line_sync (shell, &diff, NULL, NULL, &error);
164 g_assert_no_error (error);
165
166 g_error ("%s", diff);
167
168 g_free (quoted_results);
169 g_free (command_line);
170 g_free (quoted_command_line);
171 g_free (shell);
172 g_free (diff);
173 }
174
175 g_string_free (test_results, TRUE);
176 g_free (results);
177 g_free (queries);
178 }
179
180 static void
181 test_ontology_change (void)
182 {
183 gchar *ontology_file;
184 GFile *file2;
185 gchar *prefix, *build_prefix;
186 gchar *ontology_dir;
187 guint i;
188 GError *error = NULL;
189 gchar *test_schemas[5] = { NULL, NULL, NULL, NULL, NULL };
190
191 delete_db (TRUE);
192
193 prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL);
194 build_prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_BUILDDIR, "tests", "libtracker-data", NULL);
195
196 test_schemas[0] = g_build_path (G_DIR_SEPARATOR_S, prefix, "ontologies", "20-dc", NULL);
197 test_schemas[1] = g_build_path (G_DIR_SEPARATOR_S, prefix, "ontologies", "31-nao", NULL);
198 test_schemas[2] = g_build_path (G_DIR_SEPARATOR_S, prefix, "ontologies", "90-tracker", NULL);
199 test_schemas[3] = g_build_path (G_DIR_SEPARATOR_S, build_prefix, "change", "ontologies", "99-example", NULL);
200
201 ontology_file = g_build_path (G_DIR_SEPARATOR_S, build_prefix, "change", "ontologies", "99-example.ontology", NULL);
202
203 file2 = g_file_new_for_path (ontology_file);
204
205 g_file_delete (file2, NULL, NULL);
206
207 ontology_dir = g_build_path (G_DIR_SEPARATOR_S, build_prefix, "change", "ontologies", NULL);
208 g_mkdir_with_parents (ontology_dir, 0777);
209 g_free (ontology_dir);
210
211 for (i = 0; changes[i].ontology; i++) {
212 GFile *file1;
213 gchar *queries = NULL;
214 gchar *source = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "source", changes[i].ontology, NULL);
215 gchar *update = g_build_path (G_DIR_SEPARATOR_S, prefix, "change", "updates", changes[i].update, NULL);
216 gchar *from, *to;
217
218 file1 = g_file_new_for_path (source);
219
220 from = g_file_get_path (file1);
221 to = g_file_get_path (file2);
222 g_debug ("copy %s to %s", from, to);
223 g_free (from);
224 g_free (to);
225
226 g_file_copy (file1, file2, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
227
228 g_assert_no_error (error);
229 g_chmod (ontology_file, 0666);
230
231 tracker_data_manager_init (0, (const gchar **) test_schemas,
232 NULL, FALSE, FALSE,
233 100, 100, NULL, NULL, NULL, &error);
234
235 g_assert_no_error (error);
236
237 if (g_file_get_contents (update, &queries, NULL, NULL)) {
238 gchar *query = strtok (queries, "\n");
239 while (query) {
240
241 tracker_data_update_sparql (query, &error);
242
243 g_assert_no_error (error);
244 query = strtok (NULL, "\n");
245 }
246 g_free (queries);
247 }
248
249 g_free (update);
250 g_free (source);
251 g_object_unref (file1);
252
253
254 if (changes[i].test_name) {
255 gchar *query_filename;
256 gchar *results_filename;
257 gchar *test_prefix;
258
259 test_prefix = g_build_filename (prefix, changes[i].test_name, NULL);
260 query_filename = g_strconcat (test_prefix, ".rq", NULL);
261 results_filename = g_strconcat (test_prefix, ".out", NULL);
262
263 query_helper (query_filename, results_filename);
264
265 g_free (test_prefix);
266 g_free (query_filename);
267 g_free (results_filename);
268 }
269
270 tracker_data_manager_shutdown ();
271 }
272
273 delete_db (FALSE);
274
275 tracker_data_manager_init (0, (const gchar **) test_schemas,
276 NULL, TRUE, FALSE,
277 100, 100, NULL, NULL, NULL, &error);
278
279 g_assert_no_error (error);
280
281 for (i = 0; change_tests[i].test_name != NULL; i++) {
282 gchar *query_filename;
283 gchar *results_filename;
284 gchar *test_prefix;
285
286 test_prefix = g_build_filename (prefix, change_tests[i].test_name, NULL);
287 query_filename = g_strconcat (test_prefix, ".rq", NULL);
288 results_filename = g_strconcat (test_prefix, ".out", NULL);
289
290 query_helper (query_filename, results_filename);
291
292 g_free (test_prefix);
293 g_free (query_filename);
294 g_free (results_filename);
295 }
296
297 tracker_data_manager_shutdown ();
298
299 g_file_delete (file2, NULL, NULL);
300
301 g_object_unref (file2);
302 g_free (test_schemas[0]);
303 g_free (test_schemas[1]);
304 g_free (test_schemas[2]);
305 g_free (build_prefix);
306 g_free (prefix);
307 }
308
309 int
310 main (int argc, char **argv)
311 {
312 gint result;
313 gchar *data_dir;
314
315 g_test_init (&argc, &argv, NULL);
316
317 data_dir = g_build_filename (g_get_current_dir (), "test-cache", NULL);
318
319 g_setenv ("XDG_DATA_HOME", data_dir, TRUE);
320 g_setenv ("XDG_CACHE_HOME", data_dir, TRUE);
321 g_setenv ("TRACKER_DB_ONTOLOGIES_DIR", TOP_SRCDIR "/data/ontologies/", TRUE);
322
323 /* add test cases */
324
325 g_test_add_func ("/libtracker-data/ontology-change", test_ontology_change);
326
327
328 /* run tests */
329
330 result = g_test_run ();
331
332 /* clean up */
333 g_print ("Removing temporary data\n");
334 g_spawn_command_line_sync ("rm -R tracker/", NULL, NULL, NULL, NULL);
335 g_spawn_command_line_sync ("rm -R test-cache/", NULL, NULL, NULL, NULL);
336
337 g_free (data_dir);
338
339 return result;
340 }