blob: 61a3c8fb9e65a1ea641acc200d2d56600ca0f944 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.vm;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SystemVmResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.host.Host;
import com.cloud.resource.ResourceService;
import com.cloud.uservm.UserVm;
import com.cloud.utils.db.UUIDManager;
import com.cloud.vm.UserVmService;
import com.cloud.vm.VirtualMachine;
@RunWith(MockitoJUnitRunner.class)
public class MigrateVirtualMachineWithVolumeCmdTest {
@Mock
UserVmService userVmServiceMock;
@Mock
UUIDManager uuidManagerMock;
@Mock
ResourceService resourceServiceMock;
@Mock
ResponseGenerator responseGeneratorMock;
@Mock
VirtualMachine virtualMachineMock;
@Mock
Host hostMock;
@Spy
@InjectMocks
MigrateVirtualMachineWithVolumeCmd cmdSpy;
private Long hostId = 1L;
private Long virtualMachineId = 1L;
private String virtualMachineName = "VM-name";
private Map<String, String> migrateVolumeTo = null;
private SystemVmResponse systemVmResponse = new SystemVmResponse();
private UserVmResponse userVmResponse = new UserVmResponse();
@Before
public void setUp() throws Exception {
ReflectionTestUtils.setField(cmdSpy, "virtualMachineId", virtualMachineId);
migrateVolumeTo = new HashMap<>();
migrateVolumeTo.put("volume", "abc");
migrateVolumeTo.put("pool", "xyz");
}
@Test
public void executeTestRequiredArgsNullThrowsInvalidParameterValueException() {
ReflectionTestUtils.setField(cmdSpy, "hostId", null);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", null);
ReflectionTestUtils.setField(cmdSpy, "autoSelect", null);
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(InvalidParameterValueException.class, e.getClass());
String expected = String.format("Either %s or %s must be passed or %s must be true for migrating the VM.", ApiConstants.HOST_ID, ApiConstants.MIGRATE_TO, ApiConstants.AUTO_SELECT);
Assert.assertEquals(expected , e.getMessage());
}
}
@Test
public void executeTestVMIsStoppedAndHostIdIsNotNullThrowsInvalidParameterValueException() {
ReflectionTestUtils.setField(cmdSpy, "hostId", hostId);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", migrateVolumeTo);
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Stopped);
Mockito.when(virtualMachineMock.toString()).thenReturn(String.format("VM [uuid: %s, name: %s]", virtualMachineId, virtualMachineName));
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(InvalidParameterValueException.class, e.getClass());
String expected = String.format("%s is not in the Running state to migrate it to the new host.", virtualMachineMock);
Assert.assertEquals(expected , e.getMessage());
}
}
@Test
public void executeTestVMIsRunningHostIdIsNullAndAutoSelectIsFalseThrowsInvalidParameterValueException() {
ReflectionTestUtils.setField(cmdSpy, "hostId", null);
ReflectionTestUtils.setField(cmdSpy, "autoSelect", false);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", migrateVolumeTo);
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Running);
Mockito.when(virtualMachineMock.toString()).thenReturn(String.format("VM [uuid: %s, name: %s]", virtualMachineId, virtualMachineName));
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(InvalidParameterValueException.class, e.getClass());
String expected = String.format("%s is not in the Stopped state to migrate, use the %s or %s parameter to migrate it to a new host.", virtualMachineMock,
ApiConstants.HOST_ID, ApiConstants.AUTO_SELECT);
Assert.assertEquals(expected , e.getMessage());
}
}
@Test
public void executeTestHostIdIsNullThrowsInvalidParameterValueException() {
ReflectionTestUtils.setField(cmdSpy, "virtualMachineId", virtualMachineId);
ReflectionTestUtils.setField(cmdSpy, "hostId", hostId);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", migrateVolumeTo);
ReflectionTestUtils.setField(cmdSpy, "autoSelect", false);
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Running);
Mockito.when(resourceServiceMock.getHost(Mockito.anyLong())).thenReturn(null);
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(InvalidParameterValueException.class, e.getClass());
String expected = "Unable to find the specified host to migrate the VM.";
Assert.assertEquals(expected , e.getMessage());
}
}
private Map getMockedMigrateVolumeToApiCmdParam() {
Map<String, String> migrateVolumeTo = new HashMap<>();
migrateVolumeTo.put("volume", "abc");
migrateVolumeTo.put("pool", "xyz");
return Map.of("", migrateVolumeTo);
}
@Test
public void executeTestHostIsNotNullMigratedVMIsNullThrowsServerApiException() throws ManagementServerException, ResourceUnavailableException, VirtualMachineMigrationException {
ReflectionTestUtils.setField(cmdSpy, "hostId", hostId);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", getMockedMigrateVolumeToApiCmdParam());
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Running);
Mockito.when(resourceServiceMock.getHost(hostId)).thenReturn(hostMock);
Mockito.when(userVmServiceMock.migrateVirtualMachineWithVolume(Mockito.anyLong(), Mockito.any(), Mockito.anyMap())).thenReturn(null);
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(ServerApiException.class, e.getClass());
String expected = "Failed to migrate vm";
Assert.assertEquals(expected , e.getMessage());
}
}
@Test
public void executeTestHostIsNullMigratedVMIsNullThrowsServerApiException() {
ReflectionTestUtils.setField(cmdSpy, "hostId", null);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", getMockedMigrateVolumeToApiCmdParam());
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Stopped);
Mockito.when(userVmServiceMock.vmStorageMigration(Mockito.anyLong(), Mockito.anyMap())).thenReturn(null);
try {
cmdSpy.execute();
} catch (Exception e) {
Assert.assertEquals(ServerApiException.class, e.getClass());
String expected = "Failed to migrate vm";
Assert.assertEquals(expected , e.getMessage());
}
}
@Test
public void executeTestSystemVMMigratedWithSuccess() {
ReflectionTestUtils.setField(cmdSpy, "hostId", null);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", getMockedMigrateVolumeToApiCmdParam());
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getState()).thenReturn(VirtualMachine.State.Stopped);
Mockito.when(userVmServiceMock.vmStorageMigration(Mockito.anyLong(), Mockito.anyMap())).thenReturn(virtualMachineMock);
Mockito.when(virtualMachineMock.getType()).thenReturn(VirtualMachine.Type.ConsoleProxy);
Mockito.when(responseGeneratorMock.createSystemVmResponse(virtualMachineMock)).thenReturn(systemVmResponse);
cmdSpy.execute();
Mockito.verify(responseGeneratorMock, Mockito.times(1)).createSystemVmResponse(virtualMachineMock);
}
@Test
public void executeTestUserVMMigratedWithSuccess() {
UserVm userVmMock = Mockito.mock(UserVm.class);
ReflectionTestUtils.setField(cmdSpy, "hostId", null);
ReflectionTestUtils.setField(cmdSpy, "migrateVolumeTo", getMockedMigrateVolumeToApiCmdParam());
Mockito.when(userVmServiceMock.getVm(Mockito.anyLong())).thenReturn(userVmMock);
Mockito.when(userVmMock.getState()).thenReturn(VirtualMachine.State.Stopped);
Mockito.when(userVmServiceMock.vmStorageMigration(Mockito.anyLong(), Mockito.anyMap())).thenReturn(userVmMock);
Mockito.when(userVmMock.getType()).thenReturn(VirtualMachine.Type.User);
Mockito.when(responseGeneratorMock.createUserVmResponse(ResponseObject.ResponseView.Full, "virtualmachine", userVmMock)).thenReturn(List.of(userVmResponse));
cmdSpy.execute();
Mockito.verify(responseGeneratorMock, Mockito.times(1)).createUserVmResponse(ResponseObject.ResponseView.Full, "virtualmachine", userVmMock);
}
}