Commit 6efe6012 authored by unknown's avatar unknown
Browse files

ndb - prelim perl scripts to autotest


BitKeeper/deleted/.del-ndb_range_bounds.pl~ff7e47a35fb44c74:
  Delete: mysql-test/ndb/ndb_range_bounds.pl
parent 4a231e40
Loading
Loading
Loading
Loading
+0 −138
Original line number Diff line number Diff line
#
# test range scan bounds
# output to mysql-test/t/ndb_range_bounds.test
#
# give option --all to generate all cases
#

use strict;
use integer;
use Getopt::Long;

my $opt_all = 0;
my $opt_cnt = 5;
GetOptions("all" => \$opt_all, "cnt=i" => \$opt_cnt)
  or die "options are:  --all --cnt=N";

my $table = 't';

print <<EOF;
--source include/have_ndb.inc

--disable_warnings
drop table if exists $table;
--enable_warnings

# test range scan bounds
# generated by mysql-test/ndb/ndb_range_bounds.pl
# all selects must return 0

EOF

sub cut ($$@) {
  my($op, $key, @v) = @_;
  $op = '==' if $op eq '=';
  my(@w);
  eval "\@w = grep(\$_ $op $key, \@v)";
  $@ and die $@;
  return @w;
}

sub mkdummy (\@) {
  my ($val) = @_;
  return {
    'dummy' => 1,
    'exp' => '9 = 9',
    'cnt' => scalar @$val,
  };
}

sub mkone ($$$\@) {
  my($col, $op, $key, $val) = @_;
  my $cnt = scalar cut($op, $key, @$val);
  return {
    'exp' => "$col $op $key",
    'cnt' => $cnt,
  };
}

sub mktwo ($$$$$\@) {
  my($col, $op1, $key1, $op2, $key2, $val) = @_;
  my $cnt = scalar cut($op2, $key2, cut($op1, $key1, @$val));
  return {
    'exp' => "$col $op1 $key1 and $col $op2 $key2",
    'cnt' => $cnt,
  };
}

sub mkall ($$$\@) {
  my($col, $key1, $key2, $val) = @_;
  my @a = ();
  my $p = mkdummy(@$val);
  push(@a, $p) if $opt_all;
  my @ops = qw(< <= = >= >);
  for my $op (@ops) {
    my $p = mkone($col, $op, $key1, @$val);
    push(@a, $p) if $opt_all || $p->{cnt} != 0;
  }
  my @ops1 = $opt_all ? @ops : qw(= >= >);
  my @ops2 = $opt_all ? @ops : qw(<= <);
  for my $op1 (@ops1) {
    for my $op2 (@ops2) {
      my $p = mktwo($col, $op1, $key1, $op2, $key2, @$val);
      push(@a, $p) if $opt_all || $p->{cnt} != 0;
    }
  }
  return \@a;
}

for my $nn ("bcd", "") {
  my %nn;
  for my $x (qw(b c d)) {
    $nn{$x} = $nn =~ /$x/ ? "not null" : "null";
  }
  print <<EOF;
create table $table (
  a int primary key,
  b int $nn{b},
  c int $nn{c},
  d int $nn{d},
  index (b, c, d)
) engine=ndb;
EOF
  my @val = (0..($opt_cnt-1));
  my $v0 = 0;
  for my $v1 (@val) {
    for my $v2 (@val) {
      for my $v3 (@val) {
	print "insert into $table values($v0, $v1, $v2, $v3);\n";
	$v0++;
      }
    }
  }
  my $key1 = 1;
  my $key2 = 3;
  my $a1 = mkall('b', $key1, $key2, @val);
  my $a2 = mkall('c', $key1, $key2, @val);
  my $a3 = mkall('d', $key1, $key2, @val);
  for my $p1 (@$a1) {
    my $cnt1 = $p1->{cnt} * @val * @val;
    print "select count(*) - $cnt1 from $table";
    print " where $p1->{exp};\n";
    for my $p2 (@$a2) {
      my $cnt2 = $p1->{cnt} * $p2->{cnt} * @val;
      print "select count(*) - $cnt2 from $table";
      print " where $p1->{exp} and $p2->{exp};\n";
      for my $p3 (@$a3) {
	my $cnt3 = $p1->{cnt} * $p2->{cnt} * $p3->{cnt};
	print "select count(*) - $cnt3 from $table";
	print " where $p1->{exp} and $p2->{exp} and $p3->{exp};\n";
      }
    }
  }
  print <<EOF;
drop table $table;
EOF
}

# vim: set sw=2:
+179 −0
Original line number Diff line number Diff line
use strict;
use IO::Socket;
use DBI;

# mgm info
my $mgmhost = "localhost";
my $mgmport = 38101;

# location of ndb_x_fs
my $datadir = "c2";
my @schemafiles = <$datadir/ndb_*_fs/D[12]/DBDICT/P0.SchemaLog>;
@schemafiles or die "no schemafiles in $datadir";

my $dsn;
$dsn = "dbi:mysql:test:localhost;port=38100";

# this works better for me
my $cnf = $ENV{MYSQL_HOME} . "/var/my.cnf";
$dsn = "dbi:mysql:database=test;host=localhost;mysql_read_default_file=$cnf";

my $dbh;
$dbh = DBI->connect($dsn, 'root', undef, { RaiseError => 0, PrintError => 0 });
$dbh or die $DBI::errstr;

# mgm commands

my $mgm = undef;

sub mgmconnect {
  $mgm = IO::Socket::INET->new(
    Proto => "tcp",
    PeerHost => $mgmhost,
    PeerPort => $mgmport);
  $mgm or die "connect to mgm failed: $!";
  $mgm->autoflush(1);
};

mgmconnect();
warn "connected to mgm $mgmhost $mgmport\n";

my $nodeinfo = {};

sub getnodeinfo {
  $nodeinfo = {};
  $mgm->print("get status\n");
  $mgm->print("\n");
  while (defined($_ = $mgm->getline)) {
    /^node\s+status/ && last;
  }
  while (defined($_ = $mgm->getline)) {
    /^\s*$/ && last;
    /^node\.(\d+)\.(\w+):\s*(\S+)/ && ($nodeinfo->{$1}{$2} = $3);
  }
}

getnodeinfo();

my @dbnode = ();
for my $n (keys %$nodeinfo) {
  my $p = $nodeinfo->{$n};
  ($p->{type} eq 'NDB') && push(@dbnode, $n);
}
@dbnode = sort { $a <=> $b } @dbnode;
@dbnode or die "mgm error, found no db nodes";
warn "db nodes: @dbnode\n";

sub restartnode {
  my($n, $initialstart) = @_;
  warn "restart node $n initialstart=$initialstart\n";
  $mgm->print("restart node\n");
  $mgm->print("node: $n\n");
  $mgm->print("initialstart: $initialstart\n");
  $mgm->print("\n");
  while (1) {
    sleep 5;
    getnodeinfo();
    my $status = $nodeinfo->{$n}{status};
    my $sp = $nodeinfo->{$n}{startphase};
    warn "node $n status: $status sp: $sp\n";
    last if $status eq 'STARTED';
  }
}

sub restartall {
  warn "restart all\n";
  $mgm->print("restart all\n");
  $mgm->print("\n");
  while (1) {
    sleep 5;
    getnodeinfo();
    my $ok = 1;
    for my $n (@dbnode) {
      my $status = $nodeinfo->{$n}{status};
      my $sp = $nodeinfo->{$n}{startphase};
      warn "node $n status: $status sp: $sp\n";
      $ok = 0 if $status ne 'STARTED';
    }
    last if $ok;
  }
}

# the sql stuff

my $maxtab = 300;
my @tab = ();

sub create {
  my($n) = @_;
  my $sql = "create table t$n (a int primary key, b varchar(20), key (b)) engine=ndb";
  warn "create t$n\n";
  $dbh->do($sql) or die "$sql\n$DBI::errstr";
}

sub drop {
  my($n) = @_;
  my $sql = "drop table t$n";
  warn "drop t$n\n";
  $dbh->do($sql) or die "$sql\n$DBI::errstr";
}

sub dropall {
  for my $n (0..($maxtab-1)) {
    my $sql = "drop table if exists t$n";
    $dbh->do($sql) or die "$sql\n$DBI::errstr";
  }
}

sub createdrop {
  my $n = int(rand($maxtab));
  if (! $tab[$n]) {
    create($n);
    $tab[$n] = 1;
  } else {
    drop($n);
    $tab[$n] = 0;
  }
}

sub checkschemafiles {
  system("printSchemaFile -ce @schemafiles");
  $? == 0 or die "schemafiles check failed";
}

sub randomrestart {
  my($k) = @_;
  my $s = int(rand(500));
  if ($s < 2) {
    my $i = $k % scalar(@dbnode);
    my $n = $dbnode[$i];
    my $initialstart = ($s < 1 ? 0 : 1);
    restartnode($n, $initialstart);
    return 1;
  }
  if ($s < 3) {
    restartall();
    return 1;
  }
  return 0;
}

# deterministic
srand(1);

warn "drop any old tables\n";
dropall();

my $loop = 1000000;
for my $k (0..($loop-1)) {
  warn "$k\n";
  createdrop();
  checkschemafiles();
  if (randomrestart($k)) {
    checkschemafiles();
  }
}

$dbh->disconnect or die $DBI::errstr;

# vim: set sw=2:
+218 −0
Original line number Diff line number Diff line
#
# test range scan bounds
# give option --all to test all cases
# set MYSQL_HOME to installation top
#

use strict;
use integer;
use Getopt::Long;
use DBI;

my $opt_all = 0;
my $opt_cnt = 5;
my $opt_verbose = 0;
GetOptions("all" => \$opt_all, "cnt=i" => \$opt_cnt, "verbose" => \$opt_verbose)
  or die "options are:  --all --cnt=N --verbose";

my $mysql_home = $ENV{MYSQL_HOME};
defined($mysql_home) or die "no MYSQL_HOME";
my $dsn = "dbi:mysql:database=test;host=localhost;mysql_read_default_file=$mysql_home/var/my.cnf";
my $opts = { RaiseError => 0, PrintError => 0, AutoCommit => 1, };

my $dbh;
my $sth;
my $sql;

$dbh = DBI->connect($dsn, "root", undef, $opts) or die $DBI::errstr;

my $table = 't';

$sql = "drop table if exists $table";
$dbh->do($sql) or die $DBI::errstr;

sub cut ($$$) {
  my($op, $key, $val) = @_;
  $op = '==' if $op eq '=';
  my(@w) = @$val;
  eval "\@w = grep(\$_ $op $key, \@w)";
  $@ and die $@;
  return [ @w ];
}

sub mkdummy ($) {
  my ($val) = @_;
  return {
    'dummy' => 1,
    'exp' => '9 = 9',
    'res' => $val,
  };
}

sub mkone ($$$$) {
  my($col, $op, $key, $val) = @_;
  my $res = cut($op, $key, $val);
  return {
    'exp' => "$col $op $key",
    'res' => $res,
  };
}

sub mktwo ($$$$$$) {
  my($col, $op1, $key1, $op2, $key2, $val) = @_;
  my $res = cut($op2, $key2, cut($op1, $key1, $val));
  return {
    'exp' => "$col $op1 $key1 and $col $op2 $key2",
    'res' => $res,
  };
}

sub mkall ($$$$) {
  my($col, $key1, $key2, $val) = @_;
  my @a = ();
  my $p = mkdummy($val);
  push(@a, $p) if $opt_all;
  my @ops = qw(< <= = >= >);
  for my $op (@ops) {
    my $p = mkone($col, $op, $key1, $val);
    push(@a, $p) if $opt_all || @{$p->{res}} != 0;
  }
  my @ops1 = $opt_all ? @ops : qw(= >= >);
  my @ops2 = $opt_all ? @ops : qw(<= <);
  for my $op1 (@ops1) {
    for my $op2 (@ops2) {
      my $p = mktwo($col, $op1, $key1, $op2, $key2, $val);
      push(@a, $p) if $opt_all || @{$p->{res}} != 0;
    }
  }
  warn scalar(@a)." cases\n" if $opt_verbose;
  return \@a;
}

my $casecnt = 0;

sub verify ($$$) {
  my($sql, $ord, $res) = @_;
  warn "$sql\n" if $opt_verbose;
  $sth = $dbh->prepare($sql) or die "prepare: $sql: $DBI::errstr";
  $sth->execute() or die "execute: $sql: $DBI::errstr";
  #
  # BUG: execute can return success on error so check again
  #
  $sth->err and die "execute: $sql: $DBI::errstr";
  my @out = ();
  for my $b (@{$res->[0]}) {
    for my $c (@{$res->[1]}) {
      for my $d (@{$res->[2]}) {
	push(@out, [$b, $c, $d]);
      }
    }
  }
  if ($ord) {
    @out = sort {
      $ord * ($a->[0] - $b->[0]) ||
      $ord * ($a->[1] - $b->[1]) ||
      $ord * ($a->[2] - $b->[2]) ||
      0
    } @out;
  }
  my $cnt = scalar @out;
  my $n = 0;
  while (1) {
    my $row = $sth->fetchrow_arrayref;
    $row || last;
    @$row == 3 or die "bad row: $sql:  @$row";
    for my $v (@$row) {
      $v =~ s/^\s+|\s+$//g;
      $v =~ /^\d+$/ or die "bad value: $sql:  $v";
    }
    if ($ord) {
      my $out = $out[$n];
      $row->[0] == $out->[0] &&
      $row->[1] == $out->[1] &&
      $row->[2] == $out->[2] or
        die "$sql: row $n: got row @$row != @$out";
    }
    $n++;
  }
  $sth->err and die "fetch: $sql: $DBI::errstr";
  $n == $cnt or die "verify: $sql: got row count $n != $cnt";
  $casecnt++;
}

for my $nn ("bcd", "") {
  my %nn;
  for my $x (qw(b c d)) {
    $nn{$x} = $nn =~ /$x/ ? "not null" : "null";
  }
  warn "create table\n";
  $sql = <<EOF;
create table $table (
  a int primary key,
  b int $nn{b},
  c int $nn{c},
  d int $nn{d},
  index (b, c, d)
) engine=ndb
EOF
  $dbh->do($sql) or die $DBI::errstr;
  warn "insert\n";
  $sql = "insert into $table values(?, ?, ?, ?)";
  $sth = $dbh->prepare($sql) or die $DBI::errstr;
  my @val = (0..($opt_cnt-1));
  my $v0 = 0;
  for my $v1 (@val) {
    for my $v2 (@val) {
      for my $v3 (@val) {
	$sth->bind_param(1, $v0) or die $DBI::errstr;
	$sth->bind_param(2, $v1) or die $DBI::errstr;
	$sth->bind_param(3, $v2) or die $DBI::errstr;
	$sth->bind_param(4, $v3) or die $DBI::errstr;
	$sth->execute or die $DBI::errstr;
	$v0++;
      }
    }
  }
  warn "generate cases\n";
  my $key1 = 1;
  my $key2 = 3;
  my $a1 = mkall('b', $key1, $key2, \@val);
  my $a2 = mkall('c', $key1, $key2, \@val);
  my $a3 = mkall('d', $key1, $key2, \@val);
  warn "select\n";
  for my $ord (0, +1, -1) {
    my $orderby =
      $ord == 0 ? "" :
      $ord == +1 ? " order by b, c, d" :
      $ord == -1 ? " order by b desc, c desc, d desc" : die "not here";
    for my $p1 (@$a1) {
      my $res = [ $p1->{res}, \@val, \@val ];
      $sql = "select b, c, d from $table" .
	     " where $p1->{exp}" .
	     $orderby;
      verify($sql, $ord, $res);
      for my $p2 (@$a2) {
	my $res = [ $p1->{res}, $p2->{res}, \@val ];
	$sql = "select b, c, d from $table" .
	       " where $p1->{exp} and $p2->{exp}" .
	       $orderby;
	verify($sql, $ord, $res);
	for my $p3 (@$a3) {
	  my $res = [ $p1->{res}, $p2->{res}, $p3->{res} ];
	  $sql = "select b, c, d from $table" .
		 " where $p1->{exp} and $p2->{exp} and $p3->{exp}" .
		 $orderby;
	  verify($sql, $ord, $res);
	}
      }
    }
  }
  warn "drop table\n";
  $sql = "drop table $table";
  $dbh->do($sql) or die $DBI::errstr;
}

warn "verified $casecnt cases\n";
warn "done\n";

# vim: set sw=2: