]> git.proxmox.com Git - pve-container.git/blobdiff - src/test/snapshot-test.pm
snapshot-test.pm: ignore existing replication config
[pve-container.git] / src / test / snapshot-test.pm
index 69de5216ddc86683c58132f089441f5135328b89..6f0b209eaba8dc4a9dc4fcec948d1b26db2c25bd 100644 (file)
@@ -1,4 +1,4 @@
-package PVE::LXC;
+package PVE::LXC::Test;
 
 use strict;
 use warnings;
@@ -8,7 +8,9 @@ use lib qw(..);
 use PVE::Storage;
 use PVE::Storage::Plugin;
 use PVE::LXC;
+use PVE::LXC::Config;
 use PVE::Tools;
+use PVE::ReplicationConfig;
 
 use Test::MockModule;
 use Test::More;
@@ -28,6 +30,15 @@ my $kill_possible;
 
 # Mocked methods
 
+sub mocked_has_feature {
+    my ($feature, $conf, $storecfg, $snapname) = @_;
+    return $snapshot_possible;
+}
+
+sub mocked_check_running {
+    return $running;
+}
+
 sub mocked_volume_snapshot {
     my ($storecfg, $volid, $snapname) = @_;
     die "Storage config not mocked! aborting\n"
@@ -140,7 +151,7 @@ sub testcase_prepare {
        plan tests => 2;
        $@ = undef;
        eval {
-           PVE::LXC::snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
+           PVE::LXC::Config->__snapshot_prepare($vmid, $snapname, $save_vmstate, $comment);
        };
        is($@, $exp_err, "\$@ correct");
        ok(test_file("snapshot-expected/prepare/lxc/$vmid.conf", "snapshot-working/prepare/lxc/$vmid.conf"), "config file correct");
@@ -153,7 +164,7 @@ sub testcase_commit {
        plan tests => 2;
        $@ = undef;
        eval {
-           PVE::LXC::snapshot_commit($vmid, $snapname);
+           PVE::LXC::Config->__snapshot_commit($vmid, $snapname);
        };
        is($@, $exp_err, "\$@ correct");
        ok(test_file("snapshot-expected/commit/lxc/$vmid.conf", "snapshot-working/commit/lxc/$vmid.conf"), "config file correct");
@@ -170,7 +181,7 @@ sub testcase_create {
        $exp_vol_snap_delete = {} if !defined($exp_vol_snap_delete);
        $@ = undef;
        eval {
-           PVE::LXC::snapshot_create($vmid, $snapname, $save_vmstate, $comment);
+           PVE::LXC::Config->snapshot_create($vmid, $snapname, $save_vmstate, $comment);
        };
        is($@, $exp_err, "\$@ correct");
        is_deeply($vol_snapshot, $exp_vol_snap, "created correct volume snapshots");
@@ -187,7 +198,7 @@ sub testcase_delete {
        $exp_vol_snap_delete = {} if !defined($exp_vol_snap_delete);
        $@ = undef;
        eval {
-           PVE::LXC::snapshot_delete($vmid, $snapname, $force);
+           PVE::LXC::Config->snapshot_delete($vmid, $snapname, $force);
        };
        is($@, $exp_err, "\$@ correct");
        is_deeply($vol_snapshot_delete, $exp_vol_snap_delete, "deleted correct volume snapshots");
@@ -204,7 +215,7 @@ sub testcase_rollback {
        $exp_vol_snap_rollback = {} if !defined($exp_vol_snap_rollback);
        $@ = undef;
        eval {
-           PVE::LXC::snapshot_rollback($vmid, $snapname);
+           PVE::LXC::Config->snapshot_rollback($vmid, $snapname);
        };
        is($@, $exp_err, "\$@ correct");
        is_deeply($vol_snapshot_rollback, $exp_vol_snap_rollback, "rolled back to correct volume snapshots");
@@ -212,33 +223,33 @@ sub testcase_rollback {
     };
 }
 
-# BEGIN redefine PVE::LXC methods 
-sub config_file_lock {
+# BEGIN mocked PVE::LXC::Config methods
+sub mocked_config_file_lock {
     return "snapshot-working/pve-test.lock";
 }
 
-sub cfs_config_path {
-    my ($vmid, $node) = @_;
+sub mocked_cfs_config_path {
+    my ($class, $vmid, $node) = @_;
 
     $node = $nodename if !$node;
     return "snapshot-working/$node/lxc/$vmid.conf";
 }
 
-sub load_config {
-    my ($vmid, $node) = @_;
+sub mocked_load_config {
+    my ($class, $vmid, $node) = @_;
 
-    my $filename = cfs_config_path($vmid, $node);
+    my $filename = PVE::LXC::Config->cfs_config_path($vmid, $node);
 
     my $raw = PVE::Tools::file_get_contents($filename);
 
-    my $conf = PVE::LXC::parse_pct_config($filename, $raw);
+    my $conf = PVE::LXC::Config::parse_pct_config($filename, $raw);
     return $conf;
 }
 
-sub write_config {
-    my ($vmid, $conf) = @_;
+sub mocked_write_config {
+    my ($class, $vmid, $conf) = @_;
 
-    my $filename = cfs_config_path($vmid);
+    my $filename = PVE::LXC::Config->cfs_config_path($vmid);
 
     if ($conf->{snapshots}) {
        foreach my $snapname (keys %{$conf->{snapshots}}) {
@@ -247,29 +258,34 @@ sub write_config {
        }
     }
 
-    my $raw = PVE::LXC::write_pct_config($filename, $conf);
+    my $raw = PVE::LXC::Config::write_pct_config($filename, $conf);
 
     PVE::Tools::file_set_contents($filename, $raw);
 }
 
-sub has_feature {
-    my ($feature, $conf, $storecfg, $snapname) = @_;
-    return $snapshot_possible;
-}
+# END mocked PVE::LXC methods
 
-sub check_running {
-    return $running;
-}
-
-sub sync_container_namespace {
-    return;
-}
-
-# END redefine PVE::LXC methods
 
 PVE::Tools::run_command("rm -rf snapshot-working");
 PVE::Tools::run_command("cp -a snapshot-input snapshot-working");
 
+printf("\n");
+printf("Setting up Mocking for PVE::LXC and PVE::LXC::Config\n");
+my $lxc_module = new Test::MockModule('PVE::LXC');
+$lxc_module->mock('sync_container_namespace', sub { return; });
+$lxc_module->mock('check_running', \&mocked_check_running);
+
+my $lxc_config_module = new Test::MockModule('PVE::LXC::Config');
+$lxc_config_module->mock('config_file_lock', sub { return "snapshot-working/pve-test.lock"; });
+$lxc_config_module->mock('cfs_config_path', \&mocked_cfs_config_path);
+$lxc_config_module->mock('load_config', \&mocked_load_config);
+$lxc_config_module->mock('write_config', \&mocked_write_config);
+$lxc_config_module->mock('has_feature', \&mocked_has_feature);
+
+# ignore existing replication config
+my $repl_config_module = new Test::MockModule('PVE::ReplicationConfig');
+$repl_config_module->mock('check_for_existing_jobs' => sub { return undef });
+
 $running = 1;
 $freeze_possible = 1;
 
@@ -290,7 +306,7 @@ printf("Successful snapshot_prepare with one existing snapshot\n");
 testcase_prepare("102", "test2", 0, "test comment", "");
 
 printf("Expected error for snapshot_prepare on locked container\n");
-testcase_prepare("200", "test", 0, "test comment", "VM is locked (snapshot)\n");
+testcase_prepare("200", "test", 0, "test comment", "CT is locked (snapshot)\n");
 
 printf("Expected error for snapshot_prepare with duplicate snapshot name\n");
 testcase_prepare("201", "test", 0, "test comment", "snapshot name 'test' already used\n");
@@ -332,9 +348,18 @@ printf("Expected error for snapshot_commit with invalid snapshot state\n");
 testcase_commit("203", "test", "wrong snapshot state\n");
 
 $vol_snapshot_possible->{"local:snapshotable-disk-1"} = 1;
+$vol_snapshot_possible->{"local:snapshotable-disk-2"} = 1;
+$vol_snapshot_possible->{"local:snapshotable-disk-3"} = 1;
 $vol_snapshot_delete_possible->{"local:snapshotable-disk-1"} = 1;
 $vol_snapshot_rollback_enabled->{"local:snapshotable-disk-1"} = 1;
+$vol_snapshot_rollback_enabled->{"local:snapshotable-disk-2"} = 1;
+$vol_snapshot_rollback_enabled->{"local:snapshotable-disk-3"} = 1;
 $vol_snapshot_rollback_possible->{"local:snapshotable-disk-1"} = 1;
+$vol_snapshot_rollback_possible->{"local:snapshotable-disk-2"} = 1;
+$vol_snapshot_rollback_possible->{"local:snapshotable-disk-3"} = 1;
+
+# possible, but fails
+$vol_snapshot_rollback_possible->{"local:snapshotable-disk-4"} = 1;
 
 printf("\n");
 printf("Setting up Mocking for PVE::Storage\n");
@@ -363,14 +388,20 @@ testcase_create("101", "test", 0, "test comment", "", { "local:snapshotable-disk
 printf("Successful snapshot_create with one existing snapshots\n");
 testcase_create("102", "test2", 0, "test comment", "", { "local:snapshotable-disk-1" => "test2" });
 
+printf("Successful snapshot_create with multiple mps\n");
+testcase_create("103", "test", 0, "test comment", "", { "local:snapshotable-disk-1" => "test", "local:snapshotable-disk-2" => "test", "local:snapshotable-disk-3" => "test" });
+
 printf("Expected error for snapshot_create when volume snapshot is not possible\n");
 testcase_create("201", "test", 0, "test comment", "volume snapshot disabled\n\n");
 
 printf("Expected error for snapshot_create with broken lxc-freeze\n");
 $freeze_possible = 0;
-testcase_create("202", "test", 0, "test comment", "lxc-[un]freeze disabled\n\n", undef, { "local:snapshotable-disk-1" => "test" });
+testcase_create("202", "test", 0, "test comment", "lxc-[un]freeze disabled\n\n");
 $freeze_possible = 1;
 
+printf("Expected error for snapshot_create when mp volume snapshot is not possible\n");
+testcase_create("203", "test", 0, "test comment", "volume snapshot disabled\n\n", { "local:snapshotable-disk-1" => "test" }, { "local:snapshotable-disk-1" => "test" });
+
 $nodename = "delete";
 printf("\n");
 printf("Running delete tests\n");
@@ -391,11 +422,17 @@ testcase_delete("104", "test2", 0, "", { "local:snapshotable-disk-1" => "test2"
 printf("Successful snapshot_delete with broken volume_snapshot_delete and force=1\n");
 testcase_delete("105", "test", 1, "");
 
+printf("Successful snapshot_delete with mp broken volume_snapshot_delete and force=1\n");
+testcase_delete("106", "test", 1, "", { "local:snapshotable-disk-1" => "test" });
+
 printf("Expected error when snapshot_delete fails with broken volume_snapshot_delete and force=0\n");
 testcase_delete("201", "test", 0, "volume snapshot delete disabled\n");
 
+printf("Expected error when snapshot_delete fails with broken mp volume_snapshot_delete and force=0\n");
+testcase_delete("203", "test", 0, "volume snapshot delete disabled\n", { "local:snapshotable-disk-1" => "test" });
+
 printf("Expected error for snapshot_delete with locked config\n");
-testcase_delete("202", "test", 0, "VM is locked (backup)\n");
+testcase_delete("202", "test", 0, "CT is locked (backup)\n");
 
 $nodename = "rollback";
 printf("\n");
@@ -416,6 +453,9 @@ testcase_rollback("103", "test", "", { "local:snapshotable-disk-1" => "test" });
 printf("Successful snapshot_rollback to intermediate snapshot\n");
 testcase_rollback("104", "test2", "", { "local:snapshotable-disk-1" => "test2" });
 
+printf("Successful snapshot_rollback with multiple mp\n");
+testcase_rollback("105", "test", "", { "local:snapshotable-disk-1" => "test", "local:snapshotable-disk-2" => "test", "local:snapshotable-disk-3" => "test" });
+
 printf("Expected error for snapshot_rollback with non-existing snapshot\n");
 testcase_rollback("201", "test2", "snapshot 'test2' does not exist\n");
 
@@ -426,7 +466,7 @@ printf("Expected error for snapshot_rollback with incomplete snapshot\n");
 testcase_rollback("203", "test", "unable to rollback to incomplete snapshot (snapstate = delete)\n");
 
 printf("Expected error for snapshot_rollback with lock\n");
-testcase_rollback("204", "test", "VM is locked (backup)\n");
+testcase_rollback("204", "test", "CT is locked (backup)\n");
 
 printf("Expected error for snapshot_rollback with saved vmstate\n");
 testcase_rollback("205", "test", "implement me - save vmstate\n", { "local:snapshotable-disk-1" => "test" });
@@ -436,4 +476,12 @@ $kill_possible = 0;
 printf("Expected error for snapshot_rollback with unkillable container\n");
 testcase_rollback("206", "test", "unable to rollback vm 206: vm is running\n");
 
+$kill_possible = 1;
+
+printf("Expected error for snapshot_rollback with mp rollback_is_possible failure\n");
+testcase_rollback("207", "test", "volume_rollback_is_possible failed\n");
+
+printf("Expected error for snapshot_rollback with mp rollback failure (results in inconsistent state)\n");
+testcase_rollback("208", "test", "volume snapshot rollback disabled\n", { "local:snapshotable-disk-1" => "test", "local:snapshotable-disk-2" => "test" });
+
 done_testing();