From patchwork Mon Dec 27 16:01:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Goldish X-Patchwork-Id: 434591 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBRKCV9i025997 for ; Mon, 27 Dec 2010 20:16:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754404Ab0L0QCg (ORCPT ); Mon, 27 Dec 2010 11:02:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42459 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754395Ab0L0QCe (ORCPT ); Mon, 27 Dec 2010 11:02:34 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oBRG2XMl029933 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 27 Dec 2010 11:02:33 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oBRG2W81003668; Mon, 27 Dec 2010 11:02:32 -0500 Received: from moof.tlv.redhat.com (dhcp-1-185.tlv.redhat.com [10.35.1.185]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id oBRG1rG9017175; Mon, 27 Dec 2010 11:02:31 -0500 From: Michael Goldish To: autotest@test.kernel.org, kvm@vger.kernel.org Cc: Michael Goldish Subject: [KVM-AUTOTEST PATCH 21/28] KVM test: refactor whql_submission_15.cs and whql_submission.py Date: Mon, 27 Dec 2010 18:01:48 +0200 Message-Id: <1293465715-16599-21-git-send-email-mgoldish@redhat.com> In-Reply-To: <1293465715-16599-1-git-send-email-mgoldish@redhat.com> References: <1293465715-16599-1-git-send-email-mgoldish@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 27 Dec 2010 20:16:57 +0000 (UTC) diff --git a/client/tests/kvm/deps/whql_submission_15.cs b/client/tests/kvm/deps/whql_submission_15.cs index 8fa6856..0928548 100644 --- a/client/tests/kvm/deps/whql_submission_15.cs +++ b/client/tests/kvm/deps/whql_submission_15.cs @@ -1,289 +1,373 @@ -// 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 = rootPool.GetResourceByName(clientName); - machine.ChangeResourceStatus("Unsafe"); - System.Threading.Thread.Sleep(5000); - 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; - DateTime endTime = DateTime.Now.AddSeconds(120); - while (DateTime.Now < endTime) - { - machine = rootPool.GetResourceByName(clientName); - Console.WriteLine("(Client machine has {0} devices)", machine.GetDevices().Length); - foreach (IDevice d in machine.GetDevices()) - { - if (deviceRegex.IsMatch(d.FriendlyName)) - { - device = d; - goto deviceFound; - } - } - System.Threading.Thread.Sleep(5000); - } - Console.WriteLine("Error: device '{0}' not found", deviceRegex); - return 1; - - deviceFound: - Console.WriteLine("Found device '{0}'", device.FriendlyName); - - // Get requested jobs regex - Console.WriteLine("Jobs to run: "); - Regex jobRegex = new Regex(Console.ReadLine(), RegexOptions.IgnoreCase); - - // 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:"); - int jobCount = 0; - foreach (IJob j in submission.GetJobs()) - { - if (jobRegex.IsMatch(j.Name)) - { - Console.WriteLine(" " + j.Name); - schedule.AddDeviceJob(device, j); - jobCount++; - } - } - if (jobCount == 0) - { - Console.WriteLine("Error: no submission jobs match pattern '{0}'", jobRegex); - return 1; - } - 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); - 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(" 'id': {0}, 'job': r'''{1}''',", r.Job.Id, 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(); - - // Set the machine's status to Unsafe and then Reset - try - { - machine = rootPool.GetResourceByName(clientName); - machine.ChangeResourceStatus("Unsafe"); - System.Threading.Thread.Sleep(5000); - machine.ChangeResourceStatus("Reset"); - } - catch (Exception e) - { - Console.WriteLine("Warning: " + e.Message); - } - - // 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; - } - } - } -} +// 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 + { + // Wait for a machine to show up in the data store + static void FindMachine(IResourcePool rootPool, string machineName) + { + Console.WriteLine("Looking for machine '{0}'", machineName); + IResource machine = null; + while (true) + { + try + { + machine = rootPool.GetResourceByName(machineName); + } + 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})", + machineName, machine.OperatingSystem, machine.ProcessorArchitecture); + } + + // Delete a machine pool if it exists + static void DeleteResourcePool(IDeviceScript script, string poolName) + { + while (true) + { + try + { + IResourcePool pool = script.GetResourcePoolByName(poolName); + if (pool != null) + script.DeleteResourcePool(pool); + break; + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + System.Threading.Thread.Sleep(1000); + } + } + } + + // Set the machine's status to 'Reset' and optionally wait for it to become ready + static void ResetMachine(IResourcePool rootPool, string machineName, bool wait) + { + Console.WriteLine("Resetting machine '{0}'", machineName); + IResource machine; + while (true) + { + try + { + machine = rootPool.GetResourceByName(machineName); + machine.ChangeResourceStatus("Reset"); + break; + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + System.Threading.Thread.Sleep(5000); + } + } + if (wait) + { + Console.WriteLine("Waiting for machine '{0}' to be ready", machineName); + while (machine.Status != "Ready") + { + try + { + machine = rootPool.GetResourceByName(machineName); + } + catch (Exception e) + { + Console.WriteLine("Warning: " + e.Message); + } + System.Threading.Thread.Sleep(1000); + } + Console.WriteLine("Machine '{0}' is ready", machineName); + } + } + + // Look for a device in a machine, and if not found, keep trying for 3 minutes + static IDevice GetDevice(IResourcePool rootPool, string machineName, string regexStr) + { + Regex deviceRegex = new Regex(regexStr, RegexOptions.IgnoreCase); + int numAttempts = 1; + DateTime endTime = DateTime.Now.AddSeconds(180); + while (DateTime.Now < endTime) + { + IResource machine = rootPool.GetResourceByName(machineName); + Console.WriteLine("Looking for device '{0}' in machine '{1}' (machine has {2} devices)", + regexStr, machineName, machine.GetDevices().Length); + foreach (IDevice d in machine.GetDevices()) + { + if (deviceRegex.IsMatch(d.FriendlyName)) + { + Console.WriteLine("Found device '{0}'", d.FriendlyName); + return d; + } + } + Console.WriteLine("Device not found"); + if (numAttempts % 5 == 0) + ResetMachine(rootPool, machineName, true); + else + System.Threading.Thread.Sleep(5000); + numAttempts++; + } + Console.WriteLine("Error: device '{0}' not found", deviceRegex); + return null; + } + + static int Main(string[] args) + { + if (args.Length < 5) + { + Console.WriteLine("Error: incorrect number of command line arguments"); + Console.WriteLine("Usage: {0} serverName machinePoolName submissionName timeout machineName0 machineName1 ...", + System.Environment.GetCommandLineArgs()[0]); + return 1; + } + string serverName = args[0]; + string machinePoolName = args[1]; + string submissionName = args[2]; + double timeout = Convert.ToDouble(args[3]); + + List machines = new List(); + for (int i = 4; i < args.Length; i++) + machines.Add(args[i]); + + 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); + + // Wait for client machines to become available + IResourcePool rootPool = script.GetResourcePoolByName("$"); + foreach (string machineName in machines) + FindMachine(rootPool, machineName); + + // Delete the machine pool if it already exists + DeleteResourcePool(script, machinePoolName); + + // Create the machine pool and add the client machines 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); + foreach (string machineName in machines) + { + Console.WriteLine("Moving machine '{0}' to pool '{1}'", machineName, machinePoolName); + rootPool.GetResourceByName(machineName).ChangeResourcePool(newPool); + } + + // Reset client machine + foreach (string machineName in machines) + ResetMachine(rootPool, machineName, true); + + // Get requested device regex and look for a matching device in the first machine + Console.WriteLine("Device to test:"); + IDevice device = GetDevice(rootPool, machines[0], Console.ReadLine()); + if (device == null) + return 1; + + // Get requested jobs regex + Console.WriteLine("Jobs to run:"); + Regex jobRegex = new Regex(Console.ReadLine(), RegexOptions.IgnoreCase); + + // Create a 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); + } + string hardwareId = device.InstanceId.Remove(device.InstanceId.LastIndexOf("\\")); + Console.WriteLine("Creating submission '{0}' (hardware ID: {1})", submissionName, hardwareId); + ISubmission submission = script.CreateHardwareSubmission(submissionName, newPool.ResourcePoolId, hardwareId); + + // Set submission DeviceData + 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); + } + submission.SetDeviceData(deviceDataList.ToArray()); + + // Set submission descriptors + List descriptorList = new List(); + while (true) + { + Console.WriteLine("Descriptor path:"); + string descriptorPath = Console.ReadLine(); + if (descriptorPath.Length == 0) + break; + descriptorList.Add(script.GetDescriptorByPath(descriptorPath)); + } + submission.SetLogoDescriptors(descriptorList.ToArray()); + + // Set machine dimensions + foreach (string machineName in machines) + { + IResource machine = rootPool.GetResourceByName(machineName); + while (true) + { + Console.WriteLine("Dimension name ({0}):", machineName); + string dimName = Console.ReadLine(); + if (dimName.Length == 0) + break; + Console.WriteLine("Dimension value ({0}):", machineName); + machine.SetDimension(dimName, Console.ReadLine()); + } + // Set the WDKSubmissionId dimension for all machines + machine.SetDimension("WDKSubmissionId", submission.Id.ToString() + "_" + submission.Name); + } + + // Get job parameters + List paramNames = new List(); + List paramValues = new List(); + foreach (string machineName in machines) + { + while (true) + { + Console.WriteLine("Parameter name ({0}):", machineName); + string paramName = Console.ReadLine(); + if (paramName.Length == 0) + break; + Console.WriteLine("Device regex ({0}):", machineName); + IDevice d = GetDevice(rootPool, machineName, Console.ReadLine()); + if (d == null) + return 1; + string deviceName = d.GetAttribute("name")[0].ToString(); + Console.WriteLine("Setting parameter value to '{0}'", deviceName); + paramNames.Add(paramName); + paramValues.Add(deviceName); + } + } + + // Find jobs that match the requested pattern + Console.WriteLine("Scheduling jobs:"); + List jobs = new List(); + foreach (IJob j in submission.GetJobs()) + { + if (jobRegex.IsMatch(j.Name)) + { + Console.WriteLine(" " + j.Name); + // Set job parameters + for (int i = 0; i < paramNames.Count; i++) + { + IParameter p = j.GetParameterByName(paramNames[i]); + if (p != null) + p.ScheduleValue = paramValues[i]; + } + jobs.Add(j); + } + } + if (jobs.Count == 0) + { + Console.WriteLine("Error: no submission jobs match pattern '{0}'", jobRegex); + return 1; + } + + // Create a schedule, add jobs to it and run it + ISchedule schedule = script.CreateNewSchedule(); + foreach (IScheduleItem item in submission.ProcessJobs(jobs.ToArray())) + { + item.Device = device; + schedule.AddScheduleItem(item); + } + schedule.AddSubmission(submission); + schedule.SetResourcePool(newPool); + script.RunSchedule(schedule); + + // Wait for jobs to complete + Console.WriteLine("Waiting for all jobs to complete (timeout={0}s)", timeout); + DateTime endTime = DateTime.Now.AddSeconds(timeout); + int numCompleted, numFailed; + do + { + System.Threading.Thread.Sleep(30000); + // Report results in a Python readable format and count completed and failed schedule jobs + numCompleted = numFailed = 0; + Console.WriteLine(); + Console.WriteLine("---- ["); + foreach (IResult r in schedule.GetResults()) + { + if (r.ResultStatus != "InProgress") numCompleted++; + if (r.ResultStatus == "Investigate") numFailed++; + Console.WriteLine(" {"); + Console.WriteLine(" 'id': {0}, 'job': r'''{1}''',", r.Job.Id, 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(" },"); + } + Console.WriteLine("] ----"); + } while (numCompleted < schedule.GetResults().Length && DateTime.Now < endTime); + + Console.WriteLine(); + + // Cancel incomplete jobs + foreach (IResult r in schedule.GetResults()) + if (r.ResultStatus == "InProgress") + r.Cancel(); + + // Reset the machines + foreach (string machineName in machines) + ResetMachine(rootPool, machineName, false); + + // Report failures + if (numCompleted < schedule.GetResults().Length) + Console.WriteLine("Some jobs did not complete on time."); + if (numFailed > 0) + Console.WriteLine("Some jobs failed."); + if (numFailed > 0 || numCompleted < schedule.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 index 4f30aa801c8f200bd96b0de6c10d2b59c2bad268..605e2e3aa1f0761155f4aac5191e3ad0f0ddecc6 100644 GIT binary patch literal 12288 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 delta 4268 zcmai2eQX@X6@Rn0_u;jD@$A~`v+vGXf1iDK_8AP#C$STo;3&pPtUyu{$YCE~YP@9c z;wFXmQV1bb!A&}-0!K}uYN=2uF(fUhEvQs23Tj$4sA~C80%`@NfIun&(V#Z{&E8$? zgg?5MdGp?H-h1=r&70YE_U_ob;n0C~_kXf>Jr$p~NMYqHK-2&LoqV2J0b-%`p-Ez) zQ;1Y_@+tMS_wXxS!EMkUk#HZ;tLouKqhbe91>`4}6GcR$k`P;2yLKW1$UD<} zuBd~tJ7Wk=b25_if-`4hm_@7YRLogTshurXLbDZ0-E5^&KO2L!W~k1mC9^EnuNhuv z2`l>HUY}hCjC-Bif!UfI_c>GG{qUP7t=jN&pWiN*1OBu1M!=cFAP?9`fEKHiL&Y*@2;02;9=2 zBKyvy6y=KKs`G_qbH8&6uw4h(I)E_TFoC{aLeI7t<%KZHzYxZ}Mf^$Uos#=_>Y}t( z6s#*Qw$3B3^LhC~#L4HKUQaPxXS~G4>JesbHVkT1I{N|hN_Xio6sTr2>&?wrD4rYp zVo`}Kir+pTi}Rc`DDF#s;vhDJ6%*&~mC<4vt??Ld;jObdS+YhIujExWPM2mc21)pM zl@UC`(JaaHHUhVit6h2b^>B@zoklXYNPpohwy@5QIzApF6j+ z4T!rd3m3<^x6E#oE6}-)8tSo}-Owv5gzM$HIh#YJFuO^{hDB@6Ulxp)p%7#tVWt+T z&8P)HOq{8&Uw9kne^svQM>an%!<(bA?6_-1bDfepbooNm*?&1+Ic%~ z!zLc%b;)YysI=s6j^&2o2oUTHyH{F;kkcz9yGxqRK5)Fj&f|jD zY+Tlwdk%oOfJ|g;C5Usfpm&u7794_sKg znW|i<>P6L_O*l7|6ikRwqtUq^0B^i_mb@mFi8tXm_dkSk!E-m7eEA^ZE9|!f(Z-D#gRhKSTI+Y;(Re28d45*LZQ{<@6BW)`@(smfsM<+awcr^N@M55H9 z%7N=$dKajVo>is6%izV8i(2xlATS!o4NbH^G=QZRRy;_ z(@t8gY;oOfhuJmC2wdEtWH3CXOoDzBsuOfjalp?iz0f?S?4~`K@@{&7K347p{aiUf zk5IK|5O}L+21wE);Ag4l2t7tyJ<{h6Pd#*YLT8BfdLBbD$R*{6=(Oh;Jxw2ZdO<(K z@YBT9UJPsM3DBVW3%D@VU&Ab=z65^2<YLDc0XnbIX?4(D`>SQiQ`i%v?!~TN^!y!?+~Cq9rgXD5DU0_am|-Fk zkLXvI4W}ojsB0`|i)W0ViI-|p;!S;}h?t?Kp-q{ry~`QPY_RP~TARr&lvnS$HhqW4 zRR2&+n=7kFbLrf!EZKM7G&Ggjxhp+6k=r90YRtfu2}nQJp&y?`Kub@t6! z8UiI46x=}&`$N}>cSC6t0Sp$Wr#0!RvCO1gxHu8cuy2d{NTPgO;JuPk6bVQ z7}-(oxH zd=v0AjiXHIrZvz?yDm$P7utmf+9?YkS;|2xN4s1phj}b`l76yiIq9`>GrVM>bqf%3 z=O~QPusCFen2a+TDwy636${Z{2%}rf)-~u8uJ;9SqnL>{s1{L=c%nX~vi=xJMX@NX z)yTzISVYEM@)-Iob%^QkRU#E`V`1@BG~|Wl_EE92p;5dSUCu5Soeh^MtXb@9u%y#w z@py?j*mSZtdvEu@j=u5yv0qW(*{^N8uCDj32fV}r(I94EUW+kase%SnVl0U7n`qFB zKXro<$dy4k5`>c8;nJiulHJs=|t}U3K%zi&}YG(_rn(-#26ox6DUDH z6!@SEMI%AK<OJ^%xOAmH%m?9XWi+C1bf?$1x?NCD z2lPxJpx@#CU=iSh(MSOQN_{i}A;1dvf;iBcN|yeUKwcn+(N5yq?j&BUn??sl&wTHL z=~s^aWBAB}KYsuB_l-Z~6K}WX^?k)Z+o4QHC2t*WG?hauj(@jpHxqrVN(5tB-bXYb feHNd0S0DdQ%=VVydtJWn=T;o&T_3T-DgXZf6xhmD diff --git a/client/tests/kvm/tests/whql_submission.py b/client/tests/kvm/tests/whql_submission.py index 8dd48b8..a0ff87c 100644 --- a/client/tests/kvm/tests/whql_submission.py +++ b/client/tests/kvm/tests/whql_submission.py @@ -6,20 +6,24 @@ import kvm_subprocess, kvm_test_utils, kvm_utils, rss_file_transfer def run_whql_submission(test, params, env): """ WHQL submission test: - 1) Log into the guest (the client machine) and into a DTM server machine + 1) Log into the client machines and into a DTM server machine 2) Copy the automation program binary (dsso_test_binary) to the server machine 3) Run the automation program 4) Pass the program all relevant parameters (e.g. device_data) 5) Wait for the program to terminate 6) Parse and report job results - (logs and HTML reports are placed in test.bindir) + (logs and HTML reports are placed in test.debugdir) @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ - vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) - session = kvm_test_utils.wait_for_login(vm, 0, 240) + # Log into all client VMs + vms = [] + sessions = [] + for vm_name in kvm_utils.get_sub_dict_names(params, "vms"): + vms.append(kvm_test_utils.get_living_vm(env, vm_name)) + sessions.append(kvm_test_utils.wait_for_login(vms[-1], 0, 240)) # Collect parameters server_address = params.get("server_address") @@ -30,47 +34,54 @@ def run_whql_submission(test, params, env): dsso_test_binary = params.get("dsso_test_binary", "deps/whql_submission_15.exe") dsso_test_binary = kvm_utils.get_path(test.bindir, dsso_test_binary) - test_device = params.get("test_device") - job_filter = params.get("job_filter", ".*") + dsso_delete_machine_binary = params.get("dsso_delete_machine_binary", + "deps/whql_delete_machine_15.exe") + dsso_delete_machine_binary = kvm_utils.get_path(test.bindir, + dsso_delete_machine_binary) test_timeout = float(params.get("test_timeout", 600)) - wtt_services = params.get("wtt_services") - # Restart WTT service(s) on the client - logging.info("Restarting WTT services on client") - for svc in wtt_services.split(): - kvm_test_utils.stop_windows_service(session, svc) - for svc in wtt_services.split(): - kvm_test_utils.start_windows_service(session, svc) - - # Run whql_pre_command - if params.get("whql_pre_command"): - session.cmd(params.get("whql_pre_command"), - int(params.get("whql_pre_command_timeout", 600))) - - # Copy dsso_test_binary to the server - rss_file_transfer.upload(server_address, server_file_transfer_port, - dsso_test_binary, server_studio_path, timeout=60) + # Copy dsso binaries to the server + for filename in dsso_test_binary, dsso_delete_machine_binary: + rss_file_transfer.upload(server_address, server_file_transfer_port, + filename, server_studio_path, timeout=60) # Open a shell session with the server server_session = kvm_utils.remote_login("nc", server_address, server_shell_port, "", "", - session.prompt, session.linesep) - server_session.set_status_test_command(session.status_test_command) + sessions[0].prompt, + sessions[0].linesep) + server_session.set_status_test_command(sessions[0].status_test_command) - # Get the computer names of the server and client + # Get the computer names of the server and clients cmd = "echo %computername%" server_name = server_session.cmd_output(cmd).strip() - client_name = session.cmd_output(cmd).strip() - session.close() + client_names = [session.cmd_output(cmd).strip() for session in sessions] - # Run the automation program on the server + # Delete all client machines from the server's data store server_session.cmd("cd %s" % server_studio_path) + for client_name in client_names: + cmd = "%s %s %s" % (os.path.basename(dsso_delete_machine_binary), + server_name, client_name) + server_session.cmd(cmd, print_func=logging.debug) + + # Reboot the client machines + sessions = kvm_utils.parallel((kvm_test_utils.reboot, (vm, session)) + for vm, session in zip(vms, sessions)) + + # Run whql_pre_command and close the sessions + if params.get("whql_pre_command"): + for session in sessions: + session.cmd(params.get("whql_pre_command"), + int(params.get("whql_pre_command_timeout", 600))) + session.close() + + # Run the automation program on the server cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), server_name, - client_name, - "%s_pool" % client_name, - "%s_submission" % client_name, - test_timeout) + "%s_pool" % client_names[0], + "%s_submission" % client_names[0], + test_timeout, + " ".join(client_names)) server_session.sendline(cmd) # Helper function: wait for a given prompt and raise an exception if an @@ -89,13 +100,13 @@ def run_whql_submission(test, params, env): # Tell the automation program which device to test find_prompt("Device to test:") - server_session.sendline(test_device) + server_session.sendline(params.get("test_device")) # Tell the automation program which jobs to run find_prompt("Jobs to run:") - server_session.sendline(job_filter) + server_session.sendline(params.get("job_filter", ".*")) - # Give the automation program all the device data supplied by the user + # Set submission DeviceData find_prompt("DeviceData name:") for dd in kvm_utils.get_sub_dict_names(params, "device_data"): dd_params = kvm_utils.get_sub_dict(params, dd) @@ -104,8 +115,7 @@ def run_whql_submission(test, params, env): server_session.sendline(dd_params.get("dd_data")) server_session.sendline() - # Give the automation program all the descriptor information supplied by - # the user + # Set submission descriptors find_prompt("Descriptor path:") for desc in kvm_utils.get_sub_dict_names(params, "descriptors"): desc_params = kvm_utils.get_sub_dict(params, desc) @@ -113,6 +123,31 @@ def run_whql_submission(test, params, env): server_session.sendline(desc_params.get("desc_path")) server_session.sendline() + # Set machine dimensions for each client machine + for vm_name in kvm_utils.get_sub_dict_names(params, "vms"): + vm_params = kvm_utils.get_sub_dict(params, vm_name) + find_prompt(r"Dimension name\b.*:") + for dp in kvm_utils.get_sub_dict_names(vm_params, "dimensions"): + dp_params = kvm_utils.get_sub_dict(vm_params, dp) + if dp_params.get("dim_name") and dp_params.get("dim_value"): + server_session.sendline(dp_params.get("dim_name")) + server_session.sendline(dp_params.get("dim_value")) + server_session.sendline() + + # Set extra parameters for tests that require them (e.g. NDISTest) + for vm_name in kvm_utils.get_sub_dict_names(params, "vms"): + vm_params = kvm_utils.get_sub_dict(params, vm_name) + find_prompt(r"Parameter name\b.*:") + for dp in kvm_utils.get_sub_dict_names(vm_params, "device_params"): + dp_params = kvm_utils.get_sub_dict(vm_params, dp) + if dp_params.get("dp_name") and dp_params.get("dp_regex"): + server_session.sendline(dp_params.get("dp_name")) + server_session.sendline(dp_params.get("dp_regex")) + # Make sure the prompt appears again (if the device isn't found + # the automation program will terminate) + find_prompt(r"Parameter name\b.*:") + server_session.sendline() + # Wait for the automation program to terminate try: o = server_session.read_up_to_prompt(print_func=logging.info, @@ -162,38 +197,63 @@ def run_whql_submission(test, params, env): except (KeyError, OSError): pass - # Print result summary - logging.info("") - logging.info("Result summary:") - name_length = max(len(r.get("job", "")) for r in results) - fmt = "%%-6s %%-%ds %%-15s %%-8s %%-8s %%-8s %%-15s" % name_length - logging.info(fmt % ("ID", "Job", "Status", "Pass", "Fail", "NotRun", - "NotApplicable")) - logging.info(fmt % ("--", "---", "------", "----", "----", "------", - "-------------")) - for r in results: - logging.info(fmt % (r.get("id"), r.get("job"), r.get("status"), - r.get("pass"), r.get("fail"), r.get("notrun"), - r.get("notapplicable"))) - logging.info("(see logs and HTML reports in %s)" % test.debugdir) - - # Kill the VM and fail if the automation program did not terminate on time + # Print result summary (both to the regular logs and to a file named + # 'summary' in test.debugdir) + def print_summary_line(f, line): + logging.info(line) + f.write(line + "\n") + if results: + # Make sure all results have the required keys + for r in results: + r["id"] = str(r.get("id")) + r["job"] = str(r.get("job")) + r["status"] = str(r.get("status")) + r["pass"] = int(r.get("pass", 0)) + r["fail"] = int(r.get("fail", 0)) + r["notrun"] = int(r.get("notrun", 0)) + r["notapplicable"] = int(r.get("notapplicable", 0)) + # Sort the results by failures and total test count in descending order + results = [(r["fail"], + r["pass"] + r["fail"] + r["notrun"] + r["notapplicable"], + r) for r in results] + results.sort(reverse=True) + results = [r[-1] for r in results] + # Print results + logging.info("") + logging.info("Result summary:") + name_length = max(len(r["job"]) for r in results) + fmt = "%%-6s %%-%ds %%-15s %%-8s %%-8s %%-8s %%-15s" % name_length + f = open(os.path.join(test.debugdir, "summary"), "w") + print_summary_line(f, fmt % ("ID", "Job", "Status", "Pass", "Fail", + "NotRun", "NotApplicable")) + print_summary_line(f, fmt % ("--", "---", "------", "----", "----", + "------", "-------------")) + for r in results: + print_summary_line(f, fmt % (r["id"], r["job"], r["status"], + r["pass"], r["fail"], r["notrun"], + r["notapplicable"])) + f.close() + logging.info("(see logs and HTML reports in %s)" % test.debugdir) + + # Kill the client VMs and fail if the automation program did not terminate + # on time if not done: - vm.destroy() + kvm_utils.parallel(vm.destroy for vm in vms) raise error.TestFail("The automation program did not terminate " "on time") - # Fail if there are failed or incomplete jobs (kill the VM if there are - # incomplete jobs) - failed_jobs = [r.get("job") for r in results - if r.get("status", "").lower() == "investigate"] - running_jobs = [r.get("job") for r in results - if r.get("status", "").lower() == "inprogress"] + # Fail if there are failed or incomplete jobs (kill the client VMs if there + # are incomplete jobs) + failed_jobs = [r["job"] for r in results + if r["status"].lower() == "investigate"] + running_jobs = [r["job"] for r in results + if r["status"].lower() == "inprogress"] errors = [] if failed_jobs: errors += ["Jobs failed: %s." % failed_jobs] if running_jobs: - vm.destroy() + for vm in vms: + vm.destroy() errors += ["Jobs did not complete on time: %s." % running_jobs] if errors: raise error.TestFail(" ".join(errors)) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index 8d533ba..e81d879 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -347,11 +347,12 @@ variants: server_shell_port = 10022 server_file_transfer_port = 10023 server_studio_path = %programfiles%\Microsoft Driver Test Manager\Studio + dsso_test_binary = deps/whql_submission_15.exe + dsso_delete_machine_binary = deps/whql_delete_machine_15.exe wtt_services = wttsvc variants: - client_install: type = whql_client_install - dsso_delete_machine_binary = deps/whql_delete_machine_15.exe # The username and password are required for accessing the DTM client # installer binary shared by the server server_username = administrator @@ -363,7 +364,7 @@ variants: - submission: client_install type = whql_submission extra_params += " -snapshot" - dsso_test_binary = deps/whql_submission_15.exe + restart_vm = yes test_timeout = 3600 device_data = cat0 cat1 cat2 cat3 logoarch logoos whqlos whqlqual prog desc filter virt descriptors = desc1 desc2 desc3