coturn TURN server project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
coturn/tests/test_pgsql_stub.c

142 lines
4.0 KiB

/*
* SPDX-License-Identifier: BSD-3-Clause
*
* https://opensource.org/license/bsd-3-clause
*
* Link-seam mock of the subset of libpq that dbd_pgsql.c uses. It lets the
* PostgreSQL driver be unit-tested with no server: every statement the driver
* issues is captured (command text, whether it was parameterized, and the bound
* parameter values) so the test can assert the driver keeps caller values out
* of the SQL text. SELECTs return an empty (0-row) result, which is all the
* tests need -- they assert the emitted command/params, not row contents.
*
* dbd_pgsql.c is compiled against the real <libpq-fe.h>, so these definitions
* must match the real prototypes; only the implementations are fake.
*/
#include <libpq-fe.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "test_pgsql_stub.h"
/* opaque libpq types, completed here */
struct pg_conn {
int dummy;
};
struct pg_result {
ExecStatusType status;
};
static struct pg_conn g_conn;
static struct pg_result g_result;
#define PGSTUB_MAX_PARAMS 8
#define PGSTUB_STR 2048
static char g_command[PGSTUB_STR];
static int g_nparams;
static int g_used_params;
static char g_params[PGSTUB_MAX_PARAMS][PGSTUB_STR];
void pgstub_reset(void) {
g_command[0] = 0;
g_nparams = 0;
g_used_params = 0;
}
const char *pgstub_last_command(void) { return g_command; }
int pgstub_last_nparams(void) { return g_nparams; }
int pgstub_used_params(void) { return g_used_params; }
const char *pgstub_last_param(int i) {
if (i < 0 || i >= g_nparams || i >= PGSTUB_MAX_PARAMS) {
return NULL;
}
return g_params[i];
}
static struct pg_result *result_for(const char *command) {
const char *p = command;
while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') {
++p;
}
/* SELECTs return rows; everything else is a command. */
g_result.status = (strncasecmp(p, "select", 6) == 0) ? PGRES_TUPLES_OK : PGRES_COMMAND_OK;
return &g_result;
}
/////////////////////// connection ///////////////////////
ConnStatusType PQstatus(const PGconn *conn) {
(void)conn;
return CONNECTION_OK;
}
void PQfinish(PGconn *conn) { (void)conn; }
PGconn *PQconnectdb(const char *conninfo) {
(void)conninfo;
return &g_conn;
}
PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg) {
(void)conninfo;
if (errmsg) {
*errmsg = NULL;
}
/* non-NULL so the driver proceeds; it only frees this, never reads it. */
static PQconninfoOption opt;
return &opt;
}
void PQconninfoFree(PQconninfoOption *connOptions) { (void)connOptions; }
char *PQerrorMessage(const PGconn *conn) {
(void)conn;
return (char *)"";
}
/////////////////////// statements ///////////////////////
PGresult *PQexec(PGconn *conn, const char *query) {
(void)conn;
g_used_params = 0;
g_nparams = 0;
snprintf(g_command, sizeof(g_command), "%s", query ? query : "");
return result_for(g_command);
}
PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes,
const char *const *paramValues, const int *paramLengths, const int *paramFormats,
int resultFormat) {
(void)conn;
(void)paramTypes;
(void)paramLengths;
(void)paramFormats;
(void)resultFormat;
g_used_params = 1;
g_nparams = nParams;
snprintf(g_command, sizeof(g_command), "%s", command ? command : "");
for (int i = 0; i < nParams && i < PGSTUB_MAX_PARAMS; ++i) {
snprintf(g_params[i], sizeof(g_params[i]), "%s", (paramValues && paramValues[i]) ? paramValues[i] : "");
}
return result_for(g_command);
}
/////////////////////// results ///////////////////////
ExecStatusType PQresultStatus(const PGresult *res) { return res ? res->status : PGRES_FATAL_ERROR; }
int PQntuples(const PGresult *res) {
(void)res;
return 0;
}
char *PQgetvalue(const PGresult *res, int tup_num, int field_num) {
(void)res;
(void)tup_num;
(void)field_num;
return (char *)"";
}
int PQgetlength(const PGresult *res, int tup_num, int field_num) {
(void)res;
(void)tup_num;
(void)field_num;
return 0;
}
void PQclear(PGresult *res) { (void)res; }