Rev 62 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#! /usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/..";
use File::Temp qw(tempfile tempdir);
use File::Copy;
use File::Basename;
# Unit test for sneakernet script
# This test runs sneakernet in dry-run mode with maximum verbosity
# to validate configuration and command generation without making changes.
print "=" x 60 . "\n";
print "Sneakernet Unit Test\n";
print "=" x 60 . "\n\n";
my $sneakernet_script = "$FindBin::Bin/sneakernet";
my $config_file = "$sneakernet_script.conf.yaml";
# Verify files exist
unless (-f $sneakernet_script) {
die "ERROR: sneakernet script not found at: $sneakernet_script\n";
}
unless (-f $config_file) {
die "ERROR: Configuration file not found at: $config_file\n";
}
print "Test Configuration:\n";
print " Script: $sneakernet_script\n";
print " Config: $config_file\n";
print " Mode: dry-run (--dryrun)\n";
print " Verbosity: 3 (-vvv)\n";
print "\n";
# Test 1: Version check
print "-" x 60 . "\n";
print "Test 1: Version Check\n";
print "-" x 60 . "\n";
my $version_output = `perl $sneakernet_script --version 2>&1`;
my $version_exit = $? >> 8;
print "Output: $version_output";
print "Exit code: $version_exit\n";
if ($version_exit == 0 && $version_output =~ /sneakernet v\d+\.\d+/) {
print "✓ PASS: Version check successful\n\n";
} else {
print "✗ FAIL: Version check failed\n\n";
}
# Test 2: Help output
print "-" x 60 . "\n";
print "Test 2: Help Output\n";
print "-" x 60 . "\n";
my $help_output = `perl $sneakernet_script --help 2>&1`;
my $help_exit = $? >> 8;
print "Output:\n$help_output";
print "Exit code: $help_exit\n";
if ($help_exit == 0 && $help_output =~ /Usage:/) {
print "✓ PASS: Help output successful\n\n";
} else {
print "✗ FAIL: Help output failed\n\n";
}
# Test 3: Dry-run with maximum verbosity
print "-" x 60 . "\n";
print "Test 3: Dry-run Execution (High Verbosity)\n";
print "-" x 60 . "\n";
print "Running: perl $sneakernet_script --dryrun -vvv\n";
print "-" x 60 . "\n\n";
my $dryrun_output = `perl $sneakernet_script --dryrun -vvv 2>&1`;
my $dryrun_exit = $? >> 8;
print "Output:\n";
print $dryrun_output;
print "\n";
print "-" x 60 . "\n";
print "Exit code: $dryrun_exit\n";
# Analyze the output
my $has_config = $dryrun_output =~ /config|configuration/i;
my $has_dryrun = $dryrun_output =~ /dry[-\s]?run/i;
my $has_commands = $dryrun_output =~ /zfs send|command/i;
print "\nAnalysis:\n";
print " Contains config info: " . ($has_config ? "Yes" : "No") . "\n";
print " Dry-run mode active: " . ($has_dryrun ? "Yes" : "No") . "\n";
print " Generated commands: " . ($has_commands ? "Yes" : "No") . "\n";
if ($dryrun_exit == 0) {
print "\n✓ PASS: Dry-run completed successfully\n";
} else {
print "\n✗ FAIL: Dry-run exited with error code $dryrun_exit\n";
}
# Test 4: Check log file creation
print "\n";
print "-" x 60 . "\n";
print "Test 4: Log File Check\n";
print "-" x 60 . "\n";
my $log_file = "$sneakernet_script.log";
if (-f $log_file) {
print "Log file found: $log_file\n";
my $log_size = -s $log_file;
print "Log file size: $log_size bytes\n";
if ($log_size > 0) {
print "\nLast 20 lines of log file:\n";
print "- " x 30 . "\n";
my @log_lines = `tail -20 $log_file 2>/dev/null`;
print @log_lines;
print "- " x 30 . "\n";
print "✓ PASS: Log file created and populated\n";
} else {
print "✗ FAIL: Log file is empty\n";
}
} else {
print "✗ FAIL: Log file not found at $log_file\n";
}
# Test 5: Status file check
print "\n";
print "-" x 60 . "\n";
print "Test 5: Status File Check\n";
print "-" x 60 . "\n";
my $status_file = "$sneakernet_script.status";
if (-f $status_file) {
print "Status file found: $status_file\n";
my $status_size = -s $status_file;
print "Status file size: $status_size bytes\n";
if ($status_size > 0) {
print "\nStatus file contents:\n";
print "- " x 30 . "\n";
open my $fh, '<', $status_file or die "Can't open status file: $!\n";
print while <$fh>;
close $fh;
print "- " x 30 . "\n";
print "✓ INFO: Status file exists (may be from previous run)\n";
} else {
print "✓ INFO: Status file is empty (expected in dry-run)\n";
}
} else {
print "✓ INFO: Status file not found (expected in dry-run)\n";
}
# Summary
print "\n";
print "=" x 60 . "\n";
print "Test Summary\n";
print "=" x 60 . "\n";
print "All basic tests completed. Review output above for details.\n";
print "Note: Dry-run mode ensures no actual writes were performed.\n";
print "\n";
# Test 6: Target mode simulation
print "=" x 60 . "\n";
print "Test 6: Target Mode Simulation\n";
print "=" x 60 . "\n";
print "Note: This test simulates running on the target server\n";
print " by temporarily overriding the hostname.\n\n";
# Read the config to get the target hostname
my $target_hostname;
if (open my $cfg_fh, '<', $config_file) {
while (my $line = <$cfg_fh>) {
if ($line =~ /^\s*hostname:\s*['"]?([^'"]+)['"]?\s*$/) {
# This is a bit crude, but we need to find target.hostname
# We'll look for it after we see 'target:' section
my $in_target = 0;
seek($cfg_fh, 0, 0); # Reset to beginning
while (my $l2 = <$cfg_fh>) {
if ($l2 =~ /^target:/) {
$in_target = 1;
next;
}
if ($in_target && $l2 =~ /^\s*hostname:\s*['"]?([^'"]+)['"]?\s*$/) {
$target_hostname = $1;
last;
}
if ($in_target && $l2 =~ /^[a-z]+:/ && $l2 !~ /^\s/) {
$in_target = 0; # Exited target section
}
}
last;
}
}
close $cfg_fh;
}
if ($target_hostname) {
print "Target hostname from config: $target_hostname\n";
print "Running sneakernet with HOSTNAME=$target_hostname\n";
print "-" x 60 . "\n\n";
# Set environment variable to simulate target hostname
local $ENV{HOSTNAME} = $target_hostname;
my $target_output = `HOSTNAME=$target_hostname perl $sneakernet_script --dryrun -vvv 2>&1`;
my $target_exit = $? >> 8;
print "Output:\n";
print $target_output;
print "\n";
print "-" x 60 . "\n";
print "Exit code: $target_exit\n";
# Analyze the output for target-specific behavior
my $detected_target = $target_output =~ /target|receiving|import/i;
my $has_receive = $target_output =~ /zfs receive/i;
my $has_geli = $target_output =~ /geli|decrypt|mount/i;
print "\nTarget Mode Analysis:\n";
print " Running as target: " . ($detected_target ? "Yes" : "No") . "\n";
print " Contains zfs receive: " . ($has_receive ? "Yes" : "No") . "\n";
print " Contains GELI operations: " . ($has_geli ? "Yes" : "No") . "\n";
if ($target_exit == 0) {
print "\n✓ PASS: Target mode dry-run completed successfully\n";
} else {
print "\n✗ FAIL: Target mode dry-run exited with error code $target_exit\n";
}
} else {
print "⚠ SKIP: Could not determine target hostname from config\n";
print " Target mode test skipped.\n";
}
print "\n";
print "=" x 60 . "\n";
print "All Tests Complete\n";
print "=" x 60 . "\n";
print "\n";
1;