DaanHoogland closed pull request #2674: Create unit test cases for 
'ConfigDriveBuilder' class
URL: https://github.com/apache/cloudstack/pull/2674
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
 
b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
index ec461991537..07cfdc883ca 100644
--- 
a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
+++ 
b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
@@ -26,11 +26,12 @@
     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;
     }
-
-}
+}
\ No newline at end of file
diff --git 
a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
 
b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
index d847aa1d1d7..dc6b8893495 100644
--- 
a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
+++ 
b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java
@@ -23,9 +23,7 @@
 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 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 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 static String buildConfigDrive(final 
List<String[]> vmData, final String
             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)));
-
-                // 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);
-                    }
-
-                    //now write the file to the OpenStack directory
-                    metaData = buildOpenStackMetaData(metaData, dataType, 
fileName, content);
-                }
-            }
-            writeFile(openStackFolder, "meta_data.json", metaData.toString());
+            writeVendorAndNetworkEmptyJsonFile(openStackFolder);
+            writeVmMetadata(vmData, tempDirName, openStackFolder);
 
-            String linkResult = linkUserData(tempDirName);
-            if (linkResult != null) {
-                String errMsg = "Unable to create user_data link due to " + 
linkResult;
-                throw new CloudRuntimeException(errMsg);
-            }
+            linkUserData(tempDirName);
 
-            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 {
+            deleteTempDir(tempDir);
+        }
+    }
+
+    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: " 
+ tempDirName, ioe);
             }
+        } catch (IOException ioe) {
+            LOG.warn("Failed to delete ConfigDrive temporary directory: " + 
tempDir.toString(), ioe);
         }
     }
 
-    private static String linkUserData(String tempDirName) {
-        //Hard link the user_data.txt file with the user_data file in the 
OpenStack directory.
+    /**
+     *  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 @@ private static JsonArray arrayOf(JsonElement... elements) 
{
         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;
     }
 
 }
diff --git 
a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
index 50a4384d5c8..96032738edc 100644
--- 
a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
+++ 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java
@@ -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 fileToBase64StringTest() throws Exception {
+        PowerMockito.mockStatic(FileUtils.class);
+
+        String fileContent = "content";
+        Method method = getFileUtilsReadfileToByteArrayMethod();
+        PowerMockito.when(FileUtils.class, 
method).withArguments(Mockito.any(File.class)).thenReturn(fileContent.getBytes());
+
+        String returnedContentInBase64 = 
ConfigDriveBuilder.fileToBase64String(new File("file"));
+
+        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
-    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"}
-        );
-
-        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);
-
-        Assert.assertTrue(isoFile.exists());
-        Assert.assertTrue(isoFile.isFile());
-        Assert.assertTrue(isoFile.length() > 0L);
-
-        FileUtils.deleteDirectory(tempDir.toFile());
+    @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();
     }
 }
\ No newline at end of file
diff --git 
a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
new file mode 100644
index 00000000000..81294d4331b
--- /dev/null
+++ 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
@@ -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");
+    }
+
+}
\ No newline at end of file
diff --git 
a/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java 
b/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java
index e964999ee9d..01713de389d 100644
--- a/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java
+++ b/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java
@@ -31,6 +31,7 @@
 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.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.VMInstanceDao;
 import com.google.common.collect.Maps;
 
+@RunWith(PowerMockRunner.class)
 public class ConfigDriveNetworkElementTest {
 
     public static final String CLOUD_ID = "xx";
@@ -140,7 +150,7 @@
     @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 void testGetCapabilities () {
     }
 
     @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);
diff --git 
a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
 
b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
index 3462618fed9..f2e611de24f 100644
--- 
a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
+++ 
b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java
@@ -29,10 +29,9 @@
 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 void testIsMockServerCanRespond() throws Exception {
 
     @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 void testIsMockServerCanUpgradeConnectionToSsl() 
throws Exception {
 
                 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();
diff --git 
a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
 
b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 125512bba91..0bb923f8053 100644
--- 
a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ 
b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -584,16 +584,19 @@ public static String 
getTemplateOnSecStorageFilePath(String secStorageMountPoint
 
         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 @@ protected Answer 
copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObj
             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 @@ String swiftDownload(SwiftTO swift, String container, 
String rfilename, String l
         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 @@ String swiftUpload(SwiftTO swift, String container, 
String lDir, String lFilenam
         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 @@ String swiftDelete(SwiftTO swift, String container, 
String object) {
         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 String postUpload(String uuid, String filename, 
long processTimeout) {
         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();


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to