Added:
trunk/testsuites/t_sqlbrowseconnect/
trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file1.c
trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file2.c
trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.c
trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.h
Log:
This is an very incomplete test. See it as a play ground of mine to learn more about ODBC.
The code needs to be discussed with some ODBC experts. The more I think about it, the more
questions I have for the experts. Thus I'm committing a stub for discussion.
Added: trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file1.c
===================================================================
--- trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file1.c 2007-05-04 18:53:09 UTC (rev
100)
+++ trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file1.c 2007-05-08 08:58:46 UTC (rev
101)
@@ -0,0 +1,255 @@
+#include "sqlbrowcon_suite.h"
+
+#define SQLBROWCON_BUFFER 2048
+#define SQLBROWCON_INVALID_STRING_LEN -100
+
+#define SQLBROWCONN_SQL_ERROR(hdbc, rc, sqlstate, info_msg) \
+ OT_ASSERT_MSG((info_msg), sqlbrowcon_error((rc), SQL_ERROR, (hdbc),
SQL_HANDLE_DBC, \
+ (sqlstate), (info_msg), sizeof((info_msg))));
+
+#define SQLBROWCONN_SQL_INFO(hdbc, rc, sqlstate, info_msg) \
+ OT_ASSERT_MSG((info_msg), sqlbrowcon_error((rc), SQL_SUCCESS_WITH_INFO, (hdbc),
SQL_HANDLE_DBC, \
+ (sqlstate), (info_msg), sizeof((info_msg))));
+
+#define SQLBROWCONN_SQL_DATA(hdbc, rc, sqlstate, info_msg) \
+ OT_ASSERT_MSG((info_msg), sqlbrowcon_error((rc), SQL_NEED_DATA, (hdbc),
SQL_HANDLE_DBC, \
+ (sqlstate), (info_msg), sizeof((info_msg))));
+
+
+/*
+Test driver manager related error codes
+
+ SYNOPSIS
+ Driver Manager specific error codes
+
+ DESCRIPTION
+ Some of the sanity checks can also be
+ found the v5 driver source. We better check
+ twice if DM + driver apply to the documentation
+
+ RETURN VALUE
+ void
+*/
+OT_TEST_METHOD(sqlbrowcon_dm_errorcodes)
+{
+ SQLHANDLE dbc = get_dbc_handle();
+ SQLRETURN rc;
+ SQLCHAR in_conn[SQLBROWCON_BUFFER + SQL_MAX_DSN_LENGTH];
+ SQLCHAR out_conn[SQLBROWCON_BUFFER];
+ SQLSMALLINT out_conn_len;
+ SQLHANDLE env = get_env_handle();
+ SQLHANDLE mydbc;
+ SQLCHAR info_msg[SQLBROWCON_BUFFER];
+ SQLCHAR long_dsn[SQL_MAX_DSN_LENGTH + 2];
+ SQLCHAR long_driver[257];
+ /*
+ 08002 Connection name in use
+
+ (DM) The specified connection had already been used to establish a
+ connection with a data source, and the connection was open.
+ */
+ strncpy(in_conn, "", sizeof(in_conn));
+ rc = SQLBrowseConnect(dbc, in_conn, strlen(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(dbc, rc, "08002", info_msg);
+
+ /*
+ HY001 Memory allocation error
+
+ TODO: I can't think of a good way to test it.
+ */
+
+
+ /*
+ HY090 Invalid string or buffer length
+
+ (DM) The value specified for argument StringLength1 was less than 0
+ and was not equal to SQL_NTS.
+ */
+ strncpy(in_conn, "", sizeof(in_conn));
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ OT_ASSERT((SQL_NTS != SQLBROWCON_INVALID_STRING_LEN));
+ rc = SQLBrowseConnect(mydbc, in_conn, SQLBROWCON_INVALID_STRING_LEN, out_conn,
sizeof(out_conn), &out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "HY090", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+ /*
+ (DM) The value specified for argument BufferLength was less than 0.
+ */
+ /*
+ TODO: why does this return IM002 with UnixODBC as a DBM and S1090 with libiodbc as a
DM?
+ */
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ strncpy(in_conn, "DSN=", sizeof(in_conn));
+ strncat(in_conn, (SQLCHAR*)getenv("OT_DSN"), sizeof(in_conn) - strlen(in_conn) - 1);
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, -1,
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "HY090", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+
+ /*
+ IM002 Data source not found and no default driver specified
+
+ (DM) The data source name specified in the browse request connection string
+ (InConnectionString) was not found in the system information, nor was
+ there a default driver specification.
+
+ (DM) ODBC data source and default driver information could not be found
+ in the system information.
+
+ NOTE: We test only for an invalid DSN and ignore the system config
+ */
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ strncpy(in_conn, "DSN=letitbeinvalid", sizeof(in_conn));
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "IM002", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+ /*
+ IM003 Specified driver could not be loaded
+
+ (DM) The driver listed in the data source specification in the system
+ information or specified by the DRIVER keyword was not found or
+ could not be loaded for some other reason.
+
+ NOTE: we check only for the DRIVER keyword and ignore the system config
+ */
+ /*
+ TODO: same as above - why IM001?
+
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ snprintf(in_conn, sizeof(in_conn), "DSN=%s;DRIVER={letitbeinvalid}",
(SQLCHAR*)getenv("OT_DSN"));
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ OT_ASSERT_MSG(info_msg, sqlbrowcon_error(rc, mydbc, SQL_HANDLE_DBC, "IM003", info_msg,
sizeof(info_msg)));
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+ */
+
+ /*
+ IM004 Driver's SQLAllocHandle on SQL_HANDLE_ENV failed
+ IM005 Driver's SQLAllocHandle on SQL_HANDLE_DBC failed
+ IM006 Driver's SQLSetConnectAttr failed
+ IM009 Unable to load translation DLL
+
+ TODO: Don't know how to test any of those
+ */
+
+ /*
+ IM010 Data source name too long
+
+ (DM) The attribute value for the DSN keyword was longer than SQL_MAX_DSN_LENGTH
characters.
+ TODO: unixODBC returns IM012
+ */
+
+ memset(long_dsn, 'x', sizeof(long_dsn) - 1);
+ long_dsn[sizeof(long_dsn)] = '\0';
+ snprintf(in_conn, sizeof(in_conn), "DSN=%s\n", long_dsn);
+
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "IM010", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+ /*
+ IM011 Driver name too long
+
+ (DM) The attribute value for the DRIVER keyword
+ was longer than 255 characters.
+ */
+
+ memset(long_dsn, 'x', sizeof(long_driver) - 1);
+ long_dsn[sizeof(long_driver)] = '\0';
+ snprintf(in_conn, sizeof(in_conn), "DRIVER=%s\n", long_driver);
+
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "IM011", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+ /*
+ IM012 DRIVER keyword syntax error
+
+ (DM) The keyword-value pair for the DRIVER keyword
+ contained a syntax error.
+ */
+ strncpy(in_conn, "DRIVER={12ä45}\n", sizeof(in_conn));
+
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "IM012", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+}
+
+
+/*
+Test driver related error codes
+
+ SYNOPSIS
+ All error conditions that are not explicitly marked as driver
+ manager related.
+
+ DESCRIPTION
+ Some of the sanity checks can also be
+ found the v5 driver source. We better check
+ twice if DM + driver apply to the documentation
+
+ RETURN VALUE
+ void
+*/
+
+OT_TEST_METHOD(sqlbrowcon_driver_errorcodes)
+{
+ SQLHANDLE dbc = get_dbc_handle();
+ SQLRETURN rc;
+ SQLCHAR in_conn[SQLBROWCON_BUFFER + SQL_MAX_DSN_LENGTH];
+ SQLCHAR out_conn[SQLBROWCON_BUFFER];
+ SQLCHAR out_conn_small[2];
+ SQLSMALLINT out_conn_len;
+ SQLHANDLE env = get_env_handle();
+ SQLHANDLE mydbc;
+ SQLCHAR info_msg[SQLBROWCON_BUFFER];
+
+ /*
+ 01000 General warning
+
+ Driver-specific informational message.
+ (Function returns SQL_SUCCESS_WITH_INFO.)
+ TODO: Don't know how to test it
+ */
+
+ /*
+ 01004 String data, right truncated
+
+ The buffer *OutConnectionString was not large enough to
+ return the entire browse result connection string, so the
+ string was truncated. The buffer *StringLength2Ptr contains
+ the length of the untruncated browse result connection string.
+ (Function returns SQL_SUCCESS_WITH_INFO.)
+ */
+ strncpy(out_conn_small, "", sizeof(out_conn_small));
+ snprintf(in_conn, sizeof(in_conn), "DSN=%s", (SQLCHAR*)getenv("OT_DSN"));
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ rc = SQLBrowseConnect(mydbc, in_conn, sizeof(in_conn), out_conn_small,
sizeof(out_conn_small), &out_conn_len);
+ SQLBROWCONN_SQL_INFO(mydbc, rc, "01004", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+ /*
+ 01S00 Invalid connection string attribute
+
+ An invalid attribute keyword was specified in the browse
+ request connection string (InConnectionString).
+ (Function returns SQL_NEED_DATA.)
+
+ An attribute keyword was specified in the browse request
+ connection string (InConnectionString) that does not apply
+ to the current connection level. (Function returns SQL_NEED_DATA.)
+
+ TODO: we test only the first condition
+ */
+ strncpy(out_conn, "", sizeof(out_conn));
+ snprintf(in_conn, sizeof(in_conn), "DSN=%s;UNKNOWN=somevalue;",
(SQLCHAR*)getenv("OT_DSN"));
+ CHECK_SQL(SQLAllocHandle(SQL_HANDLE_DBC, env, &mydbc), env, SQL_HANDLE_ENV);
+ rc = SQLBrowseConnect(mydbc, in_conn, SQL_NTS, out_conn, sizeof(out_conn),
&out_conn_len);
+ SQLBROWCONN_SQL_ERROR(mydbc, rc, "01S00", info_msg);
+ CHECK_SQL(SQLFreeHandle(SQL_HANDLE_DBC, mydbc), mydbc, SQL_HANDLE_DBC);
+
+}
Added: trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file2.c
===================================================================
--- trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file2.c 2007-05-04 18:53:09 UTC (rev
100)
+++ trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_file2.c 2007-05-08 08:58:46 UTC (rev
101)
@@ -0,0 +1,111 @@
+#include "sqlbrowcon_suite.h"
+
+
+/*
+Helper function: check return code and SQLSTATE
+
+ SYNOPSIS
+ Check the return code of a failing ODBC call.
+
+ DESCRIPTION
+
+
+ RETURN VALUE
+ 0 - rc is not equal SQL_ERROR or the expected sqlstate was not found
+ 1 - rc is SQL_ERROR and sqlstate was found
+*/
+int sqlbrowcon_error(SQLRETURN rc, SQLRETURN exp_rc, SQLHANDLE hnd, SQLSMALLINT hnd_type,
const SQLCHAR *exp_sqlstate, SQLCHAR *info_msg, size_t len)
+{
+ SQLCHAR sqlstate[6];
+ SQLINTEGER native_error;
+ SQLCHAR error_msg[SQL_MAX_MESSAGE_LENGTH];
+ SQLSMALLINT error_msg_len, i, ret = 1;
+ SQLCHAR exp_rc_code[50];
+ SQLCHAR got_rc_code[50];
+
+ sqlbrowcon_error2string(rc, exp_rc, got_rc_code, sizeof(got_rc_code), exp_rc_code,
sizeof(exp_rc_code));
+ snprintf(info_msg, len, "Expecting %s/%s. Got %s, ", exp_rc_code, exp_sqlstate,
got_rc_code);
+
+ if (rc != exp_rc)
+ {
+ strncat(info_msg, "Got ", len - strlen(info_msg) - 1);
+ strncat(info_msg, got_rc_code, len - strlen(info_msg) - 1);
+ strncat(info_msg, " ", len - strlen(info_msg) - 1);
+ if (rc == SQL_ERROR)
+ {
+ ret = 0;
+ }
+ else
+ {
+ test_printf("RC codes do not match");
+ return 0;
+ }
+ }
+
+ i = 1;
+ while ((SQL_SUCCESS == SQLGetDiagRec(hnd_type, hnd, i,
+ sqlstate, &native_error,
+ error_msg, sizeof(error_msg),
+ &error_msg_len))
+ && (i < 100))
+ {
+ strncat(info_msg, "SQLSTATE = '", len -strlen(info_msg) -1);
+ strncat(info_msg, sqlstate, len - strlen(info_msg) - 1);
+ strncat(info_msg, "', error message: '", len - strlen(info_msg) - 1);
+ strncat(info_msg, error_msg, len - strlen(info_msg) -1);
+ strncat(info_msg, "' ", len - strlen(info_msg) -1);
+ if (0 == strncmp(exp_sqlstate, sqlstate, 5))
+ {
+ test_printf("RC and SQLSTATE are OK\n, %s ?= %s\n", exp_sqlstate, sqlstate);
+ test_printf("%s\n", info_msg);
+ return ret;
+ }
+ i++;
+ }
+ test_printf("RC is OK, but SQLSTATE not found.\n%s\n", info_msg);
+ return 0;
+}
+
+
+void sqlbrowcon_error2string(SQLRETURN rc, SQLRETURN exp_rc, SQLCHAR *rc_code, size_t
rc_code_len, SQLCHAR *exp_rc_code, size_t exp_rc_code_len)
+{
+ sqlbrowconn_do_error2string(rc, rc_code, rc_code_len);
+ sqlbrowconn_do_error2string(exp_rc, exp_rc_code, exp_rc_code_len);
+}
+
+
+void sqlbrowconn_do_error2string(SQLRETURN rc, SQLCHAR *rc_code, size_t rc_code_len)
+{
+
+ switch(rc)
+ {
+ case SQL_ERROR:
+ strncpy(rc_code, "SQL_ERROR", rc_code_len);
+ break;
+
+ case SQL_SUCCESS:
+ strncpy(rc_code, "SQL_SUCCESS", rc_code_len);
+ break;
+
+ case SQL_NEED_DATA:
+ strncpy(rc_code, "SQL_NEED_DATA", rc_code_len);
+ break;
+
+ case SQL_NO_DATA:
+ strncpy(rc_code, "SQL_NO_DATA", rc_code_len);
+ break;
+
+ case SQL_SUCCESS_WITH_INFO:
+ strncpy(rc_code, "SQL_SUCCESS_WITH_INFO", rc_code_len);
+ break;
+
+ case SQL_INVALID_HANDLE:
+ strncpy(rc_code, "SQL_INVALID_HANDLE", rc_code_len);
+ break;
+
+ default:
+ snprintf(rc_code, rc_code_len, "Unknown: %d ", rc);
+ break;
+ }
+
+}
\ No newline at end of file
Added: trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.c
===================================================================
--- trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.c 2007-05-04 18:53:09 UTC (rev
100)
+++ trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.c 2007-05-08 08:58:46 UTC (rev
101)
@@ -0,0 +1,73 @@
+#include "sqlbrowcon_suite.h"
+
+/*
+Test for:
+
+SQLBrowseConnect Function
+
+Conformance
+ Version Introduced: ODBC 1.0
+ Standards Compliance: ODBC
+Summary
+ SQLBrowseConnect supports an iterative method of discovering and enumerating the
attributes and attribute values required to connect to a data source. Each call to
SQLBrowseConnect returns successive levels of attributes and attribute values. When all
levels have been enumerated, a connection to the data source is completed and a complete
connection string is returned by SQLBrowseConnect. A return code of SQL_SUCCESS or
SQL_SUCCESS_WITH_INFO indicates that all connection information has been specified and
the application is now connected to the data source.
+
+Syntax
+
+SQLRETURN SQLBrowseConnect(
+ SQLHDBC ConnectionHandle,
+ SQLCHAR * InConnectionString,
+ SQLSMALLINT StringLength1,
+ SQLCHAR * OutConnectionString,
+ SQLSMALLINT BufferLength,
+ SQLSMALLINT * StringLength2Ptr);
+
+Arguments
+
+ConnectionHandle
+ [Input]
+ Connection handle.
+InConnectionString
+ [Input]
+ Browse request connection string (see "InConnectionString Argument" in "Comments").
+StringLength1
+ [Input]
+ Length of *InConnectionString.
+OutConnectionString
+ [Output]
+ Pointer to a buffer in which to return the browse result connection string (see
"OutConnectionString Argument" in "Comments").
+BufferLength
+ [Input]
+ Length of the *OutConnectionString buffer.
+StringLength2Ptr
+ [Output]
+ The total number of bytes (excluding the null-termination byte) available to return
in *OutConnectionString. If the number of bytes available to return is greater than or
equal to BufferLength, the connection string in *OutConnectionString is truncated to
BufferLength minus the length of a null-termination character.
+
+Returns
+
+SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_ERROR, or SQL_INVALID_HANDLE.
+*/
+
+OT_SUITE_SETUP(sqlbrowcon_suite_setup)
+{
+ return NULL;
+}
+
+OT_TEST_SETUP(sqlbrowcon_setup)
+{
+ OT_ASSERT(global_connect());
+}
+
+OT_TEST_TEARDOWN(sqlbrowcon_teardown)
+{
+ global_disconnect();
+}
+
+OT_SUITE_REGISTER_START("skeleton", sqlbrowcon_suite_setup, NULL)
+ /*
+ Parameters are: suite, test function, setup function, tear down function
+ You may pass NULL for setup and tear down but you are strongly requested
+ to write isolated tests that utilize setup and tear down.
+ */
+ OT_SUITE_ADD_TEST(sqlbrowcon_dm_errorcodes, sqlbrowcon_setup, sqlbrowcon_teardown);
+ OT_SUITE_ADD_TEST(sqlbrowcon_driver_errorcodes, sqlbrowcon_setup, sqlbrowcon_teardown);
+OT_SUITE_REGISTER_END
Added: trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.h
===================================================================
--- trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.h 2007-05-04 18:53:09 UTC (rev
100)
+++ trunk/testsuites/t_sqlbrowseconnect/sqlbrowcon_suite.h 2007-05-08 08:58:46 UTC (rev
101)
@@ -0,0 +1,22 @@
+#include <string.h>
+
+#include "odbctest.h"
+
+/* Unit testing overhead ;-) */
+OT_SUITE_SETUP(sqlbrowcon_suite_setup);
+OT_TEST_SETUP(sqlbrowcon_setup);
+OT_TEST_TEARDOWN(sqlbrowcon_teardown);
+
+
+/* The test methods */
+
+/* sqlbrowcon_file1.c */
+OT_TEST_METHOD(sqlbrowcon_dm_errorcodes);
+OT_TEST_METHOD(sqlbrowcon_driver_errorcodes);
+
+/* Helper functions */
+
+/* sqlbrowcon_file2.c */
+int sqlbrowcon_error(SQLRETURN rc, SQLRETURN exp_rc, SQLHANDLE hnd, SQLSMALLINT hnd_type,
const SQLCHAR *exp_sqlstate, SQLCHAR *info_msg, size_t len);
+void sqlbrowcon_error2string(SQLRETURN rc, SQLRETURN exp_rc, SQLCHAR *rc_code, size_t
rc_code_len, SQLCHAR *exp_rc_code, size_t exp_rc_code_len);
+
| Thread |
|---|
| • ODBC C-tests commit: r101 - in trunk/testsuites: . t_sqlbrowseconnect | uwendel | 8 May |