Code

t/utils/dbi_test: Added test queries covering 2-5 columns.
[sysdb.git] / t / utils / dbi_test.c
index 2fb739cca9338f11b6f9359fac5a5074d435baa5..2ad1cc29b1d7bb541d4702da265565adc64ac5e7 100644 (file)
@@ -67,25 +67,71 @@ static sdb_dbi_client_t *client;
  */
 
 /* field definitions */
-static struct {
-       unsigned short field_types[1];
-       char          *field_names[1];
-} rows1[] = {
-       { { DBI_TYPE_INTEGER }, { "field0" }, },
+static unsigned short field_types[] = {
+       DBI_TYPE_INTEGER,
+       DBI_TYPE_DECIMAL,
+       DBI_TYPE_STRING,
+       DBI_TYPE_DATETIME,
+       DBI_TYPE_BINARY,
+};
+static char *field_names[] = {
+       "field0",
+       "field1",
+       "field2",
+       "field3",
+       "field4",
 };
 
-static mock_data_t golden_data[][1] = {
-       { { .integer = 1234 } },
-       { { .integer = 2345 } },
-       { { .integer = 3456 } },
-       { { .integer = 4567 } },
-       { { .integer = 5678 } },
+#define DATUM(p) ((const unsigned char *)(p))
+static mock_data_t golden_data[][5] = {
+       {
+               { .integer  = 1234   },
+               { .decimal  = 1.234  },
+               { .string   = "abcd" },
+               { .datetime = 0      },
+               { .binary   = { 1, DATUM("a") } },
+       },
+       {
+               { .integer  = 2345   },
+               { .decimal  = 23.45  },
+               { .string   = "bcde" },
+               { .datetime = 1      },
+               { .binary   = { 4, DATUM("bcde") } },
+       },
+       {
+               { .integer  = 3456   },
+               { .decimal  = 345.6  },
+               { .string   = "cd"   },
+               { .datetime = 2      },
+               { .binary   = { 0, DATUM(NULL) } },
+       },
+       {
+               { .integer  = 4567   },
+               { .decimal  = 4567   },
+               { .string   = "d"    },
+               { .datetime = 3      },
+               { .binary   = { 13, DATUM("defghijklmnop") } },
+       },
+       {
+               { .integer  = 5678   },
+               { .decimal  = 56.78  },
+               { .string   = "efgh" },
+               { .datetime = 4      },
+               { .binary   = { 5, DATUM("efghi") } },
+       },
 };
 
 /* query definitions */
 static mock_query_t mock_queries[] = {
        { "mockquery0", 5, 1, 0, NULL, NULL },
-       { "mockquery1", 5, 1, 1, rows1[0].field_types, rows1[0].field_names },
+       { "mockquery1", 0, 0, 1, field_types, field_names },
+       { "mockquery2", 1, 1, 1, field_types, field_names },
+       { "mockquery3", 2, 1, 1, field_types, field_names },
+       { "mockquery4", 5, 1, 1, field_types, field_names },
+       { "mockquery5", 5, 1, 2, field_types, field_names },
+       { "mockquery6", 5, 1, 3, field_types, field_names },
+       { "mockquery7", 5, 1, 4, field_types, field_names },
+       { "mockquery8", 5, 1, 5, field_types, field_names },
 };
 
 static mock_query_t *current_query = NULL;
@@ -255,42 +301,42 @@ get_golden_data(dbi_result res, unsigned int i) {
        fail_unless(i && i <= q->nfields,
                        "dbi_result_get_*_idx() called with index out of range; "
                        "got: %u; expected [1, %u]", i, q->nfields);
-       return golden_data[q->current_row - 1][i];
+       return golden_data[q->current_row - 1][i - 1];
 } /* get_golden_data */
 
 long long
 dbi_result_get_longlong_idx(dbi_result res, unsigned int i)
 {
-       fail_unless(current_query->field_types[i] != DBI_TYPE_INTEGER,
+       fail_unless(current_query->field_types[i - 1] == DBI_TYPE_INTEGER,
                        "dbi_result_get_longlong_idx() called for non-integer "
-                       "column type %u", current_query->field_types[i]);
+                       "column type %u", current_query->field_types[i - 1]);
        return get_golden_data(res, i).integer;
 } /* dbi_result_get_longlong_idx */
 
 double
 dbi_result_get_double_idx(dbi_result res, unsigned int i)
 {
-       fail_unless(current_query->field_types[i] != DBI_TYPE_DECIMAL,
-                       "dbi_result_get_double_idx() called for non-integer "
-                       "column type %u", current_query->field_types[i]);
+       fail_unless(current_query->field_types[i - 1] == DBI_TYPE_DECIMAL,
+                       "dbi_result_get_double_idx() called for non-decimal "
+                       "column type %u", current_query->field_types[i - 1]);
        return get_golden_data(res, i).decimal;
 } /* dbi_result_get_double_idx */
 
 const char *
 dbi_result_get_string_idx(dbi_result res, unsigned int i)
 {
-       fail_unless(current_query->field_types[i] != DBI_TYPE_STRING,
-                       "dbi_result_get_string_idx() called for non-integer "
-                       "column type %u", current_query->field_types[i]);
+       fail_unless(current_query->field_types[i - 1] == DBI_TYPE_STRING,
+                       "dbi_result_get_string_idx() called for non-string "
+                       "column type %u", current_query->field_types[i - 1]);
        return get_golden_data(res, i).string;
 } /* dbi_result_get_string_idx */
 
 time_t
 dbi_result_get_datetime_idx(dbi_result res, unsigned int i)
 {
-       fail_unless(current_query->field_types[i] != DBI_TYPE_DATETIME,
-                       "dbi_result_get_datetime_idx() called for non-integer "
-                       "column type %u", current_query->field_types[i]);
+       fail_unless(current_query->field_types[i - 1] == DBI_TYPE_DATETIME,
+                       "dbi_result_get_datetime_idx() called for non-datetime "
+                       "column type %u", current_query->field_types[i - 1]);
        return get_golden_data(res, i).datetime;
 } /* dbi_result_get_datetime_idx */
 
@@ -300,14 +346,18 @@ dbi_result_get_field_length_idx(dbi_result res, unsigned int i)
        /* this will check if the parameters are valid */
        get_golden_data(res, i);
 
-       switch (current_query->field_types[i]) {
+       switch (current_query->field_types[i - 1]) {
                case DBI_TYPE_INTEGER:
+                       return sizeof(long long);
                        break;
                case DBI_TYPE_DECIMAL:
+                       return sizeof(double);
                        break;
                case DBI_TYPE_STRING:
+                       return strlen(get_golden_data(res, i).string) + 1;
                        break;
                case DBI_TYPE_DATETIME:
+                       return sizeof(time_t);
                        break;
                case DBI_TYPE_BINARY:
                        return get_golden_data(res, i).binary.length;
@@ -316,16 +366,16 @@ dbi_result_get_field_length_idx(dbi_result res, unsigned int i)
 
        fail("INTERNAL ERROR: dbi_result_get_field_length_idx() "
                        "called for unexpected field type %u",
-                       current_query->field_types[i]);
+                       current_query->field_types[i - 1]);
        return 0;
 } /* dbi_result_get_field_length_idx */
 
 const unsigned char *
 dbi_result_get_binary_idx(dbi_result res, unsigned int i)
 {
-       fail_unless(current_query->field_types[i] != DBI_TYPE_BINARY,
-                       "dbi_result_get_binary_idx() called for non-integer "
-                       "column type %u", current_query->field_types[i]);
+       fail_unless(current_query->field_types[i - 1] == DBI_TYPE_BINARY,
+                       "dbi_result_get_binary_idx() called for non-binary "
+                       "column type %u", current_query->field_types[i - 1]);
        return get_golden_data(res, i).binary.datum;
 } /* dbi_result_get_binary_idx */
 
@@ -375,6 +425,8 @@ static int
 test_query_callback(sdb_dbi_client_t *c,
                size_t n, sdb_data_t *data, sdb_object_t *user_data)
 {
+       size_t i;
+
        ++test_query_callback_called;
 
        fail_unless(c == client,
@@ -388,6 +440,64 @@ test_query_callback(sdb_dbi_client_t *c,
        fail_unless(user_data == TEST_MAGIC,
                        "query callback received user_data = %p; expected: %p",
                        user_data, TEST_MAGIC);
+
+       for (i = 0; i < n; ++i) {
+               int expected_type = DBI_TYPE_TO_SC(current_query->field_types[i]);
+               mock_data_t expected_data;
+
+               fail_unless((int)data[i].type == expected_type,
+                               "query callback received unexpected type %i for "
+                               "column %zu; expected: %i", data[i].type, i,
+                               expected_type);
+
+               expected_data = golden_data[current_query->current_row - 1][i];
+               switch (expected_type) {
+                       case SDB_TYPE_INTEGER:
+                               fail_unless(data[i].data.integer == expected_data.integer,
+                                               "query callback received unexpected data %lli "
+                                               "for column %zu; expected: %lli",
+                                               data[i].data.integer, i, expected_data.integer);
+                               break;
+                       case SDB_TYPE_DECIMAL:
+                               fail_unless(data[i].data.decimal == expected_data.decimal,
+                                               "query callback received unexpected data %g "
+                                               "for column %zu; expected: %g",
+                                               data[i].data.decimal, i, expected_data.decimal);
+                               break;
+                       case SDB_TYPE_STRING:
+                               fail_unless(data[i].data.string == expected_data.string,
+                                               "query callback received unexpected data %s "
+                                               "for column %zu; expected: %s",
+                                               data[i].data.string, i, expected_data.string);
+                               break;
+                       case SDB_TYPE_DATETIME:
+                               fail_unless(data[i].data.datetime
+                                                       == SECS_TO_SDB_TIME(expected_data.datetime),
+                                               "query callback received unexpected data "PRIscTIME
+                                               " for column %zu; expected: "PRIscTIME,
+                                               data[i].data.integer, i,
+                                               SECS_TO_SDB_TIME(expected_data.integer));
+                               break;
+                       case SDB_TYPE_BINARY:
+                               fail_unless(data[i].data.binary.length ==
+                                                       expected_data.binary.length,
+                                               "query callback received unexpected "
+                                               "binary data length %zu for column %zu; "
+                                               "expected: %lli", data[i].data.binary.length, i,
+                                               expected_data.binary.length);
+                               fail_unless(data[i].data.binary.datum ==
+                                                       expected_data.binary.datum,
+                                               "query callback received unexpected binary data %p "
+                                               "for column %zu; expected: %p",
+                                               data[i].data.binary.datum, i,
+                                               expected_data.binary.datum);
+                               break;
+                       default:
+                               fail("INTERNAL ERROR: query callback received "
+                                               "unknown type %i for column %zu",
+                                               expected_type, i);
+               }
+       }
        return 0;
 } /* test_query_callback */
 
@@ -451,9 +561,13 @@ START_TEST(test_exec_query)
                test_query_callback_called = 0;
                dbi_result_free_called = 0;
 
+               /* sdb_dbi_exec_query will only use as many type arguments are needed,
+                * so we can safely pass in the maximum number of arguments required
+                * on each call */
                check = sdb_dbi_exec_query(client, q->name, test_query_callback,
                                /* user_data = */ TEST_MAGIC, /* n = */ (int)q->nfields,
-                               SDB_TYPE_INTEGER);
+                               SDB_TYPE_INTEGER, SDB_TYPE_DECIMAL, SDB_TYPE_STRING,
+                               SDB_TYPE_DATETIME, SDB_TYPE_BINARY);
                fail_unless(check == 0,
                                "sdb_dbi_exec_query() = %i; expected: 0", check);