From a08300033d2ccaa6f2704535f977fb876da93b65 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Tue, 5 May 2020 22:42:51 +0100 Subject: Add functional tests. --- t/20-mount-unmount.t | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ t/21-ensure-mounted.t | 50 ++++++++++++++++++++++++++++++++++++++++++++++ t/22-eject.t | 41 ++++++++++++++++++++++++++++++++++++++ t/23-wait-for-insert.t | 22 ++++++++++++++++++++ t/24-wait-for-mounted.t | 41 ++++++++++++++++++++++++++++++++++++++ t/cdroms-test.iso | Bin 0 -> 376832 bytes t/helper.pm | 44 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 250 insertions(+) create mode 100644 t/20-mount-unmount.t create mode 100644 t/21-ensure-mounted.t create mode 100644 t/22-eject.t create mode 100644 t/23-wait-for-insert.t create mode 100644 t/24-wait-for-mounted.t create mode 100644 t/cdroms-test.iso create mode 100644 t/helper.pm diff --git a/t/20-mount-unmount.t b/t/20-mount-unmount.t new file mode 100644 index 0000000..02ca336 --- /dev/null +++ b/t/20-mount-unmount.t @@ -0,0 +1,52 @@ +use strict; +use lib 't'; +use helper; +use Test::More; +plan skip_all => "You need to be root to run this test" if $> != 0; +plan skip_all => "The scsi_debug kernel module is needed to run this test" if !can_create_fake_media(); + +use_ok('Hal::Cdroms'); + +my $fake_device = create_fake_media(); + +my $cdroms = Hal::Cdroms->new; + +my @udisks_paths = grep { $_ eq "/org/freedesktop/UDisks2/block_devices/$fake_device" } $cdroms->list; +ok(@udisks_paths == 1, 'device is listed'); + +# If a volume manager is running, the device may get auto-mounted. +# Wait to see if this happens, and if so, unmount it. +sleep(2); +my $mount_point = find_mount_point($fake_device); +if ($mount_point) { + ok($cdroms->get_mount_point($udisks_paths[0]) eq $mount_point, 'get_mount_point returns correct path'); + ok($cdroms->unmount($udisks_paths[0]), 'unmount returns success'); + $mount_point = find_mount_point($fake_device); + ok(!$mount_point, 'unmount works'); +} +ok(!$cdroms->get_mount_point($udisks_paths[0]), 'get_mount_point returns no path'); + +# Now test we can mount it. +my $udisks_mount_point = $cdroms->mount($udisks_paths[0]); +$mount_point = find_mount_point($fake_device); +ok($mount_point, 'mount works'); +ok($udisks_mount_point eq $mount_point, 'mount returns correct path'); +ok($cdroms->get_mount_point($udisks_paths[0]) eq $mount_point, 'get_mount_point returns correct path'); + +ok(!$cdroms->mount($udisks_paths[0]), 'repeated mount fails'); + +# And that we can unmount it. +ok($cdroms->unmount($udisks_paths[0]), 'unmount returns success'); +$mount_point = find_mount_point($fake_device); +ok(!$mount_point, 'unmount works'); +ok(!$cdroms->get_mount_point($udisks_paths[0]), 'get_mount_point returns no path'); + +ok(!$cdroms->unmount($udisks_paths[0]), 'repeated unmount fails'); + +ok(-e "/dev/$fake_device", 'device has not been ejected'); + +done_testing(); + +END { + remove_fake_media() if $> == 0; +} diff --git a/t/21-ensure-mounted.t b/t/21-ensure-mounted.t new file mode 100644 index 0000000..9cfe599 --- /dev/null +++ b/t/21-ensure-mounted.t @@ -0,0 +1,50 @@ +use strict; +use lib 't'; +use helper; +use Test::More; +plan skip_all => "You need to be root to run this test" if $> != 0; +plan skip_all => "The scsi_debug kernel module is needed to run this test" if !can_create_fake_media(); + +use_ok('Hal::Cdroms'); + +my $fake_device = create_fake_media(); + +my $cdroms = Hal::Cdroms->new; + +my @udisks_paths = grep { $_ eq "/org/freedesktop/UDisks2/block_devices/$fake_device" } $cdroms->list; +ok(@udisks_paths == 1, 'device is listed'); + +# If a volume manager is running, the device may get auto-mounted. +# Wait to see if this happens, and if so, unmount it. +sleep(2); +my $mount_point = find_mount_point($fake_device); +if ($mount_point) { + ok($cdroms->unmount($udisks_paths[0]), 'unmount returns success'); + $mount_point = find_mount_point($fake_device); +} +ok(!$mount_point, 'device is not mounted'); + +# Now test it gets mounted by ensure_mounted. +my $udisks_mount_point = $cdroms->ensure_mounted($udisks_paths[0]); +$mount_point = find_mount_point($fake_device); +ok($mount_point, 'ensure_mounted works'); +ok($udisks_mount_point eq $mount_point, 'mount returns correct path'); +ok($cdroms->get_mount_point($udisks_paths[0]) eq $mount_point, 'get_mount_point returns correct path'); + +# And that a repeated call to ensure_mounted works. +my $udisks_mount_point = $cdroms->ensure_mounted($udisks_paths[0]); +$mount_point = find_mount_point($fake_device); +ok($mount_point, 'repeated ensure_mounted works'); +ok($udisks_mount_point eq $mount_point, 'mount returns correct path'); +ok($cdroms->get_mount_point($udisks_paths[0]) eq $mount_point, 'get_mount_point returns correct path'); + +# And that we can unmount it. +ok($cdroms->unmount($udisks_paths[0]), 'unmount returns success'); + +ok(-e "/dev/$fake_device", 'device has not been ejected'); + +done_testing(); + +END { + remove_fake_media() if $> == 0; +} diff --git a/t/22-eject.t b/t/22-eject.t new file mode 100644 index 0000000..50511f1 --- /dev/null +++ b/t/22-eject.t @@ -0,0 +1,41 @@ +use strict; +use lib 't'; +use helper; +use Test::More; +plan skip_all => "You need to be root to run this test" if $> != 0; +plan skip_all => "The scsi_debug kernel module is needed to run this test" if !can_create_fake_media(); + +use_ok('Hal::Cdroms'); + +my $fake_device = create_fake_media(); + +my $cdroms = Hal::Cdroms->new; + +my @udisks_paths = grep { $_ eq "/org/freedesktop/UDisks2/block_devices/$fake_device" } $cdroms->list; +ok(@udisks_paths == 1, 'device is listed'); + +# If a volume manager is running, the device may get auto-mounted. +# Allow this to settle before proceeding. +sleep(2); + +# Ensure the device is mounted. +ok($cdroms->ensure_mounted($udisks_paths[0]), 'ensure_mounted returns success'); +my $mount_point = find_mount_point($fake_device); +ok($mount_point, 'device is mounted'); + +# Test that we can eject it. +ok($cdroms->eject($udisks_paths[0]), 'eject returns success'); +$mount_point = find_mount_point($fake_device); +ok(!$mount_point, 'device is unmounted'); +ok(!$cdroms->get_mount_point($udisks_paths[0]), 'get_mount_point returns no path'); + +# It appears the scsi_debug module doesn't support eject, so we have to skip this. +# ok(! -e "/dev/$fake_device", 'device has been ejected'); + +ok(!$cdroms->eject($udisks_paths[0]), 'repeated eject fails'); + +done_testing(); + +END { + remove_fake_media() if $> == 0; +} diff --git a/t/23-wait-for-insert.t b/t/23-wait-for-insert.t new file mode 100644 index 0000000..eb822d0 --- /dev/null +++ b/t/23-wait-for-insert.t @@ -0,0 +1,22 @@ +use strict; +use lib 't'; +use helper; +use Test::More; +plan skip_all => "You need to be root to run this test" if $> != 0; +plan skip_all => "The scsi_debug kernel module is needed to run this test" if !can_create_fake_media(); + +use_ok('Hal::Cdroms'); + +my $fake_device = create_fake_media(3); + +my $cdroms = Hal::Cdroms->new; + +my $udisks_path = $cdroms->wait_for_insert(10000); +ok($udisks_path eq "/org/freedesktop/UDisks2/block_devices/$fake_device", 'wait_for_insert returns correct path'); + +done_testing(); + +END { + system("umount /dev/$fake_device") if find_mount_point($fake_device); + remove_fake_media() if $> == 0; +} diff --git a/t/24-wait-for-mounted.t b/t/24-wait-for-mounted.t new file mode 100644 index 0000000..6695abe --- /dev/null +++ b/t/24-wait-for-mounted.t @@ -0,0 +1,41 @@ +use strict; +use lib 't'; +use helper; +use File::Temp qw(tempdir); +use Test::More; +plan skip_all => "You need to be root to run this test" if $> != 0; +plan skip_all => "The scsi_debug kernel module is needed to run this test" if !can_create_fake_media(); + +use_ok('Hal::Cdroms'); + +# Check if a volume manager is going to auto-mount the device. +my $fake_device = create_fake_media(); +sleep(2); +my $auto_mounted = 0; +if (find_mount_point($fake_device)) { + system("umount /dev/$fake_device"); + remove_fake_media(); + $auto_mounted = 1; +} + +my $fake_device = create_fake_media(3); + +if (!$auto_mounted) { + my $tmp_dir = tempdir(CLEANUP => 1); + system("echo 'sleep 4; mount /dev/$fake_device $tmp_dir' | at now >& /dev/null"); +} + +my $cdroms = Hal::Cdroms->new; + +my $udisks_path = $cdroms->wait_for_mounted(); +ok($udisks_path eq "/org/freedesktop/UDisks2/block_devices/$fake_device", 'wait_for_mounted returns correct path'); +my $mount_point = find_mount_point($fake_device); +ok($mount_point, 'device is mounted'); +ok($cdroms->get_mount_point($udisks_path) eq $mount_point, 'get_mount_point returns correct path'); + +done_testing(); + +END { + system("umount /dev/$fake_device") if find_mount_point($fake_device); + remove_fake_media() if $> == 0; +} diff --git a/t/cdroms-test.iso b/t/cdroms-test.iso new file mode 100644 index 0000000..94f3160 Binary files /dev/null and b/t/cdroms-test.iso differ diff --git a/t/helper.pm b/t/helper.pm new file mode 100644 index 0000000..3890797 --- /dev/null +++ b/t/helper.pm @@ -0,0 +1,44 @@ +use strict; + +sub can_create_fake_media { + system("modprobe -n scsi_debug") == 0; +} + +sub create_fake_media { + my ($o_delay) = @_; + + system("modprobe scsi_debug ptype=0 removable=1 num_tgts=1 add_host=1") == 0 + or die "Failed to load scsi_debug kernel module\n"; + my @paths = glob("/sys/bus/pseudo/drivers/scsi_debug/adapter0/host*/target*/*:*/block/*"); + @paths == 1 + or die "Unexpected number of scsi_debug devices\n"; + my ($prefix, $device) = split("block/", $paths[0]); + if ($o_delay) { + system("echo 'sleep $o_delay; dd if=t/cdroms-test.iso of=/dev/$device conv=nocreat' | at now >& /dev/null") == 0 + or die "Failed to schedule copy of ISO to fake SCSI device\n"; + } else { + system("dd if=t/cdroms-test.iso of=/dev/$device conv=nocreat >& /dev/null") == 0 + or die "Failed to copy ISO to fake SCSI device\n"; + } + $device; +} + +sub remove_fake_media { + my $tries = 0; + while (system("modprobe -r -q scsi_debug") != 0) { + ++$tries < 5 or die "Failed to remove scsi_debug kernel module\n"; + sleep(1); + } +} + +sub find_mount_point { + my ($device) = @_; + open(my $fh, '<', '/proc/mounts') or die "Couldn't read /proc/mounts\n"; + while (<$fh>) { + my ($device_path, $mount_point) = split(' ', $_); + return $mount_point if $device_path eq "/dev/$device"; + } + return undef; +} + +1; -- cgit v1.2.1