Created
August 8, 2022 12:39
-
-
Save Digital-Daz/1754aa73c5f8c3c3dfce1b680012bf4b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
######################################################### | |
# multitest, by Marcus Sorensen, BetterServers Inc # | |
# Licensed under the Open Software License version 3.0 # | |
# http://opensource.org/licenses/OSL-3.0 # | |
######################################################### | |
use strict; | |
$| = 1; | |
my $colors = { red => "\e[1;31m", def => "\e[0m", green => "\e[1;32m", cyan => "\e[1;36m" }; | |
my $restbetweentests = 15; | |
unless ( `which fio 2>/dev/null`) { | |
print "No executable 'fio' found in path, exiting\n"; | |
exit; | |
} | |
print <<EOF; | |
$colors->{red} | |
Multiple IO Tester$colors->{def} | |
This application emulates a busy server in several states by launching multiple | |
threads that do various types of IO. This allows us to see what the consequences | |
are of running in a multitasking environment. This test uses direct IO and | |
invalidates caches between tests, testing the disk, not the memory. | |
$colors->{red}NOTE:$colors->{def} You need at least 3GB of free space in your current working directory. | |
The following tests currently consist of: | |
8 sequential readers | |
8 sequential writers | |
8 mixed seqential readers/writers (random choice per IO) | |
8 random readers | |
8 random writers | |
8 mixed random readers/writers (random choice per IO) | |
Feel free to modify the script to meet your needs. Enjoy! | |
The test should take less than 2 minutes. Press <ENTER> to begin... | |
EOF | |
<STDIN>; | |
my $tests = { 'read' => { 'order' => 1, | |
'block' => '1024k', | |
'output' => { 'multiiotester'=>'4', '2'=>'5', '3'=>'6' }, | |
'name' => 'sequential read' }, | |
'write' => { 'order' => 2, | |
'block' => '1024k', | |
'output' => { 'multiiotester'=>'20', '2'=>'25', '3'=>'47' }, | |
'name' => 'sequential write' }, | |
'rw' => { 'order' => 3, | |
'block' => '1024k', | |
'output' => { 'multiiotester'=>'4,20', '2'=>'5,25', '3'=>'6,47' }, | |
'name' => 'seq read/seq write' }, | |
'randread' => { 'order' => 4, | |
'block' => '4k', | |
'output' => { 'multiiotester'=>'4', '2'=>'5', '3'=>'6' }, | |
'name' => 'random read' }, | |
'randwrite' => { 'order' => 5, | |
'block' => '4k', | |
'output' => { 'multiiotester'=>'20', '2'=>'25', '3'=>'47' }, | |
'name' => 'random write' } , | |
'randrw' => { 'order' => 6, | |
'block' => '4k', | |
'output' => { 'multiiotester'=>'4,20', '2'=>'5,25', '3'=>'6,47' }, | |
'name' => 'rand read/rand write' } | |
}; | |
#mkdir('./multiiotester') or die "unable to create test directory: $^E"; | |
mkdir('./multiiotester') if ! -d './multiiotester'; | |
chdir('./multiiotester') or die "unable to chdir to test directory: $^E"; | |
foreach my $t ( sort{$tests->{$a}->{order} cmp $tests->{$b}->{order}} keys %{$tests} ) { | |
print "$colors->{cyan} running IO \"$tests->{$t}->{name}\" test... $colors->{def}\n"; | |
my $cmd = "fio --direct=1 --invalidate=1 --ioengine=libaio --iodepth=8 --thread --time_based --runtime=10 --rw=$t --bs=$tests->{$t}->{block} --size=300M --numjobs=8 --name=multiiotester --minimal | grep ';'"; | |
my @output = `$cmd`; | |
$output[0] =~ /^(.*?);/; | |
my $version = $1; | |
my $data; | |
foreach my $d (@output){ | |
next unless $d =~ /;/; | |
my $field = $tests->{$t}->{output}->{$version}; | |
my @items = split(";",$d); | |
if ($field =~ /(\d+),(\d+)/) { | |
$data .= "$items[$1];$items[$2]\n"; | |
} else { | |
$data .= "$items[$field]\n"; | |
} | |
} | |
my @results = split(/;/,combinejobs($data)); | |
my @iops = map { toiops($_,$tests->{$t}->{block}) } @results; | |
@results = map { convert($_) } @results; | |
if( $t =~ /^rand/ ) { | |
print "\tresult is $colors->{green}" . join("/", @results) . "$colors->{def} per second\n"; | |
print "\tequals $colors->{green}" . join("$colors->{def}/$colors->{green}", @iops) . "$colors->{def} IOs per second\n\n"; | |
} | |
else { | |
print "\tresult is $colors->{green}" . join("$colors->{def}/$colors->{green}", @results) . "$colors->{def} per second\n\n"; | |
} | |
sleep $restbetweentests; | |
} | |
#print "cleaning up files..\n"; | |
#unlink glob "multiiotester*"; | |
#chdir(".."); | |
#rmdir("multiiotester") or print "unable to delete directory 'multiiotester'\n"; | |
########################### | |
####### subroutines ####### | |
########################### | |
sub convert { | |
my $val = shift; | |
my @units = ('KB','MB','GB'); | |
my $i = 0; | |
$val =~ /^\d+/; | |
while (length($&) > 3 ) { | |
$val = sprintf("%.2f",$val / 1024); | |
$i++; | |
$val =~ /^\d+/; | |
} | |
return $val . $units[$i]; | |
} | |
sub toiops { | |
my $val = shift; | |
my $blocksize = shift; | |
$blocksize =~ s/k//; | |
my $io = sprintf("%.1f",$val/$blocksize); | |
return $io; | |
} | |
sub combinejobs { | |
my $input = shift; | |
my @lines = split(/\n/,$input); | |
my @output = (); | |
foreach my $l (0..$#lines) { | |
my @temp = split(/;/,$lines[$l]); | |
foreach my $t (0..$#temp){ | |
$output[$t] += $temp[$t]; | |
} | |
} | |
return join(";",@output); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment