// 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 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.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.utils.security.DigestHelper; import org.apache.commons.lang3.StringUtils; 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.dao.ClusterDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; 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; @RunWith(MockitoJUnitRunner.class) public class SystemVmTemplateRegistrationTest { @Mock ClusterDao clusterDao; @Mock VMTemplateDao vmTemplateDao; @Spy @InjectMocks SystemVmTemplateRegistration systemVmTemplateRegistration = new SystemVmTemplateRegistration(); private void setupMetadataFile(MockedStatic 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 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 systemVM template metadata file")); } } @Test public void test_parseMetadataFile_invalidContent() { try (MockedStatic 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 systemVM 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 mockedStatic = Mockito.mockStatic(SystemVmTemplateRegistration.class, Mockito.CALLS_REAL_METHODS)) { setupMetadataFile(mockedStatic, metadataFileContent); String version = SystemVmTemplateRegistration.parseMetadataFile(); assertEquals("x.y.z.0", version); } assertNull(SystemVmTemplateRegistration.NewTemplateMap.get("xenserver")); SystemVmTemplateRegistration.MetadataTemplateDetails templateDetails = SystemVmTemplateRegistration.NewTemplateMap.get("kvm-x86_64"); assertNotNull(templateDetails); assertEquals(CPU.CPUArch.amd64, templateDetails.getArch()); assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType()); templateDetails = SystemVmTemplateRegistration.NewTemplateMap.get("kvm-aarch64"); assertNotNull(templateDetails); assertEquals(CPU.CPUArch.arm64, templateDetails.getArch()); assertEquals(Hypervisor.HypervisorType.KVM, templateDetails.getHypervisorType()); templateDetails = SystemVmTemplateRegistration.NewTemplateMap.get("vmware"); assertNotNull(templateDetails); assertNull(templateDetails.getArch()); assertEquals(Hypervisor.HypervisorType.VMware, templateDetails.getHypervisorType()); } @Test public void testMountStore_nullStoreUrl() throws Exception { try (MockedStatic