mirror of https://github.com/apache/cloudstack.git
Create unit test cases for 'ConfigDriveBuilder' class (#2674)
* Create unit test cases for 'ConfigDriveBuilder' class * add method 'getProgramToGenerateIso' as suggested by rohit and Daan * fix encoding for base64 to StandardCharsets.US_ASCII * fix MockServerTest.testIsMockServerCanUpgradeConnectionToSsl() This is another method that is causing Jenkins to fail for almost a month
This commit is contained in:
parent
d46fa6e198
commit
9b83337658
|
|
@ -26,11 +26,12 @@ public class ConfigDrive {
|
|||
public static final String openStackConfigDriveName = "/openstack/latest/";
|
||||
|
||||
/**
|
||||
* This is the path to iso file relative to mount point
|
||||
* @return config drive iso file path
|
||||
* Creates the path to ISO file relative to mount point.
|
||||
* The config driver path will have the following formated: {@link #CONFIGDRIVEDIR} + / + instanceName + / + {@link #CONFIGDRIVEFILENAME}
|
||||
*
|
||||
* @return config drive ISO file path
|
||||
*/
|
||||
public static String createConfigDrivePath(final String instanceName) {
|
||||
public static String createConfigDrivePath(String instanceName) {
|
||||
return ConfigDrive.CONFIGDRIVEDIR + "/" + instanceName + "/" + ConfigDrive.CONFIGDRIVEFILENAME;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -23,9 +23,7 @@ import static com.cloud.network.NetworkModel.CONFIGDATA_FILE;
|
|||
import static com.cloud.network.NetworkModel.PASSWORD_FILE;
|
||||
import static com.cloud.network.NetworkModel.USERDATA_FILE;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
|
|
@ -42,7 +40,6 @@ import org.joda.time.Duration;
|
|||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
|
@ -51,30 +48,45 @@ public class ConfigDriveBuilder {
|
|||
|
||||
public static final Logger LOG = Logger.getLogger(ConfigDriveBuilder.class);
|
||||
|
||||
private static void writeFile(final File folder, final String file, final String content) {
|
||||
if (folder == null || Strings.isNullOrEmpty(file)) {
|
||||
return;
|
||||
}
|
||||
final File vendorDataFile = new File(folder, file);
|
||||
try (final FileWriter fw = new FileWriter(vendorDataFile); final BufferedWriter bw = new BufferedWriter(fw)) {
|
||||
bw.write(content);
|
||||
/**
|
||||
* Writes a content {@link String} to a file that is going to be created in a folder. We will not append to the file if it already exists. Therefore, its content will be overwritten.
|
||||
* Moreover, the charset used is {@link com.cloud.utils.StringUtils#getPreferredCharset()}.
|
||||
*
|
||||
* We expect the folder object and the file not to be null/empty.
|
||||
*/
|
||||
static void writeFile(File folder, String file, String content) {
|
||||
try {
|
||||
FileUtils.write(new File(folder, file), content, com.cloud.utils.StringUtils.getPreferredCharset(), false);
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create config drive file " + file, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static String fileToBase64String(final File isoFile) throws IOException {
|
||||
/**
|
||||
* Read the content of a {@link File} and convert it to a String in base 64.
|
||||
* We expect the content of the file to be encoded using {@link StandardCharsets#US_ASC}
|
||||
*/
|
||||
public static String fileToBase64String(File isoFile) throws IOException {
|
||||
byte[] encoded = Base64.encodeBase64(FileUtils.readFileToByteArray(isoFile));
|
||||
return new String(encoded, StandardCharsets.US_ASCII);
|
||||
}
|
||||
|
||||
public static File base64StringToFile(final String encodedIsoData, final String folder, final String fileName) throws IOException {
|
||||
/**
|
||||
* Writes a String encoded in base 64 to a file in the given folder.
|
||||
* The content will be decoded and then written to the file. Be aware that we will overwrite the content of the file if it already exists.
|
||||
* Moreover, the content will must be encoded in {@link StandardCharsets#US_ASCII} before it is encoded in base 64.
|
||||
*/
|
||||
public static File base64StringToFile(String encodedIsoData, String folder, String fileName) throws IOException {
|
||||
byte[] decoded = Base64.decodeBase64(encodedIsoData.getBytes(StandardCharsets.US_ASCII));
|
||||
Path destPath = Paths.get(folder, fileName);
|
||||
return Files.write(destPath, decoded).toFile();
|
||||
}
|
||||
|
||||
public static String buildConfigDrive(final List<String[]> vmData, final String isoFileName, final String driveLabel) {
|
||||
/**
|
||||
* This method will build the metadata files required by OpenStack driver. Then, an ISO is going to be generated and returned as a String in base 64.
|
||||
* If vmData is null, we throw a {@link CloudRuntimeException}. Moreover, {@link IOException} are captured and re-thrown as {@link CloudRuntimeException}.
|
||||
*/
|
||||
public static String buildConfigDrive(List<String[]> vmData, String isoFileName, String driveLabel) {
|
||||
if (vmData == null) {
|
||||
throw new CloudRuntimeException("No VM metadata provided");
|
||||
}
|
||||
|
|
@ -86,103 +98,180 @@ public class ConfigDriveBuilder {
|
|||
tempDirName = tempDir.toString();
|
||||
|
||||
File openStackFolder = new File(tempDirName + ConfigDrive.openStackConfigDriveName);
|
||||
if (openStackFolder.exists() || openStackFolder.mkdirs()) {
|
||||
writeFile(openStackFolder, "vendor_data.json", "{}");
|
||||
writeFile(openStackFolder, "network_data.json", "{}");
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder " + openStackFolder);
|
||||
}
|
||||
|
||||
JsonObject metaData = new JsonObject();
|
||||
for (String[] item : vmData) {
|
||||
String dataType = item[CONFIGDATA_DIR];
|
||||
String fileName = item[CONFIGDATA_FILE];
|
||||
String content = item[CONFIGDATA_CONTENT];
|
||||
LOG.debug(String.format("[createConfigDriveIsoForVM] dataType=%s, filename=%s, content=%s",
|
||||
dataType, fileName, (fileName.equals(PASSWORD_FILE)?"********":content)));
|
||||
writeVendorAndNetworkEmptyJsonFile(openStackFolder);
|
||||
writeVmMetadata(vmData, tempDirName, openStackFolder);
|
||||
|
||||
// create file with content in folder
|
||||
if (dataType != null && !dataType.isEmpty()) {
|
||||
//create folder
|
||||
File typeFolder = new File(tempDirName + ConfigDrive.cloudStackConfigDriveName + dataType);
|
||||
if (typeFolder.exists() || typeFolder.mkdirs()) {
|
||||
if (StringUtils.isNotEmpty(content)) {
|
||||
File file = new File(typeFolder, fileName + ".txt");
|
||||
try {
|
||||
if (fileName.equals(USERDATA_FILE)) {
|
||||
// User Data is passed as a base64 encoded string
|
||||
FileUtils.writeByteArrayToFile(file, Base64.decodeBase64(content));
|
||||
} else {
|
||||
FileUtils.write(file, content, com.cloud.utils.StringUtils.getPreferredCharset());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create file ", ex);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder: " + typeFolder);
|
||||
}
|
||||
linkUserData(tempDirName);
|
||||
|
||||
//now write the file to the OpenStack directory
|
||||
metaData = buildOpenStackMetaData(metaData, dataType, fileName, content);
|
||||
}
|
||||
}
|
||||
writeFile(openStackFolder, "meta_data.json", metaData.toString());
|
||||
|
||||
String linkResult = linkUserData(tempDirName);
|
||||
if (linkResult != null) {
|
||||
String errMsg = "Unable to create user_data link due to " + linkResult;
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
File tmpIsoStore = new File(tempDirName, new File(isoFileName).getName());
|
||||
Script command = new Script("/usr/bin/genisoimage", Duration.standardSeconds(300), LOG);
|
||||
command.add("-o", tmpIsoStore.getAbsolutePath());
|
||||
command.add("-ldots");
|
||||
command.add("-allow-lowercase");
|
||||
command.add("-allow-multidot");
|
||||
command.add("-cache-inodes"); // Enable caching inode and device numbers to find hard links to files.
|
||||
command.add("-l");
|
||||
command.add("-quiet");
|
||||
command.add("-J");
|
||||
command.add("-r");
|
||||
command.add("-V", driveLabel);
|
||||
command.add(tempDirName);
|
||||
LOG.debug("Executing config drive creation command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if (result != null) {
|
||||
String errMsg = "Unable to create iso file: " + isoFileName + " due to " + result;
|
||||
LOG.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
File tmpIsoFile = new File(tmpIsoStore.getAbsolutePath());
|
||||
// Max allowed file size of config drive is 64MB: https://docs.openstack.org/project-install-guide/baremetal/draft/configdrive.html
|
||||
if (tmpIsoFile.length() > (64L * 1024L * 1024L)) {
|
||||
throw new CloudRuntimeException("Config drive file exceeds maximum allowed size of 64MB");
|
||||
}
|
||||
return fileToBase64String(tmpIsoFile);
|
||||
return generateAndRetrieveIsoAsBase64Iso(isoFileName, driveLabel, tempDirName);
|
||||
} catch (IOException e) {
|
||||
throw new CloudRuntimeException("Failed due to", e);
|
||||
} finally {
|
||||
try {
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
} catch (IOException ioe) {
|
||||
LOG.warn("Failed to delete ConfigDrive temporary directory: " + tempDirName, ioe);
|
||||
}
|
||||
deleteTempDir(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private static String linkUserData(String tempDirName) {
|
||||
//Hard link the user_data.txt file with the user_data file in the OpenStack directory.
|
||||
private static void deleteTempDir(Path tempDir) {
|
||||
try {
|
||||
if (tempDir != null) {
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
LOG.warn("Failed to delete ConfigDrive temporary directory: " + tempDir.toString(), ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the ISO file that has the tempDir content.
|
||||
*
|
||||
* Max allowed file size of config drive is 64MB [1]. Therefore, if the ISO is bigger than that, we throw a {@link CloudRuntimeException}.
|
||||
* [1] https://docs.openstack.org/project-install-guide/baremetal/draft/configdrive.html
|
||||
*/
|
||||
static String generateAndRetrieveIsoAsBase64Iso(String isoFileName, String driveLabel, String tempDirName) throws IOException {
|
||||
File tmpIsoStore = new File(tempDirName, isoFileName);
|
||||
Script command = new Script(getProgramToGenerateIso(), Duration.standardSeconds(300), LOG);
|
||||
command.add("-o", tmpIsoStore.getAbsolutePath());
|
||||
command.add("-ldots");
|
||||
command.add("-allow-lowercase");
|
||||
command.add("-allow-multidot");
|
||||
command.add("-cache-inodes"); // Enable caching inode and device numbers to find hard links to files.
|
||||
command.add("-l");
|
||||
command.add("-quiet");
|
||||
command.add("-J");
|
||||
command.add("-r");
|
||||
command.add("-V", driveLabel);
|
||||
command.add(tempDirName);
|
||||
LOG.debug("Executing config drive creation command: " + command.toString());
|
||||
String result = command.execute();
|
||||
if (StringUtils.isNotBlank(result)) {
|
||||
String errMsg = "Unable to create iso file: " + isoFileName + " due to ge" + result;
|
||||
LOG.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
File tmpIsoFile = new File(tmpIsoStore.getAbsolutePath());
|
||||
if (tmpIsoFile.length() > (64L * 1024L * 1024L)) {
|
||||
throw new CloudRuntimeException("Config drive file exceeds maximum allowed size of 64MB");
|
||||
}
|
||||
return fileToBase64String(tmpIsoFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the 'genisoimage' or 'mkisofs' is available and return the full qualified path for the program.
|
||||
* The path checked are the following:
|
||||
* <ul>
|
||||
* <li> /usr/bin/genisoimage
|
||||
* <li> /usr/bin/mkisofs
|
||||
* </ul> /usr/local/bin/mkisofs
|
||||
*/
|
||||
static String getProgramToGenerateIso() throws IOException {
|
||||
File isoCreator = new File("/usr/bin/genisoimage");
|
||||
if (!isoCreator.exists()) {
|
||||
isoCreator = new File("/usr/bin/mkisofs");
|
||||
if (!isoCreator.exists()) {
|
||||
isoCreator = new File("/usr/local/bin/mkisofs");
|
||||
}
|
||||
}
|
||||
if (!isoCreator.exists()) {
|
||||
throw new CloudRuntimeException("Cannot create iso for config drive using any know tool. Known paths [/usr/bin/genisoimage, /usr/bin/mkisofs, /usr/local/bin/mkisofs]");
|
||||
}
|
||||
if (!isoCreator.canExecute()) {
|
||||
throw new CloudRuntimeException("Cannot create iso for config drive using: " + isoCreator.getCanonicalPath());
|
||||
}
|
||||
return isoCreator.getCanonicalPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* First we generate a JSON object using {@link #createJsonObjectWithVmData(List, String)}, then we write it to a file called "meta_data.json".
|
||||
*/
|
||||
static void writeVmMetadata(List<String[]> vmData, String tempDirName, File openStackFolder) {
|
||||
JsonObject metaData = createJsonObjectWithVmData(vmData, tempDirName);
|
||||
writeFile(openStackFolder, "meta_data.json", metaData.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the following empty JSON files:
|
||||
* <ul>
|
||||
* <li> vendor_data.json
|
||||
* <li> network_data.json
|
||||
* </ul>
|
||||
*
|
||||
* If the folder does not exist and we cannot create it, we throw a {@link CloudRuntimeException}.
|
||||
*/
|
||||
static void writeVendorAndNetworkEmptyJsonFile(File openStackFolder) {
|
||||
if (openStackFolder.exists() || openStackFolder.mkdirs()) {
|
||||
writeFile(openStackFolder, "vendor_data.json", "{}");
|
||||
writeFile(openStackFolder, "network_data.json", "{}");
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to create folder " + openStackFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@link JsonObject} with VM's metadata. The vmData is a list of arrays; we expect this list to have the following entries:
|
||||
* <ul>
|
||||
* <li> [0]: config data type
|
||||
* <li> [1]: config data file name
|
||||
* <li> [2]: config data file content
|
||||
* </ul>
|
||||
*/
|
||||
static JsonObject createJsonObjectWithVmData(List<String[]> vmData, String tempDirName) {
|
||||
JsonObject metaData = new JsonObject();
|
||||
for (String[] item : vmData) {
|
||||
String dataType = item[CONFIGDATA_DIR];
|
||||
String fileName = item[CONFIGDATA_FILE];
|
||||
String content = item[CONFIGDATA_CONTENT];
|
||||
LOG.debug(String.format("[createConfigDriveIsoForVM] dataType=%s, filename=%s, content=%s", dataType, fileName, (PASSWORD_FILE.equals(fileName) ? "********" : content)));
|
||||
|
||||
createFileInTempDirAnAppendOpenStackMetadataToJsonObject(tempDirName, metaData, dataType, fileName, content);
|
||||
}
|
||||
return metaData;
|
||||
}
|
||||
|
||||
static void createFileInTempDirAnAppendOpenStackMetadataToJsonObject(String tempDirName, JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (StringUtils.isBlank(dataType)) {
|
||||
return;
|
||||
}
|
||||
//create folder
|
||||
File typeFolder = new File(tempDirName + ConfigDrive.cloudStackConfigDriveName + dataType);
|
||||
if (!typeFolder.exists() && !typeFolder.mkdirs()) {
|
||||
throw new CloudRuntimeException("Failed to create folder: " + typeFolder);
|
||||
}
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
File file = new File(typeFolder, fileName + ".txt");
|
||||
try {
|
||||
if (fileName.equals(USERDATA_FILE)) {
|
||||
// User Data is passed as a base64 encoded string
|
||||
FileUtils.writeByteArrayToFile(file, Base64.decodeBase64(content));
|
||||
} else {
|
||||
FileUtils.write(file, content, com.cloud.utils.StringUtils.getPreferredCharset());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new CloudRuntimeException("Failed to create file ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
//now write the file to the OpenStack directory
|
||||
buildOpenStackMetaData(metaData, dataType, fileName, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hard link the user_data.txt file with the user_data file in the OpenStack directory.
|
||||
*/
|
||||
static void linkUserData(String tempDirName) {
|
||||
String userDataFilePath = tempDirName + ConfigDrive.cloudStackConfigDriveName + "userdata/user_data.txt";
|
||||
if ((new File(userDataFilePath).exists())) {
|
||||
File file = new File(userDataFilePath);
|
||||
if (file.exists()) {
|
||||
Script hardLink = new Script("ln", Duration.standardSeconds(300), LOG);
|
||||
hardLink.add(userDataFilePath);
|
||||
hardLink.add(tempDirName + ConfigDrive.openStackConfigDriveName + "user_data");
|
||||
LOG.debug("execute command: " + hardLink.toString());
|
||||
return hardLink.execute();
|
||||
|
||||
String executionResult = hardLink.execute();
|
||||
if (StringUtils.isNotBlank(executionResult)) {
|
||||
throw new CloudRuntimeException("Unable to create user_data link due to " + executionResult);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static JsonArray arrayOf(JsonElement... elements) {
|
||||
|
|
@ -193,30 +282,33 @@ public class ConfigDriveBuilder {
|
|||
return array;
|
||||
}
|
||||
|
||||
private static JsonObject buildOpenStackMetaData(JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (dataType.equals(NetworkModel.METATDATA_DIR) && StringUtils.isNotEmpty(content)) {
|
||||
//keys are a special case in OpenStack format
|
||||
if (NetworkModel.PUBLIC_KEYS_FILE.equals(fileName)) {
|
||||
String[] keyArray = content.replace("\\n", "").split(" ");
|
||||
String keyName = "key";
|
||||
if (keyArray.length > 3 && StringUtils.isNotEmpty(keyArray[2])){
|
||||
keyName = keyArray[2];
|
||||
}
|
||||
|
||||
JsonObject keyLegacy = new JsonObject();
|
||||
keyLegacy.addProperty("type", "ssh");
|
||||
keyLegacy.addProperty("data", content.replace("\\n", ""));
|
||||
keyLegacy.addProperty("name", keyName);
|
||||
metaData.add("keys", arrayOf(keyLegacy));
|
||||
|
||||
JsonObject key = new JsonObject();
|
||||
key.addProperty(keyName, content);
|
||||
metaData.add("public_keys", key);
|
||||
} else if (NetworkModel.openStackFileMapping.get(fileName) != null) {
|
||||
metaData.addProperty(NetworkModel.openStackFileMapping.get(fileName), content);
|
||||
}
|
||||
private static void buildOpenStackMetaData(JsonObject metaData, String dataType, String fileName, String content) {
|
||||
if (!NetworkModel.METATDATA_DIR.equals(dataType)) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isNotBlank(content)) {
|
||||
return;
|
||||
}
|
||||
//keys are a special case in OpenStack format
|
||||
if (NetworkModel.PUBLIC_KEYS_FILE.equals(fileName)) {
|
||||
String[] keyArray = content.replace("\\n", "").split(" ");
|
||||
String keyName = "key";
|
||||
if (keyArray.length > 3 && StringUtils.isNotEmpty(keyArray[2])) {
|
||||
keyName = keyArray[2];
|
||||
}
|
||||
|
||||
JsonObject keyLegacy = new JsonObject();
|
||||
keyLegacy.addProperty("type", "ssh");
|
||||
keyLegacy.addProperty("data", content.replace("\\n", ""));
|
||||
keyLegacy.addProperty("name", keyName);
|
||||
metaData.add("keys", arrayOf(keyLegacy));
|
||||
|
||||
JsonObject key = new JsonObject();
|
||||
key.addProperty(keyName, content);
|
||||
metaData.add("public_keys", key);
|
||||
} else if (NetworkModel.openStackFileMapping.get(fileName) != null) {
|
||||
metaData.addProperty(NetworkModel.openStackFileMapping.get(fileName), content);
|
||||
}
|
||||
return metaData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,49 +17,481 @@
|
|||
|
||||
package org.apache.cloudstack.storage.configdrive;
|
||||
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.reflections.ReflectionUtils;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({FileUtils.class})
|
||||
public class ConfigDriveBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testConfigDriveIsoPath() throws IOException {
|
||||
Assert.assertEquals(ConfigDrive.createConfigDrivePath("i-x-y"), "configdrive/i-x-y/configdrive.iso");
|
||||
public void writeFileTest() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
ConfigDriveBuilder.writeFile(new File("folder"), "subfolder", "content");
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
FileUtils.write(Mockito.any(File.class), Mockito.anyString(), Mockito.any(Charset.class), Mockito.eq(false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeFileTestwriteFileTestIOExceptionWhileWritingFile() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
//Does not look good, I know... but this is the price of static methods.
|
||||
Method method = ReflectionUtils.getMethods(FileUtils.class, ReflectionUtils.withParameters(File.class, CharSequence.class, Charset.class, Boolean.TYPE)).iterator().next();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class), Mockito.anyString(), Mockito.any(Charset.class), Mockito.anyBoolean()).thenThrow(IOException.class);
|
||||
|
||||
ConfigDriveBuilder.writeFile(new File("folder"), "subfolder", "content");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigDriveBuild() throws IOException {
|
||||
List<String[]> actualVmData = Arrays.asList(
|
||||
new String[]{"userdata", "user_data", "c29tZSB1c2VyIGRhdGE="},
|
||||
new String[]{"metadata", "service-offering", "offering"},
|
||||
new String[]{"metadata", "availability-zone", "zone1"},
|
||||
new String[]{"metadata", "local-hostname", "hostname"},
|
||||
new String[]{"metadata", "local-ipv4", "192.168.111.111"},
|
||||
new String[]{"metadata", "public-hostname", "7.7.7.7"},
|
||||
new String[]{"metadata", "public-ipv4", "7.7.7.7"},
|
||||
new String[]{"metadata", "vm-id", "uuid"},
|
||||
new String[]{"metadata", "instance-id", "i-x-y"},
|
||||
new String[]{"metadata", "public-keys", "ssh-rsa some-key"},
|
||||
new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", "uuid")},
|
||||
new String[]{"password", "vm_password", "password123"}
|
||||
);
|
||||
public void fileToBase64StringTest() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
final Path tempDir = Files.createTempDirectory(ConfigDrive.CONFIGDRIVEDIR);
|
||||
final String isoData = ConfigDriveBuilder.buildConfigDrive(actualVmData, "i-x-y.iso", "config-2");
|
||||
final File isoFile = ConfigDriveBuilder.base64StringToFile(isoData, tempDir.toAbsolutePath().toString(), ConfigDrive.CONFIGDRIVEFILENAME);
|
||||
String fileContent = "content";
|
||||
Method method = getFileUtilsReadfileToByteArrayMethod();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class)).thenReturn(fileContent.getBytes());
|
||||
|
||||
Assert.assertTrue(isoFile.exists());
|
||||
Assert.assertTrue(isoFile.isFile());
|
||||
Assert.assertTrue(isoFile.length() > 0L);
|
||||
String returnedContentInBase64 = ConfigDriveBuilder.fileToBase64String(new File("file"));
|
||||
|
||||
FileUtils.deleteDirectory(tempDir.toFile());
|
||||
Assert.assertEquals("Y29udGVudA==", returnedContentInBase64);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = IOException.class)
|
||||
public void fileToBase64StringTestIOException() throws Exception {
|
||||
PowerMockito.mockStatic(FileUtils.class);
|
||||
|
||||
Method method = getFileUtilsReadfileToByteArrayMethod();
|
||||
PowerMockito.when(FileUtils.class, method).withArguments(Mockito.any(File.class)).thenThrow(IOException.class);
|
||||
|
||||
ConfigDriveBuilder.fileToBase64String(new File("file"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getFileUtilsReadfileToByteArrayMethod() {
|
||||
return ReflectionUtils.getMethods(FileUtils.class, ReflectionUtils.withName("readFileToByteArray")).iterator().next();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void base64StringToFileTest() throws Exception {
|
||||
String encodedIsoData = "Y29udGVudA==";
|
||||
|
||||
String parentFolder = "parentFolder";
|
||||
String fileName = "fileName";
|
||||
|
||||
File parentFolderFile = new File(parentFolder);
|
||||
parentFolderFile.mkdir();
|
||||
|
||||
ConfigDriveBuilder.base64StringToFile(encodedIsoData, parentFolder, fileName);
|
||||
|
||||
File file = new File(parentFolderFile, fileName);
|
||||
String contentOfFile = new String(FileUtils.readFileToByteArray(file), StandardCharsets.US_ASCII);
|
||||
|
||||
Assert.assertEquals("content", contentOfFile);
|
||||
|
||||
file.delete();
|
||||
parentFolderFile.delete();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void buildConfigDriveTestNoVmData() {
|
||||
ConfigDriveBuilder.buildConfigDrive(null, "teste", "C:");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void buildConfigDriveTestIoException() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class)).thenThrow(IOException.class);
|
||||
|
||||
//This is odd, but it was necessary to allow us to check if we catch the IOexception and re-throw as a CloudRuntimeException
|
||||
//We are mocking the class being tested; therefore, we needed to force the execution of the real method we want to test.
|
||||
PowerMockito.when(ConfigDriveBuilder.class, new ArrayList<>(), "teste", "C:").thenCallRealMethod();
|
||||
|
||||
ConfigDriveBuilder.buildConfigDrive(new ArrayList<>(), "teste", "C:");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void buildConfigDriveTest() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method writeVendorAndNetworkEmptyJsonFileMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, writeVendorAndNetworkEmptyJsonFileMethod).withArguments(Mockito.any(File.class));
|
||||
|
||||
Method writeVmMetadataMethod = getWriteVmMetadataMethod();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, writeVmMetadataMethod).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.any(File.class));
|
||||
|
||||
Method linkUserDataMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("linkUserData")).iterator().next();
|
||||
PowerMockito.doNothing().when(ConfigDriveBuilder.class, linkUserDataMethod).withArguments(Mockito.anyString());
|
||||
|
||||
Method generateAndRetrieveIsoAsBase64IsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.doReturn("mockIsoDataBase64").when(ConfigDriveBuilder.class, generateAndRetrieveIsoAsBase64IsoMethod).withArguments(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
||||
|
||||
//force execution of real method
|
||||
PowerMockito.when(ConfigDriveBuilder.class, new ArrayList<>(), "teste", "C:").thenCallRealMethod();
|
||||
|
||||
String returnedIsoData = ConfigDriveBuilder.buildConfigDrive(new ArrayList<>(), "teste", "C:");
|
||||
|
||||
Assert.assertEquals("mockIsoDataBase64", returnedIsoData);
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(Mockito.any(File.class));
|
||||
ConfigDriveBuilder.writeVmMetadata(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.any(File.class));
|
||||
ConfigDriveBuilder.linkUserData(Mockito.anyString());
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getWriteVmMetadataMethod() {
|
||||
return ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVmMetadata")).iterator().next();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeVendorAndNetworkEmptyJsonFileTestCannotCreateOpenStackFolder() {
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).mkdirs();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
public void writeVendorAndNetworkEmptyJsonFileTest() {
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).mkdirs();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void writeVendorAndNetworkEmptyJsonFileTestCreatingFolder() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
File folderFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(folderFileMock).exists();
|
||||
Mockito.doReturn(true).when(folderFileMock).mkdirs();
|
||||
|
||||
//force execution of real method
|
||||
Method writeVendorAndNetworkEmptyJsonFileMethod = getWriteVendorAndNetworkEmptyJsonFileMethod();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, writeVendorAndNetworkEmptyJsonFileMethod).withArguments(folderFileMock).thenCallRealMethod();
|
||||
|
||||
ConfigDriveBuilder.writeVendorAndNetworkEmptyJsonFile(folderFileMock);
|
||||
|
||||
Mockito.verify(folderFileMock).exists();
|
||||
Mockito.verify(folderFileMock).mkdirs();
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("vendor_data.json"), Mockito.eq("{}"));
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("network_data.json"), Mockito.eq("{}"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Method getWriteVendorAndNetworkEmptyJsonFileMethod() {
|
||||
return ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("writeVendorAndNetworkEmptyJsonFile")).iterator().next();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void writeVmMetadataTest() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = getWriteVmMetadataMethod();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(new ArrayList<>(), "metadataFile", new File("folder")).thenCallRealMethod();
|
||||
|
||||
Method createJsonObjectWithVmDataMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("createJsonObjectWithVmData")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, createJsonObjectWithVmDataMethod).withArguments(Mockito.anyListOf(String[].class), Mockito.any(File.class)).thenReturn(new JsonObject());
|
||||
|
||||
ConfigDriveBuilder.writeVmMetadata(new ArrayList<>(), "metadataFile", new File("folder"));
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.createJsonObjectWithVmData(Mockito.anyListOf(String[].class), Mockito.anyString());
|
||||
ConfigDriveBuilder.writeFile(Mockito.any(File.class), Mockito.eq("meta_data.json"), Mockito.eq("{}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTestUserDataFilePathDoesNotExist() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
ConfigDriveBuilder.linkUserData("test");
|
||||
|
||||
Mockito.verify(scriptMock, times(0)).execute();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTestUserDataFilePathExistAndExecutionPresentedSomeError() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn("message").when(scriptMock).execute();
|
||||
ConfigDriveBuilder.linkUserData("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void linkUserDataTest() throws Exception {
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(fileMock).exists();
|
||||
|
||||
PowerMockito.mockStatic(File.class, Script.class);
|
||||
PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
String tempDirName = "test";
|
||||
ConfigDriveBuilder.linkUserData(tempDirName);
|
||||
|
||||
Mockito.verify(scriptMock).add(tempDirName + ConfigDrive.cloudStackConfigDriveName + "userdata/user_data.txt");
|
||||
Mockito.verify(scriptMock).add(tempDirName + ConfigDrive.openStackConfigDriveName + "user_data");
|
||||
Mockito.verify(scriptMock).execute();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTestGenIsoFailure() throws Exception {
|
||||
PowerMockito.mockStatic(Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn("scriptMessage").when(scriptMock).execute();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTestIsoTooBig() throws Exception {
|
||||
PowerMockito.mockStatic(File.class, Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
Mockito.doReturn(64L * 1024L * 1024L + 1l).when(fileMock).length();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({File.class, Script.class, ConfigDriveBuilder.class})
|
||||
public void generateAndRetrieveIsoAsBase64IsoTest() throws Exception {
|
||||
PowerMockito.mockStatic(File.class, Script.class, ConfigDriveBuilder.class);
|
||||
|
||||
File fileMock = Mockito.mock(File.class);
|
||||
PowerMockito.whenNew(File.class).withArguments("tempDirName", "isoFileName").thenReturn(fileMock);
|
||||
|
||||
Script scriptMock = Mockito.mock(Script.class);
|
||||
PowerMockito.whenNew(Script.class).withAnyArguments().thenReturn(scriptMock);
|
||||
|
||||
Mockito.when(fileMock.getAbsolutePath()).thenReturn("absolutePath");
|
||||
Mockito.doReturn(StringUtils.EMPTY).when(scriptMock).execute();
|
||||
Mockito.doReturn(64L * 1024L * 1024L).when(fileMock).length();
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("generateAndRetrieveIsoAsBase64Iso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.any(File.class), Mockito.any(File.class), Mockito.any(File.class)).thenCallRealMethod();
|
||||
|
||||
Method getProgramToGenerateIsoMethod = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("getProgramToGenerateIso")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, getProgramToGenerateIsoMethod).withNoArguments().thenReturn("/usr/bin/genisoimage");
|
||||
|
||||
ConfigDriveBuilder.generateAndRetrieveIsoAsBase64Iso("isoFileName", "driveLabel", "tempDirName");
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(scriptMock);
|
||||
inOrder.verify(scriptMock).add("-o", "absolutePath");
|
||||
inOrder.verify(scriptMock).add("-ldots");
|
||||
inOrder.verify(scriptMock).add("-allow-lowercase");
|
||||
inOrder.verify(scriptMock).add("-allow-multidot");
|
||||
inOrder.verify(scriptMock).add("-cache-inodes");
|
||||
inOrder.verify(scriptMock).add("-l");
|
||||
inOrder.verify(scriptMock).add("-quiet");
|
||||
inOrder.verify(scriptMock).add("-J");
|
||||
inOrder.verify(scriptMock).add("-r");
|
||||
inOrder.verify(scriptMock).add("-V", "driveLabel");
|
||||
inOrder.verify(scriptMock).add("tempDirName");
|
||||
inOrder.verify(scriptMock).execute();
|
||||
|
||||
PowerMockito.verifyStatic();
|
||||
ConfigDriveBuilder.fileToBase64String(Mockito.any(File.class));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void createJsonObjectWithVmDataTesT() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("createJsonObjectWithVmData")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString()).thenCallRealMethod();
|
||||
|
||||
List<String[]> vmData = new ArrayList<>();
|
||||
vmData.add(new String[] {"dataType", "fileName", "content"});
|
||||
vmData.add(new String[] {"dataType2", "fileName2", "content2"});
|
||||
|
||||
ConfigDriveBuilder.createJsonObjectWithVmData(vmData, "tempDirName");
|
||||
|
||||
PowerMockito.verifyStatic(Mockito.times(1));
|
||||
ConfigDriveBuilder.createFileInTempDirAnAppendOpenStackMetadataToJsonObject(Mockito.eq("tempDirName"), Mockito.any(JsonObject.class), Mockito.eq("dataType"), Mockito.eq("fileName"),
|
||||
Mockito.eq("content"));
|
||||
ConfigDriveBuilder.createFileInTempDirAnAppendOpenStackMetadataToJsonObject(Mockito.eq("tempDirName"), Mockito.any(JsonObject.class), Mockito.eq("dataType2"), Mockito.eq("fileName2"),
|
||||
Mockito.eq("content2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestGenIsoExistsAndIsExecutable() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(genIsoFileMock).exists();
|
||||
Mockito.doReturn(true).when(genIsoFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(2)).exists();
|
||||
Mockito.verify(genIsoFileMock).canExecute();
|
||||
Mockito.verify(genIsoFileMock).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Test(expected = CloudRuntimeException.class)
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestGenIsoExistsbutNotExecutable() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(genIsoFileMock).exists();
|
||||
Mockito.doReturn(false).when(genIsoFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestNotGenIsoMkIsoInLinux() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(genIsoFileMock).exists();
|
||||
|
||||
File mkIsoProgramInLinuxFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(mkIsoProgramInLinuxFileMock).exists();
|
||||
Mockito.doReturn(true).when(mkIsoProgramInLinuxFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/mkisofs").thenReturn(mkIsoProgramInLinuxFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(2)).exists();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).getCanonicalPath();
|
||||
}
|
||||
|
||||
@Test
|
||||
@PrepareForTest({File.class, ConfigDriveBuilder.class})
|
||||
public void getProgramToGenerateIsoTestMkIsoMac() throws Exception {
|
||||
PowerMockito.mockStatic(File.class);
|
||||
|
||||
File genIsoFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(genIsoFileMock).exists();
|
||||
|
||||
File mkIsoProgramInLinuxFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(false).when(mkIsoProgramInLinuxFileMock).exists();
|
||||
|
||||
File mkIsoProgramInMacOsFileMock = Mockito.mock(File.class);
|
||||
Mockito.doReturn(true).when(mkIsoProgramInMacOsFileMock).exists();
|
||||
Mockito.doReturn(true).when(mkIsoProgramInMacOsFileMock).canExecute();
|
||||
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/genisoimage").thenReturn(genIsoFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/bin/mkisofs").thenReturn(mkIsoProgramInLinuxFileMock);
|
||||
PowerMockito.whenNew(File.class).withArguments("/usr/local/bin/mkisofs").thenReturn(mkIsoProgramInMacOsFileMock);
|
||||
|
||||
ConfigDriveBuilder.getProgramToGenerateIso();
|
||||
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(genIsoFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(0)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInLinuxFileMock, Mockito.times(0)).getCanonicalPath();
|
||||
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).exists();
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).canExecute();
|
||||
Mockito.verify(mkIsoProgramInMacOsFileMock, Mockito.times(1)).getCanonicalPath();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.configdrive;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ConfigDriveTest {
|
||||
|
||||
@Test
|
||||
public void testConfigDriveIsoPath() throws IOException {
|
||||
Assert.assertEquals(ConfigDrive.createConfigDrivePath("i-x-y"), "configdrive/i-x-y/configdrive.iso");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -41,12 +42,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.configdrive.ConfigDrive;
|
||||
import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.reflections.ReflectionUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
|
@ -90,6 +99,7 @@ import com.cloud.vm.dao.UserVmDetailsDao;
|
|||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
public class ConfigDriveNetworkElementTest {
|
||||
|
||||
public static final String CLOUD_ID = "xx";
|
||||
|
|
@ -140,7 +150,7 @@ public class ConfigDriveNetworkElementTest {
|
|||
@InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement();
|
||||
@InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl();
|
||||
|
||||
@org.junit.Before
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
|
|
@ -243,7 +253,14 @@ public class ConfigDriveNetworkElementTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@PrepareForTest({ConfigDriveBuilder.class})
|
||||
public void testAddPasswordAndUserData() throws Exception {
|
||||
PowerMockito.mockStatic(ConfigDriveBuilder.class);
|
||||
|
||||
Method method = ReflectionUtils.getMethods(ConfigDriveBuilder.class, ReflectionUtils.withName("buildConfigDrive")).iterator().next();
|
||||
PowerMockito.when(ConfigDriveBuilder.class, method).withArguments(Mockito.anyListOf(String[].class), Mockito.anyString(), Mockito.anyString()).thenReturn("content");
|
||||
|
||||
final Answer answer = mock(Answer.class);
|
||||
final UserVmDetailVO userVmDetailVO = mock(UserVmDetailVO.class);
|
||||
when(agentManager.easySend(anyLong(), any(HandleConfigDriveIsoCommand.class))).thenReturn(answer);
|
||||
|
|
|
|||
|
|
@ -29,10 +29,9 @@ import javax.net.SocketFactory;
|
|||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import streamer.debug.MockServer;
|
||||
import streamer.debug.MockServer.Packet;
|
||||
|
||||
|
|
@ -93,7 +92,6 @@ public class MockServerTest extends TestCase {
|
|||
|
||||
@Test
|
||||
public void testIsMockServerCanUpgradeConnectionToSsl() throws Exception {
|
||||
|
||||
final byte[] mockClientData1 = new byte[] {0x01, 0x02, 0x03};
|
||||
final byte[] mockServerData1 = new byte[] {0x03, 0x02, 0x01};
|
||||
|
||||
|
|
@ -161,8 +159,7 @@ public class MockServerTest extends TestCase {
|
|||
|
||||
final SSLSocketFactory sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(socket, address.getHostName(), address.getPort(), true);
|
||||
//sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
|
||||
sslSocket.setEnabledCipherSuites(new String[] { "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA" });
|
||||
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
|
||||
sslSocket.startHandshake();
|
||||
|
||||
InputStream is = sslSocket.getInputStream();
|
||||
|
|
|
|||
|
|
@ -584,16 +584,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(secStorageMountPoint);
|
||||
if (!secStorageMountPoint.endsWith("/"))
|
||||
if (!secStorageMountPoint.endsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
|
||||
sb.append(templateRelativeFolderPath);
|
||||
if (!secStorageMountPoint.endsWith("/"))
|
||||
if (!secStorageMountPoint.endsWith("/")) {
|
||||
sb.append("/");
|
||||
}
|
||||
|
||||
sb.append(templateName);
|
||||
if (!fileExtension.startsWith("."))
|
||||
if (!fileExtension.startsWith(".")) {
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(fileExtension);
|
||||
|
||||
return sb.toString();
|
||||
|
|
@ -904,7 +907,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
try {
|
||||
_storage.create(destFile.getAbsolutePath(), _tmpltpp);
|
||||
try ( // generate template.properties file
|
||||
FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
|
||||
FileWriter writer = new FileWriter(metaFile); BufferedWriter bufferWriter = new BufferedWriter(writer);) {
|
||||
// KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
|
||||
// to send template name back.
|
||||
bufferWriter.write("uniquename=" + destData.getName());
|
||||
|
|
@ -1450,7 +1453,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
|
||||
+ " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result != null) {
|
||||
|
|
@ -1554,7 +1557,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " list " + container + " " + rFilename);
|
||||
+ " -K " + swift.getKey() + " list " + container + " " + rFilename);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result == null && parser.getLines() != null) {
|
||||
|
|
@ -1576,7 +1579,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
Script command = new Script("/bin/bash", s_logger);
|
||||
command.add("-c");
|
||||
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
|
||||
+ " -K " + swift.getKey() + " delete " + container + " " + object);
|
||||
+ " -K " + swift.getKey() + " delete " + container + " " + object);
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
if (result != null) {
|
||||
|
|
@ -3316,7 +3319,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
for (Processor processor : processors.values()) {
|
||||
FormatInfo info = null;
|
||||
try {
|
||||
info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
|
||||
info = processor.process(resourcePath, null, templateName, processTimeout * 1000);
|
||||
} catch (InternalErrorException e) {
|
||||
s_logger.error("Template process exception ", e);
|
||||
return e.toString();
|
||||
|
|
|
|||
Loading…
Reference in New Issue