public void TestRecordingBeginEnd() { if (!_test.Config.RunWorkstationTests) { Assert.Ignore("Skipping, Workstation tests disabled."); } foreach (VMWareVirtualMachine virtualMachine in _test.PoweredVirtualMachines) { Assert.IsFalse(virtualMachine.IsRecording); string snapshotName = Guid.NewGuid().ToString(); ConsoleOutput.WriteLine("Begin recording ..."); VMWareSnapshot snapshot = virtualMachine.BeginRecording(snapshotName, Guid.NewGuid().ToString()); Assert.IsNotNull(snapshot); Assert.IsTrue(virtualMachine.IsRecording); Assert.IsFalse(virtualMachine.IsReplaying); virtualMachine.WaitForToolsInGuest(); ConsoleOutput.WriteLine("Snapshot: {0}", snapshot.DisplayName); VMWareVirtualMachine.Process cmdProcess = virtualMachine.RunProgramInGuest("cmd.exe", "/C dir"); Assert.IsNotNull(cmdProcess); ConsoleOutput.WriteLine("Process: {0}", cmdProcess.Id); ConsoleOutput.WriteLine("End recording ..."); virtualMachine.EndRecording(); Assert.IsFalse(virtualMachine.IsRecording); Assert.IsFalse(virtualMachine.IsReplaying); ConsoleOutput.WriteLine("Begin replay ..."); snapshot.BeginReplay(Constants.VIX_VMPOWEROP_LAUNCH_GUI, VMWareInterop.Timeouts.ReplayTimeout); Assert.IsTrue(virtualMachine.IsReplaying); Thread.Sleep(10000); snapshot.EndReplay(); Assert.IsFalse(virtualMachine.IsReplaying); ConsoleOutput.WriteLine("Removing snapshot ..."); snapshot.RemoveSnapshot(); } }
public void PrepareSnapshot() { ConsoleOutput.WriteLine("Preparing '{0}:{1}'", _vmConfig.Name, _snapshotConfig.Name); if (!_snapshotConfig.IsCurrentSnapshot) { ConsoleOutput.WriteLine("Restoring snapshot '{0}:{1}'", _vmConfig.Name, _snapshotConfig.Name); if (!_simulationOnly) { VMWareSnapshot snapshot = _vm.Snapshots.FindSnapshot(_snapshotConfig.Name); if (snapshot == null) { snapshot = _vm.Snapshots.GetNamedSnapshot(_snapshotConfig.Name); } if (snapshot == null) { throw new Exception(string.Format("Missing snapshot: {0}", _snapshotConfig.Name)); } snapshot.RevertToSnapshot(Constants.VIX_VMPOWEROP_SUPPRESS_SNAPSHOT_POWERON); } } PowerOn(); }
public void TestCreateSnapshotSameName() { foreach (VMWareVirtualMachine virtualMachine in _test.VirtualMachines) { // this is the root snapshot Assert.IsTrue(virtualMachine.Snapshots.Count >= 0); string name = Guid.NewGuid().ToString(); // take a snapshot at the current state ConsoleOutput.WriteLine("Creating snapshot 1: {0}", name); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot(name, Guid.NewGuid().ToString())) { // needs to be disposed } ConsoleOutput.WriteLine("Creating snapshot 2: {0}", name); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot(name, Guid.NewGuid().ToString())) { // needs to be disposed } int count = 0; IEnumerable <VMWareSnapshot> snapshots = virtualMachine.Snapshots.FindSnapshotsByName(name); foreach (VMWareSnapshot snapshot in snapshots) { ConsoleOutput.WriteLine("Removing snapshot: {0}", snapshot.Path); snapshot.RemoveSnapshot(); count++; } Assert.AreEqual(2, count); } }
public void TestEnumerateSnapshots() { foreach (VMWareVirtualMachine virtualMachine in _test.VirtualMachines) { List <string> snapshotPaths = GetSnapshotPaths(virtualMachine.Snapshots, 0); foreach (string snapshotPath in snapshotPaths) { VMWareSnapshot snapshot = virtualMachine.Snapshots.FindSnapshot(snapshotPath); Assert.IsNotNull(snapshot); ConsoleOutput.WriteLine("{0}: {1}, power state={2}", snapshot.DisplayName, snapshotPath, snapshot.PowerState); } } }
/// <summary> /// /// </summary> /// <returns></returns> public override bool Execute() { using (VMWareVirtualHost host = GetConnectedHost()) { using (VMWareVirtualMachine virtualMachine = OpenVirtualMachine(host)) { Log.LogMessage(string.Format("Creating snapshot {0}", _snapshotName)); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot( _snapshotName, _snapshotDescription, 0, _createSnapshotTimeout)) { // snapshot created } } } return(true); }
public void TestRevertToLiveSnapshot() { using (VMWareVirtualHost virtualHost = new VMWareVirtualHost()) { virtualHost.ConnectToVMWareWorkstation(); Console.WriteLine(virtualHost.ConnectionType); using (VMWareVirtualMachine virtualMachine = virtualHost.Open( @"C:\Users\dblock\Documents\Virtual Machines\Windows 98 SE\Windows 98.vmx")) { Console.WriteLine(virtualMachine.PathName); VMWareSnapshot snapshot = virtualMachine.Snapshots.GetNamedSnapshot("Live"); // snapshot.RevertToSnapshot(); // snapshot.RevertToSnapshot(Interop.VixCOM.Constants.VIX_VMPOWEROP_LAUNCH_GUI, // VMWareInterop.Timeouts.RevertToSnapshotTimeout); snapshot.RevertToSnapshot(Interop.VixCOM.Constants.VIX_VMPOWEROP_SUPPRESS_SNAPSHOT_POWERON, VMWareInterop.Timeouts.RevertToSnapshotTimeout); // virtualMachine.PowerOn(); } } }
public void TestCreateRemoveSnapshot() { foreach (VMWareVirtualMachine virtualMachine in _test.VirtualMachines) { // this is the root snapshot Assert.IsTrue(virtualMachine.Snapshots.Count >= 0); string name = Guid.NewGuid().ToString(); ConsoleOutput.WriteLine("Snapshot name: {0}", name); // take a snapshot at the current state using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot(name, Guid.NewGuid().ToString())) { ConsoleOutput.WriteLine("Created snapshot: {0}", name); } // check whether the snapshot was created Assert.IsNotNull(virtualMachine.Snapshots.GetNamedSnapshot(name)); // delete the snapshot via VM interface virtualMachine.Snapshots.RemoveSnapshot(name); // check whether the snapshot was deleted Assert.IsNull(virtualMachine.Snapshots.FindSnapshotByName(name)); } }
public void TestFindByName() { foreach (VMWareVirtualMachine virtualMachine in _test.VirtualMachines) { // this is the root snapshot string name = Guid.NewGuid().ToString(); // take two snapshots at the current state ConsoleOutput.WriteLine("Creating snapshot 1: {0}", name); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot( name, Guid.NewGuid().ToString())) { Console.WriteLine("Created snapshot: {0}", snapshot.DisplayName); } ConsoleOutput.WriteLine("Creating snapshot 2: {0}", name); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot( name, Guid.NewGuid().ToString())) { Console.WriteLine("Created snapshot: {0}", snapshot.DisplayName); } ConsoleOutput.WriteLine("Locating snapshot ..."); Assert.IsNotNull(virtualMachine.Snapshots.FindSnapshotByName(name)); ConsoleOutput.WriteLine("Locating snapshots ..."); IEnumerable <VMWareSnapshot> snapshots = virtualMachine.Snapshots.FindSnapshotsByName(name); int count = 0; foreach (VMWareSnapshot snapshot in snapshots) { count++; Assert.IsNotNull(virtualMachine.Snapshots.FindSnapshotByName(name)); ConsoleOutput.WriteLine("Removing {0}: {1}", snapshot.Path, snapshot.Description); snapshot.RemoveSnapshot(); snapshot.Close(); } Assert.AreEqual(2, count); Assert.IsNull(virtualMachine.Snapshots.FindSnapshotByName(name)); } }
public void GettingStartedWorkstation() { #region Example: Getting Started (Workstation) // declare a virtual host using (VMWareVirtualHost virtualHost = new VMWareVirtualHost()) { // connect to a local VMWare Workstation virtual host virtualHost.ConnectToVMWareWorkstation(); // open an existing virtual machine using (VMWareVirtualMachine virtualMachine = virtualHost.Open(@"C:\Virtual Machines\xp\xp.vmx")) { // power on this virtual machine virtualMachine.PowerOn(); // wait for VMWare Tools virtualMachine.WaitForToolsInGuest(); // login to the virtual machine virtualMachine.LoginInGuest("Administrator", "password"); // run notepad virtualMachine.RunProgramInGuest("notepad.exe", string.Empty); // create a new snapshot string name = "New Snapshot"; // take a snapshot at the current state VMWareSnapshot createdSnapshot = virtualMachine.Snapshots.CreateSnapshot(name, "test snapshot"); createdSnapshot.Dispose(); // power off virtualMachine.PowerOff(); // find the newly created snapshot using (VMWareSnapshot foundSnapshot = virtualMachine.Snapshots.GetNamedSnapshot(name)) { // revert to the new snapshot foundSnapshot.RevertToSnapshot(); // delete snapshot foundSnapshot.RemoveSnapshot(); } } } #endregion }
public void GettingStartedVI() { #region Example: Getting Started (VI) // declare a virtual host using (VMWareVirtualHost virtualHost = new VMWareVirtualHost()) { // connect to a remove (VMWare ESX) virtual machine virtualHost.ConnectToVMWareVIServer("esx.mycompany.com", "vmuser", "password"); // open an existing virtual machine using (VMWareVirtualMachine virtualMachine = virtualHost.Open("[storage] testvm/testvm.vmx")) { // power on this virtual machine virtualMachine.PowerOn(); // wait for VMWare Tools virtualMachine.WaitForToolsInGuest(); // login to the virtual machine virtualMachine.LoginInGuest("Administrator", "password"); // run notepad virtualMachine.RunProgramInGuest("notepad.exe", string.Empty); // create a new snapshot string name = "New Snapshot"; // take a snapshot at the current state virtualMachine.Snapshots.CreateSnapshot(name, "test snapshot"); // power off virtualMachine.PowerOff(); // find the newly created snapshot using (VMWareSnapshot snapshot = virtualMachine.Snapshots.GetNamedSnapshot(name)) { // revert to the new snapshot snapshot.RevertToSnapshot(); // delete snapshot snapshot.RemoveSnapshot(); } } } #endregion }
public void TestCreateRevertRemoveSnapshot() { foreach (VMWareVirtualMachine virtualMachine in _test.VirtualMachines) { // this is the root snapshot Assert.IsTrue(virtualMachine.Snapshots.Count >= 0); string name = Guid.NewGuid().ToString(); ConsoleOutput.WriteLine("Creating snapshot: {0}", name); // take a snapshot at the current state using (VMWareSnapshot snapshot = virtualMachine.Snapshots.CreateSnapshot(name, Guid.NewGuid().ToString())) { } // revert to the newly created snapshot ConsoleOutput.WriteLine("Locating snapshot: {0}", name); using (VMWareSnapshot snapshot = virtualMachine.Snapshots.GetNamedSnapshot(name)) { Assert.IsNotNull(snapshot); ConsoleOutput.WriteLine("Reverting snapshot: {0}", name); snapshot.RevertToSnapshot(); ConsoleOutput.WriteLine("Removing snapshot: {0}", name); snapshot.RemoveSnapshot(); } } }
/// <summary> /// Execute a file from a remote vm. /// </summary> private TaskResult Execute(SnapshotTaskConfig snapshotConfig) { TaskResult snapshotTaskResult = new TaskResult(); snapshotTaskResult.CmdLine = string.Format("Snapshot: {0} '{1}'", snapshotConfig.Command, snapshotConfig.Name); snapshotTaskResult.Name = snapshotConfig.Name; try { ConsoleOutput.WriteLine(snapshotTaskResult.CmdLine); if (!_installInstance.SimulationOnly) { switch (snapshotConfig.Command) { case SnapshotCommand.create: _installInstance.VirtualMachine.Snapshots.CreateSnapshot( snapshotConfig.Name, snapshotConfig.Description, snapshotConfig.IncludeMemory ? Constants.VIX_SNAPSHOT_INCLUDE_MEMORY : 0, VMWareInterop.Timeouts.CreateSnapshotTimeout); break; case SnapshotCommand.remove: _installInstance.VirtualMachine.Snapshots.RemoveSnapshot( snapshotConfig.Name); break; case SnapshotCommand.removeifexists: VMWareSnapshot snapshot = _installInstance.VirtualMachine.Snapshots.FindSnapshotByName( snapshotConfig.Name); if (snapshot != null) { ConsoleOutput.WriteLine("Removing {0}", snapshotTaskResult.CmdLine); snapshot.RemoveSnapshot(); } else { ConsoleOutput.WriteLine("No {0}", snapshotTaskResult.CmdLine); } break; case SnapshotCommand.revert: _installInstance.VirtualMachine.Snapshots.FindSnapshotByName( snapshotConfig.Name).RevertToSnapshot(Constants.VIX_VMPOWEROP_SUPPRESS_SNAPSHOT_POWERON); break; default: throw new Exception(string.Format("Unsupported command '{0}'", snapshotConfig.Command)); } ConsoleOutput.WriteLine(string.Format("Finished {0}", snapshotTaskResult.CmdLine)); } } catch (Exception ex) { snapshotTaskResult.LastError = ex.Message; snapshotTaskResult.Success = false; ConsoleOutput.WriteLine(ex); } return(snapshotTaskResult); }
// Main method. Start point of the program static void Main(string[] args) { /* * Print a banner to the screen */ Console.WriteLine(Properties.Resources.banner); /* * Do nothing if no arguments given. * * if the argument is -f, output to a file instead of console. */ if (args.Length == 0 || args == null) { Environment.Exit(0); } else if (args[0] == "-f") { consoleOut = false; } /* * Get the current directory and store in a variable to avoid multiple calls */ workingDir = Directory.GetCurrentDirectory(); /* * Check to ensure that the pstemp directory is present in the same directory as * the TestSuite.exe file, with all important files included */ pstempHost = workingDir + @"\pstemp"; if (!Directory.Exists(pstempHost)) { Console.WriteLine("[!] Error: the pstemp directory does not exist."); Environment.Exit(0); } else if (!File.Exists(pstempHost + @"\hstart64.exe") || !File.Exists(pstempHost + @"\PsExec.exe")) { Console.WriteLine("[!] Error: one or more files missing from pstemp directory."); Environment.Exit(0); } /* * Read lines from teh variables.ini file and set variables accordingly */ string[] vars = File.ReadAllLines(workingDir + @"\Resources\variables.ini"); foreach (string var in vars) { if (var.Contains("DOMAIN=")) { domainName = var.Replace("DOMAIN=", ""); } else if (var.Contains("USERNAME="******"USERNAME="******""); } else if (var.Contains("PASSWORD="******"PASSWORD="******""); } else if (var.Contains("VMX=")) { vmxPath = var.Replace("VMX=", ""); } else if (var.Contains("CPUID=")) { compId = var.Replace("CPUID=", ""); } else if (var.Contains("TESTSPERSNAP=")) { testPerSnap = int.Parse(var.Replace("TESTSPERSNAP=", "")); } else if (var.Contains("TASKCNXNSTRING=")) { taskString = var.Replace("TASKCNXNSTRING=", ""); } else if (var.Contains("IMAGENAME=")) { imageName = var.Replace("IMAGENAME=", ""); } else if (var.Contains("PICTIME=")) { picTime = int.Parse(var.Replace("PICTIME=", "")); } else if (var.Contains("USESERVER=")) { useServer = bool.Parse(var.Replace("USESERVER=", "")); } else if (var.Contains("HOSTNAME=")) { hostName = var.Replace("HOSTNAME=", ""); } else if (var.Contains("HOSTUSER="******"HOSTUSER="******""); } else if (var.Contains("HOSTPASS="******"HOSTPASS="******""); } else if (var.Contains("SFWRCNXNSTRING=")) { sfwrString = var.Replace("SFWRCNXNSTRING=", ""); } else if (var.Contains("SCREENSHOTSDIR=")) { screenShotsDir = var.Replace("SCREENSHOTSDIR=", ""); } } /* * If some variable is not initialized, exit. */ if (domainName == null || usrnm == null || psswd == null || vmxPath == null || compId == null || taskString == null || useServer == null || sfwrString == null) { Console.WriteLine("[!] An essential variable has not been initiated. See variables.ini"); Environment.Exit(0); } /* * If no image name was given, use the name of the VMX file */ if (imageName == null) { imageName = Path.GetFileNameWithoutExtension(vmxPath); } screenShotsDir = screenShotsDir + imageName; /* * If the output is specified to file, redirect all Console.WriteLine to a file instead of the console. */ if (!consoleOut) { FileStream fStream = new FileStream(screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt", FileMode.OpenOrCreate, FileAccess.Write); StreamWriter fileOut = new StreamWriter(fStream); Console.SetOut(fileOut); } /* * If useServer is true and any of the essential server variables are empty, quit */ if ((bool)useServer && (hostName == null || hostPass == null || hostUser == null)) { Console.WriteLine("[!] Variables.ini is not configured for server use."); Environment.Exit(0); } /* * Create a new directory with the date and time stamp to store the test results */ resultDir = workingDir + @"\Results\"; System.IO.Directory.CreateDirectory(resultDir); resultDir = resultDir + imageName + @"\"; System.IO.Directory.CreateDirectory(resultDir); /* * Create the autoLogon.reg file, used to allow auto-logon in the guest OS after snapshot revert * * Sets to auto login * Turns off screensaver (broken?) * Turns off lock screen (broken?) */ try { if (File.Exists(pstempHost + @"\autoLogon.reg")) { File.Delete(pstempHost + @"\autoLogon.reg"); } string[] lines = { "Windows Registry Editor Version 5.00", @"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]", "\"DefaultUserName\"=\"" + usrnm + "\"", "\"DefaultDomainName\"=\"" + domainName + "\"", "\"DefaultPassword\"=\"" + psswd + "\"", "\"AutoAdminLogon\"=\"1\"", "", @"[HKEY_CURRENT_USER\Control Panel\Desktop]", "\"ScreenSaveActive\"=\"0\"", "", @"[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization]", "\"NoLockScreen\"=dword:00000001" }; File.WriteAllLines(pstempHost + @"\autoLogon.reg", lines); } catch (Exception e) { Console.WriteLine("[!] Could not create auto-login registry file. You may need to do this manually."); Console.WriteLine("[?] Exception message: " + e.Message); } /* * Query the SQL database and use the reader to create a collection of * the information */ try { conn = new SqlConnection(taskString); conn.Open(); cmd = new SqlCommand(Properties.Resources.taskQuery + compId, conn); // use the command resource, add the computer ID number reader = cmd.ExecuteReader(); tests = new Dictionary <int, TestPackage>(); while (reader.Read()) { tests.Add(reader.GetInt32(1), new TestPackage(reader.GetString(0), reader.GetInt32(1).ToString())); } reader.Close(); conn.Close(); Console.WriteLine("[i] " + tests.Count + " packages assigned to this machine."); } catch (SqlException sqle) { Console.WriteLine("Exception thrown: " + sqle.Message); Environment.Exit(0); } /* * Create VirtualHost and VirtualMachine objects with using directive */ using (VMWareVirtualHost vhost = new VMWareVirtualHost()) { /* * Connect to either vSphere or Workstation, based on useServer variable */ if ((bool)useServer) { vhost.ConnectToVMWareVIServer(hostName, hostUser, hostPass); Console.WriteLine("[\u221A] Connected to vSphere."); } else { vhost.ConnectToVMWareWorkstation(); Console.WriteLine("[\u221A] Connected to VMWareWorkstation."); } /* * Open a virtual machine using the vmxPath */ using (VMWareVirtualMachine vm = vhost.Open(vmxPath)) { Console.WriteLine("[\u221A] Virtual machine opened."); /* * Power on the virtual machine and log in interactively. * Requires user to log in interactively on the VM */ try { vm.PowerOn(); Console.WriteLine("[\u221A] Powered on."); vm.WaitForToolsInGuest(); Console.WriteLine("[\u221A] Tools found in guest."); /* * Login using the interactive login procedure */ interactiveLogin(vm); /* * Copy necessary files for SYSTEM execution from host to guest. * */ if (vm.DirectoryExistsInGuest(pstempGuest)) { vm.DeleteDirectoryFromGuest(pstempGuest); } vm.CopyFileFromHostToGuest(pstempHost, pstempGuest); Console.WriteLine("[\u221A] Files copied to temp directory " + pstempGuest + "."); /* * Run the AutoLogon script for proper VM rollbacks * We try try to delete the PSEXESVC process, if it exists. If it doesn't it throws an exception, * which we ignore. */ VMWareVirtualMachine.Process reg = detachSystemCommand(@"C:\Windows\regedit.exe", "/s \"" + pstempGuest + "\\autoLogon.reg\"", vm); if (reg != null) { while (vm.GuestProcesses.FindProcess(reg.Name, StringComparison.CurrentCulture) != null) { ; } } Console.WriteLine("[\u221A] Registry configured for auto logon."); /* * Create snapshot for deployment rollbacks * If a snapshot */ try { deployPoint = vm.Snapshots.GetNamedSnapshot(snapName); deployPoint.RemoveSnapshot(); } catch (VMWareException) { } deployPoint = vm.Snapshots.CreateSnapshot(snapName, "Start point for deployment tests"); Console.WriteLine("[\u221A] Snapshot 'deployPoint' captured."); /* * Sync policies with server. */ policySync(vm); /* * Create a list of all files in the policy directory * Remove all non-xml files from the list * Look for the task ID in the file name, and map the file name to the correct package */ policyDirectoryFiles = vm.ListDirectoryInGuest(@"C:\ProgramData\LANDesk\Policies", false); policyDirectoryFiles.RemoveAll(x => !(x.Contains(".xml"))); foreach (string dir in policyDirectoryFiles) { Match m = idPattern.Match(dir); int key = (m.Success) ? Int32.Parse(m.Value.Substring(3, 4)) : -1; if (tests.ContainsKey(key)) { tests[key].Cmd = dir; } } Console.WriteLine((policyDirectoryFiles.Count == tests.Count) ? "[\u221A] All packages can be deployed." : "[!] There are " + policyDirectoryFiles.Count + " policy files and " + tests.Count + " tasks assigned."); /* * Rrun through each entry in the dictionary of test cases, * */ using (myConn = new MySqlConnection(sfwrString)) { myConn.Open(); foreach (KeyValuePair <int, TestPackage> entry in tests) { TestPackage test = entry.Value; ReTest: try { /* * Query SLM, if any result is given test is a pass else fail */ myCmd = new MySqlCommand("SELECT * FROM software WHERE task_id=" + test.TaskID, myConn); myReader = myCmd.ExecuteReader(); test.NewResult = new TestResult("SLM Entry Exists", (myReader.HasRows) ? "1" : "0", ""); myReader.Close(); /* * If there is no xml file for the package, continue * For the package that cannot be deployed, add a test result saying so * If it can be deployed, add a positive test result */ if (!test.isDeployable) { Console.WriteLine("[!] Continuing, cannot deploy " + test.Name); test.NewResult = new TestResult("LANDesk Task Available", "0", "Policy file not found."); continue; } else { Console.WriteLine("[*] Deploying " + test.Name); test.NewResult = new TestResult("LANDesk Task Available", "1", ""); } /* * Directory for pictures resolved from resultDir and taskID */ picDir = resultDir + test.TaskID + @"\"; System.IO.Directory.CreateDirectory(picDir); /* * Get the number of registry entries in the LANDesk reg folder before deployment */ int beforeDeploy = getRegEntryNum(vm); /* * Capture the process to determine when the deployment is complete * Start timing the deployment from when the PsExec process is detected */ VMWareVirtualMachine.Process deployProcess = detachSystemCommand(@"C:\Program Files (x86)\LANDesk\LDClient\SDCLIENT.EXE", test.Cmd, vm); stopwatch.Restart(); /* * While the program deploys * if 10000ms has passed since last pic taken, take a pic and increment * if the test is taking too long, add a failed test, revert snapshot, convert * png files to single gif and go to the next test */ int pictureCount = 0; while (vm.GuestProcesses.FindProcess(deployProcess.Name, StringComparison.CurrentCulture) != null) { if (stopwatch.ElapsedMilliseconds > pictureCount * picTime) { vm.CaptureScreenImage().Save(picDir + pictureCount++.ToString() + @".png"); } if (stopwatch.ElapsedMilliseconds > test.MaxTime) { test.NewResult = new TestResult("LANDesk Task Completed", "0", ""); test.Pngs = Directory.GetFiles(picDir); test.PicsDir = picDir; revertAndLogin(vm); goto NextTest; } } stopwatch.Stop(); test.Time = stopwatch.ElapsedMilliseconds; test.NewResult = new TestResult("LANDesk Task Completed", "1", test.Time.ToString()); detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname htmldialog}\"", vm); Console.WriteLine("[\u221A] Task complete. Task took " + (test.Time / 1000) + " seconds."); /* * The task has successfully completed running, we now add to the TestPackage object the * names of all .png files and the location of these files, for later gif creation. */ test.Pngs = Directory.GetFiles(picDir); test.PicsDir = picDir; /* * Test if a new registry key was added. If there are more registry entries now than before the deployment, * pass. Otherwise fail. */ test.NewResult = new TestResult("Registry Key Added", (beforeDeploy < getRegEntryNum(vm)) ? "1" : "0", ""); /* * Check to see if any of the exe's returned by query to database exist on the guest * */ bool anyExeOnGuest = false; myCmd = new MySqlCommand(Properties.Resources.exeQuery + test.TaskID, myConn); myReader = myCmd.ExecuteReader(); if (!myReader.HasRows) { anyExeOnGuest = true; } else { while (myReader.Read()) { string exeName = myReader.GetString(2); string fileId = myReader.GetString(0); if (vm.FileExistsInGuest(exeName)) { /* * If the file exists on the guest; run the exe, wait 60 seconds and take a pic. */ anyExeOnGuest = true; VMWareVirtualMachine.Process testExe = vm.DetachProgramInGuest(myReader.GetString(2)); stopwatch.Restart(); while (stopwatch.ElapsedMilliseconds < 60000 && vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null) { ; } if (vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null) { vm.CaptureScreenImage().Save(picDir + "exescreen_" + fileId + ".png"); try { testExe.KillProcessInGuest(); } catch { } } detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname @(javaw, java)}\"", vm); test.NewResult = new TestResult("Ran EXE - " + Path.GetFileName(exeName), "1", fileId); } }// end myReader.Read() while } /* * If there are no exe's on the guest, result is a fail. * If there are, result is a pass with optional message */ test.NewResult = (!anyExeOnGuest) ? new TestResult("Files Installed", "0", "") : new TestResult("Files Installed", "1", (!myReader.HasRows) ? "No executables returned" : ""); myReader.Close(); /* * * If the number of tests completed is greater than the revert * threshold, revert and continue testing. * Otherwise, kill the htmldialog.exe process for the next test. */ if (++count == testPerSnap) { revertAndLogin(vm); } } catch (Exception e) { /* * If this code is reached, test has not completed. * If this is not the first test deployed since a test passed, revert and try the test again. * Otherwise, revert and move to the next test. * Add a test result containing some info from Exception e */ if (count != 0) { Console.WriteLine("[!] Test suite error."); Console.WriteLine("[!] Restarting test of " + test.Name); revertAndLogin(vm); goto ReTest; } test.NewResult = new TestResult("Test Suite Error", "0", e.Message); Console.WriteLine("[!] Exception caught, rolling back then moving to next test: "); Console.WriteLine("Type: " + e.GetType().ToString()); Console.WriteLine("Message: " + e.Message); Console.WriteLine("Stack trace:\n" + e.StackTrace); revertAndLogin(vm); } NextTest :; }// end foreach try { /* * We now have a dictionary of all the tests with taskID as the keys. * Send the results to the SQL server */ Console.WriteLine("[\u221A] Sending test results to database."); myDeleteCmd = new MySqlCommand("DELETE FROM unit_test WHERE image=?image AND task_id=?task"); myDeleteCmd.Parameters.AddWithValue("?image", imageName); myDeleteCmd.Parameters.AddWithValue("?task", ""); myDeleteCmd.Connection = myConn; myDeleteCmd.CommandType = System.Data.CommandType.Text; myCmd = new MySqlCommand(@"INSERT INTO unit_test (task_id, image, test_name, result, message) VALUES (?task_id, ?image, ?test_name, ?result, ?message)"); myCmd.CommandType = System.Data.CommandType.Text; myCmd.Connection = myConn; myCmd.Parameters.AddWithValue("?image", imageName); myCmd.Parameters.AddWithValue("?task_id", ""); myCmd.Parameters.AddWithValue("?test_name", ""); myCmd.Parameters.AddWithValue("?result", ""); myCmd.Parameters.AddWithValue("?message", ""); foreach (KeyValuePair <int, TestPackage> entry in tests) { myDeleteCmd.Parameters["?task"].Value = entry.Value.TaskID; myDeleteCmd.ExecuteNonQuery(); myCmd.Parameters["?task_id"].Value = entry.Value.TaskID; foreach (TestResult result in entry.Value.AllResults) { myCmd.Parameters["?test_name"].Value = result.Name; myCmd.Parameters["?result"].Value = result.Result; myCmd.Parameters["?message"].Value = result.Message; myCmd.ExecuteNonQuery(); } } Console.WriteLine("[\u221A] Results committed to database."); } /* * If the database commit failed, print all results to a file in the working directory. */ catch (Exception) { string fileName = screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt"; FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write); StreamWriter fileOut = new StreamWriter(fStream); foreach (KeyValuePair <int, TestPackage> pair in tests) { foreach (TestResult result in pair.Value.AllResults) { fileOut.WriteLine(pair.Key.ToString() + "," + imageName + "," + result.Name + "," + result.Result + "," + result.Message); } } Console.WriteLine("[\u221A] Results written to file.\n" + fileName); } }// end of myConn using statement /* * Gif creation */ Console.WriteLine("[\u221A] Creating gifs."); foreach (KeyValuePair <int, TestPackage> pair in tests) { pair.Value.createGif(); } /* * Copy the screenshots and gifs to the share */ CopyFolder(resultDir, screenShotsDir); Console.WriteLine("[\u221A] Testing complete. Exiting."); }// end try /* * If for whatever reason an exception is thrown, print the error message to the screen. * Distinguish between VMWare exception and other exceptions. */ catch (VMWareException vmwe) { Console.WriteLine("[!] VMware exception: " + vmwe.Message); Console.WriteLine(vmwe.ToString()); Console.WriteLine(vmwe.Source); Environment.Exit(0); } catch (Exception e) { Console.WriteLine("[!] Exception: " + e.Message + "\n"); Console.WriteLine("[!] Type:" + e.GetType()); Console.WriteLine(e.Source); Console.WriteLine(e.StackTrace); Environment.Exit(0); } } // End vm using } // End vhost using } // end main
// Main method. Start point of the program static void Main(string[] args) { /* * Print a banner to the screen */ Console.WriteLine(Properties.Resources.banner); /* * Do nothing if no arguments given. * * if the argument is -f, output to a file instead of console. */ if (args.Length == 0 || args == null) Environment.Exit(0); else if (args[0] == "-f") consoleOut = false; /* * Get the current directory and store in a variable to avoid multiple calls */ workingDir = Directory.GetCurrentDirectory(); /* * Check to ensure that the pstemp directory is present in the same directory as * the TestSuite.exe file, with all important files included */ pstempHost = workingDir + @"\pstemp"; if (!Directory.Exists(pstempHost)) { Console.WriteLine("[!] Error: the pstemp directory does not exist."); Environment.Exit(0); } else if (!File.Exists(pstempHost + @"\hstart64.exe") || !File.Exists(pstempHost + @"\PsExec.exe")) { Console.WriteLine("[!] Error: one or more files missing from pstemp directory."); Environment.Exit(0); } /* * Read lines from teh variables.ini file and set variables accordingly */ string[] vars = File.ReadAllLines(workingDir + @"\Resources\variables.ini"); foreach (string var in vars) { if (var.Contains("DOMAIN=")) domainName = var.Replace("DOMAIN=", ""); else if (var.Contains("USERNAME="******"USERNAME="******""); else if (var.Contains("PASSWORD="******"PASSWORD="******""); else if (var.Contains("VMX=")) vmxPath = var.Replace("VMX=", ""); else if (var.Contains("CPUID=")) compId = var.Replace("CPUID=", ""); else if (var.Contains("TESTSPERSNAP=")) testPerSnap = int.Parse(var.Replace("TESTSPERSNAP=", "")); else if (var.Contains("TASKCNXNSTRING=")) taskString = var.Replace("TASKCNXNSTRING=", ""); else if (var.Contains("IMAGENAME=")) imageName = var.Replace("IMAGENAME=", ""); else if (var.Contains("PICTIME=")) picTime = int.Parse(var.Replace("PICTIME=", "")); else if (var.Contains("USESERVER=")) useServer = bool.Parse(var.Replace("USESERVER=", "")); else if (var.Contains("HOSTNAME=")) hostName = var.Replace("HOSTNAME=", ""); else if (var.Contains("HOSTUSER="******"HOSTUSER="******""); else if (var.Contains("HOSTPASS="******"HOSTPASS="******""); else if (var.Contains("SFWRCNXNSTRING=")) sfwrString = var.Replace("SFWRCNXNSTRING=", ""); else if (var.Contains("SCREENSHOTSDIR=")) screenShotsDir = var.Replace("SCREENSHOTSDIR=", ""); } /* * If some variable is not initialized, exit. */ if (domainName == null || usrnm == null || psswd == null || vmxPath == null || compId == null || taskString == null || useServer == null || sfwrString == null) { Console.WriteLine("[!] An essential variable has not been initiated. See variables.ini"); Environment.Exit(0); } /* * If no image name was given, use the name of the VMX file */ if (imageName == null) imageName = Path.GetFileNameWithoutExtension(vmxPath); screenShotsDir = screenShotsDir + imageName; /* * If the output is specified to file, redirect all Console.WriteLine to a file instead of the console. */ if (!consoleOut) { FileStream fStream = new FileStream(screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt", FileMode.OpenOrCreate, FileAccess.Write); StreamWriter fileOut = new StreamWriter(fStream); Console.SetOut(fileOut); } /* * If useServer is true and any of the essential server variables are empty, quit */ if ((bool)useServer && (hostName == null || hostPass == null || hostUser == null)) { Console.WriteLine("[!] Variables.ini is not configured for server use."); Environment.Exit(0); } /* * Create a new directory with the date and time stamp to store the test results */ resultDir = workingDir + @"\Results\"; System.IO.Directory.CreateDirectory(resultDir); resultDir = resultDir + imageName + @"\"; System.IO.Directory.CreateDirectory(resultDir); /* * Create the autoLogon.reg file, used to allow auto-logon in the guest OS after snapshot revert * Sets to auto login * Turns off screensaver (broken?) * Turns off lock screen (broken?) */ try { if (File.Exists(pstempHost + @"\autoLogon.reg")) File.Delete(pstempHost + @"\autoLogon.reg"); string[] lines = { "Windows Registry Editor Version 5.00", @"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]", "\"DefaultUserName\"=\"" + usrnm + "\"", "\"DefaultDomainName\"=\"" + domainName + "\"", "\"DefaultPassword\"=\"" + psswd + "\"", "\"AutoAdminLogon\"=\"1\"", "", @"[HKEY_CURRENT_USER\Control Panel\Desktop]", "\"ScreenSaveActive\"=\"0\"", "", @"[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Personalization]", "\"NoLockScreen\"=dword:00000001"}; File.WriteAllLines(pstempHost + @"\autoLogon.reg", lines); } catch (Exception e) { Console.WriteLine("[!] Could not create auto-login registry file. You may need to do this manually."); Console.WriteLine("[?] Exception message: " + e.Message); } /* * Query the SQL database and use the reader to create a collection of * the information */ try { conn = new SqlConnection(taskString); conn.Open(); cmd = new SqlCommand(Properties.Resources.taskQuery + compId, conn); // use the command resource, add the computer ID number reader = cmd.ExecuteReader(); tests = new Dictionary<int, TestPackage>(); while (reader.Read()) tests.Add(reader.GetInt32(1), new TestPackage(reader.GetString(0), reader.GetInt32(1).ToString())); reader.Close(); conn.Close(); Console.WriteLine("[i] " + tests.Count + " packages assigned to this machine."); } catch (SqlException sqle) { Console.WriteLine("Exception thrown: " + sqle.Message); Environment.Exit(0); } /* * Create VirtualHost and VirtualMachine objects with using directive */ using (VMWareVirtualHost vhost = new VMWareVirtualHost()) { /* * Connect to either vSphere or Workstation, based on useServer variable */ if ((bool)useServer) { vhost.ConnectToVMWareVIServer(hostName, hostUser, hostPass); Console.WriteLine("[\u221A] Connected to vSphere."); } else { vhost.ConnectToVMWareWorkstation(); Console.WriteLine("[\u221A] Connected to VMWareWorkstation."); } /* * Open a virtual machine using the vmxPath */ using (VMWareVirtualMachine vm = vhost.Open(vmxPath)) { Console.WriteLine("[\u221A] Virtual machine opened."); /* * Power on the virtual machine and log in interactively. * Requires user to log in interactively on the VM */ try { vm.PowerOn(); Console.WriteLine("[\u221A] Powered on."); vm.WaitForToolsInGuest(); Console.WriteLine("[\u221A] Tools found in guest."); /* * Login using the interactive login procedure */ interactiveLogin(vm); /* * Copy necessary files for SYSTEM execution from host to guest. * */ if (vm.DirectoryExistsInGuest(pstempGuest)) vm.DeleteDirectoryFromGuest(pstempGuest); vm.CopyFileFromHostToGuest(pstempHost, pstempGuest); Console.WriteLine("[\u221A] Files copied to temp directory " + pstempGuest + "."); /* * Run the AutoLogon script for proper VM rollbacks * We try try to delete the PSEXESVC process, if it exists. If it doesn't it throws an exception, * which we ignore. */ VMWareVirtualMachine.Process reg = detachSystemCommand(@"C:\Windows\regedit.exe", "/s \"" + pstempGuest + "\\autoLogon.reg\"", vm); if (reg != null) while (vm.GuestProcesses.FindProcess(reg.Name, StringComparison.CurrentCulture) != null) ; Console.WriteLine("[\u221A] Registry configured for auto logon."); /* * Create snapshot for deployment rollbacks * If a snapshot */ try { deployPoint = vm.Snapshots.GetNamedSnapshot(snapName); deployPoint.RemoveSnapshot(); } catch (VMWareException) { } deployPoint = vm.Snapshots.CreateSnapshot(snapName, "Start point for deployment tests"); Console.WriteLine("[\u221A] Snapshot 'deployPoint' captured."); /* * Sync policies with server. */ policySync(vm); /* * Create a list of all files in the policy directory * Remove all non-xml files from the list * Look for the task ID in the file name, and map the file name to the correct package */ policyDirectoryFiles = vm.ListDirectoryInGuest(@"C:\ProgramData\LANDesk\Policies", false); policyDirectoryFiles.RemoveAll(x => !(x.Contains(".xml"))); foreach (string dir in policyDirectoryFiles) { Match m = idPattern.Match(dir); int key = (m.Success) ? Int32.Parse(m.Value.Substring(3, 4)) : -1; if (tests.ContainsKey(key)) tests[key].Cmd = dir; } Console.WriteLine((policyDirectoryFiles.Count == tests.Count) ? "[\u221A] All packages can be deployed." : "[!] There are " + policyDirectoryFiles.Count + " policy files and " + tests.Count + " tasks assigned."); /* * Rrun through each entry in the dictionary of test cases, * */ using (myConn = new MySqlConnection(sfwrString)) { myConn.Open(); foreach (KeyValuePair<int, TestPackage> entry in tests) { TestPackage test = entry.Value; ReTest: try { /* * Query SLM, if any result is given test is a pass else fail */ myCmd = new MySqlCommand("SELECT * FROM software WHERE task_id=" + test.TaskID, myConn); myReader = myCmd.ExecuteReader(); test.NewResult = new TestResult("SLM Entry Exists", (myReader.HasRows) ? "1" : "0", ""); myReader.Close(); /* * If there is no xml file for the package, continue * For the package that cannot be deployed, add a test result saying so * If it can be deployed, add a positive test result */ if (!test.isDeployable) { Console.WriteLine("[!] Continuing, cannot deploy " + test.Name); test.NewResult = new TestResult("LANDesk Task Available", "0", "Policy file not found."); continue; } else { Console.WriteLine("[*] Deploying " + test.Name); test.NewResult = new TestResult("LANDesk Task Available", "1", ""); } /* * Directory for pictures resolved from resultDir and taskID */ picDir = resultDir + test.TaskID + @"\"; System.IO.Directory.CreateDirectory(picDir); /* * Get the number of registry entries in the LANDesk reg folder before deployment */ int beforeDeploy = getRegEntryNum(vm); /* * Capture the process to determine when the deployment is complete * Start timing the deployment from when the PsExec process is detected */ VMWareVirtualMachine.Process deployProcess = detachSystemCommand(@"C:\Program Files (x86)\LANDesk\LDClient\SDCLIENT.EXE", test.Cmd, vm); stopwatch.Restart(); /* * While the program deploys * if 10000ms has passed since last pic taken, take a pic and increment * if the test is taking too long, add a failed test, revert snapshot, convert * png files to single gif and go to the next test */ int pictureCount = 0; while (vm.GuestProcesses.FindProcess(deployProcess.Name, StringComparison.CurrentCulture) != null) { if (stopwatch.ElapsedMilliseconds > pictureCount * picTime) vm.CaptureScreenImage().Save(picDir + pictureCount++.ToString() + @".png"); if (stopwatch.ElapsedMilliseconds > test.MaxTime) { test.NewResult = new TestResult("LANDesk Task Completed", "0", ""); test.Pngs = Directory.GetFiles(picDir); test.PicsDir = picDir; revertAndLogin(vm); goto NextTest; } } stopwatch.Stop(); test.Time = stopwatch.ElapsedMilliseconds; test.NewResult = new TestResult("LANDesk Task Completed", "1", test.Time.ToString()); detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname htmldialog}\"", vm); Console.WriteLine("[\u221A] Task complete. Task took " + (test.Time / 1000) + " seconds."); /* * The task has successfully completed running, we now add to the TestPackage object the * names of all .png files and the location of these files, for later gif creation. */ test.Pngs = Directory.GetFiles(picDir); test.PicsDir = picDir; /* * Test if a new registry key was added. If there are more registry entries now than before the deployment, * pass. Otherwise fail. */ test.NewResult = new TestResult("Registry Key Added", (beforeDeploy < getRegEntryNum(vm)) ? "1" : "0", ""); /* * Check to see if any of the exe's returned by query to database exist on the guest * */ bool anyExeOnGuest = false; myCmd = new MySqlCommand(Properties.Resources.exeQuery + test.TaskID, myConn); myReader = myCmd.ExecuteReader(); if (!myReader.HasRows) anyExeOnGuest = true; else { while (myReader.Read()) { string exeName = myReader.GetString(2); string fileId = myReader.GetString(0); if (vm.FileExistsInGuest(exeName)) { /* * If the file exists on the guest; run the exe, wait 60 seconds and take a pic. */ anyExeOnGuest = true; VMWareVirtualMachine.Process testExe = vm.DetachProgramInGuest(myReader.GetString(2)); stopwatch.Restart(); while (stopwatch.ElapsedMilliseconds < 60000 && vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null) ; if (vm.GuestProcesses.FindProcess(testExe.Name, StringComparison.CurrentCulture) != null) { vm.CaptureScreenImage().Save(picDir + "exescreen_" + fileId + ".png"); try { testExe.KillProcessInGuest(); } catch { } } detachSystemCommand(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe", "-command \"& {&\'Stop-Process\' -processname @(javaw, java)}\"", vm); test.NewResult = new TestResult("Ran EXE - " + Path.GetFileName(exeName), "1", fileId); } }// end myReader.Read() while } /* * If there are no exe's on the guest, result is a fail. * If there are, result is a pass with optional message */ test.NewResult = (!anyExeOnGuest) ? new TestResult("Files Installed", "0", "") : new TestResult("Files Installed", "1", (!myReader.HasRows) ? "No executables returned" : ""); myReader.Close(); /* * * If the number of tests completed is greater than the revert * threshold, revert and continue testing. * Otherwise, kill the htmldialog.exe process for the next test. */ if (++count == testPerSnap) revertAndLogin(vm); } catch (Exception e) { /* * If this code is reached, test has not completed. * If this is not the first test deployed since a test passed, revert and try the test again. * Otherwise, revert and move to the next test. * Add a test result containing some info from Exception e */ if (count != 0) { Console.WriteLine("[!] Test suite error."); Console.WriteLine("[!] Restarting test of " + test.Name); revertAndLogin(vm); goto ReTest; } test.NewResult = new TestResult("Test Suite Error", "0", e.Message); Console.WriteLine("[!] Exception caught, rolling back then moving to next test: "); Console.WriteLine("Type: " + e.GetType().ToString()); Console.WriteLine("Message: " + e.Message); Console.WriteLine("Stack trace:\n" + e.StackTrace); revertAndLogin(vm); } NextTest:; }// end foreach try { /* * We now have a dictionary of all the tests with taskID as the keys. * Send the results to the SQL server */ Console.WriteLine("[\u221A] Sending test results to database."); myDeleteCmd = new MySqlCommand("DELETE FROM unit_test WHERE image=?image AND task_id=?task"); myDeleteCmd.Parameters.AddWithValue("?image", imageName); myDeleteCmd.Parameters.AddWithValue("?task", ""); myDeleteCmd.Connection = myConn; myDeleteCmd.CommandType = System.Data.CommandType.Text; myCmd = new MySqlCommand(@"INSERT INTO unit_test (task_id, image, test_name, result, message) VALUES (?task_id, ?image, ?test_name, ?result, ?message)"); myCmd.CommandType = System.Data.CommandType.Text; myCmd.Connection = myConn; myCmd.Parameters.AddWithValue("?image", imageName); myCmd.Parameters.AddWithValue("?task_id", ""); myCmd.Parameters.AddWithValue("?test_name", ""); myCmd.Parameters.AddWithValue("?result", ""); myCmd.Parameters.AddWithValue("?message", ""); foreach (KeyValuePair<int, TestPackage> entry in tests) { myDeleteCmd.Parameters["?task"].Value = entry.Value.TaskID; myDeleteCmd.ExecuteNonQuery(); myCmd.Parameters["?task_id"].Value = entry.Value.TaskID; foreach (TestResult result in entry.Value.AllResults) { myCmd.Parameters["?test_name"].Value = result.Name; myCmd.Parameters["?result"].Value = result.Result; myCmd.Parameters["?message"].Value = result.Message; myCmd.ExecuteNonQuery(); } } Console.WriteLine("[\u221A] Results committed to database."); } /* * If the database commit failed, print all results to a file in the working directory. */ catch (Exception) { string fileName = screenShotsDir + @"\log\" + string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now) + ".txt"; FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write); StreamWriter fileOut = new StreamWriter(fStream); foreach(KeyValuePair<int, TestPackage> pair in tests) { foreach(TestResult result in pair.Value.AllResults) { fileOut.WriteLine(pair.Key.ToString() + "," + imageName + "," + result.Name + "," + result.Result + "," + result.Message); } } Console.WriteLine("[\u221A] Results written to file.\n" + fileName); } }// end of myConn using statement /* * Gif creation */ Console.WriteLine("[\u221A] Creating gifs."); foreach (KeyValuePair<int, TestPackage> pair in tests) pair.Value.createGif(); /* * Copy the screenshots and gifs to the share */ CopyFolder(resultDir, screenShotsDir); Console.WriteLine("[\u221A] Testing complete. Exiting."); }// end try /* * If for whatever reason an exception is thrown, print the error message to the screen. * Distinguish between VMWare exception and other exceptions. */ catch (VMWareException vmwe) { Console.WriteLine("[!] VMware exception: " + vmwe.Message); Console.WriteLine(vmwe.ToString()); Console.WriteLine(vmwe.Source); Environment.Exit(0); } catch (Exception e) { Console.WriteLine("[!] Exception: " + e.Message + "\n"); Console.WriteLine("[!] Type:" + e.GetType()); Console.WriteLine(e.Source); Console.WriteLine(e.StackTrace); Environment.Exit(0); } }// End vm using }// End vhost using }// end main
/// <summary> /// Delete/remove a snapshot. /// </summary> /// <param name="item">Snapshot to delete.</param> /// <returns>True if the snapshot was deleted.</returns> public void RemoveSnapshot(VMWareSnapshot item) { RemoveSnapshot(item, VMWareInterop.Timeouts.RemoveSnapshotTimeout); }
/// <summary> /// Delete/remove a snapshot. /// </summary> /// <param name="item">Snapshot to delete.</param> /// <param name="timeoutInSeconds">Timeout in seconds.</param> /// <returns>True if the snapshot was deleted.</returns> public void RemoveSnapshot(VMWareSnapshot item, int timeoutInSeconds) { item.RemoveSnapshot(timeoutInSeconds); RemoveAll(); }