﻿// 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.
using System;
using CloudStack.Plugin.WmiWrappers.ROOT.VIRTUALIZATION;
using System.Management;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.IO;
using log4net;
using HypervResource;
using CloudStack.Plugin.AgentShell;
using System.Collections.Generic;
using System.Xml;
using Xunit;

namespace ServerResource.Tests
{
    public class HypervResourceControllerTest
    {
        protected static string testCifsUrl = AgentSettings.Default.testCifsUrl;
        protected static string testCifsPath = AgentSettings.Default.testCifsPath;
        protected static String testPrimaryDataStoreHost = HypervResourceController.config.StorageIpAddress;
        protected static String testS3TemplateName = AgentSettings.Default.testS3TemplateName;
        protected static String testCifsTemplateName = AgentSettings.Default.testS3TemplateName;
        protected static String testSystemVMTemplateName = AgentSettings.Default.testSystemVMTemplateName;
        protected static String testSystemVMTemplateNameNoExt = AgentSettings.Default.testSystemVMTemplateNameNoExt;
        protected static String testLocalStoreUUID = "5fe2bad3-d785-394e-9949-89786b8a63d2";
        protected static String testLocalStorePath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "storagepool");
        protected static String testSecondaryStoreLocalPath = Path.Combine(AgentSettings.Default.hyperv_plugin_root, "var", "test", "secondary");

        // TODO: differentiate between NFS and HTTP template URLs.
        protected static String testSampleTemplateUUID = "TestCopiedLocalTemplate.vhdx";
        protected static String testSampleTemplateURL = testSampleTemplateUUID;

        // test volumes are both a minimal size vhdx.  Changing the extension to .vhd makes on corrupt.
        protected static String testSampleVolumeWorkingUUID = "TestVolumeLegit.vhdx";
        protected static String testSampleVolumeCorruptUUID = "TestVolumeCorrupt.vhd";
        protected static String testSampleVolumeTempUUID = "TestVolumeTemp.vhdx";
        protected static String testSampleVolumeTempUUIDNoExt = "TestVolumeTemp";
        protected static String testSampleVolumeWorkingURIJSON;
        protected static String testSampleVolumeCorruptURIJSON;
        protected static String testSampleVolumeTempURIJSON;

        protected static String testSampleTemplateURLJSON;
        protected static String testLocalStorePathJSON;

        protected static WmiCallsV2 wmiCallsV2 = new WmiCallsV2();

        private static ILog s_logger = LogManager.GetLogger(typeof(HypervResourceControllerTest));

        /// <summary>
        /// Test WmiCalls to which incoming HTTP POST requests are dispatched.
        /// 
        /// TODO: revise beyond first approximation
        /// First approximation is a quick port of the existing Java tests for Hyper-V server resource.
        /// A second approximation would use the AgentShell settings files directly.
        /// A third approximation would look to invoke ServerResource methods via an HTTP request
        /// </summary>
        public HypervResourceControllerTest()
        {
            AgentService.ConfigServerResource();
            HypervResourceController.config.PrivateMacAddress = AgentSettings.Default.private_mac_address;
            HypervResourceController.config.PrivateNetmask = AgentSettings.Default.private_ip_netmask;
            HypervResourceController.config.StorageIpAddress = HypervResourceController.config.PrivateIpAddress;
            HypervResourceController.config.StorageMacAddress = HypervResourceController.config.PrivateMacAddress;
            HypervResourceController.config.StorageNetmask = HypervResourceController.config.PrivateNetmask;


            // Used to create existing StoragePool in preparation for the ModifyStoragePool
            testLocalStoreUUID = AgentSettings.Default.local_storage_uuid.ToString();

            // Make sure secondary store is available.
            string fullPath = Path.GetFullPath(testSecondaryStoreLocalPath);
            s_logger.Info("Test secondary storage in " + fullPath);
            DirectoryInfo testSecondarStoreDir = new DirectoryInfo(fullPath);
            if (!testSecondarStoreDir.Exists)
            {
                try
                {
                    testSecondarStoreDir.Create();
                }
                catch (System.IO.IOException ex)
                {
                    throw new NotImplementedException("Need to be able to create the folder " + testSecondarStoreDir.FullName + " failed due to " + ex.Message);
                }
            }

            // Convert to secondary storage string to canonical path
            testSecondaryStoreLocalPath = testSecondarStoreDir.FullName;
            AgentSettings.Default.local_secondary_storage_path = testSecondaryStoreLocalPath;

            // Make sure local primary storage is available
            DirectoryInfo testPoolDir = new DirectoryInfo(testLocalStorePath);
            Assert.True(testPoolDir.Exists, "To simulate local file system Storage Pool, you need folder at " + testPoolDir.FullName);

            // Convert to local primary storage string to canonical path
            testLocalStorePath = testPoolDir.FullName;
            AgentSettings.Default.local_storage_path = testLocalStorePath;

            // Clean up old test files in local storage folder
            FileInfo testVolWorks = new FileInfo(Path.Combine(testLocalStorePath, testSampleVolumeWorkingUUID));
            Assert.True(testVolWorks.Exists, "Create a working virtual disk at " + testVolWorks.FullName);


            // Delete all temporary files in local folder save the testVolWorks
            foreach (var file in testPoolDir.GetFiles())
            {
                if (file.FullName == testVolWorks.FullName)
                {
                    continue;
                }
                file.Delete();
                file.Refresh();
                Assert.False(file.Exists, "removed file from previous test called " + file.FullName);
            }

            // Recreate starting point files for test, and record JSON encoded paths for each ...
            testSampleVolumeTempURIJSON = CreateTestDiskImageFromExistingImage(testVolWorks, testLocalStorePath, testSampleVolumeTempUUID);
            s_logger.Info("Created " + testSampleVolumeTempURIJSON);
            testSampleVolumeCorruptURIJSON = CreateTestDiskImageFromExistingImage(testVolWorks, testLocalStorePath, testSampleVolumeCorruptUUID);
            s_logger.Info("Created " + testSampleVolumeCorruptURIJSON);
            CreateTestDiskImageFromExistingImage(testVolWorks, testLocalStorePath, testSampleTemplateUUID);
            testSampleTemplateURLJSON = JsonConvert.SerializeObject(testSampleTemplateUUID);
            s_logger.Info("Created " + testSampleTemplateURLJSON + " in local storage.");

            // ... including a secondary storage template:
            CreateTestDiskImageFromExistingImage(testVolWorks, testSecondarStoreDir.FullName, "af39aa7f-2b12-37e1-86d3-e23f2f005101.vhdx");
            s_logger.Info("Created " + "af39aa7f-2b12-37e1-86d3-e23f2f005101.vhdx" + " in secondary (NFS) storage.");


            // Capture other JSON encoded paths
            testSampleVolumeWorkingURIJSON = Newtonsoft.Json.JsonConvert.SerializeObject(testVolWorks.FullName);
            testLocalStorePathJSON = JsonConvert.SerializeObject(testLocalStorePath);

            // TODO: may need to initialise the server resource in future.
            //    s_hypervresource.initialize();

            // Verify sample template is in place storage pool
            s_logger.Info("setUp complete, sample StoragePool at " + testLocalStorePathJSON
                      + " sample template at " + testSampleTemplateURLJSON);
        }

        private String CreateTestDiskImageFromExistingImage(FileInfo srcFile,
        String dstPath,
        String dstFileName)
        {
            var newFullname = Path.Combine(dstPath, dstFileName);
            var newFileInfo = new FileInfo(newFullname);
            if (!newFileInfo.Exists)
            {
                newFileInfo = srcFile.CopyTo(newFullname);
            }
            newFileInfo.Refresh();
            Assert.True(newFileInfo.Exists, "Attempted to create " + newFullname + " from " + newFileInfo.FullName);

            return JsonConvert.SerializeObject(newFileInfo.FullName);
        }

        [Fact(Skip="these are functional tests")]
        public void TestPrimaryStorageDownloadCommandHTTP()
        {
            string downloadURI = "https://s3-eu-west-1.amazonaws.com/cshv3eu/SmallDisk.vhdx";
            corePrimaryStorageDownloadCommandTestCycle(downloadURI);
        }

        private void corePrimaryStorageDownloadCommandTestCycle(string downloadURI)
        {
            // Arrange
            HypervResourceController rsrcServer = new HypervResourceController();
            dynamic jsonPSDCmd = JsonConvert.DeserializeObject(samplePrimaryDownloadCommand());
            jsonPSDCmd.url = downloadURI;

            // Act
            dynamic jsonResult = rsrcServer.PrimaryStorageDownloadCommand(jsonPSDCmd);

            // Assert
            JObject ansAsProperty = jsonResult[0];
            dynamic ans = ansAsProperty.GetValue(CloudStackTypes.PrimaryStorageDownloadAnswer);
            Assert.True((bool)ans.result, "PrimaryStorageDownloadCommand did not succeed " + ans.details);

            // Test that URL of downloaded template works for file creation.
            dynamic jsonCreateCmd = JsonConvert.DeserializeObject(CreateCommandSample());
            jsonCreateCmd.templateUrl = ans.installPath;
            dynamic jsonAns2 = rsrcServer.CreateCommand(jsonCreateCmd);
            JObject ansAsProperty2 = jsonAns2[0];
            dynamic ans2 = ansAsProperty2.GetValue(CloudStackTypes.CreateAnswer);

            Assert.True((bool)ans2.result, (string)ans2.details);

            FileInfo newFile = new FileInfo((string)ans2.volume.path);
            Assert.True(newFile.Length > 0, "The new file should have a size greater than zero");
            newFile.Delete();
        }

        private string samplePrimaryDownloadCommand()
        {
            String cmdJson = "{\"localPath\":" + testLocalStorePathJSON +
                    ",\"poolUuid\":\"" + testLocalStoreUUID + "\",\"poolId\":201," +
                    "\"secondaryStorageUrl\":\"nfs://10.70.176.36/mnt/cshv3/secondarystorage\"," +
                    "\"primaryStorageUrl\":\"nfs://" + HypervResourceController.config.StorageIpAddress + "E:\\\\Disks\\\\Disks\"," +
                    "\"url\":\"nfs://10.70.176.36/mnt/cshv3/secondarystorage/template/tmpl//2/204//af39aa7f-2b12-37e1-86d3-e23f2f005101.vhdx\"," +
                    "\"format\":\"VHDX\",\"accountId\":2,\"name\":\"204-2-5a1db1ac-932b-3e7e-a0e8-5684c72cb862\"" +
                    ",\"contextMap\":{},\"wait\":10800}";
            return cmdJson;
        }

        public string CreateCommandSample()
        {
            String sample = "{\"volId\":17,\"pool\":{\"id\":201,\"uuid\":\"" + testLocalStoreUUID + "\",\"host\":\"" + HypervResourceController.config.StorageIpAddress + "\"" +
                            ",\"path\":" + testLocalStorePathJSON + ",\"port\":0,\"type\":\"Filesystem\"},\"diskCharacteristics\":{\"size\":0," +
                            "\"tags\":[],\"type\":\"ROOT\",\"name\":\"ROOT-15\",\"useLocalStorage\":true,\"recreatable\":true,\"diskOfferingId\":11," +
                            "\"volumeId\":17,\"hyperType\":\"Hyperv\"},\"templateUrl\":" + testSampleTemplateURLJSON + ",\"wait\":0}";
            return sample;
        }

        [Fact(Skip="these are functional tests")]
        public void TestDestroyCommand()
        {
            // Arrange
            String sampleVolume = getSampleVolumeObjectTO();
            String destroyCmd = //"{\"volume\":" + getSampleVolumeObjectTO() + "}";
                            "{\"volume\":{\"name\":\"" + testSampleVolumeTempUUIDNoExt
                                    + "\",\"storagePoolType\":\"Filesystem\","
                                    + "\"mountPoint\":"
                                    + testLocalStorePathJSON
                                   + ",\"path\":" + testSampleVolumeTempURIJSON
                                    + ",\"storagePoolUuid\":\"" + testLocalStoreUUID
                                    + "\","
                                    + "\"type\":\"ROOT\",\"id\":9,\"size\":0}}";

            HypervResourceController rsrcServer = new HypervResourceController();
            dynamic jsonDestroyCmd = JsonConvert.DeserializeObject(destroyCmd);

            // Act
            dynamic destroyAns = rsrcServer.DestroyCommand(jsonDestroyCmd);

            // Assert
            JObject ansAsProperty2 = destroyAns[0];
            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.Answer);
            String path = jsonDestroyCmd.volume.path;
            Assert.True((bool)ans.result, "DestroyCommand did not succeed " + ans.details);
            Assert.True(!File.Exists(path), "Failed to delete file " + path);
        }

        [Fact(Skip="these are functional tests")]
        public void TestCreateCommand()
        {
            // TODO: Need sample to update the test.
            // Arrange
            String createCmd = "{\"volId\":10,\"pool\":{\"id\":201,\"uuid\":\"" + testLocalStoreUUID + "\",\"host\":\"" + HypervResourceController.config.StorageIpAddress + "\"" +
                            ",\"path\":" + testLocalStorePathJSON + ",\"port\":0,\"type\":\"Filesystem\"},\"diskCharacteristics\":{\"size\":0," +
                            "\"tags\":[],\"type\":\"ROOT\",\"name\":\"ROOT-9\",\"useLocalStorage\":true,\"recreatable\":true,\"diskOfferingId\":11," +
                            "\"volumeId\":10,\"hyperType\":\"Hyperv\"},\"templateUrl\":" + testSampleTemplateURLJSON + ",\"contextMap\":{},\"wait\":0}";
            dynamic jsonCreateCmd = JsonConvert.DeserializeObject(createCmd);
            HypervResourceController rsrcServer = new HypervResourceController();

            Assert.True(Directory.Exists(testLocalStorePath));
            string filePath = Path.Combine(testLocalStorePath, (string)JsonConvert.DeserializeObject(testSampleTemplateURLJSON));
            Assert.True(File.Exists(filePath), "The template we make volumes from is missing from path " + filePath);
            int fileCount = Directory.GetFiles(testLocalStorePath).Length;
            s_logger.Debug(" test local store has " + fileCount + "files");

            // Act
            // Test requires there to be a template at the tempalteUrl, which is its location in the local file system.
            dynamic jsonResult = rsrcServer.CreateCommand(jsonCreateCmd);

            JObject ansAsProperty2 = jsonResult[0];
            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.CreateAnswer);
            Assert.NotNull(ans);
            Assert.True((bool)ans.result, "Failed to CreateCommand due to " + (string)ans.result);
            Assert.Equal(Directory.GetFiles(testLocalStorePath).Length, fileCount + 1);
            FileInfo newFile = new FileInfo((string)ans.volume.path);
            Assert.True(newFile.Length > 0, "The new file should have a size greater than zero");
            newFile.Delete();
        }

        /// <summary>
        /// Possible additional tests:  place an ISO in the drive
        /// </summary>
        [Fact(Skip="these are functional tests")]
        public void TestStartStopCommand()
        {
            string vmName = TestStartCommand();
            TestStopCommand(vmName);
        }

        public static String getSamplePrimaryDataStoreInfo()
        {
            String samplePrimaryDataStoreInfo =
            "{\"org.apache.cloudstack.storage.to.PrimaryDataStoreTO\":" +
                "{\"uuid\":\"" + testLocalStoreUUID + "\"," +
                "\"id\":201," +
                "\"host\":\"" + testPrimaryDataStoreHost + "\"," +
                "\"type\":\"Filesystem\"," +  // Not used in PrimaryDataStoreTO
                "\"poolType\":\"Filesystem\"," +  // Not used in PrimaryDataStoreTO
                "\"path\":" + testLocalStorePathJSON + "," +
                "\"port\":0}" +
            "}";
            return samplePrimaryDataStoreInfo;
        }

        public static String getSampleVolumeObjectTO()
        {
            String sampleVolumeObjectTO =
                    "{\"org.apache.cloudstack.storage.to.VolumeObjectTO\":" +
                        "{\"uuid\":\"19ae8e67-cb2c-4ab4-901e-e0b864272b59\"," +
                        "\"volumeType\":\"ROOT\"," +
                        "\"format\":\"VHDX\"," +
                        "\"dataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"" + testSampleVolumeTempUUIDNoExt + "\"," +
                        "\"size\":52428800," +
                        "\"volumeId\":10," +
                //                            "\"vmName\":\"i-3-5-VM\"," +  // TODO: do we have to fill in the vmName?
                        "\"accountId\":3,\"id\":10}" +
                    "}";  // end of destTO 
            return sampleVolumeObjectTO;
        }

        public static String getSampleStartCommand()
        {
            String sample = "{\"vm\":{\"id\":17,\"name\":\"i-2-17-VM\",\"type\":\"User\",\"cpus\":1,\"speed\":500," +
                                "\"minRam\":536870912,\"maxRam\":536870912,\"arch\":\"x86_64\"," +
                                "\"os\":\"CentOS 6.0 (64-bit)\",\"bootArgs\":\"\",\"rebootOnCrash\":false," +
                                "\"enableHA\":false,\"limitCpuUse\":false,\"vncPassword\":\"31f82f29aff646eb\"," +
                                "\"params\":{},\"uuid\":\"8b030b6a-0243-440a-8cc5-45d08815ca11\"" +
                            ",\"disks\":[" +
                               "{\"data\":" + getSampleVolumeObjectTO() + ",\"diskSeq\":0,\"type\":\"ROOT\"}," +
                               "{\"diskSeq\":1,\"type\":\"ISO\"}" +
                            "]," +
                            "\"nics\":[" +
                                    "{\"deviceId\":0,\"networkRateMbps\":100,\"defaultNic\":true,\"uuid\":\"99cb4813-23af-428c-a87a-2d1899be4f4b\"," +
                                    "\"ip\":\"10.1.1.67\",\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\"," +
                                    "\"mac\":\"02:00:51:2c:00:0e\",\"dns1\":\"4.4.4.4\",\"broadcastType\":\"Vlan\",\"type\":\"Guest\"," +
                                    "\"broadcastUri\":\"vlan://261\",\"isolationUri\":\"vlan://261\",\"isSecurityGroupEnabled\":false}" +
                            "]},\"contextMap\":{},\"wait\":0}";
            return sample;
        }


        [Fact(Skip="these are functional tests")]
        public void TestCopyCommandFromCifs()
        {
            // Arrange
            string sampleCopyCommandForTemplateDownload =
            #region string_literal
                // org.apache.cloudstack.storage.command.CopyCommand
                "{\"srcTO\":" +
                  "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                    "{\"path\":\"" + testCifsPath + "\"," +
                     "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                     "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                     "\"id\":206," +
                     "\"format\":\"VHDX\"," +
                     "\"accountId\":2," +
                     "\"checksum\":\"4b31e2846cc67fc10ea7281986519a54\"," +
                     "\"hvm\":true," +
                     "\"displayText\":\"OS031\"," +
                     "\"imageDataStore\":" +
                       "{\"com.cloud.agent.api.to.NfsTO\":" +
                         "{\"_url\":\"" + testCifsUrl + "\"," + // Unique item here
                         "\"_role\":\"Image\"}" +
                       "}," + // end of imageDataStore
                     "\"hypervisorType\":\"Hyperv\"," +
                     "\"name\":\"" + testS3TemplateName + "\"}" +
                  "}," + // end of srcTO
                 "\"destTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{" +
                        "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                        "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                        "\"id\":206," +
                        "\"format\":\"VHDX\"," +
                        "\"accountId\":2," +
                        "\"checksum\":\"4b31e2846cc67fc10ea7281986519a54\"," +
                        "\"hvm\":true," +
                        "\"displayText\":\"Test of CIFS Download\"," +
                        "\"imageDataStore\":" + getSamplePrimaryDataStoreInfo() + "," + // end of imageDataStore
                        "\"name\":\"" + testS3TemplateName + "\"," +
                        "\"hypervisorType\":\"Hyperv\"}" +
                    "}," +// end of destTO
                "\"wait\":10800}"; // end of CopyCommand
            #endregion

            HypervResourceController rsrcServer;
            dynamic jsonDownloadCopyCmd;
            string dwnldDest;
            dynamic jsonCloneCopyCmd;
            string newVolName;
            CopyCommandTestSetupCifs(null, sampleCopyCommandForTemplateDownload, out rsrcServer, out jsonDownloadCopyCmd, out dwnldDest, out jsonCloneCopyCmd, out newVolName);

            // Act & Assert
            DownloadTemplateToPrimaryStorage(rsrcServer, jsonDownloadCopyCmd, dwnldDest);

            // Repeat to verify ability to detect existing file.
            DownloadTemplateToPrimaryStorage(rsrcServer, jsonDownloadCopyCmd, dwnldDest);

            File.Delete(dwnldDest);
        }

        [Fact(Skip="these are functional tests")]
        public void TestCopyCommand()
        {
            // Arrange
            string sampleCopyCommandToCreateVolumeFromTemplate =
            #region string_literal
                // org.apache.cloudstack.storage.command.CopyCommand
                "{\"srcTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{" +
                        "\"origUrl\":\"http://people.apache.org/~bhaisaab/vms/ttylinux_pv.vhd\"," +
                        "\"uuid\":\"9873f1c0-bdcc-11e2-8baa-ea85dab5fcd0\"," +
                        "\"id\":5," +
                        "\"format\":\"VHDX\"," +
                        "\"accountId\":1," +
                        "\"checksum\":\"4b31e2846cc67fc10ea7281986519a54\"," +
                        "\"hvm\":false," +
                        "\"displayText\":\"tiny Linux\"," +
                        "\"imageDataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"" + testS3TemplateName + "\"}" +
                    "}," +  // end of srcTO
                "\"destTO\":" +
                    "{\"org.apache.cloudstack.storage.to.VolumeObjectTO\":" +
                        "{\"uuid\":\"19ae8e67-cb2c-4ab4-901e-e0b864272b59\"," +
                        "\"volumeType\":\"ROOT\"," +
                        "\"dataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"ROOT-5\"," +
                        "\"size\":52428800," +
                        "\"volumeId\":10," +
                        "\"vmName\":\"i-3-5-VM\"," +
                        "\"accountId\":3," +
                        "\"id\":10 }" +
                    "}," +  // end of destTO 
                "\"wait\":0}"; // end of Copy Command
            #endregion
            //"name":"ROOT-8","size":140616708,"volumeId":8,"vmName":"s-8-VM","accountId":1,"id":8}},"contextMap":{},"wait":0}

            string sampleCopyCommandForTemplateDownload =
            #region string_literal
                // org.apache.cloudstack.storage.command.CopyCommand
                "{\"srcTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{\"path\":\"" + testS3TemplateName + ".vhdx" + "\"," +
                        "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                        "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                        "\"id\":206," +
                        "\"format\":\"VHDX\"," +
                        "\"accountId\":2," +
                        "\"checksum\":\"4b31e2846cc67fc10ea7281986519a54\"," +
                        "\"hvm\":true," +
                        "\"displayText\":\"OS031\"," +
                        "\"imageDataStore\":" +
                            "{\"com.cloud.agent.api.to.S3TO\":" +
                                "{\"id\":1," +
                                "\"uuid\":\"95a64c8f-2128-4502-b5b4-0d7aa77406d2\"," +
                                "\"accessKey\":\"" + AgentSettings.Default.testS3AccessKey + "\"," +
                                "\"secretKey\":\"" + AgentSettings.Default.testS3SecretKey + "\"," +
                                "\"endPoint\":\"" + AgentSettings.Default.testS3Endpoint + "\"," +
                                "\"bucketName\":\"" + AgentSettings.Default.testS3Bucket + "\"," +
                                "\"httpsFlag\":false," +
                                "\"created\":\"May 19, 2013 4:17:25 PM\"}" +
                                "}," + // end of imageDataStore
                        "\"name\":\"" + testS3TemplateName + "\"}" +
                     "}," + // end of srcTO
                 "\"destTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{" +
                        "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                        "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                        "\"id\":206," +
                        "\"format\":\"VHDX\"," +
                        "\"accountId\":2," +
                        "\"checksum\":\"4b31e2846cc67fc10ea7281986519a54\"," +
                        "\"hvm\":true," +
                        "\"displayText\":\"OS031\"," +
                        "\"imageDataStore\":" + getSamplePrimaryDataStoreInfo() + "," + // end of imageDataStore
                        "\"name\":\"" + testS3TemplateName + "\"}" +
                    "}," +// end of destTO
                "\"wait\":10800}"; // end of CopyCommand
            #endregion

            HypervResourceController rsrcServer;
            dynamic jsonDownloadCopyCmd;
            string dwnldDest;
            dynamic jsonCloneCopyCmd;
            string newVolName;
            CopyCommandTestSetup(sampleCopyCommandToCreateVolumeFromTemplate, sampleCopyCommandForTemplateDownload, out rsrcServer, out jsonDownloadCopyCmd, out dwnldDest, out jsonCloneCopyCmd, out newVolName);

            // Act & Assert
            DownloadTemplateToPrimaryStorage(rsrcServer, jsonDownloadCopyCmd, dwnldDest);
            CreateVolumeFromTemplate(rsrcServer, jsonCloneCopyCmd, newVolName);

            // Repeat to verify ability to detect existing file.
            DownloadTemplateToPrimaryStorage(rsrcServer, jsonDownloadCopyCmd, dwnldDest);

            File.Delete(dwnldDest);
            File.Delete(newVolName);
        }

        private static void CreateVolumeFromTemplate(HypervResourceController rsrcServer, dynamic jsonCloneCopyCmd, string newVolName)
        {
            dynamic copyResult = rsrcServer.CopyCommand(jsonCloneCopyCmd);

            // Assert
            Assert.NotNull(copyResult[0][CloudStackTypes.CopyCmdAnswer]);
            Assert.True((bool)copyResult[0][CloudStackTypes.CopyCmdAnswer].result, "CopyCommand did not succeed " + copyResult[0][CloudStackTypes.CopyCmdAnswer].details);
            Assert.True(File.Exists(newVolName), "CopyCommand failed to generate " + newVolName);
        }

        private static void DownloadTemplateToPrimaryStorage(HypervResourceController rsrcServer, dynamic jsonDownloadCopyCmd, string dwnldDest)
        {
            dynamic dwnldResult = rsrcServer.CopyCommand(jsonDownloadCopyCmd);

            // Assert
            Assert.NotNull(dwnldResult[0][CloudStackTypes.CopyCmdAnswer]);
            Assert.True((bool)dwnldResult[0][CloudStackTypes.CopyCmdAnswer].result, "CopyCommand did not succeed " + dwnldResult[0][CloudStackTypes.CopyCmdAnswer].details);
            Assert.True(File.Exists(dwnldDest), "CopyCommand failed to generate " + dwnldDest);
        }

        [Fact(Skip="these are functional tests")]
        public void TestCopyCommandBz2Img()
        {
            // Arrange
            string sampleCopyCommandToCreateVolumeFromTemplate =
            #region string_literal
                // org.apache.cloudstack.storage.command.CopyCommand
                "{\"srcTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{" +
                        "\"origUrl\":\"http://people.apache.org/~bhaisaab/vms/ttylinux_pv.vhd\"," +
                        "\"uuid\":\"9873f1c0-bdcc-11e2-8baa-ea85dab5fcd0\"," +
                        "\"id\":5," +
                        "\"format\":\"VHD\"," +
                        "\"accountId\":1," +
                        "\"checksum\":\"f613f38c96bf039f2e5cbf92fa8ad4f8\"," +
                        "\"hvm\":false," +
                        "\"displayText\":\"tiny Linux\"," +
                        "\"imageDataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"" + testSystemVMTemplateNameNoExt + "\"}" +
                    "}," +  // end of srcTO
                "\"destTO\":" +
                    "{\"org.apache.cloudstack.storage.to.VolumeObjectTO\":" +
                        "{\"uuid\":\"19ae8e67-cb2c-4ab4-901e-e0b864272b59\"," +
                        "\"volumeType\":\"ROOT\"," +
                        "\"dataStore\":" + getSamplePrimaryDataStoreInfo() + "," +
                        "\"name\":\"ROOT-5\"," +
                        "\"size\":52428800," +
                        "\"volumeId\":10," +
                        "\"vmName\":\"i-3-5-VM\"," +
                        "\"accountId\":1," +
                        "\"id\":10}" +
                    "}," +  // end of destTO 
                "\"wait\":0}"; // end of Copy Command
            #endregion

            string sampleCopyCommandForTemplateDownload =
            #region string_literal
                // org.apache.cloudstack.storage.command.CopyCommand
                "{\"srcTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{\"path\":\"" + testSystemVMTemplateName + "\"," +
                        "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                        "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                        "\"id\":206," +
                        "\"format\":\"VHD\"," +
                        "\"accountId\":1," +
                        "\"checksum\": \"f613f38c96bf039f2e5cbf92fa8ad4f8\"," +
                        "\"hvm\":true," +
                        "\"displayText\":\"OS031\"," +
                        "\"imageDataStore\":" +
                            "{\"com.cloud.agent.api.to.S3TO\":" +
                                "{\"id\":1," +
                                "\"uuid\":\"95a64c8f-2128-4502-b5b4-0d7aa77406d2\"," +
                                "\"accessKey\":\"" + AgentSettings.Default.testS3AccessKey + "\"," +
                                "\"secretKey\":\"" + AgentSettings.Default.testS3SecretKey + "\"," +
                                "\"endPoint\":\"" + AgentSettings.Default.testS3Endpoint + "\"," +
                                "\"bucketName\":\"" + AgentSettings.Default.testS3Bucket + "\"," +
                                "\"httpsFlag\":false," +
                                "\"created\":\"May 19, 2013 4:17:25 PM\"}" +
                                "}," + // end of imageDataStore
                        "\"name\":\"" + testSystemVMTemplateNameNoExt + "\"}" +
                     "}," + // end of srcTO
                 "\"destTO\":" +
                    "{\"org.apache.cloudstack.storage.to.TemplateObjectTO\":" +
                        "{" +
                        "\"origUrl\":\"http://10.147.28.7/templates/5d67394c-4efd-4b62-966b-51aa53b35277.vhd.bz2\"," +
                        "\"uuid\":\"7e4ca941-cb1b-4113-ab9e-043960d0fb10\"," +
                        "\"id\":206," +
                        "\"format\":\"VHD\"," +
                        "\"accountId\":1," +
                        "\"checksum\": \"f613f38c96bf039f2e5cbf92fa8ad4f8\"," +
                        "\"hvm\":true," +
                        "\"displayText\":\"OS031\"," +
                        "\"imageDataStore\":" + getSamplePrimaryDataStoreInfo() + "," + // end of imageDataStore
                        "\"name\":\"" + testSystemVMTemplateNameNoExt + "\"}" +
                    "}," +// end of destTO
                "\"wait\":10800}"; // end of CopyCommand
            #endregion

            HypervResourceController rsrcServer;
            dynamic jsonDownloadCopyCmd;
            string dwnldDest;
            dynamic jsonCloneCopyCmd;
            string newVolName;
            CopyCommandTestSetup(sampleCopyCommandToCreateVolumeFromTemplate, sampleCopyCommandForTemplateDownload, out rsrcServer, out jsonDownloadCopyCmd, out dwnldDest, out jsonCloneCopyCmd, out newVolName);

            // Act & Assert
            DownloadTemplateToPrimaryStorage(rsrcServer, jsonDownloadCopyCmd, dwnldDest);
            CreateVolumeFromTemplate(rsrcServer, jsonCloneCopyCmd, newVolName);

            File.Delete(dwnldDest);
            File.Delete(newVolName);
        }

        private static void CopyCommandTestSetup(string sampleCopyCommandToCreateVolumeFromTemplate, string sampleCopyCommandForTemplateDownload, out HypervResourceController rsrcServer, out dynamic jsonDownloadCopyCmd, out string dwnldDest, out dynamic jsonCloneCopyCmd, out string newVolName)
        {
            rsrcServer = new HypervResourceController();
            jsonDownloadCopyCmd = JsonConvert.DeserializeObject(sampleCopyCommandForTemplateDownload);
            TemplateObjectTO dwnldTemplate = TemplateObjectTO.ParseJson(jsonDownloadCopyCmd.destTO);
            dwnldDest = dwnldTemplate.FullFileName;

            jsonCloneCopyCmd = JsonConvert.DeserializeObject(sampleCopyCommandToCreateVolumeFromTemplate);
            VolumeObjectTO newVol = VolumeObjectTO.ParseJson(jsonCloneCopyCmd.destTO);
            newVol.format = dwnldTemplate.format;
            newVolName = dwnldTemplate.FullFileName;

            if (File.Exists(dwnldDest))
            {
                File.Delete(dwnldDest);
            }
            if (File.Exists(newVolName))
            {
                File.Delete(newVolName);
            }
        }

        private static void CopyCommandTestSetupCifs(string sampleCopyCommandToCreateVolumeFromTemplate, string sampleCopyCommandForTemplateDownload, out HypervResourceController rsrcServer, out dynamic jsonDownloadCopyCmd, out string dwnldDest, out dynamic jsonCloneCopyCmd, out string newVolName)
        {
            rsrcServer = new HypervResourceController();
            jsonDownloadCopyCmd = JsonConvert.DeserializeObject(sampleCopyCommandForTemplateDownload);
            TemplateObjectTO dwnldTemplate = TemplateObjectTO.ParseJson(jsonDownloadCopyCmd.destTO);
            dwnldDest = dwnldTemplate.FullFileName;

            if (File.Exists(dwnldDest))
            {
                File.Delete(dwnldDest);
            }
            newVolName = null;
            jsonCloneCopyCmd = null;
        }

        [Fact(Skip="these are functional tests")]
        public void TestModifyStoragePoolCommand()
        {
            // Create dummy folder
            String folderName = Path.Combine(".", "Dummy");
            if (!Directory.Exists(folderName))
            {
                Directory.CreateDirectory(folderName);
            }

            var pool = new
            {  // From java class StorageFilerTO
                type = Enum.GetName(typeof(StoragePoolType), StoragePoolType.Filesystem),
                host = "127.0.0.1",
                port = -1,
                path = folderName,
                uuid = Guid.NewGuid().ToString(),
                userInfo = string.Empty // Used in future to hold credential
            };

            var cmd = new
            {
                add = true,
                pool = pool,
                localPath = folderName
            };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.ModifyStoragePoolCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.ModifyStoragePoolAnswer];
            Assert.True((bool)ans.result, (string)ans.details);  // always succeeds

            // Clean up
            var cmd2 = new
            {
                pool = pool,
                localPath = folderName
            };
            JToken tok2 = JToken.FromObject(cmd);

            // Act
            dynamic jsonResult2 = controller.DeleteStoragePoolCommand(tok2);

            // Assert
            dynamic ans2 = jsonResult2[0][CloudStackTypes.Answer];
            Assert.True((bool)ans2.result, (string)ans2.details);  // always succeeds
        }

        [Fact(Skip="these are functional tests")]
        public void CreateStoragePoolCommand()
        {
            var cmd = new { localPath = "NULL" };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.CreateStoragePoolCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.Answer];
            Assert.True((bool)ans.result, (string)ans.details);  // always succeeds
        }

        [Fact(Skip="these are functional tests")]
        public void MaintainCommand()
        {
            // Omit HostEnvironment object, as this is a series of settings currently not used.
            var cmd = new { };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.MaintainCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.MaintainAnswer];
            Assert.True((bool)ans.result, (string)ans.details);  // always succeeds
        }

        [Fact(Skip="these are functional tests")]
        public void SetupCommand()
        {
            // Omit HostEnvironment object, as this is a series of settings currently not used.
            var cmd = new { multipath = false, needSetup = true };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.SetupCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.SetupAnswer];
            Assert.True((bool)ans.result, (string)ans.details);  // always succeeds
        }

        [Fact(Skip="these are functional tests")]
        public void TestPassingUserdataToVm()
        {
            // Sample data
            String key = "cloudstack-vm-userdata";
            String value = "username=root;password=1pass@word1";

            // Find the VM
            List<String> vmNames = wmiCallsV2.GetVmElementNames();

            // Get associated WMI object
            var vm = wmiCallsV2.GetComputerSystem(AgentSettings.Default.testKvpVmName);

            // Get existing KVP
            var vmSettings = wmiCallsV2.GetVmSettings(vm);
            var kvpInfo = wmiCallsV2.GetKvpSettings(vmSettings);

            // HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
            string[] kvpProps = kvpInfo.HostExchangeItems;

            // If the value already exists, delete it
            foreach (var item in kvpProps)
            {
                String wmiObjectXml = item;
                String existingKey;
                String existingValue;
                ParseKVP(wmiObjectXml, out existingKey, out existingValue);

                if (existingKey == key)
                {
                    wmiCallsV2.DeleteHostKvpItem(vm, existingKey);
                    break;
                }
            }

            // Add new user data
            wmiCallsV2.AddUserData(vm, value);

            // Verify key added to subsystem
            kvpInfo = wmiCallsV2.GetKvpSettings(vmSettings);

            // HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
            kvpProps = kvpInfo.HostExchangeItems;

            // If the value already exists, delete it
            bool userDataInPlace = false;
            foreach (var item in kvpProps)
            {
                String wmiObjectXml = item;
                String existingKey;
                String existingValue;
                ParseKVP(wmiObjectXml, out existingKey, out existingValue);

                if (existingKey == key && existingValue == value)
                {
//                    wmiCallsV2.DeleteHostKvpItem(vm, existingKey);
                    userDataInPlace = true;
                    break;
                }
            }

            Assert.True(userDataInPlace, "User data key / value did no save properly");
        }

        private static void ParseKVP(String wmiObjectXml, out String existingKey, out String existingValue)
        {
            // Reference:  http://blogs.msdn.com/b/virtual_pc_guy/archive/2008/12/05/enumerating-parent-kvp-data.aspx

            // Create XML parser
            var xmlDoc = new XmlDocument();

            // Load WMI object
            xmlDoc.LoadXml(wmiObjectXml);

            // Use xpath to get name and value
            var namePropXpath = "/INSTANCE/PROPERTY[@NAME='Name']/VALUE";
            var nameNode = xmlDoc.SelectSingleNode(namePropXpath);
            existingKey = nameNode.InnerText;
            var dataPropXpath = "/INSTANCE/PROPERTY[@NAME='Data']/VALUE";
            var dataNode = xmlDoc.SelectSingleNode(dataPropXpath);
            existingValue = dataNode.InnerText;
        }

        [Fact(Skip="these are functional tests")]
        public void GetVmStatsCommandFail()
        {
            // Use WMI to find existing VMs
            List<String> vmNames = new List<String>();
            vmNames.Add("FakeVM");

            var cmd = new
            {
                hostGuid = "FAKEguid",
                hostName = AgentSettings.Default.host,
                vmNames = vmNames
            };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.GetVmStatsCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.GetVmStatsAnswer];
            Assert.True((bool)ans.result, (string)ans.details);  // always succeeds, fake VM means no answer for the named VM
        }

        [Fact(Skip="these are functional tests")]
        public void GetVmStatsCommand()
        {
            // Use WMI to find existing VMs
            List<String> vmNames = wmiCallsV2.GetVmElementNames();

            var cmd = new
            {
                hostGuid = "FAKEguid",
                hostName = AgentSettings.Default.host,
                vmNames = vmNames
            };
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.GetVmStatsCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.GetVmStatsAnswer];
            Assert.True((bool)ans.result, (string)ans.details);
        }

        [Fact(Skip="these are functional tests")]
        public void GetStorageStatsCommand()
        {
            // TODO:  Update sample data to unsure it is using correct info.
            String sample = String.Format(
            #region string_literal
"{{\"" +
                "id\":{0}," +
                "\"localPath\":{1}," +
                "\"pooltype\":\"Filesystem\"," +
                "\"contextMap\":{{}}," +
                "\"wait\":0}}",
                JsonConvert.SerializeObject(AgentSettings.Default.testLocalStoreUUID),
                JsonConvert.SerializeObject(AgentSettings.Default.testLocalStorePath)
                );
            #endregion
            var cmd = JsonConvert.DeserializeObject(sample);
            JToken tok = JToken.FromObject(cmd);
            HypervResourceController controller = new HypervResourceController();

            // Act
            dynamic jsonResult = controller.GetStorageStatsCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.GetStorageStatsAnswer];
            Assert.True((bool)ans.result, (string)ans.details);
            Assert.True((long)ans.used <= (long)ans.capacity);  // TODO: verify that capacity is indeed capacity and not used.
        }

        // TODO: can we speed up this command?  The logic takes over a second.
        [Fact(Skip="these are functional tests")]
        public void GetHostStatsCommand()
        {
            // Arrange
            long hostIdVal = 5;
            HypervResourceController controller = new HypervResourceController();
            string sample = string.Format(
            #region string_literal
"{{" +
                    "\"hostGuid\":\"B4AE5970-FCBF-4780-9F8A-2D2E04FECC34-HypervResource\"," +
                    "\"hostName\":\"CC-SVR11\"," +
                    "\"hostId\":{0}," +
                    "\"contextMap\":{{}}," +
                    "\"wait\":0}}",
                    JsonConvert.SerializeObject(hostIdVal));
            #endregion
            var cmd = JsonConvert.DeserializeObject(sample);
            JToken tok = JToken.FromObject(cmd);

            // Act
            dynamic jsonResult = controller.GetHostStatsCommand(tok);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.GetHostStatsAnswer];
            Assert.True((bool)ans.result);
            Assert.True(hostIdVal == (long)ans.hostStats.hostId);
            Assert.True(0.0 < (double)ans.hostStats.totalMemoryKBs);
            Assert.True(0.0 < (double)ans.hostStats.freeMemoryKBs);
            Assert.True(0.0 <= (double)ans.hostStats.networkReadKBs);
            Assert.True(0.0 <= (double)ans.hostStats.networkWriteKBs);
            Assert.True(0.0 <= (double)ans.hostStats.cpuUtilization);
            Assert.True(100.0 >= (double)ans.hostStats.cpuUtilization);
            Assert.True("host".Equals((string)ans.hostStats.entityType));
            Assert.True(String.IsNullOrEmpty((string)ans.details));
        }

        [Fact(Skip="these are functional tests")]
        public void GetHostStatsCommandFail()
        {
            // Arrange
            HypervResourceController controller = new HypervResourceController();
            var cmd = new { GetHostStatsCommand = new { hostId = "badvalueType" } };
            JToken tokFail = JToken.FromObject(cmd);

            // Act
            dynamic jsonResult = controller.GetHostStatsCommand(tokFail);

            // Assert
            dynamic ans = jsonResult[0][CloudStackTypes.GetHostStatsAnswer];
            Assert.False((bool)ans.result);
            Assert.Null((string)ans.hostStats);
            Assert.NotNull(ans.details);
        }

        [Fact(Skip="these are functional tests")]
        public void TestStartupCommand()
        {
            // Arrange
            HypervResourceController controller = new HypervResourceController();
            String sampleStartupRoutingCommand =
            #region string_literal
 "[{\"" + CloudStackTypes.StartupRoutingCommand + "\":{" +
                    "\"cpus\":0," +
                    "\"speed\":0," +
                    "\"memory\":0," +
                    "\"dom0MinMemory\":0," +
                    "\"poolSync\":false," +
                    "\"vms\":{}," +
                    "\"hypervisorType\":\"Hyperv\"," +
                    "\"hostDetails\":{" +
                    "\"com.cloud.network.Networks.RouterPrivateIpStrategy\":\"HostLocal\"" +
                    "}," +
                    "\"type\":\"Routing\"," +
                    "\"dataCenter\":\"1\"," +
                    "\"pod\":\"1\"," +
                    "\"cluster\":\"1\"," +
                    "\"guid\":\"16f85622-4508-415e-b13a-49a39bb14e4d\"," +
                    "\"name\":\"localhost\"," +
                    "\"version\":\"4.2.0\"," +
                    "\"privateIpAddress\":\"1\"," +
                    "\"storageIpAddress\":\"1\"," +
                    "\"contextMap\":{}," +
                    "\"wait\":0}}]";
            #endregion

            uint cores;
            uint mhz;
            wmiCallsV2.GetProcessorResources(out cores, out mhz);
            ulong memory_mb;
            ulong freememory;
            wmiCallsV2.GetMemoryResources(out memory_mb, out freememory);
            memory_mb *= 1024;
            long capacityBytes;
            long availableBytes;
            HypervResourceController.GetCapacityForLocalPath(wmiCallsV2.GetDefaultVirtualDiskFolder(),
                    out capacityBytes, out availableBytes);
            var DefaultVirtualDiskFolder = JsonConvert.SerializeObject(wmiCallsV2.GetDefaultVirtualDiskFolder());
            string expected =
            #region string_literal
                    "[{\"" + CloudStackTypes.StartupRoutingCommand + "\":{" +
                        "\"cpus\":" + cores + "," +
                        "\"speed\":" + mhz + "," +
                        "\"memory\":" + memory_mb + "," +
                        "\"dom0MinMemory\":" + (AgentSettings.Default.dom0MinMemory * 1024 * 1024) + "," +
                        "\"poolSync\":false," +
                        "\"vms\":{}," +
                        "\"hypervisorType\":\"Hyperv\"," +
                        "\"hostDetails\":{" +
                        "\"com.cloud.network.Networks.RouterPrivateIpStrategy\":\"HostLocal\"" +
                        "}," +
                        "\"type\":\"Routing\"," +
                        "\"dataCenter\":\"1\"," +
                        "\"pod\":\"1\"," +
                        "\"cluster\":\"1\"," +
                        "\"guid\":\"16f85622-4508-415e-b13a-49a39bb14e4d\"," +
                        "\"name\":\"localhost\"," +
                        "\"version\":\"4.2.0\"," +
                        "\"privateIpAddress\":\"" + AgentSettings.Default.private_ip_address + "\"," +
                        "\"storageIpAddress\":\"" + AgentSettings.Default.private_ip_address + "\"," +
                        "\"contextMap\":{}," +
                        "\"wait\":0," +
                        "\"privateNetmask\":\"" + AgentSettings.Default.private_ip_netmask + "\"," +
                        "\"privateMacAddress\":\"" + AgentSettings.Default.private_mac_address + "\"," +
                        "\"storageNetmask\":\"" + AgentSettings.Default.private_ip_netmask + "\"," +
                        "\"storageMacAddress\":\"" + AgentSettings.Default.private_mac_address + "\"," +
                        "\"gatewayIpAddress\":\"" + AgentSettings.Default.gateway_ip_address + "\"" +
                        ",\"caps\":\"hvm\"" +
                        "}}," +
                        "{\"com.cloud.agent.api.StartupStorageCommand\":{" +
                        "\"poolInfo\":{" +
                            "\"uuid\":\"16f85622-4508-415e-b13a-49a39bb14e4d\"," +
                            "\"host\":\"" + AgentSettings.Default.private_ip_address + "\"," +
                            "\"localPath\":" + DefaultVirtualDiskFolder + "," +
                            "\"hostPath\":" + DefaultVirtualDiskFolder + "," +
                            "\"poolType\":\"Filesystem\"," +
                            "\"capacityBytes\":" + capacityBytes + "," +
                            "\"availableBytes\":" + availableBytes + "," +
                            "\"details\":null" +
                        "}," +
                        "\"guid\":\"16f85622-4508-415e-b13a-49a39bb14e4d\"," +
                        "\"dataCenter\":\"1\"," +
                        "\"resourceType\":\"STORAGE_POOL\"" +
                        "}}]";
            #endregion

            dynamic jsonArray = JsonConvert.DeserializeObject(sampleStartupRoutingCommand);

            // Act
            dynamic jsonResult = controller.StartupCommand(jsonArray);

            // Assert
            string actual = JsonConvert.SerializeObject(jsonResult);
            Assert.Equal(expected, actual);
        }


        private static string TestStartCommand()
        {
            // Arrange
            HypervResourceController rsrcServer = new HypervResourceController();
            String sample = getSampleStartCommand();


            dynamic jsonStartCmd = JsonConvert.DeserializeObject(sample);

            // Act
            dynamic startAns = rsrcServer.StartCommand(jsonStartCmd);

            // Assert
            Assert.NotNull(startAns[0][CloudStackTypes.StartAnswer]);
            Assert.True((bool)startAns[0][CloudStackTypes.StartAnswer].result, "StartCommand did not succeed " + startAns[0][CloudStackTypes.StartAnswer].details);
            string vmCmdName = jsonStartCmd.vm.name.Value;
            var vm = wmiCallsV2.GetComputerSystem(vmCmdName);
            var vmSettings = wmiCallsV2.GetVmSettings(vm);
            var memSettings = wmiCallsV2.GetMemSettings(vmSettings);
            var procSettings = wmiCallsV2.GetProcSettings(vmSettings);
            dynamic jsonObj = JsonConvert.DeserializeObject(sample);
            var vmInfo = jsonObj.vm;
            string vmName = vmInfo.name;
            var nicInfo = vmInfo.nics;
            int vcpus = vmInfo.cpus;
            int memSize = vmInfo.maxRam / 1048576;
            Assert.True((long)memSettings.VirtualQuantity == memSize);
            Assert.True((long)memSettings.Reservation == memSize);
            Assert.True((long)memSettings.Limit == memSize);
            Assert.True((int)procSettings.VirtualQuantity == vcpus);
            Assert.True((int)procSettings.Reservation == vcpus);
            Assert.True((int)procSettings.Limit == 100000);

            // examine NIC for correctness
            var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm);
            Assert.True(nicSettingsViaVm.Length > 0, "Should be at least one ethernet port on VM");
            string expectedMac = (string)jsonStartCmd.vm.nics[0].mac;
            string strippedExpectedMac = expectedMac.Replace(":", string.Empty);
            Assert.Equal(nicSettingsViaVm[0].Address.ToLower(), strippedExpectedMac.ToLower());

            // Assert switchport has correct VLAN 
            var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm);
            var vlanSettings = wmiCallsV2.GetVlanSettings(ethernetConnections[0]);
            string isolationUri = (string)jsonStartCmd.vm.nics[0].isolationUri;
            string vlan = isolationUri.Replace("vlan://", string.Empty);
            Assert.Equal(vlanSettings.AccessVlanId.ToString(), vlan);

            return vmName;
        }

        private static void TestStopCommand(string vmName)
        {
            // Arrange
            HypervResourceController rsrcServer = new HypervResourceController();
            String sampleStop = "{\"isProxy\":false,\"vmName\":\"i-2-17-VM\",\"contextMap\":{},\"wait\":0}";
            dynamic jsonStopCmd = JsonConvert.DeserializeObject(sampleStop);

            // Act
            dynamic stopAns = rsrcServer.StopCommand(jsonStopCmd);

            // Assert VM is gone!
            Assert.NotNull(stopAns[0][CloudStackTypes.StopAnswer]);
            Assert.True((bool)stopAns[0][CloudStackTypes.StopAnswer].result, "StopCommand did not succeed " + stopAns[0][CloudStackTypes.StopAnswer].details);
            var finalVm = wmiCallsV2.GetComputerSystem(vmName);
            Assert.True(wmiCallsV2.GetComputerSystem(vmName) == null);
        }
    }
}
