// 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);
        }
    }
}
