| OLD | NEW |
| (Empty) |
| 1 // DTM submission automation program | |
| 2 // Author: Michael Goldish <mgoldish@redhat.com> | |
| 3 // Based on sample code by Microsoft. | |
| 4 | |
| 5 // Note: this program has only been tested with DTM version 1.5. | |
| 6 // It might fail to work with other versions, specifically because it uses | |
| 7 // a few undocumented methods/attributes. | |
| 8 | |
| 9 using System; | |
| 10 using System.Collections.Generic; | |
| 11 using System.Text.RegularExpressions; | |
| 12 using Microsoft.DistributedAutomation.DeviceSelection; | |
| 13 using Microsoft.DistributedAutomation.SqlDataStore; | |
| 14 | |
| 15 namespace automate0 | |
| 16 { | |
| 17 class AutoJob | |
| 18 { | |
| 19 static int Main(string[] args) | |
| 20 { | |
| 21 if (args.Length != 5) | |
| 22 { | |
| 23 Console.WriteLine("Error: incorrect number of command line argum
ents"); | |
| 24 Console.WriteLine("Usage: {0} serverName clientName machinePoolN
ame submissionName timeout", | |
| 25 System.Environment.GetCommandLineArgs()[0]); | |
| 26 return 1; | |
| 27 } | |
| 28 string serverName = args[0]; | |
| 29 string clientName = args[1]; | |
| 30 string machinePoolName = args[2]; | |
| 31 string submissionName = args[3]; | |
| 32 double timeout = Convert.ToDouble(args[4]); | |
| 33 | |
| 34 try | |
| 35 { | |
| 36 // Initialize DeviceScript and connect to data store | |
| 37 Console.WriteLine("Initializing DeviceScript object"); | |
| 38 DeviceScript script = new DeviceScript(); | |
| 39 Console.WriteLine("Connecting to data store"); | |
| 40 | |
| 41 script.ConnectToNamedDataStore(serverName); | |
| 42 | |
| 43 // Find client machine | |
| 44 IResourcePool rootPool = script.GetResourcePoolByName("$"); | |
| 45 Console.WriteLine("Looking for client machine '{0}'", clientName
); | |
| 46 IResource machine = null; | |
| 47 while (true) | |
| 48 { | |
| 49 try | |
| 50 { | |
| 51 machine = rootPool.GetResourceByName(clientName); | |
| 52 } | |
| 53 catch (Exception e) | |
| 54 { | |
| 55 Console.WriteLine("Warning: " + e.Message); | |
| 56 } | |
| 57 // Make sure the machine is valid | |
| 58 if (machine != null && | |
| 59 machine.OperatingSystem != null && | |
| 60 machine.OperatingSystem.Length > 0 && | |
| 61 machine.ProcessorArchitecture != null && | |
| 62 machine.ProcessorArchitecture.Length > 0 && | |
| 63 machine.GetDevices().Length > 0) | |
| 64 break; | |
| 65 System.Threading.Thread.Sleep(1000); | |
| 66 } | |
| 67 Console.WriteLine("Client machine '{0}' found ({1}, {2})", | |
| 68 clientName, machine.OperatingSystem, machine.ProcessorArchit
ecture); | |
| 69 | |
| 70 // Create machine pool and add client machine to it | |
| 71 // (this must be done because jobs cannot be scheduled for machi
nes in the | |
| 72 // default pool) | |
| 73 try | |
| 74 { | |
| 75 script.CreateResourcePool(machinePoolName, rootPool.Resource
PoolId); | |
| 76 } | |
| 77 catch (Exception e) | |
| 78 { | |
| 79 Console.WriteLine("Warning: " + e.Message); | |
| 80 } | |
| 81 IResourcePool newPool = script.GetResourcePoolByName(machinePool
Name); | |
| 82 Console.WriteLine("Moving the client machine to pool '{0}'", mac
hinePoolName); | |
| 83 machine.ChangeResourcePool(newPool); | |
| 84 | |
| 85 // Reset client machine | |
| 86 if (machine.Status != "Ready") | |
| 87 { | |
| 88 Console.WriteLine("Changing the client machine's status to '
Reset'"); | |
| 89 while (true) | |
| 90 { | |
| 91 try | |
| 92 { | |
| 93 machine = rootPool.GetResourceByName(clientName); | |
| 94 machine.ChangeResourceStatus("Unsafe"); | |
| 95 System.Threading.Thread.Sleep(5000); | |
| 96 machine.ChangeResourceStatus("Reset"); | |
| 97 break; | |
| 98 } | |
| 99 catch (Exception e) | |
| 100 { | |
| 101 Console.WriteLine("Warning: " + e.Message); | |
| 102 } | |
| 103 System.Threading.Thread.Sleep(5000); | |
| 104 } | |
| 105 Console.WriteLine("Waiting for client machine to be ready"); | |
| 106 while (machine.Status != "Ready") | |
| 107 { | |
| 108 try | |
| 109 { | |
| 110 machine = rootPool.GetResourceByName(clientName); | |
| 111 } | |
| 112 catch (Exception e) | |
| 113 { | |
| 114 Console.WriteLine("Warning: " + e.Message); | |
| 115 } | |
| 116 System.Threading.Thread.Sleep(1000); | |
| 117 } | |
| 118 } | |
| 119 Console.WriteLine("Client machine is ready"); | |
| 120 | |
| 121 // Get requested device regex and look for a matching device | |
| 122 Console.WriteLine("Device to test: "); | |
| 123 Regex deviceRegex = new Regex(Console.ReadLine(), RegexOptions.I
gnoreCase); | |
| 124 Console.WriteLine("Looking for device '{0}'", deviceRegex); | |
| 125 IDevice device; | |
| 126 DateTime endTime = DateTime.Now.AddSeconds(120); | |
| 127 while (DateTime.Now < endTime) | |
| 128 { | |
| 129 machine = rootPool.GetResourceByName(clientName); | |
| 130 Console.WriteLine("(Client machine has {0} devices)", machin
e.GetDevices().Length); | |
| 131 foreach (IDevice d in machine.GetDevices()) | |
| 132 { | |
| 133 if (deviceRegex.IsMatch(d.FriendlyName)) | |
| 134 { | |
| 135 device = d; | |
| 136 goto deviceFound; | |
| 137 } | |
| 138 } | |
| 139 System.Threading.Thread.Sleep(5000); | |
| 140 } | |
| 141 Console.WriteLine("Error: device '{0}' not found", deviceRegex); | |
| 142 return 1; | |
| 143 | |
| 144 deviceFound: | |
| 145 Console.WriteLine("Found device '{0}'", device.FriendlyName); | |
| 146 | |
| 147 // Get requested jobs regex | |
| 148 Console.WriteLine("Jobs to run: "); | |
| 149 Regex jobRegex = new Regex(Console.ReadLine(), RegexOptions.Igno
reCase); | |
| 150 | |
| 151 // Create submission | |
| 152 Object[] existingSubmissions = script.GetSubmissionByName(submis
sionName); | |
| 153 if (existingSubmissions.Length > 0) | |
| 154 { | |
| 155 Console.WriteLine("Submission '{0}' already exists -- removi
ng it", | |
| 156 submissionName); | |
| 157 script.DeleteSubmission(((ISubmission)existingSubmissions[0]
).Id); | |
| 158 } | |
| 159 Console.WriteLine("Creating submission '{0}'", submissionName); | |
| 160 ISubmission submission = script.CreateHardwareSubmission(submiss
ionName, | |
| 161 newPool.ResourcePoolId, device.InstanceId); | |
| 162 | |
| 163 // Get DeviceData objects from the user | |
| 164 List<Object> deviceDataList = new List<Object>(); | |
| 165 while (true) | |
| 166 { | |
| 167 ISubmissionDeviceData dd = script.CreateNewSubmissionDeviceD
ata(); | |
| 168 Console.WriteLine("DeviceData name: "); | |
| 169 dd.Name = Console.ReadLine(); | |
| 170 if (dd.Name.Length == 0) | |
| 171 break; | |
| 172 Console.WriteLine("DeviceData data: "); | |
| 173 dd.Data = Console.ReadLine(); | |
| 174 deviceDataList.Add(dd); | |
| 175 } | |
| 176 | |
| 177 // Set the submission's DeviceData | |
| 178 submission.SetDeviceData(deviceDataList.ToArray()); | |
| 179 | |
| 180 // Get descriptors from the user | |
| 181 List<Object> descriptorList = new List<Object>(); | |
| 182 while (true) | |
| 183 { | |
| 184 Console.WriteLine("Descriptor path: "); | |
| 185 string descriptorPath = Console.ReadLine(); | |
| 186 if (descriptorPath.Length == 0) | |
| 187 break; | |
| 188 descriptorList.Add(script.GetDescriptorByPath(descriptorPath
)); | |
| 189 } | |
| 190 | |
| 191 // Set the submission's descriptors | |
| 192 submission.SetLogoDescriptors(descriptorList.ToArray()); | |
| 193 | |
| 194 // Create a schedule | |
| 195 ISchedule schedule = script.CreateNewSchedule(); | |
| 196 Console.WriteLine("Scheduling jobs:"); | |
| 197 int jobCount = 0; | |
| 198 foreach (IJob j in submission.GetJobs()) | |
| 199 { | |
| 200 if (jobRegex.IsMatch(j.Name)) | |
| 201 { | |
| 202 Console.WriteLine(" " + j.Name); | |
| 203 schedule.AddDeviceJob(device, j); | |
| 204 jobCount++; | |
| 205 } | |
| 206 } | |
| 207 if (jobCount == 0) | |
| 208 { | |
| 209 Console.WriteLine("Error: no submission jobs match pattern '
{0}'", jobRegex); | |
| 210 return 1; | |
| 211 } | |
| 212 schedule.AddSubmission(submission); | |
| 213 schedule.SetResourcePool(newPool); | |
| 214 script.RunSchedule(schedule); | |
| 215 | |
| 216 // Wait for jobs to complete | |
| 217 Console.WriteLine("Waiting for all jobs to complete (timeout={0}
)", timeout); | |
| 218 endTime = DateTime.Now.AddSeconds(timeout); | |
| 219 int numCompleted = 0, numFailed = 0; | |
| 220 while (numCompleted < submission.GetResults().Length && DateTime
.Now < endTime) | |
| 221 { | |
| 222 // Sleep for 30 seconds | |
| 223 System.Threading.Thread.Sleep(30000); | |
| 224 // Count completed submission jobs | |
| 225 numCompleted = 0; | |
| 226 foreach (IResult r in submission.GetResults()) | |
| 227 if (r.ResultStatus != "InProgress") | |
| 228 numCompleted++; | |
| 229 // Report results in a Python readable format and count fail
ed schedule jobs | |
| 230 // (submission jobs are a subset of schedule jobs) | |
| 231 Console.WriteLine(); | |
| 232 Console.WriteLine("---- ["); | |
| 233 numFailed = 0; | |
| 234 foreach (IResult r in schedule.GetResults()) | |
| 235 { | |
| 236 Console.WriteLine(" {"); | |
| 237 Console.WriteLine(" 'id': {0}, 'job': r'''{1}''',", r
.Job.Id, r.Job.Name); | |
| 238 Console.WriteLine(" 'logs': r'''{0}''',", r.LogLocati
on); | |
| 239 if (r.ResultStatus != "InProgress") | |
| 240 Console.WriteLine(" 'report': r'''{0}''',", | |
| 241 submission.GetSubmissionResultReport(r)); | |
| 242 Console.WriteLine(" 'status': '{0}',", r.ResultStatus
); | |
| 243 Console.WriteLine(" 'pass': {0}, 'fail': {1}, 'notrun
': {2}, 'notapplicable': {3}", | |
| 244 r.Pass, r.Fail, r.NotRun, r.NotApplicable); | |
| 245 Console.WriteLine(" },"); | |
| 246 numFailed += r.Fail; | |
| 247 } | |
| 248 Console.WriteLine("] ----"); | |
| 249 } | |
| 250 Console.WriteLine(); | |
| 251 | |
| 252 // Cancel incomplete jobs | |
| 253 foreach (IResult r in schedule.GetResults()) | |
| 254 if (r.ResultStatus == "InProgress") | |
| 255 r.Cancel(); | |
| 256 | |
| 257 // Set the machine's status to Unsafe and then Reset | |
| 258 try | |
| 259 { | |
| 260 machine = rootPool.GetResourceByName(clientName); | |
| 261 machine.ChangeResourceStatus("Unsafe"); | |
| 262 System.Threading.Thread.Sleep(5000); | |
| 263 machine.ChangeResourceStatus("Reset"); | |
| 264 } | |
| 265 catch (Exception e) | |
| 266 { | |
| 267 Console.WriteLine("Warning: " + e.Message); | |
| 268 } | |
| 269 | |
| 270 // Report failures | |
| 271 if (numCompleted < submission.GetResults().Length) | |
| 272 Console.WriteLine("Some jobs did not complete on time."); | |
| 273 if (numFailed > 0) | |
| 274 Console.WriteLine("Some jobs failed."); | |
| 275 | |
| 276 if (numFailed > 0 || numCompleted < submission.GetResults().Leng
th) | |
| 277 return 1; | |
| 278 | |
| 279 Console.WriteLine("All jobs completed."); | |
| 280 return 0; | |
| 281 } | |
| 282 catch (Exception e) | |
| 283 { | |
| 284 Console.WriteLine("Error: " + e.Message); | |
| 285 return 1; | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 } | |
| OLD | NEW |