OLD | NEW |
(Empty) | |
| 1 import logging, time, os, re |
| 2 from autotest_lib.client.common_lib import error |
| 3 import kvm_subprocess, kvm_test_utils, kvm_utils, rss_file_transfer |
| 4 |
| 5 |
| 6 def run_whql_submission(test, params, env): |
| 7 """ |
| 8 WHQL submission test: |
| 9 1) Log into the guest (the client machine) and into a DTM server machine |
| 10 2) Copy the automation program binary (dsso_test_binary) to the server machi
ne |
| 11 3) Run the automation program |
| 12 4) Pass the program all relevant parameters (e.g. device_data) |
| 13 5) Wait for the program to terminate |
| 14 6) Parse and report job results |
| 15 (logs and HTML reports are placed in test.bindir) |
| 16 |
| 17 @param test: kvm test object |
| 18 @param params: Dictionary with the test parameters |
| 19 @param env: Dictionary with test environment. |
| 20 """ |
| 21 vm = kvm_test_utils.get_living_vm(env, params.get("main_vm")) |
| 22 session = kvm_test_utils.wait_for_login(vm, 0, 240) |
| 23 |
| 24 # Collect parameters |
| 25 server_address = params.get("server_address") |
| 26 server_shell_port = int(params.get("server_shell_port")) |
| 27 server_file_transfer_port = int(params.get("server_file_transfer_port")) |
| 28 server_studio_path = params.get("server_studio_path", "%programfiles%\\ " |
| 29 "Microsoft Driver Test Manager\\Studio") |
| 30 dsso_test_binary = params.get("dsso_test_binary", |
| 31 "deps/whql_submission_15.exe") |
| 32 dsso_test_binary = kvm_utils.get_path(test.bindir, dsso_test_binary) |
| 33 test_device = params.get("test_device") |
| 34 job_filter = params.get("job_filter", ".*") |
| 35 test_timeout = float(params.get("test_timeout", 600)) |
| 36 wtt_services = params.get("wtt_services") |
| 37 |
| 38 # Restart WTT service(s) on the client |
| 39 logging.info("Restarting WTT services on client") |
| 40 for svc in wtt_services.split(): |
| 41 kvm_test_utils.stop_windows_service(session, svc) |
| 42 for svc in wtt_services.split(): |
| 43 kvm_test_utils.start_windows_service(session, svc) |
| 44 |
| 45 # Copy dsso_test_binary to the server |
| 46 rss_file_transfer.upload(server_address, server_file_transfer_port, |
| 47 dsso_test_binary, server_studio_path, timeout=60) |
| 48 |
| 49 # Open a shell session with the server |
| 50 server_session = kvm_utils.remote_login("nc", server_address, |
| 51 server_shell_port, "", "", |
| 52 session.prompt, session.linesep) |
| 53 |
| 54 # Get the computer names of the server and client |
| 55 cmd = "echo %computername%" |
| 56 server_name = server_session.get_command_output(cmd).strip() |
| 57 client_name = session.get_command_output(cmd).strip() |
| 58 session.close() |
| 59 |
| 60 # Run the automation program on the server |
| 61 server_session.get_command_output("cd %s" % server_studio_path) |
| 62 cmd = "%s %s %s %s %s %s" % (os.path.basename(dsso_test_binary), |
| 63 server_name, |
| 64 client_name, |
| 65 "%s_pool" % client_name, |
| 66 "%s_submission" % client_name, |
| 67 test_timeout) |
| 68 server_session.sendline(cmd) |
| 69 |
| 70 # Helper function: wait for a given prompt and raise an exception if an |
| 71 # error occurs |
| 72 def find_prompt(prompt): |
| 73 m, o = server_session.read_until_last_line_matches( |
| 74 [prompt, server_session.prompt], print_func=logging.info, |
| 75 timeout=600) |
| 76 if m != 0: |
| 77 errors = re.findall("^Error:.*$", o, re.I | re.M) |
| 78 if errors: |
| 79 raise error.TestError(errors[0]) |
| 80 else: |
| 81 raise error.TestError("Error running automation program: could " |
| 82 "not find '%s' prompt" % prompt) |
| 83 |
| 84 # Tell the automation program which device to test |
| 85 find_prompt("Device to test:") |
| 86 server_session.sendline(test_device) |
| 87 |
| 88 # Tell the automation program which jobs to run |
| 89 find_prompt("Jobs to run:") |
| 90 server_session.sendline(job_filter) |
| 91 |
| 92 # Give the automation program all the device data supplied by the user |
| 93 find_prompt("DeviceData name:") |
| 94 for dd in kvm_utils.get_sub_dict_names(params, "device_data"): |
| 95 dd_params = kvm_utils.get_sub_dict(params, dd) |
| 96 if dd_params.get("dd_name") and dd_params.get("dd_data"): |
| 97 server_session.sendline(dd_params.get("dd_name")) |
| 98 server_session.sendline(dd_params.get("dd_data")) |
| 99 server_session.sendline() |
| 100 |
| 101 # Give the automation program all the descriptor information supplied by |
| 102 # the user |
| 103 find_prompt("Descriptor path:") |
| 104 for desc in kvm_utils.get_sub_dict_names(params, "descriptors"): |
| 105 desc_params = kvm_utils.get_sub_dict(params, desc) |
| 106 if desc_params.get("desc_path"): |
| 107 server_session.sendline(desc_params.get("desc_path")) |
| 108 server_session.sendline() |
| 109 |
| 110 # Wait for the automation program to terminate |
| 111 m, o = server_session.read_up_to_prompt(print_func=logging.info, |
| 112 timeout=test_timeout + 300) |
| 113 # (test_timeout + 300 is used here because the automation program is |
| 114 # supposed to terminate cleanly on its own when test_timeout expires) |
| 115 server_session.close() |
| 116 |
| 117 # Look for test results in the automation program's output |
| 118 result_summaries = re.findall(r"---- \[.*?\] ----", o, re.DOTALL) |
| 119 if not result_summaries: |
| 120 raise error.TestError("The automation program did not return any " |
| 121 "results") |
| 122 results = result_summaries[-1].strip("-") |
| 123 results = eval("".join(results.splitlines())) |
| 124 |
| 125 # Download logs and HTML reports from the server |
| 126 for i, r in enumerate(results): |
| 127 if "report" in r: |
| 128 try: |
| 129 rss_file_transfer.download(server_address, |
| 130 server_file_transfer_port, |
| 131 r["report"], test.debugdir) |
| 132 except rss_file_transfer.FileTransferNotFoundError: |
| 133 pass |
| 134 if "logs" in r: |
| 135 try: |
| 136 rss_file_transfer.download(server_address, |
| 137 server_file_transfer_port, |
| 138 r["logs"], test.debugdir) |
| 139 except rss_file_transfer.FileTransferNotFoundError: |
| 140 pass |
| 141 else: |
| 142 try: |
| 143 # Create symlinks to test log dirs to make it easier |
| 144 # to access them (their original names are not human |
| 145 # readable) |
| 146 link_name = "logs_%s" % r["report"].split("\\")[-1] |
| 147 link_name = link_name.replace(" ", "_") |
| 148 link_name = link_name.replace("/", "_") |
| 149 os.symlink(r["logs"].split("\\")[-1], |
| 150 os.path.join(test.debugdir, link_name)) |
| 151 except (KeyError, OSError): |
| 152 pass |
| 153 |
| 154 # Print result summary |
| 155 logging.info("") |
| 156 logging.info("Result summary:") |
| 157 name_length = max(len(r.get("job", "")) for r in results) |
| 158 fmt = "%%-6s %%-%ds %%-15s %%-8s %%-8s %%-8s %%-15s" % name_length |
| 159 logging.info(fmt % ("ID", "Job", "Status", "Pass", "Fail", "NotRun", |
| 160 "NotApplicable")) |
| 161 logging.info(fmt % ("--", "---", "------", "----", "----", "------", |
| 162 "-------------")) |
| 163 for r in results: |
| 164 logging.info(fmt % (r.get("id"), r.get("job"), r.get("status"), |
| 165 r.get("pass"), r.get("fail"), r.get("notrun"), |
| 166 r.get("notapplicable"))) |
| 167 logging.info("(see logs and HTML reports in %s)" % test.debugdir) |
| 168 |
| 169 # Kill the VM and fail if the automation program did not terminate on time |
| 170 if not m: |
| 171 vm.destroy() |
| 172 raise error.TestFail("The automation program did not terminate " |
| 173 "on time") |
| 174 |
| 175 # Fail if there are failed or incomplete jobs (kill the VM if there are |
| 176 # incomplete jobs) |
| 177 failed_jobs = [r.get("job") for r in results |
| 178 if r.get("status", "").lower() == "investigate"] |
| 179 running_jobs = [r.get("job") for r in results |
| 180 if r.get("status", "").lower() == "inprogress"] |
| 181 errors = [] |
| 182 if failed_jobs: |
| 183 errors += ["Jobs failed: %s." % failed_jobs] |
| 184 if running_jobs: |
| 185 vm.destroy() |
| 186 errors += ["Jobs did not complete on time: %s." % running_jobs] |
| 187 if errors: |
| 188 raise error.TestFail(" ".join(errors)) |
OLD | NEW |