You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bf...@apache.org on 2013/11/04 23:32:20 UTC

[38/56] [abbrv] Changes for switching all wmi calls to V2 namespace. V1 namespace is deprecated so it is better to be on v2 namespace.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1601498b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs
index c66c616..fab1b82 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs
@@ -1,1149 +1,1147 @@
-// 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 WmiCalls wmiCalls = new WmiCalls();
-        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 destoryCmd = //"{\"volume\":" + getSampleVolumeObjectTO() + "}";
-                            "{\"volume\":{\"name\":\"" + testSampleVolumeTempUUIDNoExt
-                                    + "\",\"storagePoolType\":\"Filesystem\","
-                                    + "\"mountPoint\":"
-                                    + testLocalStorePathJSON
-                                   + ",\"path\":" + testSampleVolumeTempURIJSON
-                                    + ",\"storagePoolUuid\":\"" + testLocalStoreUUID
-                                    + "\","
-                                    + "\"type\":\"ROOT\",\"id\":9,\"size\":0}}";
-
-            HypervResourceController rsrcServer = new HypervResourceController();
-            dynamic jsonDestoryCmd = JsonConvert.DeserializeObject(destoryCmd);
-
-            // Act
-            dynamic destoryAns = rsrcServer.DestroyCommand(jsonDestoryCmd);
-
-            // Assert
-            JObject ansAsProperty2 = destoryAns[0];
-            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.Answer);
-            String path = jsonDestoryCmd.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 = wmiCalls.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;
-            wmiCalls.GetProcessorResources(out cores, out mhz);
-            ulong memory_mb;
-            ulong freememory;
-            wmiCalls.GetMemoryResources(out memory_mb, out freememory);
-            memory_mb *= 1024;
-            long capacityBytes;
-            long availableBytes;
-            HypervResourceController.GetCapacityForLocalPath(wmiCalls.GetDefaultVirtualDiskFolder(),
-                    out capacityBytes, out availableBytes);
-            var DefaultVirtualDiskFolder = JsonConvert.SerializeObject(wmiCalls.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 = wmiCalls.GetComputerSystem(vmCmdName);
-            VirtualSystemSettingData vmSettings = wmiCalls.GetVmSettings(vm);
-            MemorySettingData memSettings = wmiCalls.GetMemSettings(vmSettings);
-            ProcessorSettingData procSettings = wmiCalls.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
-            SyntheticEthernetPortSettingData[] nicSettingsViaVm = wmiCalls.GetEthernetPorts(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 
-            SwitchPort[] switchPorts = wmiCalls.GetSwitchPorts(vm);
-            VirtualSwitchManagementService vmNetMgmtSvc = wmiCalls.GetVirtualSwitchManagementService();
-            VLANEndpointSettingData vlanSettings = wmiCalls.GetVlanEndpointSettings(vmNetMgmtSvc, switchPorts[0].Path);
-            string isolationUri = (string)jsonStartCmd.vm.nics[0].isolationUri;
-            string vlan = isolationUri.Replace("vlan://", string.Empty);
-            Assert.Equal(vlanSettings.AccessVLAN.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 = wmiCalls.GetComputerSystem(vmName);
-            Assert.True(wmiCalls.GetComputerSystem(vmName) == null);
-        }
-    }
-}
+// 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 destoryCmd = //"{\"volume\":" + getSampleVolumeObjectTO() + "}";
+                            "{\"volume\":{\"name\":\"" + testSampleVolumeTempUUIDNoExt
+                                    + "\",\"storagePoolType\":\"Filesystem\","
+                                    + "\"mountPoint\":"
+                                    + testLocalStorePathJSON
+                                   + ",\"path\":" + testSampleVolumeTempURIJSON
+                                    + ",\"storagePoolUuid\":\"" + testLocalStoreUUID
+                                    + "\","
+                                    + "\"type\":\"ROOT\",\"id\":9,\"size\":0}}";
+
+            HypervResourceController rsrcServer = new HypervResourceController();
+            dynamic jsonDestoryCmd = JsonConvert.DeserializeObject(destoryCmd);
+
+            // Act
+            dynamic destoryAns = rsrcServer.DestroyCommand(jsonDestoryCmd);
+
+            // Assert
+            JObject ansAsProperty2 = destoryAns[0];
+            dynamic ans = ansAsProperty2.GetValue(CloudStackTypes.Answer);
+            String path = jsonDestoryCmd.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.CopyComma

<TRUNCATED>