blob: 8028e78c9073fe0cdb892ddd4a1b958bfbb015a7 [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 com.cloud.upgrade;
import static com.cloud.upgrade.SystemVmTemplateRegistration.DEFAULT_SYSTEM_VM_GUEST_OS_NAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.utils.security.DigestHelper;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import com.cloud.cpu.CPU;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterDetailsDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.Storage;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.HttpUtils;
import com.cloud.utils.Pair;
import com.cloud.utils.UriUtils;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import com.cloud.vm.dao.VMInstanceDao;
@RunWith(MockitoJUnitRunner.class)
public class SystemVmTemplateRegistrationTest {
@Mock
ClusterDao clusterDao;
@Mock
VMTemplateDao vmTemplateDao;
@Mock
GuestOSDao guestOSDao;
@Mock
TemplateDataStoreDao templateDataStoreDao;
@Mock
ConfigurationDao configurationDao;
@Mock
DataCenterDao dataCenterDao;
@Mock
DataCenterDetailsDao dataCenterDetailsDao;
@Mock
VMTemplateZoneDao vmTemplateZoneDao;
@Mock
ImageStoreDao imageStoreDao;
@Mock
ImageStoreDetailsDao imageStoreDetailsDao;
@Mock
VMInstanceDao vmInstanceDao;
@Spy
@InjectMocks
SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration();
@Before
public void setup() {
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.clear();
}
private void setupMetadataFile(MockedStatic<SystemVmTemplateRegistration> mockedStatic, String content) {
try {
String location = "metadata.ini";
if (StringUtils.isNotBlank(content)) {
File tempFile = File.createTempFile("metadata", ".ini");
location = tempFile.getAbsolutePath();
Files.write(Paths.get(location), content.getBytes());
tempFile.deleteOnExit();
}
mockedStatic.when(SystemVmTemplateRegistration::getMetadataFilePath).thenReturn(location);
} catch (Exception e) {
fail(e.getMessage());
}
}
@Test
public void test_parseMetadataFile_noFile() {
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
setupMetadataFile(mockedStatic, null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
SystemVmTemplateRegistration::parseMetadataFile);
assertTrue(exception.getMessage().contains("Failed to parse system VM Template metadata file"));
}
}
@Test
public void test_parseMetadataFile_invalidContent() {
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
setupMetadataFile(mockedStatic, "abc");
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
SystemVmTemplateRegistration::parseMetadataFile);
assertTrue(exception.getMessage().contains("Failed to parse system VM Template metadata file"));
}
}
@Test
public void test_parseMetadataFile_success() {
String metadataFileContent = "[default]\n" +
"version = x.y.z.0\n" +
"\n" +
"[kvm-x86_64]\n" +
"templatename = systemvm-kvm-x.y.z\n" +
"checksum = abc1\n" +
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
"filename = systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
"\n" +
"[kvm-aarch64]\n" +
"templatename = systemvm-kvm-x.y.z\n" +
"checksum = abc2\n" +
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
"filename = systemvmtemplate-x.y.z-kvm.qcow2.bz2\n" +
"\n" +
"[vmware]\n" +
"templatename = systemvm-vmware-x.y.z\n" +
"checksum = abc3\n" +
"downloadurl = https://download.cloudstack.org/systemvm/x.y/systemvmtemplate-x.y.z-vmware.ova\n" +
"filename = systemvmtemplate-x.y.z-vmware.ova\n";
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) {
setupMetadataFile(mockedStatic, metadataFileContent);
String version = SystemVmTemplateRegistration.parseMetadataFile();
assertEquals("x.y.z.0", version);
}
assertNull(SystemVmTemplateRegistration.getMetadataTemplateDetails(Hypervisor.HypervisorType.XenServer,
CPU.CPUArch.getDefault()));
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
SystemVmTemplateRegistration.getMetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
CPU.CPUArch.amd64);
assertNotNull(templateDetails);
assertEquals(CPU.CPUArch.amd64, templateDetails.getArch());
assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType());
templateDetails =
SystemVmTemplateRegistration.getMetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
CPU.CPUArch.arm64);
assertNotNull(templateDetails);
assertEquals(CPU.CPUArch.arm64, templateDetails.getArch());
assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType());
templateDetails =
SystemVmTemplateRegistration.getMetadataTemplateDetails(Hypervisor.HypervisorType.VMware,
CPU.CPUArch.getDefault());
assertNotNull(templateDetails);
assertEquals(CPU.CPUArch.getDefault(), templateDetails.getArch());
assertEquals(Hypervisor.HypervisorType.VMware, templateDetails.getHypervisorType());
}
@Test
public void testMountStore_nullStoreUrl() throws Exception {
try (MockedStatic<Script> scriptMock = Mockito.mockStatic(Script.class)) {
SystemVmTemplateRegistration.mountStore(null, "/mnt/nfs", "nfs3");
scriptMock.verifyNoInteractions();
}
}
@Test
public void testMountStore_validStoreUrl() throws Exception {
String storeUrl = "nfs://192.168.1.100/export";
String path = "/mnt/nfs";
String nfsVersion = "nfs3";
String expectedMountCommand = "expectedMountCommand";
try (MockedStatic<UriUtils> uriUtilsMock = Mockito.mockStatic(UriUtils.class);
MockedStatic<SystemVmTemplateRegistration> sysVmMock =
Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS);
MockedStatic<Script> scriptMock = Mockito.mockStatic(Script.class)) {
uriUtilsMock.when(() -> UriUtils.encodeURIComponent(storeUrl)).thenReturn(storeUrl);
sysVmMock.when(() -> SystemVmTemplateRegistration.getMountCommand(
eq(nfsVersion),
eq("192.168.1.100:/export"),
eq(path)
)).thenReturn(expectedMountCommand);
SystemVmTemplateRegistration.mountStore(storeUrl, path, nfsVersion);
scriptMock.verify(() -> Script.runSimpleBashScript(expectedMountCommand), times(1));
}
}
@Test
public void testValidateTemplateFile_fileNotFound() {
SystemVmTemplateRegistration.MetadataTemplateDetails details =
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
"name", "file", "url", "checksum", CPU.CPUArch.amd64, "guestos");
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(null).when(systemVmTemplateRegistration).getTemplateFile(details);
try {
systemVmTemplateRegistration.getValidatedTemplateDetailsForHypervisorAndArch(details.getHypervisorType(),
details.getArch());
fail("Expected CloudRuntimeException due to missing template file");
} catch (CloudRuntimeException e) {
assertEquals("Failed to find local template file", e.getMessage());
}
}
@Test
public void testValidateTemplateFile_checksumMismatch() {
SystemVmTemplateRegistration.MetadataTemplateDetails details =
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
"name", "file", "url", "checksum", CPU.CPUArch.amd64, "guestos");
File dummyFile = new File("dummy.txt");
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(dummyFile).when(systemVmTemplateRegistration).getTemplateFile(details);
try (MockedStatic<DigestHelper> digestMock = Mockito.mockStatic(DigestHelper.class)) {
digestMock.when(() -> DigestHelper.calculateChecksum(dummyFile)).thenReturn("differentChecksum");
systemVmTemplateRegistration.getValidatedTemplateDetailsForHypervisorAndArch(details.getHypervisorType(),
details.getArch());
fail("Expected CloudRuntimeException due to checksum failure");
} catch (CloudRuntimeException e) {
assertEquals("Checksum failed for local template file", e.getMessage());
}
}
@Test
public void testValidateTemplateFile_success() {
SystemVmTemplateRegistration.MetadataTemplateDetails details =
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
"name", "file", "url", "checksum", CPU.CPUArch.amd64, "guestos");
File dummyFile = new File("dummy.txt");
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(dummyFile).when(systemVmTemplateRegistration).getTemplateFile(details);
try (MockedStatic<DigestHelper> digestMock = Mockito.mockStatic(DigestHelper.class)) {
digestMock.when(() -> DigestHelper.calculateChecksum(dummyFile)).thenReturn("checksum");
systemVmTemplateRegistration.getValidatedTemplateDetailsForHypervisorAndArch(details.getHypervisorType(),
details.getArch());
}
}
@Test
public void testValidateAndAddExistingTemplateToStore() {
long zoneId = 1L;
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
VMTemplateVO templateVO = new VMTemplateVO();
templateVO.setHypervisorType(hypervisor);
templateVO.setArch(CPU.CPUArch.getDefault());
TemplateDataStoreVO templateDataStoreVO = new TemplateDataStoreVO();
Long storeId = 123L;
String filePath = "/dummy/path";
SystemVmTemplateRegistration.MetadataTemplateDetails details =
mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
doReturn(details).when(systemVmTemplateRegistration)
.getValidatedTemplateDetailsForHypervisorAndArch(hypervisor, templateVO.getArch());
doNothing().when(systemVmTemplateRegistration).addExistingTemplateToStore(templateVO, details,
templateDataStoreVO, zoneId, storeId, filePath);
systemVmTemplateRegistration.validateAndAddTemplateToStore(templateVO, templateDataStoreVO, zoneId, storeId,
filePath);
verify(systemVmTemplateRegistration)
.getValidatedTemplateDetailsForHypervisorAndArch(hypervisor, templateVO.getArch());
verify(systemVmTemplateRegistration).addExistingTemplateToStore(templateVO, details, templateDataStoreVO,
zoneId, storeId, filePath);
}
@Test
public void testValidateAndAddExistingTemplateToStoreForNonExistingEntries() {
long zoneId = 1L;
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
String name = "TestTemplateNonExisting";
long storeId = 123L;
String filePath = "/dummy/path/nonexisting";
SystemVmTemplateRegistration.MetadataTemplateDetails details =
mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
doReturn(details).when(systemVmTemplateRegistration)
.getValidatedTemplateDetailsForHypervisorAndArch(hypervisor, arch);
doNothing().when(systemVmTemplateRegistration).registerNewTemplate(name, details, zoneId, storeId, filePath);
systemVmTemplateRegistration.validateAndRegisterNewTemplate(hypervisor, arch, name, zoneId, storeId, filePath);
verify(systemVmTemplateRegistration).getValidatedTemplateDetailsForHypervisorAndArch(hypervisor, arch);
verify(systemVmTemplateRegistration).registerNewTemplate(name, details, zoneId, storeId, filePath);
}
@Test
public void testGetTemplateFile_fileExists() throws Exception {
File tempFile = File.createTempFile("template", ".qcow2");
tempFile.deleteOnExit();
SystemVmTemplateRegistration.MetadataTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(details.getDefaultFilePath()).thenReturn(tempFile.getAbsolutePath());
File result = systemVmTemplateRegistration.getTemplateFile(details);
assertNotNull(result);
assertEquals(tempFile.getAbsolutePath(), result.getAbsolutePath());
}
@Test
public void testGetTemplateFile_fileDoesNotExist_downloadFails() {
SystemVmTemplateRegistration.MetadataTemplateDetails details =
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
"name", "nonexistent.qcow2", "http://example.com/file.qcow2",
"", CPU.CPUArch.arm64, "guestos");
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
MockedStatic<HttpUtils> httpMock = Mockito.mockStatic(HttpUtils.class)) {
filesMock.when(() -> Files.isWritable(any(Path.class))).thenReturn(true);
httpMock.when(() -> HttpUtils.downloadFileWithProgress(eq(details.getUrl()), anyString(), any()))
.thenReturn(false);
File result = systemVmTemplateRegistration.getTemplateFile(details);
assertNull(result);
}
}
@Test
public void testGetTemplateFile_fileDoesNotExist_downloadSucceeds() {
SystemVmTemplateRegistration.MetadataTemplateDetails details =
new SystemVmTemplateRegistration.MetadataTemplateDetails(Hypervisor.HypervisorType.KVM,
"name", "file.qcow2", "http://example.com/file.qcow2",
"", CPU.CPUArch.arm64, "guestos");
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
MockedStatic<HttpUtils> httpMock = Mockito.mockStatic(HttpUtils.class)) {
filesMock.when(() -> Files.isWritable(any(Path.class))).thenReturn(false);
File expectedFile = new File(systemVmTemplateRegistration.getTempDownloadDir(), details.getFilename());
httpMock.when(() -> HttpUtils.downloadFileWithProgress(eq(details.getUrl()), eq(expectedFile.getAbsolutePath()), any()))
.thenReturn(true);
File result = systemVmTemplateRegistration.getTemplateFile(details);
assertNotNull(result);
assertEquals(expectedFile.getAbsolutePath(), result.getAbsolutePath());
assertEquals(expectedFile.getAbsolutePath(), details.getDownloadedFilePath());
}
}
@Test
public void testValidateTemplates_metadataTemplateSkip() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.VMware;
CPU.CPUArch arch = CPU.CPUArch.arm64;
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
list.add(new Pair<>(hypervisorType, arch));
systemVmTemplateRegistration.validateTemplates(list);
verify(systemVmTemplateRegistration, never()).getValidatedTemplateDetailsForHypervisorAndArch(hypervisorType,
arch);
}
@Test(expected = CloudRuntimeException.class)
public void testValidateTemplates_fileFailure() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
list.add(new Pair<>(hypervisorType, arch));
SystemVmTemplateRegistration.MetadataTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(details.getHypervisorType()).thenReturn(hypervisorType);
when(details.getArch()).thenReturn(arch);
File mockFile = Mockito.mock(File.class);
when(details.isFileChecksumDifferent(mockFile)).thenReturn(true);
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(mockFile).when(systemVmTemplateRegistration).getTemplateFile(details);
systemVmTemplateRegistration.validateTemplates(list);
}
@Test(expected = CloudRuntimeException.class)
public void testValidateTemplates_downloadableFileNotFound() {
CPU.CPUArch arch = SystemVmTemplateRegistration.DOWNLOADABLE_TEMPLATE_ARCH_TYPES.get(0);
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
list.add(new Pair<>(hypervisorType, arch));
SystemVmTemplateRegistration.MetadataTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(details.getHypervisorType()).thenReturn(hypervisorType);
when(details.getArch()).thenReturn(arch);
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(null).when(systemVmTemplateRegistration).getTemplateFile(details);
systemVmTemplateRegistration.validateTemplates(list);
}
@Test
public void testValidateTemplates_success() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> list = new ArrayList<>();
list.add(new Pair<>(hypervisorType, arch));
SystemVmTemplateRegistration.MetadataTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(details.getHypervisorType()).thenReturn(hypervisorType);
when(details.getArch()).thenReturn(arch);
File mockFile = Mockito.mock(File.class);
when(details.isFileChecksumDifferent(mockFile)).thenReturn(false);
SystemVmTemplateRegistration.METADATA_TEMPLATE_LIST.add(details);
doReturn(mockFile).when(systemVmTemplateRegistration).getTemplateFile(details);
systemVmTemplateRegistration.validateTemplates(list);
}
@Test
public void testAddExistingTemplatesForZoneToStore() {
long zoneId = 1L;
String filePath = "dummyFilePath";
String nfsVersion = "nfs3";
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 100L);
String name = "existing";
String url = "url";
doReturn(storeUrlAndId).when(systemVmTemplateRegistration).getNfsStoreInZone(zoneId);
doReturn(nfsVersion).when(systemVmTemplateRegistration).getNfsVersion(storeUrlAndId.second());
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(
SystemVmTemplateRegistration.class)) {
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList = new ArrayList<>();
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.getDefault();
hypervisorArchList.add(new Pair<>(hypervisorType, arch));
doReturn(hypervisorArchList).when(clusterDao).listDistinctHypervisorsAndArchExcludingExternalType(zoneId);
SystemVmTemplateRegistration.MetadataTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(details.getArch()).thenReturn(CPU.CPUArch.getDefault());
when(details.getName()).thenReturn(name);
when(details.getUrl()).thenReturn(url);
mockedStatic.when(() -> SystemVmTemplateRegistration.getMetadataTemplateDetails(Mockito.any(),
Mockito.any())).thenReturn(details);
doNothing().when(systemVmTemplateRegistration).registerNewTemplate(name, details, zoneId,
storeUrlAndId.second(), filePath);
systemVmTemplateRegistration.registerTemplatesForZone(zoneId, filePath);
mockedStatic.verify(() -> SystemVmTemplateRegistration.mountStore(storeUrlAndId.first(), filePath,
nfsVersion));
verify(systemVmTemplateRegistration).registerNewTemplate(name, details, zoneId,
storeUrlAndId.second(), filePath);
}
}
@Test
public void updateOrRegisterSystemVmTemplate_UpdatesRegisteredTemplate() {
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getName()).thenReturn("templateName");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
VMTemplateVO registeredTemplate = Mockito.mock(VMTemplateVO.class);
when(registeredTemplate.getId()).thenReturn(1L);
doReturn(registeredTemplate).when(systemVmTemplateRegistration).getRegisteredTemplate(
"templateName", Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "http://example.com/template");
doNothing().when(systemVmTemplateRegistration).updateRegisteredTemplateDetails(1L, templateDetails,
null);
boolean result = systemVmTemplateRegistration.updateOrRegisterSystemVmTemplate(templateDetails,
new ArrayList<>());
assertFalse(result);
verify(systemVmTemplateRegistration).updateRegisteredTemplateDetails(1L, templateDetails, null);
}
@Test
public void updateOrRegisterSystemVmTemplate_SkipsUnusedHypervisorArch() {
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getName()).thenReturn("templateName");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
doReturn(null).when(systemVmTemplateRegistration).getRegisteredTemplate(
"templateName", Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "http://example.com/template");
doReturn(null).when(vmTemplateDao).findLatestTemplateByTypeAndHypervisorAndArch(
Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, Storage.TemplateType.SYSTEM);
boolean result = systemVmTemplateRegistration.updateOrRegisterSystemVmTemplate(templateDetails, new ArrayList<>());
assertFalse(result);
verify(systemVmTemplateRegistration, never()).registerTemplates(anyList());
}
@Test
public void updateOrRegisterSystemVmTemplate_RegistersNewTemplate() {
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getName()).thenReturn("templateName");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
doReturn(null).when(systemVmTemplateRegistration).getRegisteredTemplate(
"templateName", Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "http://example.com/template");
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse = new ArrayList<>();
hypervisorsInUse.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
doNothing().when(systemVmTemplateRegistration).registerTemplates(hypervisorsInUse);
boolean result = systemVmTemplateRegistration.updateOrRegisterSystemVmTemplate(templateDetails, hypervisorsInUse);
assertTrue(result);
verify(systemVmTemplateRegistration).registerTemplates(eq(hypervisorsInUse));
}
@Test
public void updateOrRegisterSystemVmTemplate_ThrowsExceptionOnRegistrationFailure() {
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getName()).thenReturn("templateName");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
doReturn(null).when(systemVmTemplateRegistration).getRegisteredTemplate(
"templateName", Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64, "http://example.com/template");
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorsInUse = new ArrayList<>();
hypervisorsInUse.add(new Pair<>(Hypervisor.HypervisorType.KVM, CPU.CPUArch.amd64));
doThrow(new CloudRuntimeException("Registration failed")).when(systemVmTemplateRegistration).registerTemplates(hypervisorsInUse);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
() -> systemVmTemplateRegistration.updateOrRegisterSystemVmTemplate(templateDetails, hypervisorsInUse));
assertTrue(exception.getMessage().contains("Failed to register"));
}
@Test
public void updateRegisteredTemplateDetails_UpdatesTemplateSuccessfully() {
Long templateId = 1L;
Long zoneId = 2L;
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
GuestOSVO guestOS = Mockito.mock(GuestOSVO.class);
when(templateDetails.getGuestOs()).thenReturn("Debian");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getName()).thenReturn("templateName");
when(vmTemplateDao.findById(templateId)).thenReturn(templateVO);
when(guestOSDao.findOneByDisplayName("Debian")).thenReturn(guestOS);
when(guestOS.getId()).thenReturn(10L);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(true);
doNothing().when(systemVmTemplateRegistration).updateSystemVMEntries(templateId, Hypervisor.HypervisorType.KVM);
doNothing().when(systemVmTemplateRegistration).updateConfigurationParams(Hypervisor.HypervisorType.KVM,
"templateName", zoneId);
systemVmTemplateRegistration.updateRegisteredTemplateDetails(templateId, templateDetails, zoneId);
verify(templateVO).setTemplateType(Storage.TemplateType.SYSTEM);
verify(templateVO).setGuestOSId(10);
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
verify(systemVmTemplateRegistration).updateSystemVMEntries(templateId, Hypervisor.HypervisorType.KVM);
verify(systemVmTemplateRegistration).updateConfigurationParams(Hypervisor.HypervisorType.KVM,
"templateName", zoneId);
}
@Test
public void updateRegisteredTemplateDetails_ThrowsExceptionWhenUpdateFails() {
Long templateId = 1L;
Long zoneId = 2L;
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
when(templateDetails.getGuestOs()).thenReturn("Debian");
when(vmTemplateDao.findById(templateId)).thenReturn(templateVO);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(false);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
() -> systemVmTemplateRegistration.updateRegisteredTemplateDetails(templateId, templateDetails, zoneId));
assertTrue(exception.getMessage().contains("Exception while updating template with id"));
verify(systemVmTemplateRegistration, never()).updateSystemVMEntries(anyLong(), any());
verify(systemVmTemplateRegistration, never()).updateConfigurationParams(any(), any(), any());
}
@Test
public void updateRegisteredTemplateDetails_SkipsGuestOSUpdateWhenNotFound() {
Long templateId = 1L;
Long zoneId = 2L;
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
when(templateDetails.getGuestOs()).thenReturn("NonExistentOS");
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getName()).thenReturn("templateName");
when(vmTemplateDao.findById(templateId)).thenReturn(templateVO);
when(guestOSDao.findOneByDisplayName("NonExistentOS")).thenReturn(null);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(true);
doNothing().when(systemVmTemplateRegistration).updateSystemVMEntries(templateId, Hypervisor.HypervisorType.KVM);
doNothing().when(systemVmTemplateRegistration).updateConfigurationParams(Hypervisor.HypervisorType.KVM,
"templateName", zoneId);
systemVmTemplateRegistration.updateRegisteredTemplateDetails(templateId, templateDetails, zoneId);
verify(templateVO, never()).setGuestOSId(anyInt());
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
verify(systemVmTemplateRegistration).updateSystemVMEntries(templateId, Hypervisor.HypervisorType.KVM);
verify(systemVmTemplateRegistration).updateConfigurationParams(Hypervisor.HypervisorType.KVM,
"templateName", zoneId);
}
@Test
public void registerTemplatesForZone_SuccessfullyRegistersNewTemplate() {
long zoneId = 1L;
String storeMountPath = "/mnt/nfs";
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 100L);
String nfsVersion = "nfs3";
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList = new ArrayList<>();
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
hypervisorArchList.add(new Pair<>(hypervisorType, arch));
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getHypervisorType()).thenReturn(hypervisorType);
when(templateDetails.getArch()).thenReturn(arch);
String name = "TestTemplate";
String url = "http://example.com/template";
when(templateDetails.getName()).thenReturn(name);
when(templateDetails.getUrl()).thenReturn(url);
doReturn(storeUrlAndId).when(systemVmTemplateRegistration).getNfsStoreInZone(zoneId);
doReturn(nfsVersion).when(systemVmTemplateRegistration).getNfsVersion(storeUrlAndId.second());
doReturn(null).when(systemVmTemplateRegistration).getRegisteredTemplate(
name, hypervisorType, arch, url);
doNothing().when(systemVmTemplateRegistration).registerNewTemplate(
name, templateDetails, zoneId, storeUrlAndId.second(), storeMountPath);
doReturn(hypervisorArchList).when(clusterDao).listDistinctHypervisorsAndArchExcludingExternalType(zoneId);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
mockedStatic.when(() -> SystemVmTemplateRegistration.getMetadataTemplateDetails(
hypervisorType, arch)).thenReturn(templateDetails);
systemVmTemplateRegistration.registerTemplatesForZone(zoneId, storeMountPath);
mockedStatic.verify(() -> SystemVmTemplateRegistration.mountStore(
eq(storeUrlAndId.first()), eq(storeMountPath), eq(nfsVersion)), times(1));
verify(systemVmTemplateRegistration).registerNewTemplate(
templateDetails.getName(), templateDetails, zoneId, storeUrlAndId.second(), storeMountPath);
}
}
@Test
public void registerTemplatesForZone_SkipsWhenTemplateDetailsNotFound() {
long zoneId = 1L;
String storeMountPath = "/mnt/nfs";
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 100L);
String nfsVersion = "nfs3";
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList = new ArrayList<>();
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
hypervisorArchList.add(new Pair<>(hypervisorType, arch));
doReturn(storeUrlAndId).when(systemVmTemplateRegistration).getNfsStoreInZone(zoneId);
doReturn(nfsVersion).when(systemVmTemplateRegistration).getNfsVersion(storeUrlAndId.second());
doReturn(hypervisorArchList).when(clusterDao).listDistinctHypervisorsAndArchExcludingExternalType(zoneId);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
mockedStatic.when(() -> SystemVmTemplateRegistration.getMetadataTemplateDetails(
hypervisorType, arch)).thenReturn(null);
systemVmTemplateRegistration.registerTemplatesForZone(zoneId, storeMountPath);
mockedStatic.verify(() -> SystemVmTemplateRegistration.mountStore(
eq(storeUrlAndId.first()), eq(storeMountPath), eq(nfsVersion)), times(1));
verify(systemVmTemplateRegistration, never()).registerNewTemplate(any(), any(), anyLong(), anyLong(), any());
}
}
@Test
public void registerTemplatesForZone_AddsExistingTemplateToStore() {
long zoneId = 1L;
String storeMountPath = "/mnt/nfs";
Pair<String, Long> storeUrlAndId = new Pair<>("nfs://dummy", 100L);
String nfsVersion = "nfs3";
List<Pair<Hypervisor.HypervisorType, CPU.CPUArch>> hypervisorArchList = new ArrayList<>();
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
CPU.CPUArch arch = CPU.CPUArch.amd64;
hypervisorArchList.add(new Pair<>(hypervisorType, arch));
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getHypervisorType()).thenReturn(hypervisorType);
when(templateDetails.getArch()).thenReturn(arch);
String name = "TestTemplate";
String url = "http://example.com/template";
when(templateDetails.getName()).thenReturn(name);
when(templateDetails.getUrl()).thenReturn(url);
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
long templateId = 100L;
when(templateVO.getId()).thenReturn(templateId);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
String installPath = "/template/install/path";
when(templateDataStoreVO.getInstallPath()).thenReturn(installPath);
doReturn(storeUrlAndId).when(systemVmTemplateRegistration).getNfsStoreInZone(zoneId);
doReturn(nfsVersion).when(systemVmTemplateRegistration).getNfsVersion(storeUrlAndId.second());
doReturn(hypervisorArchList).when(clusterDao).listDistinctHypervisorsAndArchExcludingExternalType(zoneId);
doReturn(templateVO).when(systemVmTemplateRegistration).getRegisteredTemplate(name, hypervisorType, arch, url);
doReturn(templateDataStoreVO).when(templateDataStoreDao)
.findByStoreTemplate(storeUrlAndId.second(), templateId);
doReturn(false).when(systemVmTemplateRegistration).validateIfSeeded(
templateDataStoreVO, storeUrlAndId.first(), installPath, nfsVersion);
doNothing().when(systemVmTemplateRegistration).addExistingTemplateToStore(
templateVO, templateDetails, templateDataStoreVO, zoneId, storeUrlAndId.second(), storeMountPath);
doNothing().when(systemVmTemplateRegistration).updateRegisteredTemplateDetails(
templateId, templateDetails, zoneId);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
mockedStatic.when(() -> SystemVmTemplateRegistration.getMetadataTemplateDetails(
hypervisorType, arch)).thenReturn(templateDetails);
systemVmTemplateRegistration.registerTemplatesForZone(zoneId, storeMountPath);
verify(systemVmTemplateRegistration).addExistingTemplateToStore(
templateVO, templateDetails, templateDataStoreVO, zoneId, storeUrlAndId.second(), storeMountPath);
verify(systemVmTemplateRegistration).updateRegisteredTemplateDetails(templateId, templateDetails, zoneId);
}
}
@Test
public void performTemplateRegistrationOperations_CreatesNewTemplateWhenNotExists() {
String name = "TestTemplate";
String url = "http://example.com/template";
String checksum = "abc123";
Storage.ImageFormat format = Storage.ImageFormat.QCOW2;
long guestOsId = 1L;
Long storeId = 100L;
Long templateId = null;
String filePath = "/mnt/nfs";
TemplateDataStoreVO templateDataStoreVO = null;
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
doReturn(new VMTemplateVO()).when(vmTemplateDao).persist(any());
doNothing().when(systemVmTemplateRegistration).createCrossZonesTemplateZoneRefEntries(anyLong());
doNothing().when(systemVmTemplateRegistration).createTemplateStoreRefEntry(any());
doNothing().when(systemVmTemplateRegistration).setupTemplateOnStore(anyString(), any(), anyString());
doNothing().when(systemVmTemplateRegistration).readTemplateProperties(anyString(), any());
doNothing().when(systemVmTemplateRegistration).updateTemplateDetails(any());
Long result = systemVmTemplateRegistration.performTemplateRegistrationOperations(name, templateDetails, url, checksum, format, guestOsId, storeId, templateId, filePath, templateDataStoreVO);
assertNotNull(result);
verify(vmTemplateDao).persist(any());
verify(systemVmTemplateRegistration).createCrossZonesTemplateZoneRefEntries(anyLong());
verify(systemVmTemplateRegistration).createTemplateStoreRefEntry(any());
verify(systemVmTemplateRegistration).setupTemplateOnStore(anyString(), any(), anyString());
verify(systemVmTemplateRegistration).updateTemplateDetails(any());
}
@Test
public void performTemplateRegistrationOperations_UpdatesExistingTemplate() {
String name = "TestTemplate";
String url = "http://example.com/template";
String checksum = "abc123";
Storage.ImageFormat format = Storage.ImageFormat.QCOW2;
long guestOsId = 1L;
Long storeId = 100L;
Long templateId = 1L;
String filePath = "/mnt/nfs";
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
doNothing().when(systemVmTemplateRegistration).createCrossZonesTemplateZoneRefEntries(anyLong());
doNothing().when(systemVmTemplateRegistration).setupTemplateOnStore(anyString(), any(), anyString());
doNothing().when(systemVmTemplateRegistration).readTemplateProperties(anyString(), any());
doNothing().when(systemVmTemplateRegistration).updateTemplateDetails(any());
Long result = systemVmTemplateRegistration.performTemplateRegistrationOperations(name, templateDetails, url, checksum, format, guestOsId, storeId, templateId, filePath, templateDataStoreVO);
assertNotNull(result);
assertEquals(templateId, result);
verify(vmTemplateDao, never()).persist(any());
verify(systemVmTemplateRegistration).createCrossZonesTemplateZoneRefEntries(anyLong());
verify(systemVmTemplateRegistration, never()).createTemplateStoreRefEntry(any());
verify(systemVmTemplateRegistration).setupTemplateOnStore(anyString(), any(), anyString());
verify(systemVmTemplateRegistration).updateTemplateDetails(any());
}
@Test
public void performTemplateRegistrationOperations_ThrowsExceptionWhenTemplateCreationFails() {
String name = "TestTemplate";
String url = "http://example.com/template";
String checksum = "abc123";
Storage.ImageFormat format = Storage.ImageFormat.QCOW2;
long guestOsId = 1L;
Long storeId = 100L;
Long templateId = null;
String filePath = "/mnt/nfs";
TemplateDataStoreVO templateDataStoreVO = null;
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
when(templateDetails.getArch()).thenReturn(CPU.CPUArch.amd64);
doReturn(null).when(vmTemplateDao).persist(any());
assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.performTemplateRegistrationOperations(name, templateDetails, url, checksum, format, guestOsId, storeId, templateId, filePath, templateDataStoreVO);
});
verify(vmTemplateDao).persist(any());
verify(systemVmTemplateRegistration, never()).createCrossZonesTemplateZoneRefEntries(anyLong());
verify(systemVmTemplateRegistration, never()).createTemplateStoreRefEntry(any());
verify(systemVmTemplateRegistration, never()).setupTemplateOnStore(anyString(), any(), anyString());
verify(systemVmTemplateRegistration, never()).updateTemplateDetails(any());
}
@Test
public void setupTemplateOnStore_ThrowsExceptionWhenScriptNotFound() {
String templateName = "templateName";
String destTempFolder = "/tmp/folder";
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
try (MockedStatic<Script> scriptMock = Mockito.mockStatic(Script.class)) {
scriptMock.when(() -> Script.findScript(SystemVmTemplateRegistration.STORAGE_SCRIPTS_DIR,
"setup-sysvm-tmplt")).thenReturn(null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.setupTemplateOnStore(templateName, templateDetails, destTempFolder);
});
assertTrue(exception.getMessage().contains("Unable to find the setup-sysvm-tmplt script"));
}
}
@Test
public void updateTemplateEntriesOnFailure_RemovesTemplateAndDataStoreEntry() {
long templateId = 1L;
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(vmTemplateDao.createForUpdate(templateId)).thenReturn(template);
when(template.getId()).thenReturn(templateId);
when(templateDataStoreDao.findByTemplate(templateId, DataStoreRole.Image)).thenReturn(templateDataStoreVO);
systemVmTemplateRegistration.updateTemplateEntriesOnFailure(templateId);
verify(vmTemplateDao).update(templateId, template);
verify(vmTemplateDao).remove(templateId);
verify(templateDataStoreDao).remove(templateDataStoreVO.getId());
}
@Test
public void updateTemplateEntriesOnFailure_SkipsDataStoreRemovalWhenNotFound() {
long templateId = 1L;
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
when(vmTemplateDao.createForUpdate(templateId)).thenReturn(template);
when(template.getId()).thenReturn(templateId);
when(templateDataStoreDao.findByTemplate(templateId, DataStoreRole.Image)).thenReturn(null);
systemVmTemplateRegistration.updateTemplateEntriesOnFailure(templateId);
verify(vmTemplateDao).update(templateId, template);
verify(vmTemplateDao).remove(templateId);
verify(templateDataStoreDao, never()).remove(anyLong());
}
@Test
public void updateConfigurationParams_UpdatesConfigurationSuccessfully() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
String templateName = "templateName";
long zoneId = 1L;
String configName = SystemVmTemplateRegistration.ROUTER_TEMPLATE_CONFIGURATION_NAMES.get(hypervisorType);
when(configurationDao.update(configName, templateName)).thenReturn(true);
when(configurationDao.update(SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY,
systemVmTemplateRegistration.getSystemVmTemplateVersion())).thenReturn(true);
systemVmTemplateRegistration.updateConfigurationParams(hypervisorType, templateName, zoneId);
verify(configurationDao).update(configName, templateName);
verify(dataCenterDetailsDao).removeDetail(zoneId, configName);
verify(configurationDao).update(SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY,
systemVmTemplateRegistration.getSystemVmTemplateVersion());
verify(dataCenterDetailsDao).removeDetail(zoneId, SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY);
}
@Test
public void updateConfigurationParams_ThrowsExceptionWhenConfigUpdateFails() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
String templateName = "templateName";
Long zoneId = 1L;
String configName = SystemVmTemplateRegistration.ROUTER_TEMPLATE_CONFIGURATION_NAMES.get(hypervisorType);
when(configurationDao.update(configName, templateName)).thenReturn(false);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.updateConfigurationParams(hypervisorType, templateName, zoneId);
});
assertTrue(exception.getMessage().contains("Failed to update configuration parameter"));
verify(configurationDao).update(configName, templateName);
verify(dataCenterDetailsDao, never()).removeDetail(anyLong(), anyString());
}
@Test
public void updateConfigurationParams_SkipsZoneDetailsRemovalWhenZoneIdIsNull() {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.VMware;
String templateName = "templateName";
Long zoneId = null;
String configName = SystemVmTemplateRegistration.ROUTER_TEMPLATE_CONFIGURATION_NAMES.get(hypervisorType);
when(configurationDao.update(configName, templateName)).thenReturn(true);
when(configurationDao.update(SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY,
systemVmTemplateRegistration.getSystemVmTemplateVersion())).thenReturn(true);
systemVmTemplateRegistration.updateConfigurationParams(hypervisorType, templateName, zoneId);
verify(configurationDao).update(configName, templateName);
verify(dataCenterDetailsDao, never()).removeDetail(anyLong(), eq(configName));
verify(configurationDao).update(SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY,
systemVmTemplateRegistration.getSystemVmTemplateVersion());
verify(dataCenterDetailsDao, never()).removeDetail(anyLong(),
eq(SystemVmTemplateRegistration.MINIMUM_SYSTEM_VM_VERSION_KEY));
}
@Test
public void createOrUpdateTemplateZoneEntry_CreatesNewEntryWhenNotExists() {
long zoneId = 1L;
long templateId = 100L;
VMTemplateZoneVO newTemplateZoneVO = Mockito.mock(VMTemplateZoneVO.class);
when(vmTemplateZoneDao.findByZoneTemplate(zoneId, templateId)).thenReturn(null);
when(vmTemplateZoneDao.persist(any(VMTemplateZoneVO.class))).thenReturn(newTemplateZoneVO);
VMTemplateZoneVO result = systemVmTemplateRegistration.createOrUpdateTemplateZoneEntry(zoneId, templateId);
assertNotNull(result);
verify(vmTemplateZoneDao).persist(any(VMTemplateZoneVO.class));
}
@Test
public void createOrUpdateTemplateZoneEntry_UpdatesExistingEntry() {
long zoneId = 1L;
long templateId = 100L;
VMTemplateZoneVO existingTemplateZoneVO = Mockito.mock(VMTemplateZoneVO.class);
when(vmTemplateZoneDao.findByZoneTemplate(zoneId, templateId)).thenReturn(existingTemplateZoneVO);
when(vmTemplateZoneDao.update(existingTemplateZoneVO.getId(), existingTemplateZoneVO)).thenReturn(true);
VMTemplateZoneVO result = systemVmTemplateRegistration.createOrUpdateTemplateZoneEntry(zoneId, templateId);
assertNotNull(result);
verify(vmTemplateZoneDao).update(existingTemplateZoneVO.getId(), existingTemplateZoneVO);
}
@Test
public void createOrUpdateTemplateZoneEntry_ReturnsNullWhenUpdateFails() {
long zoneId = 1L;
long templateId = 100L;
VMTemplateZoneVO existingTemplateZoneVO = Mockito.mock(VMTemplateZoneVO.class);
when(vmTemplateZoneDao.findByZoneTemplate(zoneId, templateId)).thenReturn(existingTemplateZoneVO);
when(vmTemplateZoneDao.update(existingTemplateZoneVO.getId(), existingTemplateZoneVO)).thenReturn(false);
VMTemplateZoneVO result = systemVmTemplateRegistration.createOrUpdateTemplateZoneEntry(zoneId, templateId);
assertNull(result);
verify(vmTemplateZoneDao).update(existingTemplateZoneVO.getId(), existingTemplateZoneVO);
}
@Test
public void createCrossZonesTemplateZoneRefEntries_ThrowsExceptionWhenEntryCreationFails() {
long templateId = 100L;
DataCenterVO dataCenter = Mockito.mock(DataCenterVO.class);
List<DataCenterVO> dataCenters = List.of(dataCenter);
when(dataCenter.getId()).thenReturn(1L);
when(dataCenterDao.listAll()).thenReturn(dataCenters);
when(systemVmTemplateRegistration.createOrUpdateTemplateZoneEntry(1L, templateId)).thenReturn(null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.createCrossZonesTemplateZoneRefEntries(templateId);
});
assertTrue(exception.getMessage().contains("Failed to create template-zone record"));
}
@Test
public void createTemplateStoreRefEntry_CreatesEntrySuccessfully() {
SystemVmTemplateRegistration.SystemVMTemplateDetails details = Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(details.getStoreId()).thenReturn(1L);
when(details.getId()).thenReturn(100L);
when(templateDataStoreDao.persist(any(TemplateDataStoreVO.class))).thenReturn(templateDataStoreVO);
systemVmTemplateRegistration.createTemplateStoreRefEntry(details);
verify(templateDataStoreDao).persist(any(TemplateDataStoreVO.class));
}
@Test
public void createTemplateStoreRefEntry_ThrowsExceptionWhenCreationFails() {
SystemVmTemplateRegistration.SystemVMTemplateDetails details = Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
when(details.getStoreId()).thenReturn(1L);
when(details.getId()).thenReturn(100L);
when(templateDataStoreDao.persist(any(TemplateDataStoreVO.class))).thenReturn(null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.createTemplateStoreRefEntry(details);
});
assertTrue(exception.getMessage().contains("Failed to create template-store record"));
}
@Test
public void updateTemplateDetails_UpdatesTemplateAndStoreSuccessfully() {
SystemVmTemplateRegistration.SystemVMTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(details.getId()).thenReturn(1L);
when(details.getStoreId()).thenReturn(2L);
when(details.getSize()).thenReturn(1024L);
when(details.getPhysicalSize()).thenReturn(2048L);
when(template.getId()).thenReturn(1L);
when(vmTemplateDao.findById(1L)).thenReturn(template);
when(templateDataStoreDao.findByStoreTemplate(2L, 1L)).thenReturn(templateDataStoreVO);
when(templateDataStoreDao.update(anyLong(), any(TemplateDataStoreVO.class))).thenReturn(true);
systemVmTemplateRegistration.updateTemplateDetails(details);
verify(template).setSize(1024L);
verify(template).setState(VirtualMachineTemplate.State.Active);
verify(vmTemplateDao).update(template.getId(), template);
verify(templateDataStoreVO).setSize(1024L);
verify(templateDataStoreVO).setPhysicalSize(2048L);
verify(templateDataStoreVO).setDownloadPercent(100);
verify(templateDataStoreVO).setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
verify(templateDataStoreVO).setLastUpdated(details.getUpdated());
verify(templateDataStoreVO).setState(ObjectInDataStoreStateMachine.State.Ready);
verify(templateDataStoreDao).update(templateDataStoreVO.getId(), templateDataStoreVO);
}
@Test
public void updateTemplateDetails_ThrowsExceptionWhenStoreUpdateFails() {
SystemVmTemplateRegistration.SystemVMTemplateDetails details =
Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(details.getId()).thenReturn(1L);
when(details.getStoreId()).thenReturn(2L);
when(details.getSize()).thenReturn(1024L);
when(details.getPhysicalSize()).thenReturn(2048L);
when(template.getId()).thenReturn(1L);
when(vmTemplateDao.findById(1L)).thenReturn(template);
when(templateDataStoreDao.findByStoreTemplate(2L, 1L)).thenReturn(templateDataStoreVO);
when(templateDataStoreDao.update(anyLong(), any(TemplateDataStoreVO.class))).thenReturn(false);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.updateTemplateDetails(details);
});
assertTrue(exception.getMessage().contains("Failed to update template-store record"));
verify(templateDataStoreDao).update(templateDataStoreVO.getId(), templateDataStoreVO);
}
@Test
public void getNfsStoreInZone_ReturnsStoreDetailsWhenStoreExists() {
long zoneId = 1L;
ImageStoreVO storeVO = Mockito.mock(ImageStoreVO.class);
when(imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs")).thenReturn(storeVO);
when(storeVO.getUrl()).thenReturn("nfs://example.com/store");
when(storeVO.getId()).thenReturn(100L);
Pair<String, Long> result = systemVmTemplateRegistration.getNfsStoreInZone(zoneId);
assertNotNull(result);
assertEquals("nfs://example.com/store", result.first());
assertEquals(100L, result.second().longValue());
}
@Test
public void getNfsStoreInZone_ThrowsExceptionWhenStoreNotFound() {
long zoneId = 1L;
when(imageStoreDao.findOneByZoneAndProtocol(zoneId, "nfs")).thenReturn(null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.getNfsStoreInZone(zoneId);
});
assertTrue(exception.getMessage().contains("Failed to fetch NFS store in zone"));
}
@Test
public void readTemplateProperties_SetsTemplateSizesCorrectly() {
String path = "/template/path";
SystemVmTemplateRegistration.SystemVMTemplateDetails details = Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
Pair<Long, Long> templateSizes = new Pair<>(1024L, 2048L);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
mockedStatic.when(() -> SystemVmTemplateRegistration.readTemplatePropertiesSizes(path)).thenReturn(templateSizes);
systemVmTemplateRegistration.readTemplateProperties(path, details);
verify(details).setSize(1024L);
verify(details).setPhysicalSize(2048L);
}
}
@Test
public void readTemplateProperties_ThrowsExceptionWhenPathIsInvalid() {
String path = "/invalid/path";
SystemVmTemplateRegistration.SystemVMTemplateDetails details = Mockito.mock(SystemVmTemplateRegistration.SystemVMTemplateDetails.class);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
mockedStatic.when(() -> SystemVmTemplateRegistration.readTemplatePropertiesSizes(path))
.thenThrow(new CloudRuntimeException("Invalid path"));
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.readTemplateProperties(path, details);
});
assertTrue(exception.getMessage().contains("Invalid path"));
}
}
@Test
public void getEligibleZoneIds_ReturnsUniqueZoneIds() {
ImageStoreVO store1 = Mockito.mock(ImageStoreVO.class);
ImageStoreVO store2 = Mockito.mock(ImageStoreVO.class);
ImageStoreVO store3 = Mockito.mock(ImageStoreVO.class);
when(store1.getDataCenterId()).thenReturn(1L);
when(store2.getDataCenterId()).thenReturn(2L);
when(store3.getDataCenterId()).thenReturn(1L);
when(imageStoreDao.findByProtocol("nfs")).thenReturn(List.of(store1, store2, store3));
List<Long> result = systemVmTemplateRegistration.getEligibleZoneIds();
assertNotNull(result);
assertEquals(2, result.size());
assertTrue(result.contains(1L));
assertTrue(result.contains(2L));
}
@Test
public void getEligibleZoneIds_ReturnsEmptyListWhenNoStoresExist() {
when(imageStoreDao.findByProtocol("nfs")).thenReturn(new ArrayList<>());
List<Long> result = systemVmTemplateRegistration.getEligibleZoneIds();
assertNotNull(result);
assertTrue(result.isEmpty());
}
@Test
public void getNfsVersion_ReturnsStoreSpecificVersionWhenPresent() {
long storeId = 1L;
String configKey = "secstorage.nfs.version";
String expectedVersion = "nfs4";
Map<String, String> storeDetails = Map.of(configKey, expectedVersion);
when(imageStoreDetailsDao.getDetails(storeId)).thenReturn(storeDetails);
String result = systemVmTemplateRegistration.getNfsVersion(storeId);
assertNotNull(result);
assertEquals(expectedVersion, result);
}
@Test
public void getNfsVersion_ReturnsGlobalVersionWhenStoreSpecificVersionNotPresent() {
long storeId = 1L;
String expectedVersion = "nfs3";
ConfigurationVO globalConfig = Mockito.mock(ConfigurationVO.class);
when(imageStoreDetailsDao.getDetails(storeId)).thenReturn(null);
when(configurationDao.findByName(anyString())).thenReturn(globalConfig);
when(globalConfig.getValue()).thenReturn(expectedVersion);
String result = systemVmTemplateRegistration.getNfsVersion(storeId);
assertNotNull(result);
assertEquals(expectedVersion, result);
}
@Test
public void getNfsVersion_ReturnsNullWhenNoVersionConfigured() {
long storeId = 1L;
when(imageStoreDetailsDao.getDetails(storeId)).thenReturn(null);
when(configurationDao.findByName(anyString())).thenReturn(null);
String result = systemVmTemplateRegistration.getNfsVersion(storeId);
assertNull(result);
}
@Test
public void validateIfSeeded_ReturnsTrueWhenTemplateIsSeeded() throws Exception {
TemplateDataStoreVO templDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
String url = "nfs://example.com/store";
Path local = Files.createTempDirectory("local");
Files.createDirectory(local.resolve("template"));
String path = "/template/path";
String nfsVersion = "nfs3";
Path secondary = Files.createTempDirectory("secondary");
Files.createDirectory(secondary.resolve("template"));
Files.createFile(secondary.resolve("template").resolve("template.properties"));
String tempDir = secondary.toString();
Pair<Long, Long> templateSizes = new Pair<>(1024L, 2048L);
when(templDataStoreVO.getTemplateId()).thenReturn(1L);
when(templDataStoreVO.getDataStoreId()).thenReturn(2L);
doNothing().when(systemVmTemplateRegistration).updateSeededTemplateDetails(anyLong(), anyLong(), anyLong(), anyLong());
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
filesMock.when(() -> Files.createTempDirectory(SystemVmTemplateRegistration.TEMPORARY_SECONDARY_STORE)).thenReturn(Path.of(tempDir));
mockedStatic.when(() -> SystemVmTemplateRegistration.readTemplatePropertiesSizes(anyString())).thenReturn(templateSizes);
boolean result = systemVmTemplateRegistration.validateIfSeeded(templDataStoreVO, url, path, nfsVersion);
assertTrue(result);
verify(systemVmTemplateRegistration).updateSeededTemplateDetails(1L, 2L, 1024L, 2048L);
}
}
@Test
public void validateIfSeeded_ReturnsFalseWhenTemplateIsNotSeeded() throws Exception {
TemplateDataStoreVO templDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
String url = "nfs://example.com/store";
String path = "/template/path";
String nfsVersion = "nfs3";
String tempDir = "/tmp/secondary";
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class)) {
filesMock.when(() -> Files.createTempDirectory(SystemVmTemplateRegistration.TEMPORARY_SECONDARY_STORE)).thenReturn(Path.of(tempDir));
boolean result = systemVmTemplateRegistration.validateIfSeeded(templDataStoreVO, url, path, nfsVersion);
assertFalse(result);
verify(systemVmTemplateRegistration, never()).updateSeededTemplateDetails(anyLong(), anyLong(), anyLong(), anyLong());
}
}
@Test
public void validateIfSeeded_ThrowsExceptionWhenTempDirectoryCreationFails() {
TemplateDataStoreVO templDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
String url = "nfs://example.com/store";
String path = "/template/path";
String nfsVersion = "nfs3";
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class)) {
filesMock.when(() -> Files.createTempDirectory(SystemVmTemplateRegistration.TEMPORARY_SECONDARY_STORE)).thenThrow(IOException.class);
assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.validateIfSeeded(templDataStoreVO, url, path, nfsVersion);
});
}
}
@Test
public void validateIfSeeded_ThrowsExceptionWhenUnmountFails() throws Exception {
TemplateDataStoreVO templDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
String url = "nfs://example.com/store";
String path = "/template/path";
String nfsVersion = "nfs3";
String tempDir = "/tmp/secondary";
try (MockedStatic<Files> filesMock = Mockito.mockStatic(Files.class);
MockedStatic<SystemVmTemplateRegistration> mockedStatic = Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
filesMock.when(() -> Files.createTempDirectory(SystemVmTemplateRegistration.TEMPORARY_SECONDARY_STORE)).thenReturn(Path.of(tempDir));
mockedStatic.when(() -> SystemVmTemplateRegistration.unmountStore(anyString())).thenThrow(CloudRuntimeException.class);
assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.validateIfSeeded(templDataStoreVO, url, path, nfsVersion);
});
}
}
@Test
public void registerNewTemplate_RegistersTemplateSuccessfully() {
String name = "templateName";
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getUrl()).thenReturn("a");
when(templateDetails.getChecksum()).thenReturn("b");
long zoneId = 1L;
Long storeId = 2L;
String filePath = "/tmp/store";
Long templateId = 100L;
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
when(templateDetails.getHypervisorType()).thenReturn(hypervisor);
doReturn(templateId).when(systemVmTemplateRegistration)
.performTemplateRegistrationOperations(
name, templateDetails, "a", "b",
SystemVmTemplateRegistration.HYPERVISOR_IMAGE_FORMAT_MAP.get(hypervisor),
SystemVmTemplateRegistration.hypervisorGuestOsMap.get(hypervisor),
storeId, null, filePath, null);
doNothing().when(systemVmTemplateRegistration).updateConfigurationParams(hypervisor, name, zoneId);
doNothing().when(systemVmTemplateRegistration).updateSystemVMEntries(templateId, hypervisor);
systemVmTemplateRegistration.registerNewTemplate(name, templateDetails, zoneId, storeId, filePath);
verify(systemVmTemplateRegistration).performTemplateRegistrationOperations(
name, templateDetails, templateDetails.getUrl(), templateDetails.getChecksum(),
SystemVmTemplateRegistration.HYPERVISOR_IMAGE_FORMAT_MAP.get(hypervisor),
SystemVmTemplateRegistration.hypervisorGuestOsMap.get(hypervisor),
storeId, null, filePath, null);
verify(systemVmTemplateRegistration).updateConfigurationParams(hypervisor, name, zoneId);
verify(systemVmTemplateRegistration).updateSystemVMEntries(templateId, hypervisor);
}
@Test
public void registerNewTemplate_ThrowsExceptionWhenRegistrationFails() {
String name = "templateName";
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getUrl()).thenReturn("a");
when(templateDetails.getChecksum()).thenReturn("b");
long zoneId = 1L;
Long storeId = 2L;
String filePath = "/tmp/store";
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
when(templateDetails.getHypervisorType()).thenReturn(hypervisor);
doThrow(new CloudRuntimeException("Registration failed")).when(systemVmTemplateRegistration)
.performTemplateRegistrationOperations(
name, templateDetails, "a", "b",
SystemVmTemplateRegistration.HYPERVISOR_IMAGE_FORMAT_MAP.get(hypervisor),
SystemVmTemplateRegistration.hypervisorGuestOsMap.get(hypervisor),
storeId, null, filePath, null);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.registerNewTemplate(name, templateDetails, zoneId, storeId, filePath);
});
assertTrue(exception.getMessage().contains("Failed to register Template for"));
verify(systemVmTemplateRegistration).performTemplateRegistrationOperations(
name, templateDetails, templateDetails.getUrl(), templateDetails.getChecksum(),
SystemVmTemplateRegistration.HYPERVISOR_IMAGE_FORMAT_MAP.get(hypervisor),
SystemVmTemplateRegistration.hypervisorGuestOsMap.get(hypervisor),
storeId, null, filePath, null);
verify(systemVmTemplateRegistration, never()).updateConfigurationParams(any(), any(), anyLong());
verify(systemVmTemplateRegistration, never()).updateSystemVMEntries(anyLong(), any());
}
@Test
public void registerNewTemplate_CleansUpOnFailure() {
String name = "templateName";
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getUrl()).thenReturn("a");
when(templateDetails.getChecksum()).thenReturn("b");
long zoneId = 1L;
Long storeId = 2L;
String filePath = "/tmp/store";
Long templateId = 100L;
Hypervisor.HypervisorType hypervisor = Hypervisor.HypervisorType.KVM;
when(templateDetails.getHypervisorType()).thenReturn(hypervisor);
doReturn(templateId).when(systemVmTemplateRegistration)
.performTemplateRegistrationOperations(
name, templateDetails, "a", "b",
SystemVmTemplateRegistration.HYPERVISOR_IMAGE_FORMAT_MAP.get(hypervisor),
SystemVmTemplateRegistration.hypervisorGuestOsMap.get(hypervisor),
storeId, null, filePath, null);
doThrow(new CloudRuntimeException("Update failed")).when(systemVmTemplateRegistration)
.updateConfigurationParams(hypervisor, name, zoneId);
doNothing().when(systemVmTemplateRegistration).updateTemplateEntriesOnFailure(templateId);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.registerNewTemplate(name, templateDetails, zoneId, storeId, filePath);
});
assertTrue(exception.getMessage().contains("Failed to register Template for"));
verify(systemVmTemplateRegistration).updateTemplateEntriesOnFailure(templateId);
mockedStatic.verify(() -> SystemVmTemplateRegistration.cleanupStore(templateId, filePath));
}
}
@Test
public void addExistingTemplateToStore_AddsTemplateSuccessfully() {
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
when(templateVO.getId()).thenReturn(1L);
when(templateVO.getName()).thenReturn("templateName");
when(templateVO.getUrl()).thenReturn("http://example.com/template");
when(templateVO.getChecksum()).thenReturn("abc123");
when(templateVO.getFormat()).thenReturn(Storage.ImageFormat.QCOW2);
when(templateVO.getGuestOSId()).thenReturn(1L);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
long zoneId = 1L;
Long storeId = 2L;
String filePath = "/tmp/store";
doReturn(1L).when(systemVmTemplateRegistration)
.performTemplateRegistrationOperations("templateName", templateDetails,
"http://example.com/template", "abc123", Storage.ImageFormat.QCOW2,
1L, storeId, 1L, filePath, templateDataStoreVO);
systemVmTemplateRegistration.addExistingTemplateToStore(templateVO, templateDetails, templateDataStoreVO, zoneId, storeId, filePath);
verify(systemVmTemplateRegistration).performTemplateRegistrationOperations(
templateVO.getName(), templateDetails, templateVO.getUrl(), templateVO.getChecksum(),
templateVO.getFormat(), templateVO.getGuestOSId(), storeId, templateVO.getId(), filePath, templateDataStoreVO);
}
@Test
public void addExistingTemplateToStore_CleansUpOnFailure() {
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
when(templateVO.getId()).thenReturn(1L);
when(templateVO.getName()).thenReturn("templateName");
when(templateVO.getUrl()).thenReturn("http://example.com/template");
when(templateVO.getChecksum()).thenReturn("abc123");
when(templateVO.getFormat()).thenReturn(Storage.ImageFormat.QCOW2);
when(templateVO.getGuestOSId()).thenReturn(1L);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails =
Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
long zoneId = 1L;
Long storeId = 2L;
String filePath = "/tmp/store";
doThrow(new CloudRuntimeException("Operation failed")).when(systemVmTemplateRegistration)
.performTemplateRegistrationOperations("templateName", templateDetails,
"http://example.com/template", "abc123", Storage.ImageFormat.QCOW2,
1L, storeId, 1L, filePath, templateDataStoreVO);
try (MockedStatic<SystemVmTemplateRegistration> mockedStatic =
Mockito.mockStatic(SystemVmTemplateRegistration.class)) {
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.addExistingTemplateToStore(templateVO, templateDetails, templateDataStoreVO, zoneId, storeId, filePath);
});
assertTrue(exception.getMessage().contains("Failed to add"));
mockedStatic.verify(() -> SystemVmTemplateRegistration.cleanupStore(templateVO.getId(), filePath));
}
}
@Test
public void updateSeededTemplateDetails_UpdatesTemplateAndStoreSuccessfully() {
long templateId = 1L;
long storeId = 2L;
long size = 1024L;
long physicalSize = 2048L;
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
when(template.getId()).thenReturn(templateId);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(vmTemplateDao.findById(templateId)).thenReturn(template);
when(templateDataStoreDao.findByStoreTemplate(storeId, templateId)).thenReturn(templateDataStoreVO);
when(templateDataStoreDao.update(anyLong(), any(TemplateDataStoreVO.class))).thenReturn(true);
systemVmTemplateRegistration.updateSeededTemplateDetails(templateId, storeId, size, physicalSize);
verify(template).setSize(size);
verify(vmTemplateDao).update(template.getId(), template);
verify(templateDataStoreVO).setSize(size);
verify(templateDataStoreVO).setPhysicalSize(physicalSize);
verify(templateDataStoreVO).setLastUpdated(any(Date.class));
verify(templateDataStoreDao).update(templateDataStoreVO.getId(), templateDataStoreVO);
}
@Test
public void updateSeededTemplateDetails_ThrowsExceptionWhenStoreUpdateFails() {
long templateId = 1L;
long storeId = 2L;
long size = 1024L;
long physicalSize = 2048L;
VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
when(template.getId()).thenReturn(templateId);
TemplateDataStoreVO templateDataStoreVO = Mockito.mock(TemplateDataStoreVO.class);
when(vmTemplateDao.findById(templateId)).thenReturn(template);
when(templateDataStoreDao.findByStoreTemplate(storeId, templateId)).thenReturn(templateDataStoreVO);
when(templateDataStoreDao.update(anyLong(), any(TemplateDataStoreVO.class))).thenReturn(false);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.updateSeededTemplateDetails(templateId, storeId, size, physicalSize);
});
assertTrue(exception.getMessage().contains("Failed to update template-store record for seeded system VM Template"));
verify(templateDataStoreDao).update(templateDataStoreVO.getId(), templateDataStoreVO);
}
@Test
public void updateSystemVMEntries_UpdatesTemplateIdSuccessfully() {
long templateId = 1L;
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
systemVmTemplateRegistration.updateSystemVMEntries(templateId, hypervisorType);
verify(vmInstanceDao).updateSystemVmTemplateId(templateId, hypervisorType);
}
@Test
public void updateHypervisorGuestOsMap_UpdatesGuestOsMapSuccessfully() {
GuestOSVO guestOS = Mockito.mock(GuestOSVO.class);
when(guestOS.getId()).thenReturn(10L);
when(guestOSDao.findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME)).thenReturn(guestOS);
systemVmTemplateRegistration.updateHypervisorGuestOsMap();
verify(guestOSDao).findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME);
assertEquals(10, SystemVmTemplateRegistration.LINUX_12_ID.intValue());
assertEquals(10, SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.KVM).intValue());
assertEquals(10, SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.Hyperv).intValue());
assertEquals(10, SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.LXC).intValue());
assertEquals(10, SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.Ovm3).intValue());
}
@Test
public void updateHypervisorGuestOsMap_SkipsUpdateWhenGuestOsNotFound() {
Integer value = SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.KVM);
when(guestOSDao.findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME)).thenReturn(null);
systemVmTemplateRegistration.updateHypervisorGuestOsMap();
verify(guestOSDao).findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME);
assertEquals(value, SystemVmTemplateRegistration.hypervisorGuestOsMap.get(Hypervisor.HypervisorType.KVM));
}
@Test
public void updateHypervisorGuestOsMap_LogsWarningOnException() {
when(guestOSDao.findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME)).thenThrow(new RuntimeException("Database error"));
systemVmTemplateRegistration.updateHypervisorGuestOsMap();
verify(guestOSDao).findOneByDisplayName(DEFAULT_SYSTEM_VM_GUEST_OS_NAME);
}
@Test
public void updateTemplateUrlChecksumAndGuestOsId_UpdatesSuccessfully() {
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
GuestOSVO guestOS = Mockito.mock(GuestOSVO.class);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
when(templateDetails.getChecksum()).thenReturn("abc123");
when(templateDetails.getGuestOs()).thenReturn("Debian");
when(guestOSDao.findOneByDisplayName("Debian")).thenReturn(guestOS);
when(guestOS.getId()).thenReturn(10L);
when(templateVO.getId()).thenReturn(1L);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(true);
systemVmTemplateRegistration.updateTemplateUrlChecksumAndGuestOsId(templateVO, templateDetails);
verify(templateVO).setUrl("http://example.com/template");
verify(templateVO).setChecksum("abc123");
verify(templateVO).setGuestOSId(10L);
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
}
@Test
public void updateTemplateUrlChecksumAndGuestOsId_SkipsGuestOsUpdateWhenNotFound() {
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
when(templateDetails.getChecksum()).thenReturn("abc123");
when(templateDetails.getGuestOs()).thenReturn("NonExistentOS");
when(guestOSDao.findOneByDisplayName("NonExistentOS")).thenReturn(null);
when(templateVO.getId()).thenReturn(1L);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(true);
systemVmTemplateRegistration.updateTemplateUrlChecksumAndGuestOsId(templateVO, templateDetails);
verify(templateVO).setUrl("http://example.com/template");
verify(templateVO).setChecksum("abc123");
verify(templateVO, never()).setGuestOSId(anyLong());
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
}
@Test
public void updateTemplateUrlChecksumAndGuestOsId_ThrowsExceptionWhenUpdateFails() {
VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class);
SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = Mockito.mock(SystemVmTemplateRegistration.MetadataTemplateDetails.class);
when(templateDetails.getUrl()).thenReturn("http://example.com/template");
when(templateDetails.getChecksum()).thenReturn("abc123");
when(templateDetails.getGuestOs()).thenReturn("Debian");
when(templateVO.getId()).thenReturn(1L);
when(vmTemplateDao.update(templateVO.getId(), templateVO)).thenReturn(false);
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class, () -> {
systemVmTemplateRegistration.updateTemplateUrlChecksumAndGuestOsId(templateVO, templateDetails);
});
assertTrue(exception.getMessage().contains("Exception while updating 'url' and 'checksum' for hypervisor type"));
verify(vmTemplateDao).update(templateVO.getId(), templateVO);
}
}