1 /*
2 * SysDB - t/utils/dbi_test.c
3 * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #include "libsysdb_test.h"
29 #include "utils/dbi.h"
31 #include <check.h>
32 #include <dbi/dbi.h>
34 #define TEST_MAGIC ((void *)0x1337)
36 /*
37 * private variables
38 */
40 static sdb_dbi_client_t *client;
42 /*
43 * mocked functions
44 */
46 /* dbi_driver, dbi_conn, dbi_result are void pointers */
48 dbi_driver
49 dbi_driver_open(const char *name)
50 {
51 if (strcmp(name, "mockdriver"))
52 return NULL;
53 return (dbi_driver)strdup(name);
54 } /* dbi_driver_open */
56 dbi_driver
57 dbi_driver_list(dbi_driver curr)
58 {
59 if (!curr)
60 return "mockdriver";
61 return NULL;
62 } /* dbi_driver_list */
64 const char *
65 dbi_driver_get_name(dbi_driver driver)
66 {
67 return (const char *)driver;
68 } /* dbi_driver_get_name */
70 int
71 dbi_conn_set_option(dbi_conn __attribute__((unused)) conn,
72 const char __attribute__((unused)) *key,
73 const char __attribute__((unused)) *value)
74 {
75 return 0;
76 } /* dbi_conn_set_option */
78 const char *
79 dbi_conn_get_option_list(dbi_conn __attribute__((unused)) conn,
80 const char __attribute__((unused)) *key)
81 {
82 return NULL;
83 } /* dbi_conn_get_option_list */
85 dbi_conn
86 dbi_conn_open(dbi_driver driver)
87 {
88 if (strcmp((const char *)driver, "mockdriver"))
89 return NULL;
90 return (dbi_conn)"mockconnection";
91 } /* dbi_conn_open */
93 static int dbi_conn_connect_called = 0;
94 int
95 dbi_conn_connect(dbi_conn conn)
96 {
97 ++dbi_conn_connect_called;
98 if (strcmp((const char *)conn, "mockconnection"))
99 return DBI_ERROR_NOCONN;
100 return 0;
101 } /* dbi_conn_connect */
103 int
104 dbi_conn_ping(dbi_conn conn)
105 {
106 if (strcmp((const char *)conn, "mockconnection"))
107 return 0;
108 return 1;
109 } /* dbi_conn_connect */
111 void
112 dbi_conn_close(dbi_conn __attribute__((unused)) conn)
113 {
114 return;
115 } /* dbi_conn_close */
117 static int dbi_conn_query_called = 0;
118 dbi_result
119 dbi_conn_query(dbi_conn conn, const char __attribute__((unused)) *statement)
120 {
121 ++dbi_conn_query_called;
122 if (strcmp((const char *)conn, "mockconnection"))
123 return NULL;
124 return (dbi_result)"mockresult";
125 } /* dbi_conn_query */
127 unsigned long long
128 dbi_result_get_numrows(dbi_result res)
129 {
130 if (strcmp((const char *)res, "mockresult"))
131 return DBI_ROW_ERROR;
132 return 5;
133 } /* dbi_result_get_numrows */
135 static int dbi_result_free_called = 0;
136 int
137 dbi_result_free(dbi_result res)
138 {
139 ++dbi_result_free_called;
140 if (strcmp((const char *)res, "mockresult"))
141 return -1;
142 return 0;
143 } /* dbi_result_free */
145 unsigned int
146 dbi_result_get_numfields(dbi_result res)
147 {
148 if (strcmp((const char *)res, "mockresult"))
149 return DBI_FIELD_ERROR;
150 return 0;
151 } /* dbi_result_get_numfields */
153 unsigned short
154 dbi_result_get_field_type_idx(dbi_result res,
155 unsigned int __attribute__((unused)) i)
156 {
157 if (strcmp((const char *)res, "mockresult"))
158 return DBI_TYPE_ERROR;
159 return DBI_TYPE_ERROR;
160 } /* dbi_result_get_field_type_idx */
162 const char *
163 dbi_result_get_field_name(dbi_result res,
164 unsigned int __attribute__((unused)) i)
165 {
166 if (strcmp((const char *)res, "mockresult"))
167 return NULL;
168 return NULL;
169 } /* dbi_result_get_field_name */
171 /*
172 * private helper functions
173 */
175 static void
176 setup(void)
177 {
178 client = sdb_dbi_client_create("mockdriver", "mockdatabase");
179 fail_unless(client != NULL,
180 "sdb_dbi_client_create() = NULL; expected client object");
181 } /* setup */
183 static void
184 connect(void)
185 {
186 int check = sdb_dbi_client_connect(client);
187 fail_unless(check == 0,
188 "sdb_dbi_client_connect() = %i; expected: 0", check);
189 } /* connect */
191 static void
192 teardown(void)
193 {
194 sdb_dbi_client_destroy(client);
195 client = NULL;
196 } /* teardown */
198 static int test_query_callback_called = 0;
199 static int
200 test_query_callback(sdb_dbi_client_t *c,
201 size_t n, sdb_data_t *data, sdb_object_t *user_data)
202 {
203 ++test_query_callback_called;
205 fail_unless(c == client,
206 "query callback received unexpected client = %p; "
207 "expected: %p", c, client);
208 fail_unless(n == 0,
209 "query callback received n = %i; expected: 0", n);
210 fail_unless(data == NULL,
211 "query callback received data = %p; expected: NULL", data);
212 fail_unless(user_data == TEST_MAGIC,
213 "query callback received user_data = %p; expected: %p",
214 user_data, TEST_MAGIC);
215 return 0;
216 } /* test_query_callback */
218 /*
219 * tests
220 */
222 START_TEST(test_client_connect)
223 {
224 int check = sdb_dbi_client_connect(client);
225 fail_unless(check == 0,
226 "sdb_dbi_client_connect() = %i; expected: 0", check);
228 fail_unless(dbi_conn_connect_called == 1,
229 "sdb_dbi_client_create() called dbi_conn_connect %i times; "
230 "expected: 1", dbi_conn_connect_called);
231 }
232 END_TEST
234 START_TEST(test_client_check_conn)
235 {
236 int check = sdb_dbi_client_check_conn(client);
237 fail_unless(check == 0,
238 "sdb_dbi_client_check_conn() = %i; expected: 0", check);
240 /* the first call will actually connect to the database */
241 fail_unless(dbi_conn_connect_called == 1,
242 "sdb_dbi_client_check_conn() called dbi_conn_connect %i times; "
243 "expected: 1", dbi_conn_connect_called);
245 check = sdb_dbi_client_check_conn(client);
246 fail_unless(check == 0,
247 "sdb_dbi_client_check_conn() = %i; expected: 0", check);
249 /* should not reconnect */
250 fail_unless(dbi_conn_connect_called == 1,
251 "sdb_dbi_client_check_conn() called dbi_conn_connect %i time(s); "
252 "expected: 0", dbi_conn_connect_called - 1);
253 }
254 END_TEST
256 START_TEST(test_exec_query)
257 {
258 int check = sdb_dbi_exec_query(client, "mockquery", test_query_callback,
259 /* user_data = */ TEST_MAGIC, /* n = */ 0);
260 /* not connected yet */
261 fail_unless(check < 0,
262 "sdb_dbi_exec_query() = %i; expected: < 0", check);
264 connect();
266 check = sdb_dbi_exec_query(client, "mockquery", test_query_callback,
267 /* user_data = */ TEST_MAGIC, /* n = */ 0);
268 fail_unless(check == 0,
269 "sdb_dbi_exec_query() = %i; expected: 0", check);
271 fail_unless(dbi_conn_query_called == 1,
272 "sdb_dbi_exec_query() called dbi_conn_query %i times; "
273 "expected: 1", dbi_conn_query_called);
274 fail_unless(test_query_callback_called == 0,
275 "sdb_dbi_exec_query() did not call the registered callback "
276 "for each result row; got %i call%s; expected: 0",
277 test_query_callback_called,
278 (test_query_callback_called == 1) ? "" : "s");
280 fail_unless(dbi_result_free_called == 1,
281 "sdb_dbi_exec_query() did not free the query result object");
282 }
283 END_TEST
285 /*
286 * test API
287 */
289 Suite *
290 util_dbi_suite(void)
291 {
292 Suite *s = suite_create("utils::dbi");
293 TCase *tc;
295 tc = tcase_create("core");
296 tcase_add_checked_fixture(tc, setup, teardown);
297 tcase_add_test(tc, test_client_connect);
298 tcase_add_test(tc, test_client_check_conn);
299 tcase_add_test(tc, test_exec_query);
300 suite_add_tcase(s, tc);
302 return s;
303 } /* util_llist_suite */
305 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */