Skip to content

Commit 45f0abb

Browse files
committed
add test for pre/post migration
1 parent 4903339 commit 45f0abb

File tree

2 files changed

+669
-0
lines changed

2 files changed

+669
-0
lines changed
Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package com.cloud.hypervisor.kvm.resource.wrapper;
21+
22+
import com.cloud.agent.api.Answer;
23+
import com.cloud.agent.api.PostMigrationAnswer;
24+
import com.cloud.agent.api.PostMigrationCommand;
25+
import com.cloud.agent.api.to.VirtualMachineTO;
26+
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
27+
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
28+
import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
29+
import org.junit.Assert;
30+
import org.junit.Before;
31+
import org.junit.Test;
32+
import org.junit.runner.RunWith;
33+
import org.libvirt.Connect;
34+
import org.libvirt.LibvirtException;
35+
import org.mockito.Mock;
36+
import org.mockito.MockedStatic;
37+
import org.mockito.Mockito;
38+
import org.mockito.junit.MockitoJUnitRunner;
39+
40+
import java.util.ArrayList;
41+
import java.util.List;
42+
43+
import static org.mockito.ArgumentMatchers.any;
44+
import static org.mockito.ArgumentMatchers.eq;
45+
import static org.mockito.Mockito.times;
46+
import static org.mockito.Mockito.when;
47+
@RunWith(MockitoJUnitRunner.class)
48+
public class LibvirtPostMigrationCommandWrapperTest {
49+
50+
@Mock
51+
private LibvirtComputingResource libvirtComputingResource;
52+
53+
@Mock
54+
private PostMigrationCommand postMigrationCommand;
55+
56+
@Mock
57+
private VirtualMachineTO virtualMachineTO;
58+
59+
@Mock
60+
private Connect connect;
61+
62+
private LibvirtPostMigrationCommandWrapper wrapper;
63+
64+
private static final String VM_NAME = "test-vm";
65+
66+
@Before
67+
public void setUp() {
68+
wrapper = new LibvirtPostMigrationCommandWrapper();
69+
when(postMigrationCommand.getVmName()).thenReturn(VM_NAME);
70+
when(postMigrationCommand.getVirtualMachine()).thenReturn(virtualMachineTO);
71+
}
72+
73+
@Test
74+
public void testExecute_NoClvmVolumes_Success() throws LibvirtException {
75+
List<DiskDef> disks = createNonClvmDisks();
76+
77+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class)) {
78+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
79+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
80+
81+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
82+
83+
Assert.assertTrue(answer.getResult());
84+
Assert.assertTrue(answer instanceof PostMigrationAnswer);
85+
}
86+
}
87+
88+
@Test
89+
public void testExecute_ClvmVolumes_ConvertedToExclusiveMode() throws LibvirtException {
90+
List<DiskDef> disks = createClvmDisks();
91+
92+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class);
93+
MockedStatic<LibvirtComputingResource> mockedResource = Mockito.mockStatic(LibvirtComputingResource.class)) {
94+
95+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
96+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
97+
98+
mockedResource.when(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
99+
eq(disks),
100+
eq(libvirtComputingResource),
101+
eq(virtualMachineTO),
102+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
103+
)).then(invocation -> null);
104+
105+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
106+
107+
Assert.assertTrue(answer.getResult());
108+
mockedResource.verify(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
109+
eq(disks),
110+
eq(libvirtComputingResource),
111+
eq(virtualMachineTO),
112+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
113+
), times(1));
114+
}
115+
}
116+
117+
@Test
118+
public void testExecute_ClvmNgVolumes_ConvertedToExclusiveMode() throws LibvirtException {
119+
List<DiskDef> disks = createClvmNgDisks();
120+
121+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class);
122+
MockedStatic<LibvirtComputingResource> mockedResource = Mockito.mockStatic(LibvirtComputingResource.class)) {
123+
124+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
125+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
126+
127+
mockedResource.when(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
128+
any(),
129+
any(),
130+
any(),
131+
any()
132+
)).then(invocation -> null);
133+
134+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
135+
136+
Assert.assertTrue(answer.getResult());
137+
mockedResource.verify(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
138+
eq(disks),
139+
eq(libvirtComputingResource),
140+
eq(virtualMachineTO),
141+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
142+
), times(1));
143+
}
144+
}
145+
146+
@Test
147+
public void testExecute_MixedVolumes_OnlyClvmConverted() throws LibvirtException {
148+
List<DiskDef> disks = createMixedDisks();
149+
150+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class);
151+
MockedStatic<LibvirtComputingResource> mockedResource = Mockito.mockStatic(LibvirtComputingResource.class)) {
152+
153+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
154+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
155+
156+
mockedResource.when(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
157+
any(),
158+
any(),
159+
any(),
160+
any()
161+
)).then(invocation -> null);
162+
163+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
164+
165+
Assert.assertTrue(answer.getResult());
166+
mockedResource.verify(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
167+
eq(disks),
168+
eq(libvirtComputingResource),
169+
eq(virtualMachineTO),
170+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
171+
), times(1));
172+
}
173+
}
174+
175+
@Test
176+
public void testExecute_LibvirtException_ReturnsFailure() throws LibvirtException {
177+
LibvirtException libvirtException = Mockito.mock(LibvirtException.class);
178+
when(libvirtException.getMessage()).thenReturn("Connection failed");
179+
180+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class)) {
181+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME))
182+
.thenThrow(libvirtException);
183+
184+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
185+
186+
Assert.assertFalse(answer.getResult());
187+
Assert.assertTrue(answer.getDetails().contains("Connection failed"));
188+
}
189+
}
190+
191+
@Test
192+
public void testExecute_RuntimeException_ReturnsFailure() throws LibvirtException {
193+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class)) {
194+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
195+
when(libvirtComputingResource.getDisks(connect, VM_NAME))
196+
.thenThrow(new RuntimeException("Unexpected error"));
197+
198+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
199+
200+
Assert.assertFalse(answer.getResult());
201+
Assert.assertTrue(answer.getDetails().contains("Unexpected error"));
202+
}
203+
}
204+
205+
@Test
206+
public void testExecute_NullVmName_ReturnsFailure() {
207+
when(postMigrationCommand.getVmName()).thenReturn(null);
208+
209+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
210+
211+
Assert.assertFalse(answer.getResult());
212+
Assert.assertTrue(answer.getDetails().contains("VM or VM name is null"));
213+
}
214+
215+
@Test
216+
public void testExecute_NullVirtualMachine_ReturnsFailure() {
217+
when(postMigrationCommand.getVirtualMachine()).thenReturn(null);
218+
219+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
220+
221+
Assert.assertFalse(answer.getResult());
222+
Assert.assertTrue(answer.getDetails().contains("VM or VM name is null"));
223+
}
224+
225+
@Test
226+
public void testExecute_EmptyDiskList_Success() throws LibvirtException {
227+
List<DiskDef> disks = new ArrayList<>();
228+
229+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class)) {
230+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
231+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
232+
233+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
234+
235+
Assert.assertTrue(answer.getResult());
236+
}
237+
}
238+
239+
@Test
240+
public void testExecute_MultipleClvmVolumes_AllConverted() throws LibvirtException {
241+
List<DiskDef> disks = new ArrayList<>();
242+
for (int i = 0; i < 5; i++) {
243+
DiskDef disk = Mockito.mock(DiskDef.class);
244+
Mockito.lenient().when(disk.getDiskPath()).thenReturn("/dev/clvm-vg/volume" + i);
245+
disks.add(disk);
246+
}
247+
248+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class);
249+
MockedStatic<LibvirtComputingResource> mockedResource = Mockito.mockStatic(LibvirtComputingResource.class)) {
250+
251+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
252+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
253+
254+
mockedResource.when(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
255+
any(),
256+
any(),
257+
any(),
258+
any()
259+
)).then(invocation -> null);
260+
261+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
262+
263+
Assert.assertTrue(answer.getResult());
264+
mockedResource.verify(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
265+
eq(disks),
266+
eq(libvirtComputingResource),
267+
eq(virtualMachineTO),
268+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
269+
), times(1));
270+
}
271+
}
272+
273+
@Test
274+
public void testExecute_ClvmAndClvmNgMixed_BothConverted() throws LibvirtException {
275+
List<DiskDef> disks = new ArrayList<>();
276+
277+
DiskDef clvmDisk1 = Mockito.mock(DiskDef.class);
278+
Mockito.lenient().when(clvmDisk1.getDiskPath()).thenReturn("/dev/clvm-vg/volume1");
279+
disks.add(clvmDisk1);
280+
281+
DiskDef clvmNgDisk = Mockito.mock(DiskDef.class);
282+
Mockito.lenient().when(clvmNgDisk.getDiskPath()).thenReturn("/dev/clvmng-vg/volume2");
283+
disks.add(clvmNgDisk);
284+
285+
DiskDef clvmDisk2 = Mockito.mock(DiskDef.class);
286+
Mockito.lenient().when(clvmDisk2.getDiskPath()).thenReturn("/dev/clvm-vg/volume3");
287+
disks.add(clvmDisk2);
288+
289+
try (MockedStatic<LibvirtConnection> mockedConnection = Mockito.mockStatic(LibvirtConnection.class);
290+
MockedStatic<LibvirtComputingResource> mockedResource = Mockito.mockStatic(LibvirtComputingResource.class)) {
291+
292+
mockedConnection.when(() -> LibvirtConnection.getConnectionByVmName(VM_NAME)).thenReturn(connect);
293+
when(libvirtComputingResource.getDisks(connect, VM_NAME)).thenReturn(disks);
294+
295+
mockedResource.when(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
296+
any(),
297+
any(),
298+
any(),
299+
any()
300+
)).then(invocation -> null);
301+
302+
Answer answer = wrapper.execute(postMigrationCommand, libvirtComputingResource);
303+
304+
Assert.assertTrue(answer.getResult());
305+
mockedResource.verify(() -> LibvirtComputingResource.modifyClvmVolumesStateForMigration(
306+
eq(disks),
307+
eq(libvirtComputingResource),
308+
eq(virtualMachineTO),
309+
eq(LibvirtComputingResource.ClvmVolumeState.EXCLUSIVE)
310+
), times(1));
311+
}
312+
}
313+
314+
private List<DiskDef> createNonClvmDisks() {
315+
List<DiskDef> disks = new ArrayList<>();
316+
317+
DiskDef disk1 = Mockito.mock(DiskDef.class);
318+
Mockito.lenient().when(disk1.getDiskPath()).thenReturn("/mnt/nfs/volume1.qcow2");
319+
disks.add(disk1);
320+
321+
DiskDef disk2 = Mockito.mock(DiskDef.class);
322+
Mockito.lenient().when(disk2.getDiskPath()).thenReturn("/mnt/nfs/volume2.qcow2");
323+
disks.add(disk2);
324+
325+
return disks;
326+
}
327+
328+
private List<DiskDef> createClvmDisks() {
329+
List<DiskDef> disks = new ArrayList<>();
330+
331+
DiskDef disk1 = Mockito.mock(DiskDef.class);
332+
Mockito.lenient().when(disk1.getDiskPath()).thenReturn("/dev/clvm-vg/volume1");
333+
disks.add(disk1);
334+
335+
DiskDef disk2 = Mockito.mock(DiskDef.class);
336+
Mockito.lenient().when(disk2.getDiskPath()).thenReturn("/dev/clvm-vg/volume2");
337+
disks.add(disk2);
338+
339+
return disks;
340+
}
341+
342+
private List<DiskDef> createClvmNgDisks() {
343+
List<DiskDef> disks = new ArrayList<>();
344+
345+
DiskDef disk1 = Mockito.mock(DiskDef.class);
346+
Mockito.lenient().when(disk1.getDiskPath()).thenReturn("/dev/clvmng-vg/volume1");
347+
disks.add(disk1);
348+
349+
DiskDef disk2 = Mockito.mock(DiskDef.class);
350+
Mockito.lenient().when(disk2.getDiskPath()).thenReturn("/dev/clvmng-vg/volume2");
351+
disks.add(disk2);
352+
353+
return disks;
354+
}
355+
356+
private List<DiskDef> createMixedDisks() {
357+
List<DiskDef> disks = new ArrayList<>();
358+
359+
DiskDef clvmDisk = Mockito.mock(DiskDef.class);
360+
Mockito.lenient().when(clvmDisk.getDiskPath()).thenReturn("/dev/clvm-vg/volume1");
361+
disks.add(clvmDisk);
362+
363+
DiskDef nfsDisk = Mockito.mock(DiskDef.class);
364+
Mockito.lenient().when(nfsDisk.getDiskPath()).thenReturn("/mnt/nfs/volume2.qcow2");
365+
disks.add(nfsDisk);
366+
367+
DiskDef clvmNgDisk = Mockito.mock(DiskDef.class);
368+
Mockito.lenient().when(clvmNgDisk.getDiskPath()).thenReturn("/dev/clvmng-vg/volume3");
369+
disks.add(clvmNgDisk);
370+
371+
return disks;
372+
}
373+
}
374+
375+
376+
377+
378+

0 commit comments

Comments
 (0)