mariadb/tests/check_async_queries.pl
unknown a5b881594d MWL#192: Non-blocking client API for libmysqlclient.
All client functions that can block on I/O have alternate _start() and
_cont() versions that do not block but return control back to the
application, which can then issue I/O wait in its own fashion and later
call back into the library to continue the operation.

Works behind the scenes by spawning a co-routine/fiber to run the
blocking operation and suspend it while waiting for I/O. This
co-routine/fiber use is invisible to applications.

For i368/x86_64 on GCC, uses very fast assembler co-routine support. On
Windows uses native Win32 Fibers. Falls back to POSIX ucontext on other
platforms. Assembler routines for more platforms are relatively easy to
add by extending mysys/my_context.c, eg. similar to the Lua lcoco
library.

For testing, mysqltest and mysql_client_test are extended with the
option --non-blocking-api. This causes the programs to use the
non-blocking API for database access. mysql-test-run.pl has a similar
option --non-blocking-api that uses this, as well as additional
testcases.

An example program tests/async_queries.c is included that uses the new
non-blocking API with libevent to show how, in a single-threaded
program, to issue many queries in parallel against a database.


client/async_example.c:
  Fix const warning
  ******
  Fix bug with wrong timeout value for poll().
include/Makefile.am:
  Fix missing include for `make dist`
include/mysql.h:
  Add prototypes for all non-blocking API calls.
include/mysql.h.pp:
  Add prototypes for all non-blocking API calls.
mysys/my_context.c:
  Fix type warning for makecontext() function pointer argument.
sql-common/mysql_async.c:
  Fix crashes in the non-blocking API for functions that can take MYSQL argument
  that is NULL.
tests/Makefile.am:
  Add header file to `make dist`
tests/mysql_client_test.c:
  Replace blocking calls with wrappers around the non-blocking calls, used in
  mysql_client_test to test the new non-blocking API.
tests/nonblock-wrappers.h:
  Replace blocking calls with wrappers around the non-blocking calls, used in
  mysql_client_test to test the new non-blocking API.
2011-09-20 12:49:25 +02:00

73 lines
2.2 KiB
Perl

#! /usr/bin/perl
# Read the output of async_queries.c. Run the queries again serially, using
# the normal (not asynchronous) API. Compare the two results for correctness.
use strict;
use warnings;
use DBI;
my $D= [];
die "Usage: $0 <host> <user> <password> <database>\n"
unless @ARGV == 4;
my $dbh= DBI->connect("DBI:mysql:database=$ARGV[3];host=$ARGV[0]",
$ARGV[1], $ARGV[2],
{ RaiseError => 1, PrintError => 0 });
while (<STDIN>) {
chomp;
if (/^([0-9]+) ! (.*);$/) {
my ($index, $query)= ($1, $2);
$D->[$index]= { QUERY => $query, OUTPUT => [] };
} elsif (/^([0-9]+) - (.*)$/) {
my ($index, $data)= ($1, $2);
push @{$D->[$index]{OUTPUT}}, $data;
} elsif (/^([0-9]+) \| Error: (.*)$/) {
my ($index, $errmsg)= ($1, $2);
my $rows;
my $res= eval {
my $stm= $dbh->prepare($D->[$index]{QUERY});
$stm->execute();
$rows= $stm->fetchall_arrayref();
1;
};
if ($res) {
die "Query $index succeeded, but should have failed with error.\nquery=$D->[$index]{QUERY}\nerror=$errmsg\n";
}
my $errmsg2= $@;
if ($errmsg2 =~ /^DBD::.*failed: (.*) at .*$/s) {
$errmsg2= $1;
} else {
die "Unexpected DBD error message format: '$errmsg2'\n";
}
if ($errmsg2 ne $errmsg) {
die "Query $index failed with different error message\nquery=$D->[$index]{QUERY}\nerror1=$errmsg\nerror2=$errmsg2\n";
}
print "OK $index\n";
delete $D->[$index];
} elsif (/^([0-9]+) \| EOF$/) {
my $index= $1;
my $rows;
my $res= eval {
my $stm= $dbh->prepare($D->[$index]{QUERY});
$stm->execute();
$rows= $stm->fetchall_arrayref();
1;
};
if (!$res) {
die "Query $index failed, but should have succeeded.\nquery=$D->[$index]{QUERY}\nerror=$@\n";
}
my $result_string= join("\n", sort @{$D->[$index]{OUTPUT}});
my $result_string2= join("\n", sort(map(join("\t", map((defined($_) ? $_ : "(null)"), @$_)), @$rows)));
if ($result_string ne $result_string2) {
die "Query $index result difference.\nquery=$D->[$index]{QUERY}\noutput1=\n$$result_string\noutput2=\n$result_string2\n";
}
delete $D->[$index];
} else {
die "Unexpected line: '$_'\n";
}
}
$dbh->disconnect();