Fix telemetry test when compiled without SSL support

The telemetry test failed with a missing SSL support error when there
was no SSL support compiled into the extension. This change
transparently uses plain connections in case of no SSL support so that
the test doesn't fail with an SSL-specific error.

A minor bug is also fixed in `plain_connect()`. This bug caused the
function to return success in case of name resolution errors. This was
in most cases harmless since the subsequent connect would fail in any
case.
This commit is contained in:
Erik Nordström 2018-10-01 15:24:07 +02:00 committed by Erik Nordström
parent bff0d4e405
commit 65817c8cc5
5 changed files with 43 additions and 36 deletions

View File

@ -50,7 +50,22 @@ plain_connect(Connection *conn, const char *host, const char *servname, int port
ret = getaddrinfo(host, servname, &hints, &ainfo);
if (ret != 0)
{
ret = SOCKET_ERROR;
#ifdef WIN32
WSASetLastError(WSAHOST_NOT_FOUND);
#else
/*
* The closest match for a name resolution error. Strictly, this error
* should not be used here, but to fix we need to support using
* gai_strerror()
*/
errno = EADDRNOTAVAIL;
#endif
goto out;
}
#ifdef WIN32

View File

@ -249,16 +249,21 @@ build_version_request(const char *host, const char *path)
Connection *
telemetry_connect(const char *host, const char *service)
{
Connection *conn;
Connection *conn = NULL;
int ret;
conn = connection_create(CONNECTION_SSL);
if (strcmp("http", service) == 0)
conn = connection_create(CONNECTION_PLAIN);
else if (strcmp("https", service) == 0)
conn = connection_create(CONNECTION_SSL);
else
ereport(WARNING,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("scheme \"%s\" not supported for telemetry",
service)));
if (conn == NULL)
{
elog(WARNING, "could not create telemetry connection");
return NULL;
}
ret = connection_connect(conn, host, service, 0);
@ -271,7 +276,7 @@ telemetry_connect(const char *host, const char *service)
ereport(WARNING,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not make a connection to %s://%s", service, host),
errmsg("telemetry could not connect to \"%s\"", host),
errdetail("%s", errstr)));
}
@ -305,10 +310,7 @@ telemetry_main(const char *host, const char *path, const char *service)
conn = telemetry_connect(host, service);
if (conn == NULL)
{
elog(WARNING, "telemetry connect error: could not make connection");
goto cleanup;
}
req = build_version_request(host, path);

View File

@ -8,7 +8,7 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_status_mock(text) RETURNS
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_parse_version(response text, installed_major int, installed_minor int, installed_patch int, installed_modtag text = NULL)
RETURNS TABLE(version_string text, major int, minor int, patch int, modtag text, up_to_date bool)
AS :MODULE_PATHNAME, 'ts_test_telemetry_parse_version' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text, text)
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text)
RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE;
\c single :ROLE_DEFAULT_PERM_USER
@ -262,25 +262,9 @@ SELECT * FROM _timescaledb_internal.test_telemetry_parse_version('{"current_time
ERROR: parsing failed for version string "1.0.0-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
\set ON_ERROR_STOP 1
SET timescaledb.telemetry_level=basic;
SELECT _timescaledb_internal.test_telemetry_main_conn('timescale.com', 'path', 'http');
WARNING: could not make a connection to http://timescale.com
WARNING: telemetry connect error: could not make connection
test_telemetry_main_conn
--------------------------
f
(1 row)
SELECT _timescaledb_internal.test_telemetry_main_conn('timescale.com', 'path', 'https');
WARNING: could not make a connection to https://timescale.com
WARNING: telemetry connect error: could not make connection
test_telemetry_main_conn
--------------------------
f
(1 row)
SELECT _timescaledb_internal.test_telemetry_main_conn('telemetry.timescale.com', 'path', 'http');
WARNING: could not make a connection to http://telemetry.timescale.com
WARNING: telemetry connect error: could not make connection
-- Connect to a bogus host and path to test error handling in telemetry_main()
SELECT _timescaledb_internal.test_telemetry_main_conn('noservice.timescale.com', 'path');
WARNING: telemetry could not connect to "noservice.timescale.com"
test_telemetry_main_conn
--------------------------
f

View File

@ -8,7 +8,7 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.test_status_mock(text) RETURNS
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_parse_version(response text, installed_major int, installed_minor int, installed_patch int, installed_modtag text = NULL)
RETURNS TABLE(version_string text, major int, minor int, patch int, modtag text, up_to_date bool)
AS :MODULE_PATHNAME, 'ts_test_telemetry_parse_version' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text, text)
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry_main_conn(text, text)
RETURNS BOOLEAN AS :MODULE_PATHNAME, 'ts_test_telemetry_main_conn' LANGUAGE C IMMUTABLE PARALLEL SAFE;
CREATE OR REPLACE FUNCTION _timescaledb_internal.test_telemetry(host text = NULL, servname text = NULL, port int = NULL) RETURNS JSONB AS :MODULE_PATHNAME, 'ts_test_telemetry' LANGUAGE C IMMUTABLE PARALLEL SAFE;
@ -117,7 +117,6 @@ SELECT * FROM _timescaledb_internal.test_telemetry_parse_version('{"current_time
SELECT * FROM _timescaledb_internal.test_telemetry_parse_version('{"current_timescaledb_version": "1.0.0-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"}', 1, 0, 0, 'alpha2');
\set ON_ERROR_STOP 1
SET timescaledb.telemetry_level=basic;
SELECT _timescaledb_internal.test_telemetry_main_conn('timescale.com', 'path', 'http');
SELECT _timescaledb_internal.test_telemetry_main_conn('timescale.com', 'path', 'https');
SELECT _timescaledb_internal.test_telemetry_main_conn('telemetry.timescale.com', 'path', 'http');
-- Connect to a bogus host and path to test error handling in telemetry_main()
SELECT _timescaledb_internal.test_telemetry_main_conn('noservice.timescale.com', 'path');
SET timescaledb.telemetry_level=off;

View File

@ -194,15 +194,22 @@ ts_test_telemetry_parse_version(PG_FUNCTION_ARGS)
return HeapTupleGetDatum(tuple);
}
/* Try to get the telemetry function to handle errors. Never connect to the actual endpoint. Only test cases that will result in connection errors. */
/* Try to get the telemetry function to handle errors. Never connect to the
* actual endpoint. Only test cases that will result in connection errors. */
Datum
ts_test_telemetry_main_conn(PG_FUNCTION_ARGS)
{
text *host = PG_GETARG_TEXT_P(0);
text *path = PG_GETARG_TEXT_P(1);
text *service = PG_GETARG_TEXT_P(2);
const char *scheme;
PG_RETURN_BOOL(telemetry_main(text_to_cstring(host), text_to_cstring(path), text_to_cstring(service)));
#ifdef TS_USE_OPENSSL
scheme = "https";
#else
scheme = "http";
#endif
PG_RETURN_BOOL(telemetry_main(text_to_cstring(host), text_to_cstring(path), scheme));
}
Datum