This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch 4.11
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.11 by this push:
     new 9b83337  Create unit test cases for 'ConfigDriveBuilder' class (#2674)
9b83337 is described below

commit 9b83337658ede7f55bc404f869ae996d929ae9cb
Author: Rafael Weingärtner <[email protected]>
AuthorDate: Mon Jun 4 08:20:09 2018 -0300

    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
---
 .../storage/configdrive/ConfigDrive.java           |  11 +-
 .../storage/configdrive/ConfigDriveBuilder.java    | 322 +++++++++-----
 .../configdrive/ConfigDriveBuilderTest.java        | 492 +++++++++++++++++++--
 .../storage/configdrive/ConfigDriveTest.java}      |  20 +-
 .../element/ConfigDriveNetworkElementTest.java     |  19 +-
 .../src/test/java/rdpclient/MockServerTest.java    |   7 +-
 .../resource/NfsSecondaryStorageResource.java      |  19 +-
 7 files changed, 714 insertions(+), 176 deletions(-)

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 ec46199..07cfdc8 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 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;
     }
-
-}
+}
\ 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 d847aa1..dc6b889 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.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)));
-
-                // 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 @@ 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;
     }
 
 }
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 50a4384..9603273 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/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
similarity index 58%
copy from 
engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
copy to 
engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
index ec46199..81294d4 100644
--- 
a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDrive.java
+++ 
b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveTest.java
@@ -17,20 +17,16 @@
 
 package org.apache.cloudstack.storage.configdrive;
 
-public class ConfigDrive {
+import java.io.IOException;
 
-    public final static String CONFIGDRIVEFILENAME = "configdrive.iso";
-    public final static String CONFIGDRIVEDIR = "configdrive";
+import org.junit.Assert;
+import org.junit.Test;
 
-    public static final String cloudStackConfigDriveName = "/cloudstack/";
-    public static final String openStackConfigDriveName = "/openstack/latest/";
+public class ConfigDriveTest {
 
-    /**
-     * This is the path to iso file relative to mount point
-     * @return config drive iso file path
-     */
-    public static String createConfigDrivePath(final String instanceName) {
-        return ConfigDrive.CONFIGDRIVEDIR + "/" + instanceName + "/"  + 
ConfigDrive.CONFIGDRIVEFILENAME;
+    @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 e964999..01713de 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.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);
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 3462618..f2e611d 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.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();
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 125512b..0bb923f 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 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();

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to