tracker-0.16.2/tests/libtracker-data/tracker-ontology-change-test.c

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)) {
Access to field 'str' results in a dereference of a null pointer (loaded from variable 'test_results')
(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 }