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 |