KVMBackupExportServiceImplTest

This commit is contained in:
Abhisar Sinha 2026-05-11 10:13:47 +05:30
parent b49453e41c
commit 77d7d43a4f
1 changed files with 177 additions and 0 deletions

View File

@ -20,7 +20,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -30,24 +34,39 @@ import java.util.List;
import java.util.Map;
import org.apache.cloudstack.api.command.admin.backup.StartBackupCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.backup.dao.ImageTransferDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.AccountService;
import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.dao.VMInstanceDetailsDao;
@ -72,9 +91,36 @@ public class KVMBackupExportServiceImplTest {
@Mock
ImageTransferDao imageTransferDao;
@Mock
AgentManager agentManager;
@Mock
HostDao hostDao;
@Mock
PrimaryDataStoreDao primaryDataStoreDao;
@Mock
AccountService accountService;
@Mock
VirtualMachineManager virtualMachineManager;
@Mock
BackupVO backup;
@Mock
VolumeVO volume;
@Mock
HostVO hostVO;
@Mock
CallContext callContext;
@Mock
User user;
VMInstanceVO vm;
@Before
@ -278,4 +324,135 @@ public class KVMBackupExportServiceImplTest {
verify(backupDao).update(10L, backup);
verify(backupDao).remove(10L);
}
@Test
public void finalizeImageTransfer_downloadStoppedVm_stopNbdFails_throwsAndDoesNotUpdate() throws Exception {
ImageTransferVO transfer = new ImageTransferVO("tx-download-fail", 11L, 21L, 31L, "sock",
ImageTransferVO.Phase.transferring, ImageTransfer.Direction.download, 1L, 1L, 1L);
ReflectionTestUtils.setField(transfer, "id", 501L);
when(imageTransferDao.findById(501L)).thenReturn(transfer);
when(backupDao.findById(11L)).thenReturn(backup);
when(backup.getHostId()).thenReturn(31L);
when(backup.getVmId()).thenReturn(41L);
when(vmInstanceDao.findById(41L)).thenReturn(vm);
when(vm.getState()).thenReturn(State.Stopped);
when(agentManager.send(eq(31L), any(Command.class))).thenReturn(
new Answer(null, true, null),
new Answer(null, false, "stop failed")
);
CloudRuntimeException ex = assertThrows(CloudRuntimeException.class,
() -> service.finalizeImageTransfer(501L));
assert ex.getMessage().contains("Failed to stop the nbd server");
verify(imageTransferDao, never()).update(eq(501L), any(ImageTransferVO.class));
verify(imageTransferDao, never()).remove(501L);
}
@Test
public void createImageTransfer_uploadFileBackend_success() throws Exception {
ReflectionTestUtils.setField(BackupManager.BackupFrameworkEnabled, "_value", Boolean.FALSE);
try (MockedStatic<CallContext> mocked = mockStatic(CallContext.class)) {
mocked.when(CallContext::current).thenReturn(callContext);
when(callContext.getCallingUser()).thenReturn(user);
when(volumeDao.findById(601L)).thenReturn(volume);
when(volume.getId()).thenReturn(601L);
when(volume.getDataCenterId()).thenReturn(1L);
when(volume.getPoolId()).thenReturn(701L);
when(volume.getPath()).thenReturn("vol-601.qcow2");
when(volume.getAccountId()).thenReturn(11L);
when(volume.getDomainId()).thenReturn(12L);
when(imageTransferDao.findByVolume(601L)).thenReturn(null);
StoragePoolVO pool = new StoragePoolVO();
pool.setId(701L);
pool.setScope(ScopeType.ZONE);
pool.setDataCenterId(1L);
pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
pool.setUuid("pool-701");
pool.setPath("/primary");
when(primaryDataStoreDao.findById(701L)).thenReturn(pool);
when(hostDao.findByDataCenterId(1L)).thenReturn(List.of(hostVO));
when(hostVO.getId()).thenReturn(801L);
when(hostVO.getDataCenterId()).thenReturn(1L);
when(agentManager.send(eq(801L), any(Command.class)))
.thenReturn(new CreateImageTransferAnswer(null, true, null, "ticket-1", "https://transfer/file"));
final ImageTransferVO[] persisted = new ImageTransferVO[1];
when(imageTransferDao.persist(any(ImageTransferVO.class))).thenAnswer(i -> {
persisted[0] = i.getArgument(0);
ReflectionTestUtils.setField(persisted[0], "id", 901L);
return persisted[0];
});
when(imageTransferDao.findById(901L)).thenAnswer(i -> persisted[0]);
ImageTransfer created = service.createImageTransfer(601L, null, ImageTransfer.Direction.upload, ImageTransfer.Format.cow);
assertNotNull(created);
assertEquals(901L, created.getId());
assertEquals(ImageTransfer.Direction.upload, created.getDirection());
verify(agentManager, times(1)).send(eq(801L), any(Command.class));
}
}
@Test
public void createImageTransfer_downloadStoppedVm_startsNbdAndCreatesTransfer() throws Exception {
ReflectionTestUtils.setField(BackupManager.BackupFrameworkEnabled, "_value", Boolean.FALSE);
try (MockedStatic<CallContext> mocked = mockStatic(CallContext.class)) {
mocked.when(CallContext::current).thenReturn(callContext);
when(callContext.getCallingUser()).thenReturn(user);
when(volumeDao.findById(602L)).thenReturn(volume);
when(volume.getId()).thenReturn(602L);
when(volume.getUuid()).thenReturn("vol-602");
when(volume.getDataCenterId()).thenReturn(1L);
when(volume.getPoolId()).thenReturn(702L);
when(volume.getPath()).thenReturn("vol-602.raw");
when(imageTransferDao.findByVolume(602L)).thenReturn(null);
StoragePoolVO pool = new StoragePoolVO();
pool.setId(702L);
pool.setScope(ScopeType.ZONE);
pool.setDataCenterId(1L);
pool.setPoolType(Storage.StoragePoolType.NetworkFilesystem);
pool.setUuid("pool-702");
when(primaryDataStoreDao.findById(702L)).thenReturn(pool);
when(backupDao.findById(612L)).thenReturn(backup);
when(backup.getVmId()).thenReturn(55L);
when(backup.getHostId()).thenReturn(802L);
when(backup.getUuid()).thenReturn("backup-612");
when(backup.getFromCheckpointId()).thenReturn("ckp-prev");
when(backup.getAccountId()).thenReturn(11L);
when(backup.getDomainId()).thenReturn(12L);
when(backup.getZoneId()).thenReturn(1L);
when(vmInstanceDao.findById(55L)).thenReturn(vm);
when(vm.getState()).thenReturn(State.Stopped);
when(vmInstanceDetailsDao.listDetailsKeyPairs(55L)).thenReturn(Map.of(VmDetailConstants.ACTIVE_CHECKPOINT_ID, "ckp-active"));
when(hostDao.findById(802L)).thenReturn(hostVO);
when(hostVO.getDataCenterId()).thenReturn(1L);
when(agentManager.send(eq(802L), any(Command.class))).thenReturn(
new StartNBDServerAnswer(null, true, null),
new CreateImageTransferAnswer(null, true, null, "ticket-2", "https://transfer/nbd")
);
final ImageTransferVO[] persisted = new ImageTransferVO[1];
when(imageTransferDao.persist(any(ImageTransferVO.class))).thenAnswer(i -> {
persisted[0] = i.getArgument(0);
ReflectionTestUtils.setField(persisted[0], "id", 902L);
return persisted[0];
});
when(imageTransferDao.findById(902L)).thenAnswer(i -> persisted[0]);
ImageTransfer created = service.createImageTransfer(602L, 612L, ImageTransfer.Direction.download, ImageTransfer.Format.raw);
assertNotNull(created);
assertEquals(902L, created.getId());
assertEquals(ImageTransfer.Direction.download, created.getDirection());
verify(agentManager, times(2)).send(eq(802L), any(Command.class));
}
}
}