]> git.proxmox.com Git - qemu-server.git/blob - test/MigrationTest/Shared.pm
tests: mock storage locking for migration tests
[qemu-server.git] / test / MigrationTest / Shared.pm
1 package MigrationTest::Shared;
2
3 use strict;
4 use warnings;
5
6 use JSON;
7 use Test::MockModule;
8 use Socket qw(AF_INET);
9
10 use PVE::QemuConfig;
11 use PVE::Tools qw(file_set_contents file_get_contents lock_file_full);
12
13 my $RUN_DIR_PATH = $ENV{RUN_DIR_PATH} or die "no RUN_DIR_PATH set\n";
14
15 my $storage_config = decode_json(file_get_contents("${RUN_DIR_PATH}/storage_config"));
16 my $replication_config = decode_json(file_get_contents("${RUN_DIR_PATH}/replication_config"));
17 my $fail_config = decode_json(file_get_contents("${RUN_DIR_PATH}/fail_config"));
18 my $migrate_params = decode_json(file_get_contents("${RUN_DIR_PATH}/migrate_params"));
19 my $test_vmid = $migrate_params->{vmid};
20
21 # helpers
22
23 sub add_target_volid {
24 my ($volid) = @_;
25
26 lock_file_full("${RUN_DIR_PATH}/target_volids.lock", undef, 0, sub {
27 my $target_volids = decode_json(file_get_contents("${RUN_DIR_PATH}/target_volids"));
28 die "target volid already present " if defined($target_volids->{$volid});
29 $target_volids->{$volid} = 1;
30 file_set_contents("${RUN_DIR_PATH}/target_volids", to_json($target_volids));
31 });
32 die $@ if $@;
33 }
34
35 sub remove_target_volid {
36 my ($volid) = @_;
37
38 lock_file_full("${RUN_DIR_PATH}/target_volids.lock", undef, 0, sub {
39 my $target_volids = decode_json(file_get_contents("${RUN_DIR_PATH}/target_volids"));
40 die "target volid does not exist " if !defined($target_volids->{$volid});
41 delete $target_volids->{$volid};
42 file_set_contents("${RUN_DIR_PATH}/target_volids", to_json($target_volids));
43 });
44 die $@ if $@;
45 }
46
47 my $mocked_cfs_read_file = sub {
48 my ($file) = @_;
49
50 if ($file eq 'datacenter.cfg') {
51 return {};
52 } elsif ($file eq 'replication.cfg') {
53 return $replication_config;
54 }
55 die "cfs_read_file (mocked) - implement me: $file\n";
56 };
57
58 # mocked modules
59
60 our $cluster_module = Test::MockModule->new("PVE::Cluster");
61 $cluster_module->mock(
62 cfs_read_file => $mocked_cfs_read_file,
63 check_cfs_quorum => sub {
64 return 1;
65 },
66 );
67
68 our $ha_config_module = Test::MockModule->new("PVE::HA::Config");
69 $ha_config_module->mock(
70 vm_is_ha_managed => sub {
71 return 0;
72 },
73 );
74
75 our $qemu_config_module = Test::MockModule->new("PVE::QemuConfig");
76 $qemu_config_module->mock(
77 assert_config_exists_on_node => sub {
78 return;
79 },
80 load_config => sub {
81 my ($class, $vmid, $node) = @_;
82 die "trying to load wrong config: '$vmid'\n" if $vmid ne $test_vmid;
83 return decode_json(file_get_contents("${RUN_DIR_PATH}/vm_config"));
84 },
85 lock_config => sub { # no use locking here because lock is local to node
86 my ($self, $vmid, $code, @param) = @_;
87 return $code->(@param);
88 },
89 write_config => sub {
90 my ($class, $vmid, $conf) = @_;
91 die "trying to write wrong config: '$vmid'\n" if $vmid ne $test_vmid;
92 file_set_contents("${RUN_DIR_PATH}/vm_config", to_json($conf));
93 },
94 );
95
96 our $qemu_server_cloudinit_module = Test::MockModule->new("PVE::QemuServer::Cloudinit");
97 $qemu_server_cloudinit_module->mock(
98 generate_cloudinitconfig => sub {
99 return;
100 },
101 );
102
103 our $qemu_server_module = Test::MockModule->new("PVE::QemuServer");
104 $qemu_server_module->mock(
105 clear_reboot_request => sub {
106 return 1;
107 },
108 get_efivars_size => sub {
109 return 128 * 1024;
110 },
111 );
112
113 our $replication_module = Test::MockModule->new("PVE::Replication");
114 $replication_module->mock(
115 run_replication => sub {
116 die "run_replication error" if $fail_config->{run_replication};
117
118 my $vm_config = PVE::QemuConfig->load_config($test_vmid);
119 return PVE::QemuConfig->get_replicatable_volumes(
120 $storage_config,
121 $test_vmid,
122 $vm_config,
123 );
124 },
125 );
126
127 our $replication_config_module = Test::MockModule->new("PVE::ReplicationConfig");
128 $replication_config_module->mock(
129 cfs_read_file => $mocked_cfs_read_file,
130 );
131
132 our $storage_module = Test::MockModule->new("PVE::Storage");
133 $storage_module->mock(
134 activate_volumes => sub {
135 return 1;
136 },
137 deactivate_volumes => sub {
138 return 1;
139 },
140 config => sub {
141 return $storage_config;
142 },
143 get_bandwitdth_limit => sub {
144 return 123456;
145 },
146 );
147
148 our $storage_plugin_module = Test::MockModule->new("PVE::Storage::Plugin");
149 $storage_plugin_module->mock(
150 cluster_lock_storage => sub {
151 my ($class, $storeid, $shared, $timeout, $func, @param) = @_;
152
153 mkdir "${RUN_DIR_PATH}/lock";
154
155 my $path = "${RUN_DIR_PATH}/lock/pve-storage-${storeid}";
156 return PVE::Tools::lock_file($path, $timeout, $func, @param);
157 },
158 );
159
160 our $systemd_module = Test::MockModule->new("PVE::Systemd");
161 $systemd_module->mock(
162 wait_for_unit_removed => sub {
163 return;
164 },
165 enter_systemd_scope => sub {
166 return;
167 },
168 );
169
170 my $migrate_port_counter = 60000;
171
172 our $tools_module = Test::MockModule->new("PVE::Tools");
173 $tools_module->mock(
174 get_host_address_family => sub {
175 return AF_INET;
176 },
177 next_migrate_port => sub {
178 return $migrate_port_counter++;
179 },
180 );
181
182 1;