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

[27/31] A plugin for Hyper-V control is available for CloudStack. The plugin implements basic VM control; however, its architecture allows additional functionality to be easily added. Incorporating the plugin in CloudStack will allow the community to

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/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
new file mode 100644
index 0000000..7513311
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/HypervResourceControllerTest.cs
@@ -0,0 +1,1064 @@
+// 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 Microsoft.VisualStudio.TestTools.UnitTesting;
+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;
+
+namespace ServerResource.Tests
+{
+    [TestClass]
+    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;
+
+        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>
+        [TestInitializeAttribute]
+        public void setUp()
+        {
+            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)
+                {
+                    Assert.Fail("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.IsTrue(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.IsTrue(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.IsFalse(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.IsTrue(newFileInfo.Exists, "Attempted to create " + newFullname + " from " + newFileInfo.FullName);
+
+            return JsonConvert.SerializeObject(newFileInfo.FullName);
+        }
+
+        [TestMethod]
+        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.IsTrue((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.IsTrue((bool)ans2.result, (string)ans2.details);
+
+            FileInfo newFile = new FileInfo((string)ans2.volume.path);
+            Assert.IsTrue(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;
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, "DestroyCommand did not succeed " + ans.details);
+            Assert.IsTrue(!File.Exists(path), "Failed to delete file " + path);
+        }
+
+        [TestMethod]
+        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.IsTrue(Directory.Exists(testLocalStorePath));
+            string filePath = Path.Combine(testLocalStorePath, (string)JsonConvert.DeserializeObject(testSampleTemplateURLJSON));
+            Assert.IsTrue(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.IsNotNull(ans, "Should be an answer object of type CreateAnswer");
+            Assert.IsTrue((bool)ans.result, "Failed to CreateCommand due to " + (string)ans.result);
+            Assert.AreEqual(Directory.GetFiles(testLocalStorePath).Length, fileCount + 1);
+            FileInfo newFile = new FileInfo((string)ans.volume.path);
+            Assert.IsTrue(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>
+        [TestMethod]
+        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;
+        }
+
+
+        [TestMethod]
+        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);
+        }
+
+        [TestMethod]
+        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.IsNotNull(copyResult[0][CloudStackTypes.CopyCmdAnswer], "CopyCommand should return a StartAnswer in all cases");
+            Assert.IsTrue((bool)copyResult[0][CloudStackTypes.CopyCmdAnswer].result, "CopyCommand did not succeed " + copyResult[0][CloudStackTypes.CopyCmdAnswer].details);
+            Assert.IsTrue(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.IsNotNull(dwnldResult[0][CloudStackTypes.CopyCmdAnswer], "CopyCommand should return a StartAnswer in all cases");
+            Assert.IsTrue((bool)dwnldResult[0][CloudStackTypes.CopyCmdAnswer].result, "CopyCommand did not succeed " + dwnldResult[0][CloudStackTypes.CopyCmdAnswer].details);
+            Assert.IsTrue(File.Exists(dwnldDest), "CopyCommand failed to generate " + dwnldDest);
+        }
+
+        [TestMethod]
+        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;
+        }
+
+        [TestMethod]
+        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.IsTrue((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.IsTrue((bool)ans2.result, (string)ans2.details);  // always succeeds
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);  // always succeeds
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);  // always succeeds
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);  // always succeeds
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);  // always succeeds, fake VM means no answer for the named VM
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);
+        }
+
+        [TestMethod]
+        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.IsTrue((bool)ans.result, (string)ans.details);
+            Assert.IsTrue((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.
+        [TestMethod]
+        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.IsTrue((bool)ans.result);
+            Assert.IsTrue(hostIdVal == (long)ans.hostStats.hostId);
+            Assert.IsTrue(0.0 < (double)ans.hostStats.totalMemoryKBs);
+            Assert.IsTrue(0.0 < (double)ans.hostStats.freeMemoryKBs);
+            Assert.IsTrue(0.0 <= (double)ans.hostStats.networkReadKBs);
+            Assert.IsTrue(0.0 <= (double)ans.hostStats.networkWriteKBs);
+            Assert.IsTrue(0.0 <= (double)ans.hostStats.cpuUtilization);
+            Assert.IsTrue(100.0 >= (double)ans.hostStats.cpuUtilization);
+            Assert.IsTrue("host".Equals((string)ans.hostStats.entityType));
+            Assert.IsTrue(String.IsNullOrEmpty((string)ans.details));
+        }
+
+        [TestMethod]
+        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.IsFalse((bool)ans.result);
+            Assert.IsNull((string)ans.hostStats);
+            Assert.IsNotNull(ans.details);
+        }
+
+        [TestMethod]
+        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.AreEqual(expected, actual, "StartupRoutingCommand not populated properly");
+        }
+
+
+        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.IsNotNull(startAns[0][CloudStackTypes.StartAnswer], "StartCommand should return a StartAnswer in all cases");
+            Assert.IsTrue((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.IsTrue((long)memSettings.VirtualQuantity == memSize);
+            Assert.IsTrue((long)memSettings.Reservation == memSize);
+            Assert.IsTrue((long)memSettings.Limit == memSize);
+            Assert.IsTrue((int)procSettings.VirtualQuantity == vcpus);
+            Assert.IsTrue((int)procSettings.Reservation == vcpus);
+            Assert.IsTrue((int)procSettings.Limit == 100000);
+
+            // examine NIC
+            SyntheticEthernetPortSettingData[] nicSettingsViaVm = WmiCalls.GetEthernetPorts(vm);
+            Assert.IsTrue(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.AreEqual(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.AreEqual(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.IsNotNull(stopAns[0][CloudStackTypes.StopAnswer], "StopCommand should return a StopAnswer in all cases");
+            Assert.IsTrue((bool)stopAns[0][CloudStackTypes.StopAnswer].result, "StopCommand did not succeed " + stopAns[0][CloudStackTypes.StopAnswer].details);
+            var finalVm = WmiCalls.GetComputerSystem(vmName);
+            Assert.IsTrue(WmiCalls.GetComputerSystem(vmName) == null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/Properties/AssemblyInfo.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1a2b6e6
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ServerResource.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ServerResource.Tests")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("727beb1c-6e7c-49b2-8fbd-f03dbe481b08")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/ServerResource.Tests.csproj
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/ServerResource.Tests.csproj b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/ServerResource.Tests.csproj
new file mode 100644
index 0000000..381245e
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/ServerResource.Tests.csproj
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>
+    </ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{925FD1DE-6211-4E10-9949-3751B8ABDF59}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ServerResource.Tests</RootNamespace>
+    <AssemblyName>ServerResource.Tests</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTestsDebug|AnyCPU'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\NoUnitTestsDebug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'NoUnitTests|AnyCPU'">
+    <OutputPath>bin\NoUnitTests\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Ionic.Zip">
+      <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
+    </Reference>
+    <Reference Include="log4net">
+      <HintPath>..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Management" />
+    <Reference Include="System.ServiceProcess" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Web.ApplicationServices" />
+    <Reference Include="System.Web.Extensions" />
+    <Reference Include="System.Web.Abstractions" />
+    <Reference Include="System.Web.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="System.Web.Routing" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Net.Http">
+    </Reference>
+    <Reference Include="System.Net.Http.WebRequest">
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="HypervResourceControllerTest.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="App.config">
+      <SubType>Designer</SubType>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config">
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\AgentShell\AgentShell.csproj">
+      <Project>{9060b539-62d0-4e71-a6c6-5944828774e9}</Project>
+      <Name>AgentShell</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HypervResource\HypervResource.csproj">
+      <Project>{c963dfff-65ba-4e71-ada5-526a4da4e0b2}</Project>
+      <Name>HypervResource</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\WmiWrappers\WmiWrappers.csproj">
+      <Project>{db824727-bdc3-437c-a364-7a811d8a160f}</Project>
+      <Name>WmiWrappers</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/packages.config
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/packages.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/packages.config
new file mode 100644
index 0000000..08ef691
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.Tests/packages.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="DotNetZip" version="1.9.1.8" targetFramework="net45" />
+  <package id="log4net" version="2.0.0" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
+</packages>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln
new file mode 100644
index 0000000..fa0eb30
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/ServerResource.sln
@@ -0,0 +1,61 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerResource.Tests", "ServerResource.Tests\ServerResource.Tests.csproj", "{925FD1DE-6211-4E10-9949-3751B8ABDF59}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AgentShell", "AgentShell\AgentShell.csproj", "{9060B539-62D0-4E71-A6C6-5944828774E9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WmiWrappers", "WmiWrappers\WmiWrappers.csproj", "{DB824727-BDC3-437C-A364-7A811D8A160F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypervResource", "HypervResource\HypervResource.csproj", "{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{3481E04E-4BB9-4E0B-94A9-DB70A4F4D218}"
+	ProjectSection(SolutionItems) = preProject
+		.nuget\NuGet.Config = .nuget\NuGet.Config
+		.nuget\NuGet.exe = .nuget\NuGet.exe
+		.nuget\NuGet.targets = .nuget\NuGet.targets
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		NoUnitTests|Any CPU = NoUnitTests|Any CPU
+		NoUnitTestsDebug|Any CPU = NoUnitTestsDebug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.NoUnitTests|Any CPU.ActiveCfg = NoUnitTests|Any CPU
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.NoUnitTestsDebug|Any CPU.ActiveCfg = NoUnitTestsDebug|Any CPU
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{925FD1DE-6211-4E10-9949-3751B8ABDF59}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.NoUnitTests|Any CPU.ActiveCfg = NoUnitTests|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.NoUnitTests|Any CPU.Build.0 = NoUnitTests|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.NoUnitTestsDebug|Any CPU.ActiveCfg = NoUnitTestsDebug|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.NoUnitTestsDebug|Any CPU.Build.0 = NoUnitTestsDebug|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9060B539-62D0-4E71-A6C6-5944828774E9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.NoUnitTests|Any CPU.ActiveCfg = NoUnitTests|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.NoUnitTests|Any CPU.Build.0 = NoUnitTests|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.NoUnitTestsDebug|Any CPU.ActiveCfg = NoUnitTestsDebug|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.NoUnitTestsDebug|Any CPU.Build.0 = NoUnitTestsDebug|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DB824727-BDC3-437C-A364-7A811D8A160F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.NoUnitTests|Any CPU.ActiveCfg = NoUnitTests|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.NoUnitTests|Any CPU.Build.0 = NoUnitTests|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.NoUnitTestsDebug|Any CPU.ActiveCfg = NoUnitTestsDebug|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.NoUnitTestsDebug|Any CPU.Build.0 = NoUnitTestsDebug|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C963DFFF-65BA-4E71-ADA5-526A4DA4E0B2}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d0a931d/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/Properties/AssemblyInfo.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/Properties/AssemblyInfo.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ef230d5
--- /dev/null
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/WmiWrappers/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WmiWrappers")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WmiWrappers")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e78f4bad-16a9-4e0e-8f46-083c093492db")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]