List:Commits« Previous MessageNext Message »
From:Serge Kozlov Date:February 18 2011 9:17pm
Subject:bzr push into nuts branch (Serge.Kozlov:390 to 391) WL#5576
View as plain text  
  391 Serge Kozlov	2011-02-19
      WL#5576. The test case for NUTS added as combination for stress::basic_stress

    added:
      suites/stress/
      suites/stress/basic/
      suites/stress/basic/create_table_select.pl
      suites/stress/basic_stress.pm
    modified:
      lib/My/Nuts/Library/Kernel/ServerResult.pm
  390 Serge Kozlov	2011-01-31
      rep_func::crash_safe_master
      do not compare databases for MyISAM storage engine

    modified:
      suites/rep_func/crash_safe_master.pm
=== modified file 'lib/My/Nuts/Library/Kernel/ServerResult.pm'
--- a/lib/My/Nuts/Library/Kernel/ServerResult.pm	2011-01-30 21:09:31 +0000
+++ b/lib/My/Nuts/Library/Kernel/ServerResult.pm	2011-02-18 21:07:39 +0000
@@ -3,7 +3,7 @@ use Exporter;
 our @ISA = qw(Exporter);
 our @EXPORT =
   qw(ok_diff_databases diff_databases get_supported_engines get_table_list get_variable get_status 
-    get_errmsg_by_num ok_wait_status ok_wait_sql dump_sql dump_server_state);
+    get_errmsg_by_num ok_wait_status ok_wait_sql dump_sql dump_server_state sql_result sql_results);
 use strict;
 use warnings;
 use My;
@@ -198,6 +198,29 @@ sub sql_result
     return $result;
 }
 
+sub sql_results
+{
+    my ($server, $query) = @_;
+    my $result = undef;
+    my $rs = sql ( $server, $query );
+    if ($rs)
+    {
+	my @rs_data;
+	$result = "";
+	@rs_data = get_next($rs);
+	while (defined($rs_data[0]))
+	{
+	    foreach my $item (@rs_data)
+	    {
+		$result .= " " . $item;
+	    }
+	    $result .= "\n";
+	    @rs_data = get_next($rs);
+	}
+    }
+    return $result;
+}
+
 sub get_supported_engines
 {
   my ($conn, $filter) = @_;

=== added directory 'suites/stress'
=== added directory 'suites/stress/basic'
=== added file 'suites/stress/basic/create_table_select.pl'
--- a/suites/stress/basic/create_table_select.pl	1970-01-01 00:00:00 +0000
+++ b/suites/stress/basic/create_table_select.pl	2011-02-18 21:07:39 +0000
@@ -0,0 +1,113 @@
+#!/usr/bin/perl -w
+
+# Simple mysql client
+# Parameters:
+#  ./create_table_select_client.pl dsn id max_client_num path
+#  dsn			- dsn of the server
+#  id   		- client id
+#  max_client_num   	- max number of clients
+#  path 		- path to file with list of regular queries 
+#  			(a query per line)
+
+use DBI;
+use strict;
+use warnings;
+
+# Variables
+
+# Command line arguments
+my $dsn = $ARGV[0];
+my $id = $ARGV[1];
+my $max_client_num = $ARGV[2];
+my $qfile = $ARGV[3];
+
+# Variables
+my $dbname = "test_$id";
+my $table_prefix = "ct$id"."_";
+my $sth;
+
+# Connect to DB
+my $dbh = DBI->connect($dsn, "root") or die ("Cannot open connection to mysql server $dsn");
+$dbh->{PrintError} = 0;
+$dbh->{RaiseError} = 0;
+
+# Read queries from file
+open F, $qfile or die ("Cannot open $qfile");
+my @qlines = <F>;
+close F;
+
+# Prepare database
+$dbh->do("DROP DATABASE IF EXISTS $dbname");
+$dbh->do("CREATE DATABASE $dbname");
+$dbh->do("USE $dbname");
+
+# Create functions 
+my $create_func = qq{
+    CREATE FUNCTION f1()
+    RETURNS INT DETERMINISTIC
+    BEGIN
+	DELETE FROM t1;
+	RETURN 1;
+    END
+};
+
+$dbh->do($create_func);
+for (my $i = 2; $i <= 10; $i++)
+{
+    my $call_func = $i-1;
+    $create_func = qq{
+	CREATE FUNCTION f$i()
+	RETURNS INT DETERMINISTIC
+	BEGIN
+	    RETURN f$call_func();
+	END
+    };
+    $dbh->do($create_func);
+}
+
+# Wait until all clients started and connected to server
+# and try to execute statements at same time for all clients
+$dbh->do("INSERT INTO nuts.run_clients VALUES($id)");
+my $cur_client_num = 0;
+until ($cur_client_num == $max_client_num)
+{
+    $sth = $dbh->prepare("SELECT COUNT(*) FROM nuts.run_clients");
+    $sth->execute();
+    ($cur_client_num) = $sth->fetchrow_array();
+    $sth->finish();
+    sleep 1;
+}
+
+# Execute statements
+my $idx= 1;
+foreach my $query (@qlines)
+{
+    $dbh->do($query);
+    # We randomly try run CREATE TABLE SELECT f();
+    if (rand(10) > 7)
+    {
+	my $deep = int(rand(9)) + 1;
+	my $test_query= "CREATE TABLE $table_prefix$idx SELECT f$deep()";
+	my $err_str= undef;
+	$dbh->do($test_query) or $err_str= $dbh->errstr();
+	# We expects an error
+	if (defined($err_str))
+	{
+	    # Check text of given error 
+	    if ($err_str !~ /update table .+while.+is being created/i)
+	    {
+		$err_str =~s/\'/\\'/g;
+		$dbh->do("INSERT INTO nuts.client_failures(client_id, client_text) VALUES ($id, '$test_query is failed with another error: $err_str')");		
+	    }	    
+	}
+	else
+	{
+	    $dbh->do("INSERT INTO nuts.client_failures(client_id, client_text) VALUES ($id, '$test_query is passed but shoud be failed')");
+	}
+	$idx++;
+    }
+}
+
+# Close connection
+$dbh->disconnect;
+

=== added file 'suites/stress/basic_stress.pm'
--- a/suites/stress/basic_stress.pm	1970-01-01 00:00:00 +0000
+++ b/suites/stress/basic_stress.pm	2011-02-18 21:07:39 +0000
@@ -0,0 +1,191 @@
+package stress::basic_stress;
+use Exporter;
+our @ISA = qw(Exporter My::Nuts::Library::Tests::SimpleTest);
+use strict;
+use warnings;
+use IO::File;
+use My;
+use My::Nuts::Library::Kernel::Server;
+use My::Nuts::Library::Kernel::ServerResult;
+use My::Nuts::Library::Kernel::Manager;
+use My::Nuts::Library::Kernel::Result;
+use My::Nuts::Library::Tests::SimpleTest;
+use My::Nuts::Library::DataSource;
+use Test::More;
+
+
+my @client_num = (
+    "5", "20", "50" 
+);
+
+my @client_scripts = (
+    "create_table_select"
+);
+
+sub combinations
+{
+    my @combinations= ();
+    foreach my $script ( @client_scripts )
+    {
+	foreach my $num ( @client_num )
+	{
+	    push(@combinations, "$script-$num");
+	}    
+    }
+    return @combinations;
+}
+
+sub prepare
+{
+    return;
+}
+
+sub startup
+{
+    return;
+}
+
+sub fire
+{
+    my ($test) = @_;
+    my ($client_script, $client_num)= split(/-/, get_combination($test));
+    
+    # Read list of statements from data source
+    my $data = get_data_from_source();
+    
+    # Store queries to file for clients
+    my $qfile = File::Spec->catfile(get_test_tmp_dir(), "data_source.sql");
+    my $dump_file = new IO::File($qfile, "w+");
+    print $dump_file join("\n", @$data);
+    $dump_file = undef;
+    
+    # Subtests
+    plan tests => 5;
+
+    # Run server
+    my $server = ok_server ($test);
+
+    # Create the table which used for start of execution of queries
+    # and for collect results
+    ok_sql ( $server, "CREATE DATABASE IF NOT EXISTS nuts");
+    ok_sql ( $server, "CREATE TABLE nuts.run_clients (run_clients INT NOT NULL DEFAULT 0)");
+    ok_sql ( $server, "CREATE TABLE nuts.client_failures (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, client_id INT NOT NULL, client_text TEXT NOT NULL)");
+    # Main test
+    my @pids = ();
+    my $i;
+    my $dsn = get_dsn($server);
+
+    # Start clients
+    for ($i = 1; $i <= $client_num; $i++)
+    {
+	my $pid = fork();
+	if ( defined ($pid) )
+	{
+	    if ( $pid )
+	    {
+		# Store pid of client
+		push (@pids, $pid)
+	    }
+	    else
+	    {
+		# Run the client
+		my $client_path= File::Spec->catfile(get_suites_dir(), "stress", "basic", "$client_script.pl");
+		exec($client_path . " $dsn $i $client_num $qfile") 
+		    or die("Cannot exec $client_path $dsn $i $client_num $qfile");
+	    }
+	}
+	else
+	{
+	    die("Cannot fork process for client $i");
+	}
+    }
+    
+    # Wait until all clients are finished
+    foreach (@pids)
+    {
+	waitpid($_, 0);
+    }
+    
+    # Check results
+    my $res_num= sql_result($server, "SELECT COUNT(*) FROM nuts.client_failures");    
+    if (!ok ($res_num == 0, "Number of failures generated by clients: $res_num"))
+    {
+	diag(sql_results($server, "SELECT client_id, client_text FROM nuts.client_failures ORDER BY id"));	
+    }
+}
+
+sub shutdown
+{
+    return;
+}
+
+1;
+__END__;
+
+=head1 NAME
+
+stress::basic_stress - General stress test for MySQL server
+
+=head1 PURPOSE
+
+The purpose is testing of a given SQL statement in stress environmet 
+as part of regular statements.
+
+=head1 SYNOPSYS
+
+Main test (basic_stress )prepares list of regular queries from 
+DataSource, stores them into a dump file, start several clients 
+(the number depends by current combination) and connect clients to 
+MySQL server. 
+
+The test creates two tables:
+
+nuts.run_clients - a client puts a row with its id when it is ready
+nuts.client_failures - a client puts rows if a failure happend
+
+The client command line contains the list of following options:
+dsn	- DSN to MySQL server
+id 	- id of this client (it will be inserted into nuts.run_clients by a client)
+num	- total number of clients (the client reqiures to know that)
+path	- path to DataSource dump
+
+
+Each client starts, connects to DB, inserts its ID into nuts.run_clients 
+and waits until numbers of rows of nuts.run_clients will be equal 
+total number of running clients.
+Then each client executes statements from dump and randomly adds test queries.
+Client analyzes the results of execution of test queries and insert 
+information into nuts.client_failures about the failure.
+
+The test case waits until all clients are finished. Then check 
+nuts.client_failures and print its contents if the table is not
+empty.
+
+=head1 HOW TO TEST A NEW SQL STATEMENT?
+
+=over
+
+=item Create own client based on create_table_select.pl in directory 'suites/stress/basic' 
+
+=item Add name of client to stress::basic_stress, array @client_scripts
+
+=back
+
+==head1 REFERENCES
+
+=over
+
+=item * WL#5576
+
+=back
+
+=head1 AUTHOR
+
+Serge Kozlov S<< <Serge.Kozlov@stripped> >>
+
+
+=head1 COPYRIGHT
+
+Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+=cut


Attachment: [text/bzr-bundle] bzr/serge.kozlov@oracle.com-20110218210739-r0495yve0nxaw8sf.bundle
Thread
bzr push into nuts branch (Serge.Kozlov:390 to 391) WL#5576Serge Kozlov18 Feb