| /* |
| * 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.jclouds.azurecompute.arm.features; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.jclouds.util.Predicates2.retry; |
| import static org.testng.Assert.assertEquals; |
| import static org.testng.Assert.assertNotNull; |
| import static org.testng.Assert.assertTrue; |
| |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.jclouds.azurecompute.arm.domain.DataDisk; |
| import org.jclouds.azurecompute.arm.domain.HardwareProfile; |
| import org.jclouds.azurecompute.arm.domain.IdReference; |
| import org.jclouds.azurecompute.arm.domain.ImageReference; |
| import org.jclouds.azurecompute.arm.domain.IpConfiguration; |
| import org.jclouds.azurecompute.arm.domain.IpConfigurationProperties; |
| import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters; |
| import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard; |
| import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties; |
| import org.jclouds.azurecompute.arm.domain.NetworkProfile; |
| import org.jclouds.azurecompute.arm.domain.OSDisk; |
| import org.jclouds.azurecompute.arm.domain.OSProfile; |
| import org.jclouds.azurecompute.arm.domain.ResourceDefinition; |
| import org.jclouds.azurecompute.arm.domain.StorageAccountType; |
| import org.jclouds.azurecompute.arm.domain.StorageProfile; |
| import org.jclouds.azurecompute.arm.domain.StorageService; |
| import org.jclouds.azurecompute.arm.domain.Subnet; |
| import org.jclouds.azurecompute.arm.domain.VHD; |
| import org.jclouds.azurecompute.arm.domain.VirtualMachine; |
| import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; |
| import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.PowerState; |
| import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; |
| import org.jclouds.azurecompute.arm.functions.ParseJobStatus; |
| import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest; |
| import org.testng.annotations.BeforeClass; |
| import org.testng.annotations.Test; |
| |
| import com.google.common.base.Predicate; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.Iterables; |
| |
| @Test(groups = "live", testName = "VirtualMachineApiLiveTest") |
| public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { |
| |
| private String subscriptionid; |
| private String vmName; |
| private String nicName; |
| private String virtualNetworkName; |
| private String subnetId; |
| |
| @BeforeClass |
| @Override |
| public void setup() { |
| super.setup(); |
| subscriptionid = getSubscriptionId(); |
| |
| createTestResourceGroup(); |
| virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name")); |
| |
| // Subnets belong to a virtual network so that needs to be created first |
| assertNotNull(createDefaultVirtualNetwork(resourceGroupName, virtualNetworkName, "10.2.0.0/16", LOCATION)); |
| |
| //Subnet needs to be up & running before NIC can be created |
| String subnetName = String.format("s-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name")); |
| Subnet subnet = createDefaultSubnet(resourceGroupName, subnetName, virtualNetworkName, "10.2.0.0/23"); |
| assertNotNull(subnet); |
| assertNotNull(subnet.id()); |
| subnetId = subnet.id(); |
| |
| NetworkInterfaceCard nic = createNetworkInterfaceCard(resourceGroupName, "jc-nic-" + RAND, LOCATION, "ipConfig-" + RAND); |
| assertNotNull(nic); |
| nicName = nic.name(); |
| |
| vmName = String.format("%3.24s", System.getProperty("user.name") + RAND + this.getClass().getSimpleName()).toLowerCase().substring(0, 15); |
| } |
| |
| @Test |
| public void testCreate() { |
| VirtualMachine vm = api().createOrUpdate(vmName, LOCATION, getProperties(nicName, null), |
| Collections.<String, String> emptyMap(), null); |
| assertTrue(!vm.name().isEmpty()); |
| waitUntilReady(vmName); |
| } |
| |
| @Test(dependsOnMethods = "testCreate") |
| public void testGet() { |
| VirtualMachine vm = api().get(vmName); |
| assertTrue(!vm.name().isEmpty()); |
| } |
| |
| @Test(dependsOnMethods = "testCreate") |
| public void testGetInstanceView() { |
| VirtualMachineInstance vmi = api().getInstanceDetails(vmName); |
| assertTrue(!vmi.statuses().isEmpty()); |
| } |
| |
| @Test(dependsOnMethods = "testGet") |
| public void testStart() { |
| api().start(vmName); |
| assertTrue(stateReached(vmName, PowerState.RUNNING), "start operation did not complete in the configured timeout"); |
| } |
| |
| @Test(dependsOnMethods = "testStart") |
| public void testUpdate() { |
| VirtualMachine vm = api().get(vmName); |
| VirtualMachineProperties oldProperties = vm.properties(); |
| StorageProfile oldStorageProfile = oldProperties.storageProfile(); |
| |
| DataDisk newDataDisk = DataDisk.builder() |
| .name(vmName + "new-data-disk") |
| .diskSizeGB("1") |
| .lun(1) |
| .createOption(DataDisk.DiskCreateOptionTypes.EMPTY) |
| .build(); |
| List<DataDisk> oldDataDisks = oldStorageProfile.dataDisks(); |
| assertEquals(oldDataDisks.size(), 1); |
| |
| ImmutableList<DataDisk> newDataDisks = ImmutableList.<DataDisk> builder().addAll(oldDataDisks).add(newDataDisk).build(); |
| StorageProfile newStorageProfile = oldStorageProfile.toBuilder().dataDisks(newDataDisks).build(); |
| VirtualMachineProperties newProperties = oldProperties.toBuilder().storageProfile(newStorageProfile).build(); |
| |
| VirtualMachine newVm = vm.toBuilder().properties(newProperties).build(); |
| vm = api().createOrUpdate(vmName, newVm.location(), newVm.properties(), newVm.tags(), newVm.plan()); |
| |
| assertEquals(vm.properties().storageProfile().dataDisks().size(), oldDataDisks.size() + 1); |
| } |
| |
| @Test(dependsOnMethods = "testUpdate") |
| public void testStop() { |
| api().stop(vmName); |
| assertTrue(stateReached(vmName, PowerState.STOPPED), "stop operation did not complete in the configured timeout"); |
| } |
| |
| @Test(dependsOnMethods = "testStop") |
| public void testRestart() { |
| api().start(vmName); |
| assertTrue(stateReached(vmName, PowerState.RUNNING), "start operation did not complete in the configured timeout"); |
| api().restart(vmName); |
| assertTrue(stateReached(vmName, PowerState.RUNNING), "restart operation did not complete in the configured timeout"); |
| } |
| |
| @Test(dependsOnMethods = "testCreate") |
| public void testList() { |
| List<VirtualMachine> list = api().list(); |
| final VirtualMachine vm = api().get(vmName); |
| |
| boolean vmPresent = Iterables.any(list, new Predicate<VirtualMachine>() { |
| public boolean apply(VirtualMachine input) { |
| return input.name().equals(vm.name()); |
| } |
| }); |
| |
| assertTrue(vmPresent); |
| } |
| |
| @Test(dependsOnMethods = "testRestart") |
| public void testGeneralize() throws IllegalStateException { |
| api().stop(vmName); |
| assertTrue(stateReached(vmName, PowerState.STOPPED), "restart operation did not complete in the configured timeout"); |
| api().generalize(vmName); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Test |
| public void testCapture() throws IllegalStateException { |
| // Capture is only allowed for Blob based VMs, so let's create one VM for this test |
| NetworkInterfaceCard nic = createNetworkInterfaceCard(resourceGroupName, "capture-nic-" + RAND, LOCATION, "ipConfig-" + RAND); |
| StorageService storageService = createStorageService(resourceGroupName, "capture" + RAND, LOCATION); |
| String blob = storageService.storageServiceProperties().primaryEndpoints().get("blob"); |
| |
| String captureVmName = "capture-" + RAND; |
| api().createOrUpdate(captureVmName, LOCATION, getProperties(nic.name(), blob), |
| Collections.<String, String> emptyMap(), null); |
| waitUntilReady(captureVmName); |
| |
| api().stop(captureVmName); |
| assertTrue(stateReached(captureVmName, PowerState.STOPPED), |
| "restart operation did not complete in the configured timeout"); |
| api().generalize(captureVmName); |
| |
| URI uri = api().capture(captureVmName, captureVmName, captureVmName); |
| assertNotNull(uri); |
| |
| if (imageAvailablePredicate.apply(uri)) { |
| List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri); |
| if (definitions != null) { |
| for (ResourceDefinition definition : definitions) { |
| Map<String, String> properties = (Map<String, String>) definition.properties(); |
| Object storageObject = properties.get("storageProfile"); |
| Map<String, String> properties2 = (Map<String, String>) storageObject; |
| Object osDiskObject = properties2.get("osDisk"); |
| Map<String, String> osProperties = (Map<String, String>) osDiskObject; |
| assertNotNull(osProperties.get("name")); |
| } |
| } |
| } |
| } |
| |
| @Test(dependsOnMethods = "testGeneralize", alwaysRun = true) |
| public void testDelete() throws Exception { |
| URI uri = api().delete(vmName); |
| assertResourceDeleted(uri); |
| } |
| |
| private VirtualMachineApi api() { |
| return api.getVirtualMachineApi(resourceGroupName); |
| } |
| |
| private VirtualMachineProperties getProperties(String nic, String blob) { |
| |
| HardwareProfile hwProf = HardwareProfile.create("Standard_D1"); |
| ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServerEssentials") |
| .offer("WindowsServerEssentials").sku("WindowsServerEssentials").version("latest").build(); |
| |
| DataDisk.Builder dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY); |
| |
| OSDisk.Builder osDisk = OSDisk.builder() |
| .name("os") |
| .osType("Windows") |
| .caching(DataDisk.CachingTypes.READ_WRITE.toString()) |
| .createOption("FromImage"); |
| |
| if (blob == null) { |
| osDisk.managedDiskParameters(ManagedDiskParameters.create(null, StorageAccountType.STANDARD_LRS.toString())); |
| } else { |
| osDisk.vhd(VHD.create(blob + "vhds/" + vmName + ".vhd")); |
| dataDisk.vhd(VHD.create(blob + "vhds/" + vmName + "data.vhd")); |
| } |
| |
| StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk.build(), ImmutableList.of(dataDisk.build())); |
| OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true, |
| null); |
| OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig); |
| IdReference networkInterface = |
| IdReference.create("/subscriptions/" + subscriptionid + |
| "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" |
| + nic); |
| List<IdReference> networkInterfaces = |
| new ArrayList<IdReference>(); |
| networkInterfaces.add(networkInterface); |
| NetworkProfile networkProfile = NetworkProfile.create(networkInterfaces); |
| VirtualMachineProperties properties = VirtualMachineProperties.create(null, |
| null, null, hwProf, storageProfile, osProfile, networkProfile, null, VirtualMachineProperties.ProvisioningState.CREATING); |
| return properties; |
| } |
| |
| private NetworkInterfaceCard createNetworkInterfaceCard(final String resourceGroupName, String networkInterfaceCardName, String locationName, String ipConfigurationName) { |
| //Create properties object |
| final NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties |
| .builder() |
| .ipConfigurations( |
| Arrays.asList(IpConfiguration.create(ipConfigurationName, null, null, null, IpConfigurationProperties |
| .create(null, null, "Dynamic", IdReference.create(subnetId), null, null, null)))).build(); |
| |
| final Map<String, String> tags = ImmutableMap.of("jclouds", "livetest"); |
| return api.getNetworkInterfaceCardApi(resourceGroupName).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, tags); |
| } |
| |
| private StorageService createStorageService(final String resourceGroupName, final String storageServiceName, |
| final String location) { |
| URI uri = api.getStorageAccountApi(resourceGroupName).create(storageServiceName, location, |
| ImmutableMap.of("property_name", "property_value"), |
| ImmutableMap.of("accountType", StorageService.AccountType.Standard_LRS.toString())); |
| if (uri != null) { |
| assertTrue(uri.toString().contains("api-version")); |
| |
| boolean jobDone = retry(new Predicate<URI>() { |
| @Override |
| public boolean apply(final URI uri) { |
| return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri); |
| } |
| }, 60 * 1 * 1000 /* 1 minute timeout */).apply(uri); |
| assertTrue(jobDone, "create operation did not complete in the configured timeout"); |
| } |
| return api.getStorageAccountApi(resourceGroupName).get(storageServiceName); |
| } |
| |
| private boolean waitForState(String name, final PowerState state) { |
| return api().getInstanceDetails(name).powerState().equals(state); |
| } |
| |
| private void waitUntilReady(String vmName) { |
| boolean ready = retry(new Predicate<String>() { |
| @Override |
| public boolean apply(String name) { |
| return !api().get(name).properties().provisioningState().equals(VirtualMachineProperties.ProvisioningState.CREATING); |
| } |
| }, 60 * 20 * 1000).apply(vmName); |
| assertTrue(ready, "createOrUpdate operation did not complete in the configured timeout"); |
| |
| VirtualMachineProperties.ProvisioningState status = api().get(vmName).properties().provisioningState(); |
| // Cannot be creating anymore. Should be succeeded or running but not failed. |
| assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.CREATING); |
| assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.FAILED); |
| } |
| |
| private boolean stateReached(String vmName, final PowerState state) { |
| return retry(new Predicate<String>() { |
| @Override |
| public boolean apply(String name) { |
| return waitForState(name, state); |
| } |
| }, 60 * 4 * 1000).apply(vmName); |
| } |
| } |