#
# Some functional checks for the content of performance_schema.socket_instances.
#

--source include/not_embedded.inc
--source include/windows.inc
--source include/have_perfschema.inc

# Set this to enable debugging output
let $my_socket_debug= 0;

#
# Set IP address defaults with respect to IPV6 support
#

# Determine if IPV6 supported
let $check_ipv6_just_check= 1;
--source include/check_ipv6.inc

# Determine if IPV4 mapped to IPV6 supported
let $check_ipv4_mapped_just_check= 1;
--source include/check_ipv4_mapped.inc

let $my_localhost= 127.0.0.1;

if($check_ipv6_supported)
{
  let $my_localhost= ::1;
}

if($check_ipv4_mapped_supported)
{
  let $my_localhost= ::ffff:127.0.0.1;
}

if($my_socket_debug)
{
  --echo IPV6=$check_ipv6_supported, IPV4_MAPPED=$check_ipv4_mapped_supported, LOCALHOST=$my_localhost
}

#
# Preserve the current state of SOCKET_INSTANCES
#

--echo # Take a snapshot of SOCKET_INSTANCES
CREATE TEMPORARY TABLE my_socket_instances AS
SELECT * FROM performance_schema.socket_instances;

--echo # Get thread id of the default connection
SELECT THREAD_ID INTO @thread_id
FROM performance_schema.threads
WHERE PROCESSLIST_ID = CONNECTION_ID();

let $con0_thread_id= `SELECT @thread_id`;

#
# ESTABLISH TCP/IP CONNECTION 1
#
# Start connection with IP = localhost (127.0.0.1 or ::1)

--echo # Establish local TCP/IP connection (con1,localhost,root,,test,,)
--disable_query_log
--connect (con1,$my_localhost,root,,test,,$MASTER_MYPORT)
--enable_query_log

if($my_socket_debug)
{
#  --replace_result '::ffff:127.0.0.1' <LOCALHOST> '127.0.0.1' <LOCALHOST> '::1' <LOCALHOST> '::' <BINDADDR> '0.0.0.0' <BINDADDR>
  SELECT * FROM performance_schema.socket_instances;
}

--echo # Store the thread id of connection 1 (tcp/ip)
SELECT THREAD_ID INTO @thread_id
FROM performance_schema.threads
WHERE PROCESSLIST_ID = CONNECTION_ID();

--echo # Store the port of connection 1 (tcp/ip)
eval SELECT PORT INTO @port
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

let $con1_thread_id= `SELECT @thread_id`;
let $con1_port= `SELECT @port`;

--echo # Switch to connection default
--connection default

#
# ESTABLISH TCP/IP CONNECTION 2
#
# Start a second connection with IP = localhost (127.0.0.1 or ::1)

--echo # Establish second local TCP/IP connection (con1,localhost,root,,test,,)
--disable_query_log
--connect (con2,$my_localhost,root,,test,,$MASTER_MYPORT)
--enable_query_log

if($my_socket_debug)
{
#  --replace_result '::ffff:127.0.0.1' <LOCALHOST> '127.0.0.1' <LOCALHOST> '::1' <LOCALHOST> '::' <BINDADDR> '0.0.0.0' <BINDADDR>
  SELECT * FROM performance_schema.socket_instances;
}

--echo # Store the thread_id of connection 2 (tcp/ip)
SELECT THREAD_ID INTO @thread_id
FROM performance_schema.threads
WHERE PROCESSLIST_ID = CONNECTION_ID();

--echo # Store the port of connection 2 (tcp/ip)
eval SELECT PORT INTO @port
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

let $con2_thread_id= `SELECT @thread_id`;
let $con2_port = `SELECT @port`;

--echo # Switch to connection default
--connection default

#
# VERIFY EVENT NAMES
#

--echo # EVENT_NAME is the "wait/io/socket/*" instrument identifier.

SELECT COUNT(*) = 0 AS "Expect 1"
FROM performance_schema.socket_instances
WHERE EVENT_NAME NOT LIKE 'wait/io/socket/%';

#
# VERIFY UNIQUE EVENT IDs
#

--echo # OBJECT_INSTANCE_BEGIN is an arbitrary identifier, guaranteed to be unique.

SELECT COUNT(*) = COUNT(DISTINCT OBJECT_INSTANCE_BEGIN) AS "Expect 1"
FROM performance_schema.socket_instances;

#
# VERIFY UNIQUE SOCKET ID
#

--echo # SOCKET_ID is the internal file handle assigned to the socket.

SELECT COUNT(*) = COUNT(DISTINCT SOCKET_ID) AS "Expect 1"
FROM performance_schema.socket_instances;

#
# VERIFY UNIQUE THREAD IDs
#

--echo # Characteristics per our thread
--echo #    There must be only one entry with our thread_id

--disable_query_log
eval SET @thread_id= $con0_thread_id;
--enable_query_log

eval SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

#
# VERIFY UNIQUE PORT NUMBERS FOR TCP/IP CLIENTS
#

--echo # TCP/IP connections should have a unique port number
--disable_query_log
eval SET @port= $con1_port;
--enable_query_log

--echo # Connection 1 (tcp/ip)
eval SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE PORT = @port;

--disable_query_log
eval SET @port= $con2_port;
--enable_query_log

--echo # Connection 2 (tcp/ip)
eval SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE PORT = @port;

#
# VERIFY CONNECTION DETAILS FOR THE DEFAULT CONNECTION
#

--echo #    Check the content for the default connection (tcpip)
# EVENT_NAME                           OBJECT_INSTANCE_BEGIN THREAD_ID SOCKET_ID IP        PORT STATE
# wait/io/socket/sql/client_connection              26139912        16    907296 127.0.0.1 2631 ACTIVE

--disable_query_log
eval SET @thread_id = $con0_thread_id;
--enable_query_log

SELECT EVENT_NAME = 'wait/io/socket/sql/client_connection'
       AND (IP LIKE '%127.0.0.1' OR IP = '::1') AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

#
# VERIFY SERVER LISTENING SOCKET, TCP/IP
#

--echo # Characteristics of 'server_tcpip_socket' entry
--echo #    Server listening socket, TCP/IP
--echo #    There is only one entry with 'wait/io/socket/sql/server_tcpip_socket'.
--echo #    It shares the same thread id as 'wait/io/socket/sql/server_unix_socket'.

SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';

# Store the thread id of server_tcpip_socket
--echo # Get the 'server_tcpip_socket' thread id

SELECT THREAD_ID INTO @thread_id
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';

let $server_tcpip_thread_id= `SELECT @thread_id`;

--echo #    Check the content.
--disable_query_log
eval SET @port = $MASTER_MYPORT;
--enable_query_log

eval SELECT THREAD_ID = @thread_id
     AND (IP = '0.0.0.0' OR IP = '::')
     AND PORT = @port
     AND STATE = 'ACTIVE' AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';

#
# VERIFY TCP/IP CLIENT CONNECTION 1
#

# EVENT_NAME                           OBJECT_INSTANCE_BEGIN THREAD_ID SOCKET_ID IP        PORT  STATE
# wait/io/socket/sql/client_connection       140707865187120        18        59 127.0.0.1 59298 IDLE or ACTIVE

--echo #    Check content for client connection 1 (tcpip)

--disable_query_log
eval SET @port = $con1_port;
eval SET @thread_id = $con1_thread_id;
eval SET @addr = '$my_localhost';
--enable_query_log

eval SELECT EVENT_NAME = 'wait/io/socket/sql/client_connection'
        AND (IP LIKE '%127.0.0.1' OR IP = '::1')
        AND PORT = @port
AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

--echo # Characteristics of entries with THREAD_ID of con1
--echo #    There is only one entry with this id.

eval SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

#
# VERIFY TCP/IP CLIENT CONNECTION 2
#

# EVENT_NAME                           OBJECT_INSTANCE_BEGIN THREAD_ID SOCKET_ID IP        PORT  STATE
# wait/io/socket/sql/client_connection       140707865187120        18        59 127.0.0.1 59298 IDLE or ACTIVE

--echo #    Check content for client connection 2 (tcpip)

--disable_query_log
eval SET @port = $con2_port;
eval SET @thread_id = $con2_thread_id;
eval SET @addr = '$my_localhost';
--enable_query_log

eval SELECT EVENT_NAME = 'wait/io/socket/sql/client_connection'
        AND (IP LIKE '%127.0.0.1' OR IP = '::1')
        AND PORT = @port
AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

--echo # Characteristics of entries with THREAD_ID of con2
--echo #    There is only one entry with this id.

eval SELECT COUNT(*) = 1 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;

#
# LIST CLIENT CONNECTIONS
#

--echo # Show differences to socket_instances before con1, con2 and con3 connecting
let $part=
FROM performance_schema.socket_instances
WHERE (EVENT_NAME,OBJECT_INSTANCE_BEGIN,THREAD_ID,SOCKET_ID,IP,PORT,STATE)
NOT IN (SELECT EVENT_NAME,OBJECT_INSTANCE_BEGIN,THREAD_ID,SOCKET_ID,IP,PORT,STATE
        FROM my_socket_instances)
ORDER BY THREAD_ID;
--replace_result '::ffff:127.0.0.1' <LOCALHOST> '127.0.0.1' <LOCALHOST> '::1' <LOCALHOST> '::' <BINDADDR> '0.0.0.0' <BINDADDR>
eval
SELECT EVENT_NAME, IP
$part;

--connection default

#
# DROP CLIENT CONNECTIONS
#

--echo # Disconnect con1 and con2
--connection con1
--disconnect con1
--source include/wait_until_disconnected.inc
--connection con2
--disconnect con2
--source include/wait_until_disconnected.inc
--connection default

#
# VERIFY CONNECTIONS DROPPED
#

--echo # After waiting a bit we should have no differences to socket_instances
--echo # before con1, con2 connecting.
let $wait_timeout= 10;
let $wait_condition= SELECT COUNT(*) = 0 $part;
--source include/wait_condition.inc
#
eval
SELECT *
$part;

