source: gs2-extensions/parallel-building/trunk/src/bin/script/batch-testing.pl@ 24695

Last change on this file since 24695 was 24695, checked in by jmt12, 13 years ago

Script to run a battery of tests and record the results in a database

  • Property svn:executable set to *
File size: 8.9 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4
5use POSIX qw(strftime);
6
7BEGIN
8{
9 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
10}
11
12print STDOUT "===== Batch Testing =====\n";
13print STDOUT "Runs a multitude of tests against a 'lorem' collection and making\n";
14print STDOUT "use of parallel importing.\n\n";
15
16# 0. Configuration
17#my $infodb_type = 'GDBM';
18#my $infodb_type = 'GDBMServer';
19#my $infodb_type = 'SQLite';
20my $infodb_type = 'TDB';
21my @sizes = (100);
22#my @sizes = (100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000);
23my @threads = (1);
24my @batchsize = (100);
25my $test_iterations = 1;
26#my $test_iterations = 9;
27
28# 1. Initialization
29my $machine_name = `hostname -s`;
30chomp($machine_name);
31$machine_name = ucfirst($machine_name);
32my $os_name = `lsb_release -i`;
33$os_name =~ s/^Distributor ID:\s+(.*)\r?\n$/$1/i;
34my $fs_name = `df -T $ENV{'GSDLHOME'}`;
35$fs_name =~ s/^.*(ext2|ext3|ext4|xfs|zfs).*$/$1/is;
36$fs_name = uc($fs_name);
37my $sizes_str = 'd' . $sizes[0];
38if (scalar(@sizes) > 1)
39{
40 $sizes_str .= '-' . $sizes[(scalar(@sizes) - 1)];
41}
42my $threads_str = 't' . $threads[0];
43if (scalar(@threads) > 1)
44{
45 $threads_str .= '-' . $threads[(scalar(@threads) - 1)];
46}
47my $batch_str = 'b' . $batchsize[0];
48if (scalar(@batchsize) > 1)
49{
50 $batch_str .= '-' . $batchsize[(scalar(@batchsize) - 1)];
51}
52my $db_name = $machine_name . '_' . $os_name . '_' . $fs_name . '_' . $infodb_type . '_' . $sizes_str . '_' . $threads_str . '_' . $batch_str . '_i' . $test_iterations . '.db';
53my $db_path = $ENV{'GSDLHOME'} . '/collect/' . $db_name;
54
55# 2. If we haven't already, initialize the database by creating the tables and
56# populating the pending tests queue
57my $init_database = 0;
58
59if (!-f $db_path)
60{
61 $init_database = 1;
62}
63elsif('0' eq getValueSQL($db_path, 'SELECT COUNT(*) FROM tests'))
64{
65 $init_database = 1;
66}
67
68if ($init_database > 0)
69{
70 print STDOUT " * Creating database tables\n";
71 # create tests table
72 execSQL($db_path, 'CREATE TABLE IF NOT EXISTS tests (walltime INTEGER DEFAULT 0, collection TEXT, type TEXT, testrun INTEGER, realtime REAL DEFAULT 0, systime REAL DEFAULT 0, usertime REAL DEFAULT 0, PRIMARY KEY (collection, type, testrun))');
73 execSQL($db_path, 'CREATE TABLE IF NOT EXISTS testoutput (walltime INTEGER DEFAULT 0, collection TEXT, type TEXT, testrun INTEGER, output TEXT, PRIMARY KEY (collection, type, testrun))');
74
75 # populate with anticpated tests
76 print STDOUT " * Populating tests table\n";
77 foreach my $size (@sizes)
78 {
79 my $collection = lc($infodb_type) . sprintf("%07d", $size);
80 print STDOUT ' - generating tests for collection=' . $collection . "\n";
81 my $a_test_iterations = $test_iterations;
82 for (my $test_run = 1; $test_run <= $a_test_iterations; $test_run++)
83 {
84 my $sql = "INSERT INTO tests (collection, type, testrun) VALUES ('" . $collection . "','rm'," . $test_run . ")";
85 print STDERR ' - sql: ' . $sql . "\n";
86 execSQL($db_path, $sql);
87 $sql = "INSERT INTO tests (collection, type, testrun) VALUES ('" . $collection . "','import'," . $test_run . ")";
88 print STDERR ' - sql: ' . $sql . "\n";
89 execSQL($db_path, $sql);
90 $sql = "INSERT INTO testoutput (collection, type, testrun) VALUES ('" . $collection . "','rm'," . $test_run . ")";
91 print STDERR ' - sql: ' . $sql . "\n";
92 execSQL($db_path, $sql);
93 $sql = "INSERT INTO testoutput (collection, type, testrun) VALUES ('" . $collection . "','import'," . $test_run . ")";
94 print STDERR ' - sql: ' . $sql . "\n";
95 execSQL($db_path, $sql);
96 }
97 }
98}
99
100# 3. While there are still pending tests in the queue
101my $total_count = getValueSQL($db_path, 'SELECT COUNT(*) FROM tests');
102my $test_count = getValueSQL($db_path, 'SELECT COUNT(*) FROM tests WHERE realtime=0');
103my $exit_file_path = $ENV{'GSDLHOME'} . '/collect/exit.now';
104while ($test_count ne "0" && !-f $exit_file_path)
105{
106 my $x = $total_count - $test_count;
107 my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
108 print STDERR ' * [' . $now_string . '] Progress: ' . sprintf("%.0f",(($x/$total_count)*100)) . '% complete! [' . $test_count . " tests remaining]\n";
109 my $cmd;
110 my $result;
111 my $rtime; my $utime; my $stime;
112 # 4. Pick a random test (thread count and epoch) and run and time it
113 my ($counter, $collection, $test_run) = getRecordSQL($db_path, 'SELECT _rowid_, collection, testrun FROM tests WHERE realtime=0 ORDER BY RANDOM() LIMIT 1');
114 print STDOUT ' - running test import for collection=' . $collection . ', and test_run=' . $test_run . "\n";
115
116 # Command one: run rm_archives.pl and record information in database
117 $cmd = 'time -p rm_archives.pl ' . $collection . ' 2>&1';
118 print STDOUT ' - command: ' . $cmd . "\n";
119 $result = `$cmd`;
120 $rtime = 0;
121 if ($result =~ /real\s+(\d+\.\d+)/)
122 {
123 $rtime = $1;
124 }
125 $utime = 0;
126 if ($result =~ /user\s+(\d+\.\d+)/)
127 {
128 $utime = $1;
129 }
130 $stime = 0;
131 if ($result =~ /sys\s+(\d+\.\d+)/)
132 {
133 $stime = $1;
134 }
135 $result =~ s/'//g;
136 my $walltime = time();
137 execSQL($db_path, 'UPDATE tests SET walltime=' . $walltime . ', realtime=' . $rtime . ', usertime=' . $utime . ', systime=' . $stime . ' WHERE collection=\'' . $collection . '\' AND type=\'rm\' AND testrun=' . $test_run);
138 execSQL($db_path, 'UPDATE testoutput SET walltime=' . $walltime . ', output=\'' . $result . '\' WHERE collection=\'' . $collection . '\' AND type=\'rm\' AND testrun=' . $test_run);
139
140 # Have a sleep to try and prevent any headaches caused by 'rm' influencing
141 # later processes
142 #sleep(5);
143
144 # Command two: use sudoedit and other black magic to clear out the memory-
145 # based disk cache (which is done by writing the number 3 to a certain
146 # system file)
147 print STDOUT " - Synching file system... ";
148 `sync`;
149 print STDOUT "Done!\n";
150 print STDOUT " - Dropping memory disk cache... ";
151 # - save our current default editor
152 my $current_editor = $ENV{'EDITOR'};
153 # - replace default editor with a script that simply clobbers the contents
154 # of any file it's handed with the number "3"
155 $ENV{'EDITOR'} = 'reset_memcache_editor.sh';
156 # - we now call sudoedit on the system file. How sudoedit works is that it
157 # starts by making a temp copy of the system file with appropriate
158 # permissions allowing the user to edit. It then passes the path to the
159 # temp file to the default editor - typically this would be an interactive
160 # editor like 'vi'. However, we've just replaced the editor with a custom
161 # script that just writes '3' as the content of the tmp file. Finally, when
162 # the editor exits, sudoedit copies the tmp file over the top of the system
163 # file, restoring appropriate root-level permissions
164 `sudoedit /proc/sys/vm/drop_caches`;
165 # - restore the default editor, just in case something in Greenstone
166 # depends on this being a reasonably value
167 $ENV{'EDITOR'} = $current_editor;
168 print STDOUT "Done!\n";
169
170 # Command three: run import.pl and record information in database
171 $cmd = 'time -p import.pl -removeold -verbosity 0 ' . $collection . ' 2>&1';
172 print STDOUT ' - command: ' . $cmd . "\n";
173 $result = `$cmd`;
174 $rtime = 0;
175 if ($result =~ /real\s+(\d+\.\d+)/)
176 {
177 $rtime = $1;
178 }
179 $utime = 0;
180 if ($result =~ /user\s+(\d+\.\d+)/)
181 {
182 $utime = $1;
183 }
184 $stime = 0;
185 if ($result =~ /sys\s+(\d+\.\d+)/)
186 {
187 $stime = $1;
188 }
189 $result =~ s/'//g;
190 $walltime = time();
191 execSQL($db_path, 'UPDATE tests SET walltime=' . $walltime . ', realtime=' . $rtime . ', usertime=' . $utime . ', systime=' . $stime . ' WHERE collection=\'' . $collection . '\' AND type=\'import\' AND testrun=' . $test_run);
192 execSQL($db_path, 'UPDATE testoutput SET walltime=' . $walltime . ', output=\'' . $result . '\' WHERE collection=\'' . $collection . '\' AND type=\'import\' AND testrun=' . $test_run);
193
194 # Repeat until we have exhausted pending tests
195 $test_count = getValueSQL($db_path, 'SELECT COUNT(*) FROM tests WHERE realtime=0');
196}
197
198# Remove any exit file
199if (-f $exit_file_path)
200{
201 print STDOUT " - Removing exit file... ";
202 unlink($exit_file_path);
203 print STDOUT "Done!\n";
204}
205
206
207print STDOUT "Complete!\n\n";
208
209exit;
210
211sub execSQL
212{
213 my ($db_path, $sql) = @_;
214 # call getValueSQL but don't care about result
215 getValueSQL($db_path, $sql);
216}
217# /** execSQL() **/
218
219sub getRecordSQL
220{
221 my ($db_path, $sql) = @_;
222 if ($sql !~ /LIMIT 1/i)
223 {
224 $sql .= ' LIMIT 1';
225 }
226 my $value = getValueSQL($db_path, $sql);
227 return split(/\|/,$value);
228}
229# /** getRecordSQL() **/
230
231sub getValueSQL
232{
233 my ($db_path, $sql) = @_;
234 my $result = `sqlite3 "$db_path" "$sql" 2>&1`;
235 if ($result =~ /Error:/)
236 {
237 die($result);
238 }
239 # trim
240 $result =~ s/^\s*|\s*$//g;
241 return $result;
242}
243# /** getValueSQL() **/
244
245sub printUsage
246{
247 my ($msg) = @_;
248 # flush STDOUT
249 select((select(STDOUT), $|=1)[0]);
250 print STDOUT '';
251 select((select(STDOUT), $|=0)[0]);
252 # output any error message
253 if (defined $msg)
254 {
255 print STDERR 'Error! ' . $msg . "\n";
256 }
257 # and finally the usage
258 print STDERR "Usage: mpitesting.pl <path to database> <number docs> <worker threads>\n";
259 print STDERR "\n";
260 exit;
261}
262
2631;
Note: See TracBrowser for help on using the repository browser.