1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use DB::HandlerSocket::Pool;
6use DBI;
7
8my %conf = ();
9for my $i (@ARGV) {
10	my ($k, $v) = split(/=/, $i);
11	$conf{$k} = $v;
12}
13
14my $verbose = get_conf("verbose", 0);
15my $actions_str = get_conf("actions",
16	"create,insert,verify,verify2,verify3,verify4,clean");
17my $tablesize = get_conf("tablesize", 1000);
18my $db = get_conf("db", "hstestdb");
19my $table = get_conf("table", "testtbl");
20my $table_schema = get_conf("table_schema", undef);
21my $engine = get_conf("engine", "innodb");
22my $host = get_conf("host", "localhost");
23my $mysqlport = get_conf("mysqlport", 3306);
24my $hsport_rd = get_conf("hsport_rd", 9998);
25my $hsport_wr = get_conf("hsport_wr", 9999);
26my $loop = get_conf("loop", 10000);
27my $op = get_conf("op", "=");
28my $ssps = get_conf("ssps", 0);
29my $num_moreflds = get_conf("moreflds", 0);
30my $moreflds_prefix = get_conf("moreflds_prefix", "f");
31my $mysql_user = 'root';
32my $mysql_password = '';
33
34my $dsn = "DBI:mysql:database=;host=$host;port=$mysqlport"
35        . ";mysql_server_prepare=$ssps";
36my $dbh = DBI->connect($dsn, $mysql_user, $mysql_password,
37	{ RaiseError => 1 });
38my $hsargs = { 'host' => $host, 'port' => $hsport_rd };
39my $hspool = new DB::HandlerSocket::Pool({
40	hostmap => {
41		"$db.$table" => {
42			host => $host,
43			port => $hsport_rd,
44		},
45	},
46	resolve => undef,
47	error => undef,
48});
49$table_schema = "(k int primary key, fc30 varchar(30), ft text)"
50	if (!defined($table_schema));
51
52my @actions = split(/,/, $actions_str);
53for my $action (@actions) {
54	print "ACTION: $action\n";
55	eval "hstest_$action()";
56	if ($@) {
57		die $@;
58	}
59	print "ACTION: $action DONE\n";
60}
61
62sub get_conf {
63	my ($key, $def) = @_;
64	my $val = $conf{$key};
65	if ($val) {
66		print "$key=$val\n";
67	} else {
68		$val = $def;
69		my $defstr = $def || "(undef)";
70		print "$key=$defstr(default)\n";
71	}
72	return $val;
73}
74
75sub hstest_create {
76	$dbh->do("drop database if exists $db");
77	$dbh->do("create database $db");
78	$dbh->do("use $db");
79	$dbh->do("create table $table $table_schema engine=$engine");
80}
81
82sub hstest_dump {
83	$dbh->do("use $db");
84	my $sth = $dbh->prepare("select * from $table");
85	$sth->execute();
86	my $arr = $sth->fetchall_arrayref();
87	for my $rec (@$arr) {
88		print "REC:";
89		for my $row (@$rec) {
90			print " $row";
91		}
92		print "\n";
93	}
94}
95
96sub hstest_insert {
97	$dbh->do("use $db");
98	my $sth = $dbh->prepare("insert into $table values (?, ?, ?)");
99	for (my $k = 0; $k < $tablesize; ++$k) {
100		my $fc30 = "fc30_$k";
101		my $ft = "ft_$k";
102		$sth->execute($k, $fc30, $ft);
103	}
104}
105
106sub hstest_verify {
107	$dbh->do("use $db");
108	my $sth = $dbh->prepare("select * from $table order by k");
109	$sth->execute();
110	my $arr = $sth->fetchall_arrayref();
111	my $hsres = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
112		">=", [ 0 ], $tablesize, 0);
113	for (my $i = 0; $i < $tablesize; ++$i) {
114		my $rec = $arr->[$i];
115		my $differ = 0;
116		print "REC:" if $verbose;
117		for (my $j = 0; $j < 3; ++$j) {
118			my $fld = $rec->[$j];
119			my $hsidx = $i * 3 + $j;
120			my $hsfld = $hsres->[$hsidx];
121			if ($hsfld ne $fld) {
122				$differ = 1;
123			}
124			if ($differ) {
125				print " $fld:$hsfld" if $verbose;
126			} else {
127				print " $hsfld" if $verbose;
128			}
129		}
130		print "\n" if $verbose;
131		if ($differ) {
132			die "verification failed";
133		}
134	}
135}
136
137sub hstest_verify2 {
138	$dbh->do("use $db");
139	my $sth = $dbh->prepare("select * from $table order by k");
140	$sth->execute();
141	my $arr = $sth->fetchall_arrayref();
142	my $hsresa = $hspool->index_find_multi($db, $table, "PRIMARY",
143		"k,fc30,ft", [ [ -1, ">=", [ 0 ], $tablesize, 0 ] ]);
144	my $hsres = $hsresa->[0];
145	for (my $i = 0; $i < $tablesize; ++$i) {
146		my $rec = $arr->[$i];
147		my $differ = 0;
148		print "REC:" if $verbose;
149		for (my $j = 0; $j < 3; ++$j) {
150			my $fld = $rec->[$j];
151			my $hsidx = $i * 3 + $j;
152			my $hsfld = $hsres->[$hsidx];
153			if ($hsfld ne $fld) {
154				$differ = 1;
155			}
156			if ($differ) {
157				print " $fld:$hsfld" if $verbose;
158			} else {
159				print " $hsfld" if $verbose;
160			}
161		}
162		print "\n" if $verbose;
163		if ($differ) {
164			die "verification failed";
165		}
166	}
167}
168
169sub hashref_to_str {
170	my $href = $_[0];
171	my $r = '';
172	for my $k (sort keys %$href) {
173		my $v = $href->{$k};
174		$r .= "($k=>$v)";
175	}
176	return $r;
177}
178
179sub hstest_verify3 {
180	$dbh->do("use $db");
181	my $sth = $dbh->prepare("select * from $table order by k");
182	$sth->execute();
183	my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
184			">=", [ 0 ], $tablesize, 0);
185	my $hsres = DB::HandlerSocket::Pool::result_single_to_hasharr(
186		[ 'k', 'fc30', 'ft' ], $hsres_t);
187	for (my $i = 0; $i < $tablesize; ++$i) {
188		my $mystr = hashref_to_str($sth->fetchrow_hashref());
189		my $hsstr = hashref_to_str($hsres->[$i]);
190		if ($mystr ne $hsstr) {
191			print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose;
192			die "verification failed";
193		} else {
194			print "OK $hsstr\n" if $verbose;
195		}
196	}
197}
198
199sub hstest_verify4 {
200	$dbh->do("use $db");
201	my $sth = $dbh->prepare("select * from $table order by k");
202	$sth->execute();
203	my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft",
204			">=", [ 0 ], $tablesize, 0);
205	my $hsres = DB::HandlerSocket::Pool::result_single_to_hashhash(
206		[ 'k', 'fc30', 'ft' ], 'k', $hsres_t);
207	my $rechash = $sth->fetchall_hashref('k');
208	while (my ($k, $href) = each (%$rechash)) {
209		my $mystr = hashref_to_str($href);
210		my $hsstr = hashref_to_str($hsres->{$k});
211		if ($mystr ne $hsstr) {
212			print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose;
213			die "verification failed";
214		} else {
215			print "OK $hsstr\n" if $verbose;
216		}
217	}
218}
219
220sub hstest_clean {
221	$hspool->clear_pool();
222	$dbh->do("drop database if exists $db");
223}
224
225