mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-03-03 15:45:46 +03:00
Merge branch 'dont_set_datestyle_in_replication_mode'
This commit is contained in:
commit
c9798ecb15
|
@ -494,6 +494,25 @@ conn_setup_cancel(connectionObject *self, PGconn *pgconn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 if the "replication" keyword is set in the DSN, 0 otherwise */
|
||||
static int
|
||||
dsn_has_replication(char *pgdsn)
|
||||
{
|
||||
int ret = 0;
|
||||
PQconninfoOption *connopts, *ptr;
|
||||
|
||||
connopts = PQconninfoParse(pgdsn, NULL);
|
||||
|
||||
for(ptr = connopts; ptr->keyword != NULL; ptr++) {
|
||||
if(strcmp(ptr->keyword, "replication") == 0 && ptr->val != NULL)
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
PQconninfoFree(connopts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Return 1 if the server datestyle allows us to work without problems,
|
||||
0 if it needs to be set to something better, e.g. ISO. */
|
||||
|
@ -522,28 +541,29 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
|||
{
|
||||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
int rv = -1;
|
||||
|
||||
self->equote = conn_get_standard_conforming_strings(pgconn);
|
||||
self->server_version = conn_get_server_version(pgconn);
|
||||
self->protocol = conn_get_protocol_version(self->pgconn);
|
||||
if (3 != self->protocol) {
|
||||
PyErr_SetString(InterfaceError, "only protocol 3 supported");
|
||||
return -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0 > conn_read_encoding(self, pgconn)) {
|
||||
return -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0 > conn_setup_cancel(self, pgconn)) {
|
||||
return -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&self->lock);
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
if (!conn_is_datestyle_ok(self->pgconn)) {
|
||||
if (!dsn_has_replication(self->dsn) && !conn_is_datestyle_ok(self->pgconn)) {
|
||||
int res;
|
||||
Py_UNBLOCK_THREADS;
|
||||
res = pq_set_guc_locked(self, "datestyle", "ISO",
|
||||
|
@ -551,18 +571,23 @@ conn_setup(connectionObject *self, PGconn *pgconn)
|
|||
Py_BLOCK_THREADS;
|
||||
if (res < 0) {
|
||||
pq_complete_error(self, &pgres, &error);
|
||||
return -1;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/* for reset */
|
||||
self->autocommit = 0;
|
||||
|
||||
/* success */
|
||||
rv = 0;
|
||||
|
||||
unlock:
|
||||
Py_UNBLOCK_THREADS;
|
||||
pthread_mutex_unlock(&self->lock);
|
||||
Py_END_ALLOW_THREADS;
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* conn_connect - execute a connection to the database */
|
||||
|
@ -859,8 +884,11 @@ _conn_poll_setup_async(connectionObject *self)
|
|||
self->autocommit = 1;
|
||||
|
||||
/* If the datestyle is ISO or anything else good,
|
||||
* we can skip the CONN_STATUS_DATESTYLE step. */
|
||||
if (!conn_is_datestyle_ok(self->pgconn)) {
|
||||
* we can skip the CONN_STATUS_DATESTYLE step.
|
||||
* Note that we cannot change the datestyle on a replication
|
||||
* connection.
|
||||
*/
|
||||
if (!dsn_has_replication(self->dsn) && !conn_is_datestyle_ok(self->pgconn)) {
|
||||
Dprintf("conn_poll: status -> CONN_STATUS_DATESTYLE");
|
||||
self->status = CONN_STATUS_DATESTYLE;
|
||||
if (0 == pq_send_query(self, psyco_datestyle)) {
|
||||
|
|
|
@ -23,10 +23,27 @@ create () {
|
|||
dbname=psycopg2_test
|
||||
|
||||
pg_createcluster -p $port --start-conf manual $version psycopg
|
||||
|
||||
# for two-phase commit testing
|
||||
set_param "$version" max_prepared_transactions 10
|
||||
|
||||
# for replication testing
|
||||
set_param "$version" max_wal_senders 5
|
||||
set_param "$version" max_replication_slots 5
|
||||
if [ "$version" == "9.2" -o "$version" == "9.3" ]
|
||||
then
|
||||
set_param "$version" wal_level hot_standby
|
||||
else
|
||||
set_param "$version" wal_level logical
|
||||
fi
|
||||
|
||||
echo "local replication travis trust" \
|
||||
>> "/etc/postgresql/$version/psycopg/pg_hba.conf"
|
||||
|
||||
|
||||
pg_ctlcluster "$version" psycopg start
|
||||
|
||||
sudo -u postgres psql -c "create user travis" "port=$port"
|
||||
sudo -u postgres psql -c "create user travis replication" "port=$port"
|
||||
sudo -u postgres psql -c "create database $dbname" "port=$port"
|
||||
sudo -u postgres psql -c "grant create on database $dbname to travis" "port=$port"
|
||||
sudo -u postgres psql -c "create extension hstore" "port=$port dbname=$dbname"
|
||||
|
|
|
@ -14,11 +14,13 @@ run_test () {
|
|||
export PSYCOPG2_TESTDB=$dbname
|
||||
export PSYCOPG2_TESTDB_PORT=$port
|
||||
export PSYCOPG2_TESTDB_USER=travis
|
||||
make check
|
||||
export PSYCOPG2_TEST_REPL_DSN=
|
||||
|
||||
python -c "from psycopg2 import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
|
||||
|
||||
printf "\n\nRunning tests against PostgreSQL $version (green mode)\n\n"
|
||||
export PSYCOPG2_TEST_GREEN=1
|
||||
make check
|
||||
python -c "from psycopg2 import tests; tests.unittest.main(defaultTest='tests.test_suite')" --verbose
|
||||
}
|
||||
|
||||
run_test 9.6 54396
|
||||
|
|
28
tests/test_replication.py
Normal file → Executable file
28
tests/test_replication.py
Normal file → Executable file
|
@ -23,14 +23,14 @@
|
|||
# License for more details.
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.extensions
|
||||
from psycopg2.extras import (
|
||||
PhysicalReplicationConnection, LogicalReplicationConnection, StopReplication)
|
||||
|
||||
import testconfig
|
||||
from testutils import unittest
|
||||
from testutils import skip_before_postgres
|
||||
from testutils import ConnectingTestCase
|
||||
from testutils import unittest, ConnectingTestCase
|
||||
from testutils import skip_before_postgres, skip_if_green
|
||||
|
||||
skip_repl_if_green = skip_if_green("replication not supported in green mode")
|
||||
|
||||
|
||||
class ReplicationTestCase(ConnectingTestCase):
|
||||
|
@ -89,6 +89,20 @@ class ReplicationTest(ReplicationTestCase):
|
|||
cur.execute("IDENTIFY_SYSTEM")
|
||||
cur.fetchall()
|
||||
|
||||
@skip_before_postgres(9, 0)
|
||||
def test_datestyle(self):
|
||||
if testconfig.repl_dsn is None:
|
||||
return self.skipTest("replication tests disabled by default")
|
||||
|
||||
conn = self.repl_connect(
|
||||
dsn=testconfig.repl_dsn, options='-cdatestyle=german',
|
||||
connection_factory=PhysicalReplicationConnection)
|
||||
if conn is None:
|
||||
return
|
||||
cur = conn.cursor()
|
||||
cur.execute("IDENTIFY_SYSTEM")
|
||||
cur.fetchall()
|
||||
|
||||
@skip_before_postgres(9, 4)
|
||||
def test_logical_replication_connection(self):
|
||||
conn = self.repl_connect(connection_factory=LogicalReplicationConnection)
|
||||
|
@ -110,6 +124,7 @@ class ReplicationTest(ReplicationTestCase):
|
|||
psycopg2.ProgrammingError, self.create_replication_slot, cur)
|
||||
|
||||
@skip_before_postgres(9, 4) # slots require 9.4
|
||||
@skip_repl_if_green
|
||||
def test_start_on_missing_replication_slot(self):
|
||||
conn = self.repl_connect(connection_factory=PhysicalReplicationConnection)
|
||||
if conn is None:
|
||||
|
@ -123,6 +138,7 @@ class ReplicationTest(ReplicationTestCase):
|
|||
cur.start_replication(self.slot)
|
||||
|
||||
@skip_before_postgres(9, 4) # slots require 9.4
|
||||
@skip_repl_if_green
|
||||
def test_start_and_recover_from_error(self):
|
||||
conn = self.repl_connect(connection_factory=LogicalReplicationConnection)
|
||||
if conn is None:
|
||||
|
@ -144,6 +160,7 @@ class ReplicationTest(ReplicationTestCase):
|
|||
cur.start_replication(slot_name=self.slot)
|
||||
|
||||
@skip_before_postgres(9, 4) # slots require 9.4
|
||||
@skip_repl_if_green
|
||||
def test_stop_replication(self):
|
||||
conn = self.repl_connect(connection_factory=LogicalReplicationConnection)
|
||||
if conn is None:
|
||||
|
@ -163,12 +180,13 @@ class ReplicationTest(ReplicationTestCase):
|
|||
|
||||
class AsyncReplicationTest(ReplicationTestCase):
|
||||
@skip_before_postgres(9, 4) # slots require 9.4
|
||||
@skip_repl_if_green
|
||||
def test_async_replication(self):
|
||||
conn = self.repl_connect(
|
||||
connection_factory=LogicalReplicationConnection, async=1)
|
||||
if conn is None:
|
||||
return
|
||||
self.wait(conn)
|
||||
|
||||
cur = conn.cursor()
|
||||
|
||||
self.create_replication_slot(cur, output_plugin='test_decoding')
|
||||
|
|
|
@ -130,8 +130,17 @@ class ConnectingTestCase(unittest.TestCase):
|
|||
import psycopg2
|
||||
try:
|
||||
conn = self.connect(**kwargs)
|
||||
if conn.async == 1:
|
||||
self.wait(conn)
|
||||
except psycopg2.OperationalError, e:
|
||||
# If pgcode is not set it is a genuine connection error
|
||||
# Otherwise we tried to run some bad operation in the connection
|
||||
# (e.g. bug #482) and we'd rather know that.
|
||||
if e.pgcode is None:
|
||||
return self.skipTest("replication db not configured: %s" % e)
|
||||
else:
|
||||
raise
|
||||
|
||||
return conn
|
||||
|
||||
def _get_conn(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user