Added connRes tests to Github

This commit is contained in:
David Puglielli 2017-06-01 15:11:20 -07:00
parent c2bc84e267
commit 0efa3e3141
10 changed files with 1369 additions and 0 deletions

View file

@ -0,0 +1,82 @@
<?php
require_once("MsSetup.inc");
// Using the tempdb database for two tables specifically constructed
// for the connection resiliency tests
$dbName = "tempdb";
$tableName1 = "test_connres1";
$tableName2 = "test_connres2";
// Generate tables for use with the connection resiliency tests.
// Using generated tables will eventually allow us to put the
// connection resiliency tests on Github, since the integrated testing
// from AppVeyor does not have AdventureWorks.
function GenerateTables( $server, $uid, $pwd, $dbName, $tableName1, $tableName2 )
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ;", $uid, $pwd );
if ( $conn === false )
{
die ( print_r( sqlsrv_errors() ) );
}
// Create table
$sql = "CREATE TABLE $tableName1 ( c1 INT, c2 VARCHAR(40) )";
$stmt = $conn->query( $sql );
// Insert data
$sql = "INSERT INTO $tableName1 VALUES ( ?, ? )";
for( $t = 100; $t < 116; $t++ )
{
$stmt = $conn->prepare( $sql );
$ts = substr( sha1( $t ),0,5 );
$params = array( $t,$ts );
$stmt->execute( $params );
}
// Create table
$sql = "CREATE TABLE $tableName2 ( c1 INT, c2 VARCHAR(40) )";
$stmt = $conn->query( $sql );
// Insert data
$sql = "INSERT INTO $tableName2 VALUES ( ?, ? )";
for( $t = 200; $t < 209; $t++ )
{
$stmt = $conn->prepare( $sql );
$ts = substr( sha1( $t ),0,5 );
$params = array( $t,$ts );
$stmt->execute( $params );
}
$conn = null;
}
// Break connection by getting the session ID and killing it.
// Note that breaking a connection and testing reconnection requires a
// TCP/IP protocol connection (as opposed to a Shared Memory protocol).
function BreakConnection( $conn, $conn_break )
{
$stmt1 = $conn->query( "SELECT @@SPID" );
$obj = $stmt1->fetch( PDO::FETCH_NUM );
$spid = $obj[0];
$stmt2 = $conn_break->query( "KILL ".$spid );
sleep(1);
}
// Remove any databases previously created by GenerateDatabase
function DropTables( $server, $uid, $pwd, $tableName1, $tableName2 )
{
$conn = new PDO( "sqlsrv:server = $server ; ", $uid, $pwd );
$query="IF OBJECT_ID('tempdb.dbo.$tableName1', 'U') IS NOT NULL DROP TABLE tempdb.dbo.$tableName1";
$stmt=$conn->query( $query );
$query="IF OBJECT_ID('tempdb.dbo.$tableName2', 'U') IS NOT NULL DROP TABLE tempdb.dbo.$tableName2";
$stmt=$conn->query( $query );
}
DropTables( $server, $uid, $pwd, $tableName1, $tableName2 );
GenerateTables( $server, $uid, $pwd, $dbName, $tableName1, $tableName2 );
?>

View file

@ -0,0 +1,248 @@
--TEST--
Connection recovery test
--DESCRIPTION--
Connect and execute a command, kill the connection, execute another command.
Then do it again without a buffered result set, by freeing the statement before
killing the connection and then not freeing it. The latter case is the only one
that should fail. Finally, execute two queries in two threads on a recovered
non-MARS connection. This should fail too.
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
// There is a lot of repeated code here that could be refactored with helper methods,
// mostly for statement allocation. But that would affect scoping for the $stmt variables,
// which could affect the results when attempting to reconnect. What happens to statements
// when exiting the helper method? Do the associated cursors remain active? It is an
// unnecessary complication, so I have left the code like this.
require_once( "break_pdo.php" );
$conn_break = new PDO( "sqlsrv:server = $server ; Database = $dbName ;", $uid, $pwd );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Expected to successfully execute second query because buffered cursor for
// first query means connection is idle when broken
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = "ConnectRetryCount = 10; ConnectRetryInterval = 10;";
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
$query1 = "SELECT * FROM $tableName1";
try
{
$stmt1 = $conn->prepare( $query1, array( PDO::ATTR_CURSOR=> PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE=> PDO::SQLSRV_CURSOR_BUFFERED ) );
if ( $stmt1->execute() ) echo "Statement 1 successful.\n";
$rowcount = $stmt1->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 1.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
$query2 = "SELECT * FROM $tableName2";
try
{
$stmt2 = $conn->prepare( $query2, array( PDO::ATTR_CURSOR=> PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE=> PDO::SQLSRV_CURSOR_BUFFERED ) );
if ( $stmt2->execute() ) echo "Statement 2 successful.\n";
$rowcount = $stmt2->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 2.\n";
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Expected to successfully execute second query because first statement is
// freed before breaking connection
///////////////////////////////////////////////////////////////////////////////
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
$query1 = "SELECT * FROM $tableName1";
try
{
$stmt3 = $conn->query( $query1 );
if ( $stmt3 ) echo "Statement 3 successful.\n";
$rowcount = $stmt3->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 3.\n";
print_r( $e->getMessage() );
}
$stmt3 = null;
BreakConnection( $conn, $conn_break );
$query2 = "SELECT * FROM $tableName2";
try
{
$stmt4 = $conn->query( $query2 );
if ( $stmt4 ) echo "Statement 4 successful.\n";
$rowcount = $stmt4->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 4.\n";
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 3
// Expected to fail executing second query because default cursor for first
// query is still active when connection is broken
///////////////////////////////////////////////////////////////////////////////
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
$query1 = "SELECT * FROM $tableName1";
try
{
$stmt5 = $conn->query( $query1 );
if ( $stmt5 ) echo "Statement 5 successful.\n";
$rowcount = $stmt5->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 5.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
$query2 = "SELECT * FROM $tableName2";
try
{
$stmt6 = $conn->query( $query2 );
if ( $stmt6 ) echo "Statement 6 successful.\n";
$rowcount = $stmt6->rowCount();
echo $rowcount." rows in result set.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 6.\n";
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 4
// Expected to trigger an error because there are two active statements with
// pending results and MARS is off
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = "ConnectRetryCount = 10; ConnectRetryInterval = 10; MultipleActiveResultSets = false;";
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
try
{
$stmt7 = $conn->query( "SELECT * FROM $tableName1" );
if ( $stmt7 ) echo "Statement 7 successful.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 7.\n";
print_r( $e->getMessage() );
}
try
{
$stmt8 = $conn->query( "SELECT * FROM $tableName2" );
if ( $stmt8 ) echo "Statement 8 successful.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 8.\n";
print_r( $e->getMessage() );
}
$conn = null;
$conn_break = null;
?>
--EXPECTREGEX--
Statement 1 successful.
16 rows in result set.
Statement 2 successful.
9 rows in result set.
Statement 3 successful.
-1 rows in result set.
Statement 4 successful.
-1 rows in result set.
Statement 5 successful.
-1 rows in result set.
Error executing statement 6.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
Statement 7 successful.
Error executing statement 8.
SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.

View file

@ -0,0 +1,216 @@
--TEST--
Test connection resiliency with a prepared statement and transaction.
--DESCRIPTION--
Prepare a statement, break the connection, and execute the statement. Then
test transactions by breaking the connection before beginning a transaction
and in the middle of the transaction. The latter case should fail.
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
require_once( "break_pdo.php" );
$conn_break = new PDO( "sqlsrv:server = $server ; Database = $dbName ;", $uid, $pwd );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Statement expected to be executed because the connection is idle after
// statement has been prepared
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = "ConnectRetryCount = 10; ConnectRetryInterval = 10;";
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
try
{
$stmt1 = $conn->prepare( "SELECT * FROM $tableName1" );
if ( $stmt1 ) echo "Statement 1 prepared.\n";
else echo "Error preparing statement 1.\n";
}
catch( PDOException $e )
{
echo "Exception preparing statement 1.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
try
{
if ( $stmt1->execute() ) echo "Statement 1 executed.\n";
else echo "Statement 1 failed.\n";
}
catch( PDOException $e )
{
echo "Exception executing statement 1.\n";
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Transaction should be committed because connection is broken before
// transaction begins
///////////////////////////////////////////////////////////////////////////////
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
try
{
if ( $conn->beginTransaction() ) echo "Transaction begun.\n";
else echo "Could not begin transaction.\n";
}
catch( PDOException $e )
{
print_r( $e->getMessage() );
echo "Exception: could not begin transaction.\n";
}
$tsql = "INSERT INTO $tableName1 VALUES ( 700, 'zyxwv' )";
try
{
$stmt2 = $conn->query( $tsql );
if ( $stmt2 )
{
if ( $conn->commit() )
{
echo "Transaction was committed.\n";
}
else
{
echo "Statement valid but commit failed.\n";
print_r( sqlsrv_errors() );
}
}
else
{
if ( $conn->rollBack() )
{
echo "Transaction was rolled back.\n";
}
else
{
echo "Statement not valid and rollback failed.\n";
print_r( sqlsrv_errors() );
}
}
}
catch ( PDOException $e )
{
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 3
// Expected to trigger an error because connection is interrupted in the middle
// of a transaction
///////////////////////////////////////////////////////////////////////////////
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
try
{
if ( $conn->beginTransaction() ) echo "Transaction begun.\n";
else echo "Could not begin transaction.\n";
}
catch( PDOException $e )
{
print_r( $e->getMessage() );
echo "Exception: could not begin transaction.\n";
}
BreakConnection( $conn, $conn_break );
$tsql = "INSERT INTO $tableName1 VALUES ( 700, 'zyxwv' )";
try
{
$stmt2 = $conn->query( $tsql );
if ( $stmt2 )
{
if ( $conn->commit() )
{
echo "Transaction was committed.\n";
}
else
{
echo "Statement valid but commit failed.\n";
print_r( sqlsrv_errors() );
}
}
else
{
if ( $conn->rollBack() )
{
echo "Transaction was rolled back.\n";
}
else
{
echo "Statement not valid and rollback failed.\n";
print_r( sqlsrv_errors() );
}
}
}
catch ( PDOException $e )
{
print_r( $e->getMessage() );
}
// This try catch block prevents an Uncaught PDOException error that occurs
// when trying to free the connection.
try
{
$conn = null;
}
catch ( PDOException $e )
{
print_r( $e->getMessage() );
}
$conn_break = null;
?>
--EXPECTREGEX--
Statement 1 prepared.
Statement 1 executed.
Transaction begun.
Transaction was committed.
Transaction begun.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
SQLSTATE\[08S01\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure

View file

@ -0,0 +1,87 @@
--TEST--
Test connection resiliency timeouts
--DESCRIPTION--
1. Connect with ConnectRetryCount equal to 0.
2. Reconnect with the default value of ConnectRetryCount(1).
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
require_once( "break_pdo.php" );
$conn_break = new PDO( "sqlsrv:server = $server ; Database = $dbName ;", $uid, $pwd );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Expected to error out because ConnectRetryCount equals 0
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = "ConnectRetryCount = 0;";
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
try
{
$stmt1 = $conn->query( "SELECT * FROM $tableName1" );
if ( $stmt1 ) echo "Query successfully executed.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 1.\n";
print_r( $e->getMessage() );
}
$conn = null;
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Expected to succeed with a single reconnection attempt
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = "ConnectRetryInterval = 10;";
try
{
$conn = new PDO( "sqlsrv:server = $server ; Database = $dbName ; $connectionInfo", $uid, $pwd );
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e )
{
echo "Could not connect.\n";
print_r( $e->getMessage() );
}
BreakConnection( $conn, $conn_break );
try
{
$stmt2 = $conn->query( "SELECT * FROM $tableName1" );
if ( $stmt2 ) echo "Query successfully executed.\n";
}
catch( PDOException $e )
{
echo "Error executing statement 2.\n";
print_r( $e->getMessage() );
}
$conn = null;
$conn_break = null;
DropTables( $server, $uid, $pwd, $tableName1, $tableName2 );
?>
--EXPECTREGEX--
Error executing statement 1.
SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
Query successfully executed.

View file

@ -0,0 +1,35 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
if (!extension_loaded("pdo_sqlsrv")) {
die("skip Extension not loaded");
}
require_once( "MsSetup.inc" );
$conn = new PDO( "sqlsrv:server = $server ;", $uid, $pwd );
if( $conn === false )
{
die( "skip Could not connect during SKIPIF." );
}
// Get process ID. Not the same as the one during the actual test, but
// we only need to know the protocol for a particular connection.
$stmt = $conn->query( "SELECT @@SPID" );
if ( $stmt )
{
$spid = $stmt->fetch(PDO::FETCH_NUM)[0];
}
else
{
die( "skip Could not fetch SPID during SKIPIF.");
}
$stmt = $conn->query( "SELECT * FROM sys.dm_exec_connections WHERE session_id = ".$spid);
$prot = $stmt->fetchColumn(3);
if ($prot != 'TCP')
{
die("skip Not using a TCP protocol." );
}
?>

88
test/sqlsrv/break.php Normal file
View file

@ -0,0 +1,88 @@
<?php
require_once("MsSetup.inc");
// Using the tempdb database for two tables specifically constructed
// for the connection resiliency tests
$dbName = "tempdb";
$tableName1 = "test_connres1";
$tableName2 = "test_connres2";
// Generate tables for use with the connection resiliency tests.
// Using generated tables will eventually allow us to put the
// connection resiliency tests on Github, since the integrated testing
// from AppVeyor does not have AdventureWorks.
function GenerateTables( $server, $uid, $pwd, $dbName, $tableName1, $tableName2 )
{
$connectionInfo = array( "Database"=>$dbName, "uid"=>$uid, "pwd"=>$pwd );
$conn = sqlsrv_connect( $server, $connectionInfo );
if ( $conn === false )
{
die ( print_r( sqlsrv_errors() ) );
}
// Create table
$sql = "CREATE TABLE $tableName1 ( c1 INT, c2 VARCHAR(40) )";
$stmt = sqlsrv_query( $conn, $sql );
// Insert data
$sql = "INSERT INTO $tableName1 VALUES ( ?, ? )";
for( $t = 100; $t < 116; $t++ )
{
$ts = substr( sha1( $t ),0,5 );
$params = array( $t,$ts );
$stmt = sqlsrv_prepare( $conn, $sql, $params );
sqlsrv_execute( $stmt );
}
// Create table
$sql = "CREATE TABLE $tableName2 ( c1 INT, c2 VARCHAR(40) )";
$stmt = sqlsrv_query( $conn, $sql );
// Insert data
$sql = "INSERT INTO $tableName2 VALUES ( ?, ? )";
for( $t = 200; $t < 209; $t++ )
{
$ts = substr( sha1( $t ),0,5 );
$params = array( $t,$ts );
$stmt = sqlsrv_prepare( $conn, $sql, $params );
sqlsrv_execute( $stmt );
}
sqlsrv_close( $conn );
}
// Break connection by getting the session ID and killing it.
// Note that breaking a connection and testing reconnection requires a
// TCP/IP protocol connection (as opposed to a Shared Memory protocol).
function BreakConnection( $conn, $conn_break )
{
$stmt1 = sqlsrv_query( $conn, "SELECT @@SPID" );
if ( sqlsrv_fetch( $stmt1 ) )
{
$spid=sqlsrv_get_field( $stmt1, 0 );
}
$stmt2 = sqlsrv_prepare( $conn_break, "KILL ".$spid );
sqlsrv_execute( $stmt2 );
sleep(1);
}
// Remove the tables generated by GenerateTables
function DropTables( $server, $uid, $pwd, $tableName1, $tableName2 )
{
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd );
$conn = sqlsrv_connect( $server, $connectionInfo );
$query="IF OBJECT_ID('tempdb.dbo.$tableName1', 'U') IS NOT NULL DROP TABLE tempdb.dbo.$tableName1";
$stmt=sqlsrv_query( $conn, $query );
$query="IF OBJECT_ID('tempdb.dbo.$tableName2', 'U') IS NOT NULL DROP TABLE tempdb.dbo.$tableName2";
$stmt=sqlsrv_query( $conn, $query );
}
DropTables( $server, $uid, $pwd, $tableName1, $tableName2 );
GenerateTables( $server, $uid, $pwd, $dbName, $tableName1, $tableName2 );
?>

View file

@ -0,0 +1,262 @@
--TEST--
Connection recovery test
--DESCRIPTION--
Connect and execute a command, kill the connection, execute another command.
Then do it again without a buffered result set, by freeing the statement before
killing the connection and then not freeing it. The latter case is the only one
that should fail. Finally, execute two queries in two threads on a recovered
non-MARS connection. This should fail too.
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
// There is a lot of repeated code here that could be refactored with helper methods,
// mostly for statement allocation. But that would affect scoping for the $stmt variables,
// which could affect the results when attempting to reconnect. What happens to statements
// when exiting the helper method? Do the associated cursors remain active? It is an
// unnecessary complication, so I have left the code like this.
require_once( "break.php" );
$conn_break = sqlsrv_connect( $server, array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd) );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Expected to successfully execute second query because buffered cursor for
// first query means connection is idle when broken
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd, "ConnectionPooling"=>false,
"ConnectRetryCount"=>10, "ConnectRetryInterval"=>10 );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
$stmt1 = sqlsrv_query( $conn, "SELECT * FROM $tableName1", array(), array( "Scrollable"=>"buffered" ) );
if( $stmt1 === false )
{
echo "Error in statement 1.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 1 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt1 );
echo $rowcount." rows in result set.\n";
}
BreakConnection( $conn, $conn_break );
$stmt2 = sqlsrv_query( $conn, "SELECT * FROM $tableName2", array(), array( "Scrollable"=>"buffered" ) );
if( $stmt2 === false )
{
echo "Error in statement 2.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 2 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt2 );
echo $rowcount." rows in result set.\n";
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Expected to successfully execute second query because first statement is
// freed before breaking connection
///////////////////////////////////////////////////////////////////////////////
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
$stmt3 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt3 === false )
{
echo "Error in statement 3.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 3 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt3 );
echo $rowcount." rows in result set.\n";
}
sqlsrv_free_stmt( $stmt3 );
BreakConnection( $conn, $conn_break );
$stmt4 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" );
if( $stmt4 === false )
{
echo "Error in statement 4.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 4 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt4 );
echo $rowcount." rows in result set.\n";
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 3
// Expected to fail executing second query because default cursor for first
// query is still active when connection is broken
///////////////////////////////////////////////////////////////////////////////
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
$stmt5 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt5 === false )
{
echo "Error in statement 5.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 5 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt5 );
echo $rowcount." rows in result set.\n";
}
BreakConnection( $conn, $conn_break );
$stmt6 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" );
if( $stmt6 === false )
{
echo "Error in statement 6.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 6 successful.\n";
$rowcount = sqlsrv_num_rows( $stmt6 );
echo $rowcount." rows in result set.\n";
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 4
// Expected to trigger an error because there are two active statements with
// pending results and MARS is off
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd,
"ConnectRetryCount"=>10, "ConnectRetryInterval"=>10, "MultipleActiveResultSets"=>false );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
BreakConnection( $conn, $conn_break );
$stmt7 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt7 === false )
{
echo "Error in statement 7.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 7 successful.\n";
}
$stmt8 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" );
if( $stmt8 === false )
{
echo "Error in statement 8.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 8 successful.\n";
}
sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>
--EXPECTREGEX--
Statement 1 successful.
16 rows in result set.
Statement 2 successful.
9 rows in result set.
Statement 3 successful.
rows in result set.
Statement 4 successful.
rows in result set.
Statement 5 successful.
rows in result set.
Error in statement 6.
Array
\(
\[0\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\)
\)
Statement 7 successful.
Error in statement 8.
Array
\(
\[0\] => Array
\(
\[0\] => IMSSP
\[SQLSTATE\] => IMSSP
\[1\] => -44
\[code\] => -44
\[2\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.
\[message\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option.
\)
\[1\] => Array
\(
\[0\] => HY000
\[SQLSTATE\] => HY000
\[1\] => 0
\[code\] => 0
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command
\)
\)

View file

@ -0,0 +1,207 @@
--TEST--
Test connection resiliency with a prepared statement and transaction.
--DESCRIPTION--
Prepare a statement, break the connection, and execute the statement. Then
test transactions by breaking the connection before beginning a transaction
and in the middle of the transaction. The latter case should fail (i.e., the
transaction should be rolled back).
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
require_once( "break.php" );
$conn_break = sqlsrv_connect( $server, array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd) );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Statement expected to be executed because the connection is idle after
// statement has been prepared
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd, "ConnectionPooling"=>false,
"ConnectRetryCount"=>10, "ConnectRetryInterval"=>10 );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
$stmt1 = sqlsrv_prepare( $conn, "SELECT * FROM $tableName1" );
if( $stmt1 === false )
{
echo "Error in statement preparation.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 1 prepared.\n";
}
BreakConnection( $conn, $conn_break );
if( sqlsrv_execute( $stmt1 ) )
{
echo "Statement 1 executed.\n";
}
else
{
echo "Statement 1 could not be executed.\n";
print_r( sqlsrv_errors() );
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Transaction should be committed because connection is broken before
// transaction begins
///////////////////////////////////////////////////////////////////////////////
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
BreakConnection( $conn, $conn_break );
if ( sqlsrv_begin_transaction( $conn ) === false )
{
echo "Could not begin transaction.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Transaction begun.\n";
}
$number = 700;
$string = 'zxywv';
$tsql = "INSERT INTO $tableName1 VALUES ( ?, ? )";
$params = array( $number, $string );
$stmt2 = sqlsrv_query( $conn, $tsql, $params );
if( $stmt2 )
{
if ( sqlsrv_commit( $conn ) )
{
echo "Transaction was committed.\n";
}
else
{
echo "Statement valid but commit failed.\n";
print_r( sqlsrv_errors() );
}
}
else
{
if ( sqlsrv_rollback( $conn ) )
{
echo "Transaction was rolled back.\n";
}
else
{
echo "Statement not valid and rollback failed.\n";
print_r( sqlsrv_errors() );
}
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 3
// Expected to trigger an error because connection is interrupted in the middle
// of a transaction
///////////////////////////////////////////////////////////////////////////////
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
if ( sqlsrv_begin_transaction( $conn ) === false )
{
echo "Could not begin transaction.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Transaction begun.\n";
}
BreakConnection( $conn, $conn_break );
$number = 700;
$string = 'zxywv';
$tsql = "INSERT INTO $tableName1 VALUES ( ?, ? )";
$params = array( $number, $string );
$stmt2 = sqlsrv_query( $conn, $tsql, $params );
if( $stmt2 )
{
if ( sqlsrv_commit( $conn ) )
{
echo "Transaction was committed.\n";
}
else
{
echo "Statement valid but commit failed.\n";
print_r( sqlsrv_errors() );
}
}
else
{
if ( sqlsrv_rollback( $conn ) )
{
echo "Transaction was rolled back.\n";
}
else
{
echo "Statement not valid and rollback failed.\n";
print_r( sqlsrv_errors() );
}
}
sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
?>
--EXPECTREGEX--
Statement 1 prepared.
Statement 1 executed.
Transaction begun.
Transaction was committed.
Transaction begun.
Statement not valid and rollback failed.
Array
\(
\[0\] => Array
\(
\[0\] => 08S02
\[SQLSTATE\] => 08S02
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S02
\[SQLSTATE\] => 08S02
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session
\)
\)

View file

@ -0,0 +1,105 @@
--TEST--
Test connection resiliency timeouts
--DESCRIPTION--
1. Connect with ConnectRetryCount equal to 0.
2. Reconnect with the default value of ConnectRetryCount (the default is 1).
--SKIPIF--
<?php require('skipif_protocol_not_tcp.inc'); ?>
--FILE--
<?php
require_once( "break.php" );
$conn_break = sqlsrv_connect( $server, array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd) );
///////////////////////////////////////////////////////////////////////////////
// Part 1
// Expected to error out because ConnectRetryCount equals 0
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd,
"ConnectRetryCount"=>0 );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
BreakConnection( $conn, $conn_break );
$stmt1 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt1 === false )
{
echo "Error in statement 1.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 1 successful.\n";
}
sqlsrv_close( $conn );
///////////////////////////////////////////////////////////////////////////////
// Part 2
// Expected to succeed with a single reconnection attempt
///////////////////////////////////////////////////////////////////////////////
$connectionInfo = array( "Database"=>$dbName, "UID"=>$uid, "PWD"=>$pwd,
"ConnectRetryInterval"=>10 );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
echo "Could not connect.\n";
print_r( sqlsrv_errors() );
}
BreakConnection( $conn, $conn_break );
$stmt2 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" );
if( $stmt2 === false )
{
echo "Error in statement 2.\n";
print_r( sqlsrv_errors() );
}
else
{
echo "Statement 2 successful.\n";
}
sqlsrv_close( $conn );
sqlsrv_close( $conn_break );
DropTables( $server, $uid, $pwd, $tableName1, $tableName2 )
?>
--EXPECTREGEX--
Error in statement 1.
Array
\(
\[0\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host.
\)
\[1\] => Array
\(
\[0\] => 08S01
\[SQLSTATE\] => 08S01
\[1\] => 10054
\[code\] => 10054
\[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure
\)
\)
Statement 2 successful.

View file

@ -0,0 +1,39 @@
<?php
if ( !( strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN' ) ) die( "Skip Test on windows only." );
if (!extension_loaded("sqlsrv")) {
die("skip Extension not loaded");
}
require_once( "MsSetup.inc" );
$connectionInfo = array( "UID"=>$userName, "PWD"=>$userPassword );
$conn = sqlsrv_connect( $server, $connectionInfo );
if( $conn === false )
{
die( "skip Could not connect during SKIPIF." );
}
// Get process ID. Not the same as the one during the actual test, but
// we only need to know the protocol for a particular connection.
$stmt = sqlsrv_query( $conn, "SELECT @@SPID" );
if ( sqlsrv_fetch( $stmt ) )
{
$spid = sqlsrv_get_field( $stmt, 0 );
}
else
{
die("skip Could not fetch SPID.");
}
$stmt = sqlsrv_query( $conn, "SELECT * FROM sys.dm_exec_connections WHERE session_id = $spid");
if ( sqlsrv_fetch( $stmt ) )
{
$prot = sqlsrv_get_field( $stmt, 3 );
if ($prot != 'TCP')
{
die( "skip Not using a TCP protocol." );
}
}
?>