5
use Getopt::Long qw(:config no_ignore_case );
8
my $DEBUG = $MySQL::Sandbox::DEBUG;
10
for my $prog (qw( make_sandbox
11
make_replication_sandbox
13
make_multiple_custom_sandbox ) ) {
14
unless ( exists_in_path ($prog) ) {
15
die "script <$prog> not found\n";
22
# my @versions = ( '5.0.51', '5.0.64', '5.1.23', '5.1.24', '5.1.25', '5.1.26', '6.0.6' );
23
my @versions = ( '5.0.67', '5.1.30');
24
my $verbose = $DEBUG || $ENV{'VERBOSE'} || 0;
36
my %custom_tests = ();
38
my ($user_tests, $user_versions, $get_help);
42
"tarball|versions=s" => \$user_versions,
43
"tests=s" => \$user_tests,
44
"verbose" => \$verbose,
45
"help|h" => \$get_help,
51
my @new_versions = grep {$_} split /,/, $user_versions;
52
die "at least one version is required\n" unless @new_versions;
54
# ensuring that each version is used only once.
56
map { $_->[0] } # sorting with the Schwartzian Transform
57
sort { $a->[1] cmp $b->[1] }
58
map { /(\d+)\.(\d+)\.(\d+)/;
59
[ $_, sprintf('%02d-%02d-%02d',$1,$2,$3)] }
60
keys %{{ map { $_, 1} @new_versions }};
61
for my $ver (@new_versions) {
65
for my $ver (@versions) {
66
$ver =~ s/^~/$ENV{HOME}/;
67
unless (( -d "/opt/mysql/$ver")
68
or ( -d "$ENV{HOME}/opt/mysql/$ver")
70
print "version $ver not found in either /opt/mysql or $ENV{HOME}/opt/mysql\n";
71
die "use --versions to list the versions you want to test\n";
76
my @todo = grep {$_} split /,/, $user_tests;
77
die "at least one test is required\n" unless @todo;
80
if (exists $tests{$t} ) {
84
die "unrecognized test <$t>\n";
87
for my $t (keys %tests) {
88
if ( exists $new_tests{$t} ) {
97
my $sandbox_home = "$ENV{'HOME'}/sandboxes";
105
# cleaning up existing sandbox directory
107
if ( $ENV{'SANDBOX_HOME'} ) {
108
$sandbox_home = $ENV{'SANDBOX_HOME'};
111
$ENV{'SANDBOX_HOME'} = $sandbox_home;
113
my $sh_stop_all = "$sandbox_home/stop_all";
115
if ( -x $sh_stop_all ) {
120
# setting the current sandbox directory for this test
122
$sandbox_home = "$ENV{'HOME'}/test_sb";
123
$ENV{'SANDBOX_HOME'} = $sandbox_home;
124
$sh_stop_all = "$sandbox_home/stop_all";
125
my $sh_clear_all = "$sandbox_home/clear_all";
126
my $sh_start_all = "$sandbox_home/start_all";
127
my $sh_use_all = "$sandbox_home/use_all";
130
# cleaning up the test directory if exists
132
if ( -x $sh_stop_all ) {
133
system($sh_stop_all);
134
system qq(rm -rf $sandbox_home) ;
138
# checking if there are other servers running
140
my $how_many_mysqld = get_number_of_processes('mysqld');
141
my $how_many_mysqld_safe = get_number_of_processes('mysqld_safe');
142
printf "** currently there are (%d) mysqld processes and (%d) mysqld_safe processes\n",
144
$how_many_mysqld_safe;
149
for my $ver (@versions) {
150
my $bare_version = get_bare_version ($ver);
151
my $version = $bare_version;
152
$version =~ s/\./_/g;
154
if ($tests{'single'}) {
155
run_single_test($ver, $version, $bare_version);
158
if ($tests{'replication'} ) {
159
run_replication_test($ver, $version, $bare_version);
162
if ($tests{'circular'}) {
163
run_circular_test($ver, $version, $bare_version);
166
if ($tests{'multiple'}) {
167
run_multiple_test($ver, $version, $bare_version);
171
if ($tests{'custom'}) {
176
for my $test (keys %tests) {
177
if ($tests{$test} && ($test ne 'tuning') && ($test ne 'smoke' )) {
187
if ($tests{tuning}) {
192
for my $ver ( @versions ) {
193
if (-f "$sandbox_home/stop_all") {
194
system qq($sandbox_home/stop_all);
195
system qq(rm -rf $sandbox_home/*) ;
197
run_smoke_test($ver);
202
printf "*** Executed %d tests. Passed %d (%5.2f%%). Failed %d (%5.2f%%)\n",
204
$test_results{passed},
205
$test_results{passed} / $test_results{run} * 100,
206
$test_results{failed},
207
$test_results{failed} / $test_results{run} * 100
217
# runs a shell command and returns the output
219
sub get_exec_result {
220
my ($cmd, $verbose) = @_;
221
print "(shell) $cmd\n" if $verbose;
222
my $output = qx($cmd );
224
die ("error executing $cmd ($!)\n");
232
# runs a SQL command and returns the output
235
my ($sb, $query, $verbose) = @_;
236
print "(sql) $query\n" if $verbose;
237
if ( -f "$sb/use" ) {
238
# print qq(<echo "$query" | $sb/use -N -B >\n);
239
my $output = qx(echo "$query" | $sb/use -N -B );
240
if (defined $output) {
246
if ($verbose && $verbose > 1) {
249
die "error executing query $query on sandbox $sb\n" if $?;
253
die "can't find a 'use' command on $sb\n";
259
# get_number_of_processes
261
# returns the number of processes for a given name
263
sub get_number_of_processes {
264
my ($proc_name) = @_;
266
my $grep_cmd = 'ps -ef | grep -w %s | grep -v "grep -w %s" | wc -l ';
267
my $cmd = sprintf($grep_cmd, $proc_name, $proc_name );
268
print "$cmd\n" if ($verbose && ($verbose > 1));
269
my $how_many = get_exec_result($cmd, 0);
276
# displays option for this program
281
test for MySQL Sandbox
283
--versions=version1[,version2,version3]
284
uses specific versions for testing.
285
currently: (@{[join ",", @versions]})
287
--tarball=/path/to/tarball
288
it's an alias for --versions
290
--tests=testname[,testname,testname]
291
executes specific tests.
292
currently: (@{[join ",", grep {$tests{$_}} keys %tests]})
295
shows the commands executed during tests
312
# evaluates a condition and prints a ok/not ok message
315
my ($condition, $msg) = @_;
317
$msg = '***' unless defined $msg;
318
$test_results{run}++;
320
$test_results{passed}++;
324
$test_results{failed}++;
327
if ($verbose) { die "halting the test on verbose\n" unless $condition; }
331
sub run_single_test {
332
my ($ver, $version, $bare_version) = @_;
333
my $single_sandbox = get_exec_result(
334
"make_sandbox $ver --no_confirm",
336
ok( $single_sandbox =~ /sandbox server started/,
337
"single SB ($bare_version) started" );
338
my $sql_result = get_sql_result(
339
"$sandbox_home/msb_$version",
340
'select version(), @@server_id',
342
ok( $sql_result =~ /$bare_version/,
343
"single SB ($bare_version) SQL " );
344
$sql_result = get_sql_result(
345
"$sandbox_home/msb_$version",
346
'create database \`a-a\`', # Bug#278394 - this will fail on 'clear' if not fixed
351
sub run_replication_test {
352
my ($ver, $version, $bare_version) = @_;
353
my $replication_sandbox = get_exec_result(
354
"make_replication_sandbox $ver",
356
ok( $replication_sandbox !~ /not started yet/,
357
"replication sandbox ($bare_version) started");
358
my $sql_result = get_sql_result(
359
"$sandbox_home/rsandbox_$version/master",
360
'select version(), @@server_id',
362
ok( ($sql_result =~ /$bare_version/),
363
"replication SB master ($bare_version) SQL - version" );
364
ok( ($sql_result =~ /\b1\s*$/),
365
"replication SB master ($bare_version) SQL - server_id" );
368
$sql_result = get_sql_result(
369
"$sandbox_home/rsandbox_$version/node1",
370
'select version(), @@server_id',
372
ok( ($sql_result =~ /$bare_version/),
373
"replication SB slave1 ($bare_version) SQL - version" );
374
ok( ($sql_result =~ /\b101\s*$/),
375
"replication SB slave1 ($bare_version) SQL - server_id" );
377
$sql_result = get_sql_result(
378
"$sandbox_home/rsandbox_$version/node2",
379
'select version(), @@server_id',
381
ok( ($sql_result =~ /$bare_version/),
382
"replication SB slave2 ($bare_version) SQL - version" );
383
ok( ($sql_result =~ /\b102\s*$/),
384
"replication SB slave2 ($bare_version) SQL - server_id" );
385
$sql_result = get_sql_result(
386
"$sandbox_home/rsandbox_$version/master",
387
q{drop table if exists test.t1; create table test.t1 (id int); show tables from test},
389
ok( ($sql_result =~ /t1/) ,
390
"replication SB - table created on master" );
392
$sql_result = get_sql_result(
393
"$sandbox_home/rsandbox_$version/node1",
394
q{show tables from test},
396
ok( ($sql_result =~ /t1/),
397
"replication SB - table exists on slave1" );
398
$sql_result = get_sql_result(
399
"$sandbox_home/rsandbox_$version/node2",
400
q{show tables from test},
402
ok( ($sql_result =~ /t1/),
403
"replication SB - table exists on slave2" );
406
sub run_circular_test {
407
my ($ver, $version, $bare_version) = @_;
408
my $replication_sandbox = get_exec_result(
409
"make_replication_sandbox --how_many_slaves=3 --topology=circular $ver",
411
ok( $replication_sandbox !~ /not started yet/,
412
"circular replication sandbox ($bare_version) started");
414
for my $node ( 1 .. 3) {
416
my $sql_result = get_sql_result(
417
"$sandbox_home/rcsandbox_$version/node$node",
418
'show slave status\G',
420
ok( $sql_result =~ /IO_Running.+Yes/ ,
421
"circular replication SB node$node ($bare_version) SQL - IO Running" );
422
ok( $sql_result =~ /SQL_Running.+Yes/ ,
423
"circular replication SB node$node ($bare_version) SQL - SQL Running" );
428
sub run_multiple_test {
429
my ($ver, $version, $bare_version) = @_;
430
my $multiple_sandbox = get_exec_result(
431
"make_multiple_sandbox $ver",
433
ok( $multiple_sandbox !~ /not started yet/,
434
"multiple sandbox ($bare_version) started");
436
for my $node (1 .. 3 ) {
437
my $sql_result = get_sql_result(
438
"$sandbox_home/multi_msb_$version/node$node",
439
'select version(), @@server_id',
441
ok($sql_result =~ /$bare_version/,
442
"multiple SB node $node ($bare_version) SQL - version" );
443
ok( $sql_result =~ /\b10$node\s*$/,
444
"multiple SB node $node ($bare_version) SQL - server_id" );
448
sub run_custom_test {
449
my $custom_sandbox = get_exec_result(
450
"make_multiple_custom_sandbox @versions",
452
ok($custom_sandbox !~ /not started yet/,
453
"custom sandbox ( @{[map {get_bare_version($_)} @versions]} ) started");
455
if ($custom_sandbox =~ /group directory installed on (\S+)/) {
457
ok(-d $custom_dir, 'custom group directory exists')
458
or die "custom group directory not created\n";
461
die "can't find custom group directory\n";
464
for my $ver (@versions) {
465
my $bare_version = get_bare_version($ver);
467
my $sql_result = get_sql_result(
468
"$custom_dir/node$counter",
469
'select version(), @@server_id',
471
ok($sql_result =~ /$bare_version/,
472
"multiple custom SB node $counter ($bare_version) SQL - version" );
473
ok($sql_result =~ /\b10$counter\s*$/,
474
"multiple custom SB node $counter ($bare_version) SQL - server_id" );
478
sub run_summary_tests {
479
my $new_mysqld_procs = get_number_of_processes('mysqld');
480
my $new_mysqld_safe_procs = get_number_of_processes('mysqld_safe');
482
printf "** created (%d) mysqld processes and (%d) mysqld_safe processes\n",
483
$new_mysqld_procs - $how_many_mysqld,
484
$new_mysqld_safe_procs - $how_many_mysqld_safe;
487
( 1 * $tests{single} # single
488
+ 3 * $tests{replication} # replicated
489
+ 3 * $tests{circular} # circular
490
+ 3 * $tests{multiple} # multiple
492
my $expected_processes =
493
$instances * scalar(@versions)
494
+ (scalar(@versions) * $tests{custom}) ; # custom counts only once
496
ok( $expected_processes == ($new_mysqld_safe_procs - $how_many_mysqld_safe),
497
"expected processes ($expected_processes)" );
499
print "** stopping all - please wait\n";
500
my $stop_all = get_exec_result("$sandbox_home/stop_all", $verbose);
502
$new_mysqld_procs = get_number_of_processes('mysqld');
503
$new_mysqld_safe_procs = get_number_of_processes('mysqld_safe');
505
printf "** (%d) mysqld processes and (%d) mysqld_safe processes\n",
506
$new_mysqld_procs - $how_many_mysqld,
507
$new_mysqld_safe_procs - $how_many_mysqld_safe;
508
ok( ($new_mysqld_safe_procs - $how_many_mysqld_safe ) == 0,
509
'expected processes (0)' );
511
print "** starting all - please wait\n";
512
my $start_all = get_exec_result("$sandbox_home/start_all", $verbose);
514
$new_mysqld_procs = get_number_of_processes('mysqld');
515
$new_mysqld_safe_procs = get_number_of_processes('mysqld_safe');
516
printf "** created (%d) mysqld processes and (%d) mysqld_safe processes\n",
517
$new_mysqld_procs - $how_many_mysqld,
518
$new_mysqld_safe_procs - $how_many_mysqld_safe;
520
ok( $expected_processes == ($new_mysqld_safe_procs - $how_many_mysqld_safe),
521
"expected processes ($expected_processes)" );
523
unless ($ENV{PRESERVE_TESTS}) {
524
print "** cleaning up - please wait\n";
525
my $clear_all = get_exec_result("$sandbox_home/clear_all", $verbose);
527
$new_mysqld_procs = get_number_of_processes('mysqld');
528
$new_mysqld_safe_procs = get_number_of_processes('mysqld_safe');
530
printf "** (%d) mysqld processes and (%d) mysqld_safe processes\n",
531
$new_mysqld_procs - $how_many_mysqld,
532
$new_mysqld_safe_procs - $how_many_mysqld_safe;
533
ok( ($new_mysqld_safe_procs - $how_many_mysqld_safe ) == 0,
534
'expected processes (0)' )
535
or die "can't continue without a clean environment\n";
537
system qq(rm -rf $sandbox_home/*) ;
541
sub run_tuning_test {
543
for my $v (@versions) {
545
if ($ver =~ /^[^34]/) {
549
if ($ver =~ /^[34]/) {
550
print "skipping tuning test. It requires version >=5\n";
553
my $bare_version = get_bare_version($ver);
554
my $version = $bare_version;
555
$version =~ s/\./_/g;
557
my $single_sandbox = get_exec_result("make_sandbox $ver --no_confirm -c skip-innodb -c sql_mode=strict_all_tables");
558
my $sql_result = get_sql_result(
559
"$sandbox_home/msb_$version",
562
ok( ($sql_result !~ /innodb\s*yes/i),
563
"single SB with option skip-innodb ($bare_version) SQL " )
564
or print "engines: $sql_result\n";
566
$sql_result = get_sql_result(
567
"$sandbox_home/msb_$version",
568
q(show variables like 'SQL_MODE'),
570
ok( ($sql_result =~ /STRICT_ALL_TABLES/i),
571
"single SB with option sql_mode ($bare_version) SQL " )
572
or print "SQL_MODE: $sql_result\n";
574
$sql_result = get_sql_result(
575
"$sandbox_home/msb_$version",
576
q(create database xyz; show databases like 'xyz'),
578
ok ( $sql_result =~ /xyz/,
579
"single SB ($bare_version) - create database");
580
my $clear_sandbox = get_exec_result("$sandbox_home/msb_$version/clear");
581
ok ($clear_sandbox !~ /error/i, "single SB ($bare_version) - clear result" );
583
# my $sandbox_dirs = get_exec_result("ls -d $sandbox_home/msb_$version/data/*/ | wc -l ");
584
my $sandbox_dirs = how_many_dirs("$sandbox_home/msb_$version/data");
586
ok($sandbox_dirs == 2 , "single SB ($bare_version) - effective clear ");
588
print "** cleaning up - please wait\n";
589
my $clear_all = get_exec_result("$sandbox_home/clear_all", $verbose);
592
sub get_bare_version {
595
if ($ver =~ /(\d+\.\d+\.\d+)/) {
599
die "'$ver' does not contain a valid version\n";
605
if ($ver =~ /^[34]/) {
606
print "skipping tuning test. It requires version >=5\n";
609
my $bare_version = get_bare_version($ver);
610
my $version = $bare_version;
611
$version =~ s/\./_/g;
612
if ($ver =~ m{(.+)/[^/]+(?:tgz|tar\.gz)$}) {
614
if ( -d "$bindir/$bare_version" ) {
615
system "rm -rf $bindir/$bare_version";
619
my $previous_mysqld = get_number_of_processes('mysqld');
620
my $previous_mysqld_safe = get_number_of_processes('mysqld_safe');
622
my $single_sandbox = get_exec_result("make_sandbox $ver --no_confirm");
623
ok( $single_sandbox =~ /sandbox server started/,
624
"single SB ($bare_version) started" );
626
my $first_mysqld = get_number_of_processes('mysqld');
627
my $first_mysqld_safe = get_number_of_processes('mysqld_safe');
629
ok($first_mysqld_safe > $previous_mysqld_safe, 'mysqld_safe started') ;
630
ok($first_mysqld > $previous_mysqld, 'mysqld started') ;
632
my $sql_result = get_sql_result(
633
"$sandbox_home/msb_$version",
634
q{show variables like 'pid_file'},
637
if ($sql_result =~ m{\s*(\S+\.pid)} ) {
640
ok ($pid_file , 'pid_file found')
641
or die "can't find pid file\n";
643
my $pid = get_pid($pid_file)
644
or die "can't get PID from $pid_file\n" ;
645
my $pid_ts1 = get_pid_timestamp($pid_file)
646
or die "can't get timestamp for file $pid_file\n";
648
my $kill_result = get_exec_result("kill -9 $pid");
649
ok (! $kill_result, "mysqld killed");
653
my $second_mysqld = 0;
655
while (! $started ) {
657
if ($counter >= $timeout) {
660
$second_mysqld = get_number_of_processes('mysqld');
661
$started = $second_mysqld >= $first_mysqld;
663
print "-- waiting for mysqld to restart ($counter)\n";
667
my $pid_ts2 = get_pid_timestamp($pid_file);
669
# print "PID_TS ==== $pid_ts1 $pid_ts2\n";
670
while ((!$pid_ts2) or ($pid_ts2 eq $pid_ts1)) {
672
print ">> waiting for mysqld to restart ($counter)\n";
674
$pid_ts2 = get_pid($pid_file);
675
if ($counter > $timeout) {
676
die "error recovering killed process\n";
679
ok ($second_mysqld >= $first_mysqld, "new mysqld process created (1)") ;
680
my $secondpid = get_pid($pid_file)
681
or die "can't get PID from $pid_file\n" ;
684
print "previous pid ($pid) current pid ($secondpid)\n" if $verbose;
685
ok ($secondpid ne $pid, "new mysqld process created (2)");
687
$sql_result = get_sql_result(
688
"$sandbox_home/msb_$version",
692
ok( $sql_result =~ /$bare_version/,
693
"single SB ($bare_version) version (1)" );
695
$sql_result = get_sql_result(
696
"$sandbox_home/msb_$version",
697
q{show variables like 'version'},
699
ok( $sql_result =~ /$bare_version/,
700
"single SB ($bare_version) version (2) " );
702
my $visual_version = $sql_result;
703
chomp $visual_version;
704
$sql_result = get_sql_result(
705
"$sandbox_home/msb_$version",
706
'select @@version_comment limit 1',
708
my $visual_comment = $sql_result;
709
chomp $visual_comment;
711
$sql_result = get_sql_result(
712
"$sandbox_home/msb_$version",
715
# print "HELP: $sql_result\n";
716
ok( $sql_result && (! ( $sql_result =~ /nothing\s*found/i)),
717
"single SB ($bare_version) HELP tables filled " );
719
$sql_result = get_sql_result(
720
"$sandbox_home/msb_$version",
721
q(create database install_test; show databases like 'install_test'),
723
ok ( $sql_result =~ /install_test/,
724
"single SB ($bare_version) - create database");
741
for my $test_engine (@test_engines) {
742
my $major_version = substr($version,0,1);
743
if ($major_version < $test_engine->{min_version} ) {
746
my $engine = $test_engine->{engine};
747
$sql_result = get_sql_result(
748
"$sandbox_home/msb_$version",
749
qq{drop table if exists install_test.testib;
750
create table install_test.testib (
751
id int UNSIGNED NOT NULL AUTO_INCREMENT ,
752
nr int UNSIGNED NOT NULL ,
754
) engine=$engine; show tables from install_test },
756
ok ( $sql_result =~ /testib/,
757
"single SB ($bare_version) - create table");
759
$sql_result = get_sql_result(
760
"$sandbox_home/msb_$version",
761
q{select engine from information_schema.tables
762
where table_schema='install_test'
763
and table_name = 'testib'
766
my $right_engine= ($sql_result and ($sql_result =~ /$engine/i));
770
"single SB ($bare_version) - create table - check engine ($engine)")
771
or print "result:<$sql_result>\n" ;
773
$sql_result = get_sql_result(
774
"$sandbox_home/msb_$version",
775
q{alter table install_test.testib add index nr (nr);
776
insert into install_test.testib(id,nr) values ( '1','1');
777
insert into install_test.testib(id,nr) values ( '2','2');
778
insert into install_test.testib(id,nr) values ( '3','2');
779
select * from install_test.testib where nr=2 order by id asc;},
781
ok ( $sql_result =~ /2\t2\s*3\t2/, 'smoke 1');
784
$sql_result = get_sql_result(
785
"$sandbox_home/msb_$version",
786
q{select * from install_test.testib where nr=2 order by id desc;},
788
ok ( $sql_result =~ /3\t2\s*2\t2/, 'smoke 2');
790
$sql_result = get_sql_result(
791
"$sandbox_home/msb_$version",
792
q{select count(*) from install_test.testib},
794
ok ($sql_result =~ /^3$/, 'rows in table');
796
$sql_result = get_sql_result(
797
"$sandbox_home/msb_$version",
798
q{truncate table install_test.testib; },
800
$sql_result = get_sql_result(
801
"$sandbox_home/msb_$version",
802
q{select count(*) from install_test.testib},
804
ok ($sql_result =~ /^0$/, 'table truncation');
806
$sql_result = get_sql_result(
807
"$sandbox_home/msb_$version",
808
q{ drop table install_test.testib; },
811
$sql_result = get_sql_result(
812
"$sandbox_home/msb_$version",
813
q{select count(*) from information_schema.tables where table_schema='install_test'},
816
ok ($sql_result =~ /^0$/, 'tables in install_test');
818
$sql_result = get_sql_result(
819
"$sandbox_home/msb_$version",
820
q{ drop database install_test;},
822
# my $sandbox_dirs = get_exec_result("ls -d $sandbox_home/msb_$version/data/*/ | wc -l ", $verbose);
823
my $sandbox_dirs = how_many_dirs("$sandbox_home/msb_$version/data");
825
ok($sandbox_dirs == 2 , "single SB ($bare_version) - effective clean up ");
827
print "** cleaning up - please wait\n";
828
my $clear = get_exec_result("$sandbox_home/msb_$version/clear", $verbose);
829
if ($ver =~ m{(.+)/[^/]+(?:tgz|tar\.gz)$}) {
831
if ( -d "$bindir/$bare_version" ) {
832
system "rm -rf $bindir/$bare_version";
833
system "rm -rf $sandbox_home/msb_$version";
837
print "\n[VISUAL IDENTIFICATION]\n";
838
print "\tcheck version: <$visual_version>\n";
839
print "\tcheck comment: <$visual_comment>\n\n";
849
open( $PFILE, q{<}, $pfile)
854
if ($counter >= $timeout) {
855
die "can't open $pfile\n";
862
print Dumper $PFILE if $verbose;
863
die "can't open $pfile\n" unless $PFILE;
867
if ($pid && ($pid =~ /^\d+$/) ) {
873
sub get_pid_timestamp {
876
my @stats = stat $pidfile
878
# or die "can't get timestamp for file $pidfile ($!)\n";
884
my @subdirs = glob("$path/*/");
887
$dir_count++ if -d $_;
894
my @paths = split /:/, $ENV{PATH};
895
for my $path (@paths) {
897
if ( -f "$path/$fname") {