16f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// DTM submission automation program
26f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// Author: Michael Goldish <mgoldish@redhat.com>
36f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// Based on sample code by Microsoft.
46f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
56f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// Note: this program has only been tested with DTM version 1.5.
66f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// It might fail to work with other versions, specifically because it uses
76f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li// a few undocumented methods/attributes.
86f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
96f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liusing System;
106f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liusing System.Collections.Generic;
116f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liusing System.Text.RegularExpressions;
126f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liusing Microsoft.DistributedAutomation.DeviceSelection;
136f27d4f22a1ba5063968b8c322fa0845f3279adeEric Liusing Microsoft.DistributedAutomation.SqlDataStore;
146f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
156f27d4f22a1ba5063968b8c322fa0845f3279adeEric Linamespace automate0
166f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li{
176f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li    class AutoJob
186f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li    {
19861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        // Wait for a machine to show up in the data store
20861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        static void FindMachine(IResourcePool rootPool, string machineName)
21861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        {
22861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            Console.WriteLine("Looking for machine '{0}'", machineName);
23861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            IResource machine = null;
24861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            while (true)
25861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            {
26861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                try
27861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
28861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine = rootPool.GetResourceByName(machineName);
29861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
30861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                catch (Exception e)
31861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
32861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("Warning: " + e.Message);
33861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
34861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Make sure the machine is valid
35861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (machine != null &&
36861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.OperatingSystem != null &&
37861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.OperatingSystem.Length > 0 &&
38861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.ProcessorArchitecture != null &&
39861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.ProcessorArchitecture.Length > 0 &&
40861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.GetDevices().Length > 0)
41861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    break;
42861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                System.Threading.Thread.Sleep(1000);
43861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            }
44861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            Console.WriteLine("Client machine '{0}' found ({1}, {2})",
45861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                machineName, machine.OperatingSystem, machine.ProcessorArchitecture);
46861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        }
47861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
48861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        // Delete a machine pool if it exists
49861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        static void DeleteResourcePool(IDeviceScript script, string poolName)
50861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        {
51861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            while (true)
52861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            {
53861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                try
54861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
55861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    IResourcePool pool = script.GetResourcePoolByName(poolName);
56861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    if (pool != null)
57861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        script.DeleteResourcePool(pool);
58861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    break;
59861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
60861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                catch (Exception e)
61861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
62861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("Warning: " + e.Message);
63861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    System.Threading.Thread.Sleep(1000);
64861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
65861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            }
66861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        }
67861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
68861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        // Set the machine's status to 'Reset' and optionally wait for it to become ready
69861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        static void ResetMachine(IResourcePool rootPool, string machineName, bool wait)
70861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        {
71861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            Console.WriteLine("Resetting machine '{0}'", machineName);
72861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            IResource machine;
73861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            while (true)
74861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            {
75861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                try
76861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
77861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine = rootPool.GetResourceByName(machineName);
78861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.ChangeResourceStatus("Reset");
79861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    break;
80861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
81861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                catch (Exception e)
82861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
83861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("Warning: " + e.Message);
84861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    System.Threading.Thread.Sleep(5000);
85861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
86861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            }
87861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if (wait)
88861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            {
89861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Waiting for machine '{0}' to be ready", machineName);
90861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                while (machine.Status != "Ready")
91861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
92861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    try
93861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
94861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        machine = rootPool.GetResourceByName(machineName);
95861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    }
96861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    catch (Exception e)
97861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
98861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Warning: " + e.Message);
99861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    }
100861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    System.Threading.Thread.Sleep(1000);
101861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
102861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Machine '{0}' is ready", machineName);
103861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            }
104861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        }
105861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
106861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        // Look for a device in a machine, and if not found, keep trying for 3 minutes
107861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        static IDevice GetDevice(IResourcePool rootPool, string machineName, string regexStr)
108861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        {
109861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            Regex deviceRegex = new Regex(regexStr, RegexOptions.IgnoreCase);
110861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            int numAttempts = 1;
111861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            DateTime endTime = DateTime.Now.AddSeconds(180);
112861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            while (DateTime.Now < endTime)
113861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            {
114861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                IResource machine = rootPool.GetResourceByName(machineName);
115861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Looking for device '{0}' in machine '{1}' (machine has {2} devices)",
116861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    regexStr, machineName, machine.GetDevices().Length);
117861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (IDevice d in machine.GetDevices())
118861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
119861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    if (deviceRegex.IsMatch(d.FriendlyName))
120861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
121861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Found device '{0}'", d.FriendlyName);
122861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        return d;
123861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    }
124861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
125861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Device not found");
126861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (numAttempts % 5 == 0)
127861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    ResetMachine(rootPool, machineName, true);
128861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                else
129861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    System.Threading.Thread.Sleep(5000);
130861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                numAttempts++;
131861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            }
132861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            Console.WriteLine("Error: device '{0}' not found", deviceRegex);
133861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            return null;
134861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li        }
135861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
1366f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li        static int Main(string[] args)
1376f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li        {
138861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            if (args.Length < 5)
1396f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            {
1406f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("Error: incorrect number of command line arguments");
141861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Usage: {0} serverName machinePoolName submissionName timeout machineName0 machineName1 ...",
1426f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    System.Environment.GetCommandLineArgs()[0]);
1436f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                return 1;
1446f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            }
1456f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            string serverName = args[0];
146861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            string machinePoolName = args[1];
147861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            string submissionName = args[2];
148861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            double timeout = Convert.ToDouble(args[3]);
149861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
150861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            List<string> machines = new List<string>();
151861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li            for (int i = 4; i < args.Length; i++)
152861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                machines.Add(args[i]);
1536f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
1546f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            try
1556f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            {
1566f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // Initialize DeviceScript and connect to data store
1576f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("Initializing DeviceScript object");
1586f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                DeviceScript script = new DeviceScript();
1596f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("Connecting to data store");
1606f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                script.ConnectToNamedDataStore(serverName);
1616f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
162861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Wait for client machines to become available
1636f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                IResourcePool rootPool = script.GetResourcePoolByName("$");
164861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
165861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    FindMachine(rootPool, machineName);
1667edb30498d75a29a3287fe07070f2b51a116c5d4Eric Li
167861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Delete the machine pool if it already exists
168861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                DeleteResourcePool(script, machinePoolName);
169861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
170861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Create the machine pool and add the client machines to it
1716f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // (this must be done because jobs cannot be scheduled for machines in the
1726f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // default pool)
1736f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                try
1746f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
1756f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    script.CreateResourcePool(machinePoolName, rootPool.ResourcePoolId);
1766f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
1776f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                catch (Exception e)
1786f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
1796f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("Warning: " + e.Message);
1806f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
1816f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                IResourcePool newPool = script.GetResourcePoolByName(machinePoolName);
182861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
1836f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
184861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("Moving machine '{0}' to pool '{1}'", machineName, machinePoolName);
185861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    rootPool.GetResourceByName(machineName).ChangeResourcePool(newPool);
1866f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
1876f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
188861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Reset client machine
189861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
190861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    ResetMachine(rootPool, machineName, true);
1916f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
192861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Get requested device regex and look for a matching device in the first machine
193861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Device to test:");
194861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                IDevice device = GetDevice(rootPool, machines[0], Console.ReadLine());
195861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (device == null)
196861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    return 1;
1976f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
1986f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // Get requested jobs regex
199861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Jobs to run:");
2006f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Regex jobRegex = new Regex(Console.ReadLine(), RegexOptions.IgnoreCase);
2016f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
202861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Create a submission
2036f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Object[] existingSubmissions = script.GetSubmissionByName(submissionName);
2046f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                if (existingSubmissions.Length > 0)
2056f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
2066f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("Submission '{0}' already exists -- removing it",
2076f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        submissionName);
2086f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    script.DeleteSubmission(((ISubmission)existingSubmissions[0]).Id);
2096f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
210861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                string hardwareId = device.InstanceId.Remove(device.InstanceId.LastIndexOf("\\"));
211861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Creating submission '{0}' (hardware ID: {1})", submissionName, hardwareId);
212861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                ISubmission submission = script.CreateHardwareSubmission(submissionName, newPool.ResourcePoolId, hardwareId);
2136f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
214861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Set submission DeviceData
2156f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                List<Object> deviceDataList = new List<Object>();
2166f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                while (true)
2176f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
2186f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    ISubmissionDeviceData dd = script.CreateNewSubmissionDeviceData();
219861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("DeviceData name:");
2206f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    dd.Name = Console.ReadLine();
2216f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    if (dd.Name.Length == 0)
2226f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        break;
223861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("DeviceData data:");
2246f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    dd.Data = Console.ReadLine();
2256f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    deviceDataList.Add(dd);
2266f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
2276f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                submission.SetDeviceData(deviceDataList.ToArray());
2286f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
229861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Set submission descriptors
2306f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                List<Object> descriptorList = new List<Object>();
2316f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                while (true)
2326f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
233861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    Console.WriteLine("Descriptor path:");
2346f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    string descriptorPath = Console.ReadLine();
2356f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    if (descriptorPath.Length == 0)
2366f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        break;
2376f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    descriptorList.Add(script.GetDescriptorByPath(descriptorPath));
2386f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
239bdaab795cffa33f9a37995bb283047cb03699272Kenneth Waters                submission.SetLogoDescriptors(descriptorList.ToArray());
2407edb30498d75a29a3287fe07070f2b51a116c5d4Eric Li
241861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Set machine dimensions
242861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
243861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
244861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    IResource machine = rootPool.GetResourceByName(machineName);
245861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    while (true)
246861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
247861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Dimension name ({0}):", machineName);
248861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        string dimName = Console.ReadLine();
249861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if (dimName.Length == 0)
250861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            break;
251861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Dimension value ({0}):", machineName);
252861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        machine.SetDimension(dimName, Console.ReadLine());
253861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    }
254861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    // Set the WDKSubmissionId dimension for all machines
255861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    machine.SetDimension("WDKSubmissionId", submission.Id.ToString() + "_" + submission.Name);
256861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
257861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
258861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Get job parameters
259861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                List<string> paramNames = new List<string>();
260861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                List<string> paramValues = new List<string>();
261861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
262861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
263861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    while (true)
264861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
265861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Parameter name ({0}):", machineName);
266861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        string paramName = Console.ReadLine();
267861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if (paramName.Length == 0)
268861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            break;
269861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Device regex ({0}):", machineName);
270861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        IDevice d = GetDevice(rootPool, machineName, Console.ReadLine());
271861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if (d == null)
272861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            return 1;
273861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        string deviceName = d.GetAttribute("name")[0].ToString();
274861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("Setting parameter value to '{0}'", deviceName);
275861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        paramNames.Add(paramName);
276861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        paramValues.Add(deviceName);
277861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    }
278861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
279861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
280861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Find jobs that match the requested pattern
2816f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("Scheduling jobs:");
282861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                List<IJob> jobs = new List<IJob>();
2836f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                foreach (IJob j in submission.GetJobs())
2846f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
2856f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    if (jobRegex.IsMatch(j.Name))
286861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    {
287861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        Console.WriteLine("    " + j.Name);
288861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        // Set job parameters
289861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        for (int i = 0; i < paramNames.Count; i++)
290861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        {
291861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            IParameter p = j.GetParameterByName(paramNames[i]);
292861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                            if (p != null)
293861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                                p.ScheduleValue = paramValues[i];
294861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        }
295861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        jobs.Add(j);
2966f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    }
2976f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
298861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (jobs.Count == 0)
2996f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
3006f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("Error: no submission jobs match pattern '{0}'", jobRegex);
3016f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    return 1;
3026f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                }
303861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
304861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Create a schedule, add jobs to it and run it
305861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                ISchedule schedule = script.CreateNewSchedule();
306861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (IScheduleItem item in submission.ProcessJobs(jobs.ToArray()))
307861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                {
308861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    item.Device = device;
309861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    schedule.AddScheduleItem(item);
310861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                }
3116f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                schedule.AddSubmission(submission);
3126f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                schedule.SetResourcePool(newPool);
3136f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                script.RunSchedule(schedule);
3146f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
3156f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // Wait for jobs to complete
316861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                Console.WriteLine("Waiting for all jobs to complete (timeout={0}s)", timeout);
317861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                DateTime endTime = DateTime.Now.AddSeconds(timeout);
318861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                int numCompleted, numFailed;
319861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                do
3206f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                {
3216f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    System.Threading.Thread.Sleep(30000);
322861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    // Report results in a Python readable format and count completed and failed schedule jobs
323861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    numCompleted = numFailed = 0;
3246f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine();
3256f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("---- [");
3266f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    foreach (IResult r in schedule.GetResults())
3276f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    {
328861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if (r.ResultStatus != "InProgress") numCompleted++;
329861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                        if (r.ResultStatus == "Investigate") numFailed++;
3306f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("  {");
3316f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("    'id': {0}, 'job': r'''{1}''',", r.Job.Id, r.Job.Name);
3326f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("    'logs': r'''{0}''',", r.LogLocation);
3336f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        if (r.ResultStatus != "InProgress")
3346f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                            Console.WriteLine("    'report': r'''{0}''',",
3356f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                                submission.GetSubmissionResultReport(r));
3366f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("    'status': '{0}',", r.ResultStatus);
3376f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("    'pass': {0}, 'fail': {1}, 'notrun': {2}, 'notapplicable': {3}",
3386f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                            r.Pass, r.Fail, r.NotRun, r.NotApplicable);
3396f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        Console.WriteLine("  },");
3406f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    }
3416f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("] ----");
342861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                } while (numCompleted < schedule.GetResults().Length && DateTime.Now < endTime);
343861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li
3446f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine();
3456f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
3466f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // Cancel incomplete jobs
3476f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                foreach (IResult r in schedule.GetResults())
3486f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    if (r.ResultStatus == "InProgress")
3496f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                        r.Cancel();
3506f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
351861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                // Reset the machines
352861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                foreach (string machineName in machines)
353861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                    ResetMachine(rootPool, machineName, false);
3546f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
3556f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                // Report failures
356861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (numCompleted < schedule.GetResults().Length)
3576f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("Some jobs did not complete on time.");
3586f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                if (numFailed > 0)
3596f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    Console.WriteLine("Some jobs failed.");
360861b2d54aec24228cdb3895dbc40062cb40cb2adEric Li                if (numFailed > 0 || numCompleted < schedule.GetResults().Length)
3616f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                    return 1;
3626f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li
3636f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("All jobs completed.");
3646f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                return 0;
3656f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            }
3666f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            catch (Exception e)
3676f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            {
3686f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                Console.WriteLine("Error: " + e.Message);
3696f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li                return 1;
3706f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li            }
3716f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li        }
3726f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li    }
3736f27d4f22a1ba5063968b8c322fa0845f3279adeEric Li}
374