From patchwork Thu Jul 15 15:57:33 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Goldish X-Patchwork-Id: 112261 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6FFvj1g008921 for ; Thu, 15 Jul 2010 15:57:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933163Ab0GOP5k (ORCPT ); Thu, 15 Jul 2010 11:57:40 -0400 Received: from mx1.redhat.com ([209.132.183.28]:11713 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932992Ab0GOP5i (ORCPT ); Thu, 15 Jul 2010 11:57:38 -0400 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6FFva0I001455 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Jul 2010 11:57:36 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6FFvaEB008387; Thu, 15 Jul 2010 11:57:36 -0400 Received: from localhost.localdomain (dhcp-1-188.tlv.redhat.com [10.35.1.188]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o6FFvUQN021960; Thu, 15 Jul 2010 11:57:34 -0400 From: Michael Goldish To: autotest@test.kernel.org, kvm@vger.kernel.org Cc: 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> In-Reply-To: <1279209458-19590-3-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> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 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 (demeter.kernel.org [140.211.167.41]); Thu, 15 Jul 2010 15:57:46 +0000 (UTC) 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; + } + } + } +}