From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michael Goldish Subject: [KVM-AUTOTEST PATCH 4/9] [RFC] KVM test: DTM automation program for WHQL tests Date: Thu, 15 Jul 2010 18:57:33 +0300 Message-ID: <1279209458-19590-4-git-send-email-mgoldish@redhat.com> References: <1279209458-19590-1-git-send-email-mgoldish@redhat.com> <1279209458-19590-2-git-send-email-mgoldish@redhat.com> <1279209458-19590-3-git-send-email-mgoldish@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: autotest@test.kernel.org, kvm@vger.kernel.org Return-path: In-Reply-To: <1279209458-19590-3-git-send-email-mgoldish@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: autotest-bounces@test.kernel.org Errors-To: autotest-bounces@test.kernel.org List-Id: kvm.vger.kernel.org This C# program should run on a DTM/WHQL server. It's used by the whql_submission test to schedule and monitor device submission jobs. Note: the binary is copied to the server at run time, so it doesn't need to be packaged in winutils.iso. Signed-off-by: Michael Goldish --- client/tests/kvm/deps/whql_submission_15.cs | 254 ++++++++++++++++++++++++++ client/tests/kvm/deps/whql_submission_15.exe | Bin 0 -> 10240 bytes 2 files changed, 254 insertions(+), 0 deletions(-) create mode 100644 client/tests/kvm/deps/whql_submission_15.cs create mode 100644 client/tests/kvm/deps/whql_submission_15.exe diff --git a/client/tests/kvm/deps/whql_submission_15.cs b/client/tests/kvm/deps/whql_submission_15.cs new file mode 100644 index 0000000..540674a --- /dev/null +++ b/client/tests/kvm/deps/whql_submission_15.cs @@ -0,0 +1,254 @@ +// DTM submission automation program +// Author: Michael Goldish +// Based on sample code by Microsoft. + +// Note: this program has only been tested with DTM version 1.5. +// It might fail to work with other versions, specifically because it uses +// a few undocumented methods/attributes. + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Microsoft.DistributedAutomation.DeviceSelection; +using Microsoft.DistributedAutomation.SqlDataStore; + +namespace automate0 +{ + class AutoJob + { + static int Main(string[] args) + { + if (args.Length != 5) + { + Console.WriteLine("Error: incorrect number of command line arguments"); + Console.WriteLine("Usage: {0} serverName clientName machinePoolName submissionName timeout", + System.Environment.GetCommandLineArgs()[0]); + return 1; + } + string serverName = args[0]; + string clientName = args[1]; + string machinePoolName = args[2]; + string submissionName = args[3]; + double timeout = Convert.ToDouble(args[4]); + + try + { + // Initialize DeviceScript and connect to data store + Console.WriteLine("Initializing DeviceScript object"); + DeviceScript script = new DeviceScript(); + Console.WriteLine("Connecting to data store"); + + script.ConnectToNamedDataStore(serverName); + + // Find client machine + IResourcePool rootPool = script.GetResourcePoolByName("$"); + Console.WriteLine("Looking for client machine '{0}'", clientName); + IResource machine = null; + while (true) + { + try + { + machine = rootPool.GetResourceByName(clientName); + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + } + // Make sure the machine is valid + if (machine != null && + machine.OperatingSystem != null && + machine.OperatingSystem.Length > 0 && + machine.ProcessorArchitecture != null && + machine.ProcessorArchitecture.Length > 0 && + machine.GetDevices().Length > 0) + break; + System.Threading.Thread.Sleep(1000); + } + Console.WriteLine("Client machine '{0}' found ({1}, {2})", + clientName, machine.OperatingSystem, machine.ProcessorArchitecture); + + // Create machine pool and add client machine to it + // (this must be done because jobs cannot be scheduled for machines in the + // default pool) + try + { + script.CreateResourcePool(machinePoolName, rootPool.ResourcePoolId); + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + } + IResourcePool newPool = script.GetResourcePoolByName(machinePoolName); + Console.WriteLine("Moving the client machine to pool '{0}'", machinePoolName); + machine.ChangeResourcePool(newPool); + + // Reset client machine + if (machine.Status != "Ready") + { + Console.WriteLine("Changing the client machine's status to 'Reset'"); + while (true) + { + try + { + machine.ChangeResourceStatus("Reset"); + break; + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + } + System.Threading.Thread.Sleep(5000); + } + Console.WriteLine("Waiting for client machine to be ready"); + while (machine.Status != "Ready") + { + try + { + machine = rootPool.GetResourceByName(clientName); + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + } + System.Threading.Thread.Sleep(1000); + } + } + Console.WriteLine("Client machine is ready"); + + // Get requested device regex and look for a matching device + Console.WriteLine("Device to test: "); + Regex deviceRegex = new Regex(Console.ReadLine(), RegexOptions.IgnoreCase); + Console.WriteLine("Looking for device '{0}'", deviceRegex); + IDevice device = null; + foreach (IDevice d in machine.GetDevices()) + { + if (deviceRegex.IsMatch(d.FriendlyName)) + { + device = d; + Console.WriteLine("Found device '{0}'", d.FriendlyName); + break; + } + } + if (device == null) + { + Console.WriteLine("Error: device '{0}' not found", deviceRegex); + return 1; + } + + // Create submission + Object[] existingSubmissions = script.GetSubmissionByName(submissionName); + if (existingSubmissions.Length > 0) + { + Console.WriteLine("Submission '{0}' already exists -- removing it", + submissionName); + script.DeleteSubmission(((ISubmission)existingSubmissions[0]).Id); + } + Console.WriteLine("Creating submission '{0}'", submissionName); + ISubmission submission = script.CreateHardwareSubmission(submissionName, + newPool.ResourcePoolId, device.InstanceId); + + // Get DeviceData objects from the user + List deviceDataList = new List(); + while (true) + { + ISubmissionDeviceData dd = script.CreateNewSubmissionDeviceData(); + Console.WriteLine("DeviceData name: "); + dd.Name = Console.ReadLine(); + if (dd.Name.Length == 0) + break; + Console.WriteLine("DeviceData data: "); + dd.Data = Console.ReadLine(); + deviceDataList.Add(dd); + } + + // Set the submission's DeviceData + submission.SetDeviceData(deviceDataList.ToArray()); + + // Get descriptors from the user + List descriptorList = new List(); + while (true) + { + Console.WriteLine("Descriptor path: "); + string descriptorPath = Console.ReadLine(); + if (descriptorPath.Length == 0) + break; + descriptorList.Add(script.GetDescriptorByPath(descriptorPath)); + } + + // Set the submission's descriptors + submission.SetLogoDescriptors(descriptorList.ToArray()); + + // Create a schedule + ISchedule schedule = script.CreateNewSchedule(); + Console.WriteLine("Scheduling jobs:"); + foreach (IJob j in submission.GetJobs()) + { + Console.WriteLine(" " + j.Name); + schedule.AddDeviceJob(device, j); + } + schedule.AddSubmission(submission); + schedule.SetResourcePool(newPool); + script.RunSchedule(schedule); + + // Wait for jobs to complete + Console.WriteLine("Waiting for all jobs to complete (timeout={0})", timeout); + DateTime endTime = DateTime.Now.AddSeconds(timeout); + int numCompleted = 0, numFailed = 0; + while (numCompleted < submission.GetResults().Length && DateTime.Now < endTime) + { + // Sleep for 30 seconds + System.Threading.Thread.Sleep(30000); + // Count completed submission jobs + numCompleted = 0; + foreach (IResult r in submission.GetResults()) + if (r.ResultStatus != "InProgress") + numCompleted++; + // Report results in a Python readable format and count failed schedule jobs + // (submission jobs are a subset of schedule jobs) + Console.WriteLine(); + Console.WriteLine("---- ["); + numFailed = 0; + foreach (IResult r in schedule.GetResults()) + { + Console.WriteLine(" {"); + Console.WriteLine(" 'job': r'''{0}''',", r.Job.Name); + Console.WriteLine(" 'logs': r'''{0}''',", r.LogLocation); + if (r.ResultStatus != "InProgress") + Console.WriteLine(" 'report': r'''{0}''',", + submission.GetSubmissionResultReport(r)); + Console.WriteLine(" 'status': '{0}',", r.ResultStatus); + Console.WriteLine(" 'pass': {0}, 'fail': {1}, 'notrun': {2}, 'notapplicable': {3}", + r.Pass, r.Fail, r.NotRun, r.NotApplicable); + Console.WriteLine(" },"); + numFailed += r.Fail; + } + Console.WriteLine("] ----"); + } + Console.WriteLine(); + + // Cancel incomplete jobs + foreach (IResult r in schedule.GetResults()) + if (r.ResultStatus == "InProgress") + r.Cancel(); + + // Report failures + if (numCompleted < submission.GetResults().Length) + Console.WriteLine("Some jobs did not complete on time."); + if (numFailed > 0) + Console.WriteLine("Some jobs failed."); + + if (numFailed > 0 || numCompleted < submission.GetResults().Length) + return 1; + + Console.WriteLine("All jobs completed."); + + return 0; + } + catch (Exception e) + { + Console.WriteLine("Error: " + e.Message); + return 1; + } + } + } +} diff --git a/client/tests/kvm/deps/whql_submission_15.exe b/client/tests/kvm/deps/whql_submission_15.exe new file mode 100644 index 0000000000000000000000000000000000000000..1e513a1783db619fbc8b17f9245783087f235232 GIT binary patch literal 10240 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²#|-;Ek8`?tHKq$$ehD)%PFC4819(wM@Fz+QFW&6kB3^Cq*+Oj3xYB>z zr?cm*Kkz+xxw`c@dz3%kOA5a%@dwdbuNwZaZ|oDtU;=*g3p#&ImSLIxKgvOr-u>E3 z2M#S&$~um`_zdM>?^tfMS2wFgn@@WV_MV(SGQ77}=W~vdQMRk*!QN%l={Nse#&g1m)RP$(1rRyuo z@+GV@I0;&15q^w-RaG2{9qgT5_P@y0d7DwI^^SNNTv>PAeD%D2oA&JLRdN{HF^hE^ z4=(#SC=v%!u+uD^kk%!fN-mntZED>eXw`8w^k69}*4g42^O9NC%iJF9HJp6)lKnAL z_Ud(OqR2;a2Yb&OWykcLQc6Z{VohNB$ST_pjI0C!3