def get_corners(vmi, win_title): """Gets the coordinates of the 4 corners of the window. Info ---- http://www.x.org/archive/X11R6.8.0/doc/X.7.html#sect6 Parameters ---------- win_title : str XXX. Return ------ list Corners in format: [('+470', '+187'), ('-232', '+187'), ('-232', '-13'), ('+470', '-13')] """ rv_xinfo_cmd = "xwininfo -name %s" % win_title rv_xinfo_cmd += " | grep Corners" cmd1 = utils.Cmd("xwininfo", "-name", win_title) cmd2 = utils.Cmd("grep", "Corners") cmd = utils.combine(cmd1, "|", cmd2) # Expected format: Corners: +470+187 -232+187 -232-13 +470-13 raw_out = act.run(vmi, cmd) line = raw_out.strip() corners = [tuple(re.findall("[+-]\d+", i)) for i in line.split()[1:]] return corners
def firefox_auto_open_vv(vmi): """Automatically open remote-viewer for proposed .vv file. Doesn't work as expected. See: https://github.com/SeleniumHQ/selenium/issues/3013 See content type at: ~/.mozilla/firefox/<profile_name>/mimeTypes.rdf application/x-virt-viewer """ pdir = vmi.firefox_profile_dir if not pdir: vmi.vm.error("Firefox profile dir is not defined") return user_js = os.path.join(pdir, "user.js") opts = [] opts.append("browser.helperApps.neverAsk.saveToDisk") opts.append("browser.helperApps.neverAsk.openFile") cmd = utils.Cmd("test", "-e", user_js) status, _ = act.rstatus(vmi, cmd) if status == 0: for o in opts: utils.info(vmi, "Remove old value %s from Firefox profile: %s", o, user_js) cmd = utils.Cmd("sed", "-i", "-e", "/%s/d" % o, user_js) act.run(vmi, cmd) line = 'user_pref("browser.helperApps.neverAsk.openFile",' '"application/x-virt-viewer");' cmd1 = utils.Cmd("echo", line) cmd2 = utils.Cmd(user_js) cmd = utils.combine(cmd1, ">>", cmd2) utils.info(vmi, "Add new line %s to Firefox profile: %s", line, user_js) act.run(vmi, cmd)
def verify_vdagent(vmi): """Verifying vdagent is installed on a VM. """ cmd1 = utils.Cmd("rpm", "-qa") cmd2 = utils.Cmd("grep", "spice-vdagentd") cmd = utils.combine(cmd1, "|", cmd2) act.run(vmi, cmd)
def rv_connect_cmd(vmi, ssn, env): cmd = act.rv_basic_opts(vmi) url = act.rv_url(vmi) cmd.append(url) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) utils.set_ticket(vmi.test) act.rv_run(vmi, cmd, ssn, env) act.rv_auth(vmi)
def rv_connect_cmd(vmi, ssn, env): cmd = act.rv_basic_opts(vmi) url = act.rv_url(vmi) cmd.append(url) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) utils.set_ticket(vmi.test) act.rv_run(vmi, cmd, ssn) act.rv_auth(vmi)
def rv_connect_menu(vmi, ssn, env): cmd = act.rv_basic_opts(vmi) utils.set_ticket(vmi.test) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) act.rv_run(vmi, cmd, ssn) url = act.rv_url(vmi) act.str_input(vmi, url) act.rv_auth(vmi)
def rv_connect_menu(vmi, ssn, env): cmd = act.rv_basic_opts(vmi) utils.set_ticket(vmi.test) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) act.rv_run(vmi, cmd, ssn, env) url = act.rv_url(vmi) act.str_input(vmi, url) act.rv_auth(vmi)
def x_turn_on(vmi): ssn = act.new_admin_ssn(vmi) runner = remote.RemoteRunner(session=ssn) srv_mng = service.Factory.create_service(run=runner.run) srv_mng.set_target("graphical.target") # pylint: disable=no-member cmd1 = utils.Cmd("ss", "-x", "src", "*X11-unix*") cmd2 = utils.Cmd("grep", "-q", "-s", "X11") cmd = utils.combine(cmd1, "|", cmd2) status, _ = act.rstatus(vmi, cmd) assert status == 0, "X is: off. But it should not." # TODO utils.info(vmi, "X is: on.")
def rv_connect_file(vmi, ssn, env): cmd = utils.Cmd(vmi.cfg.rv_binary) vv_file_host = act.gen_vv_file(vmi) with open(vv_file_host, 'r') as rvfile: file_contents = rvfile.read() act.info(vmi, "RV file contents:\n%s", file_contents) vv_file_client = act.cp_file(vmi, vv_file_host) cmd.append(vv_file_client) utils.set_ticket(vmi.test) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) act.rv_run(vmi, cmd, ssn)
def rv_connect_file(vmi, ssn, env): cmd = utils.Cmd(vmi.cfg.rv_binary) vv_file_host = act.gen_vv_file(vmi) with open(vv_file_host, 'r') as rvfile: file_contents = rvfile.read() act.info(vmi, "RV file contents:\n%s", file_contents) vv_file_client = act.cp_file(vmi, vv_file_host) cmd.append(vv_file_client) utils.set_ticket(vmi.test) cmd = utils.combine(cmd, "2>&1") act.info(vmi, "Final RV command: %s", cmd) act.rv_run(vmi, cmd, ssn, env)
def get_connected_displays(vmi): """Get list of video devices on a VM. Return ------ List of active displays on the VM. """ cmd1 = utils.Cmd("xrandr") cmd2 = utils.Cmd("grep", "-E", "[[:space:]]connected[[:space:]]") cmd = utils.combine(cmd1, "|", cmd2) raw = act.run(vmi, cmd) displays = [a.split()[0] for a in raw.split("n") if a is not ""] return displays
def get_display_resolution(vmi): """Returns list of resolutions on all displays of a VM. Return ------ List of resolutions. """ cmd1 = utils.Cmd("xrandr") cmd2 = utils.Cmd("grep", "*") cmd = utils.combine(cmd1, "|", cmd2) raw = act.run(vmi, cmd) res = [a.split()[0] for a in raw.split("\n") if a is not ""] return res
def dst_dir(vmi): dst_dir = vmi.cfg.dst_dir if dst_dir: return dst_dir cmd1 = utils.Cmd("getent", "passwd", vmi.cfg.username) cmd2 = utils.Cmd("cut", "-d:", "-f6") cmd = utils.combine(cmd1, "|", cmd2) out = act.run(vmi, cmd) home_dir = out.rstrip("\r\n") dst_dir = os.path.join(home_dir, "tp-spice") cmd = utils.Cmd("mkdir", "-p", dst_dir) act.run(vmi, cmd) vmi.cfg.dst_dir = dst_dir return dst_dir
def get_res(vmi): """Gets the resolution of a VM ..todo:: ? MONITOR # ? Return ------ """ cmd1 = utils.Cmd("xrandr", "-d", ":0") cmd1.append_raw("2>/dev/null") cmd2 = utils.Cmd("grep", "*") cmd = utils.combine(cmd1, "|", cmd2) guest_res_raw = act.run(vmi, cmd) guest_res = guest_res_raw.split()[0] return guest_res
def wait_for_win(vmi, pattern, prop="_NET_WM_NAME"): """Wait until active window has "pattern" in window name. ..todo:: Write same function for MS Windows. Info ---- http://superuser.com/questions/382616/detecting-currently-active-window Parameters ---------- pattern : str Pattern for window name. Raises ------ SpiceUtilsError Timeout and no window was found. """ cmd1 = utils.Cmd("xprop", "-root", "32x", r"\t$0", "_NET_ACTIVE_WINDOW") cmd2 = utils.Cmd("cut", "-f", "2") cmd_win_id = utils.combine(cmd1, "|", cmd2) @deco.retry(8, exceptions=(utils.SpiceUtilsError, aexpect.ShellCmdError, aexpect.ShellTimeoutError)) def is_active(): utils.info(vmi, "Test if window is active: %s", pattern) win_id = act.run(vmi, cmd_win_id) # Active windows ID. cmd = utils.Cmd("xprop", "-notype", "-id", win_id, prop) output = act.run(vmi, cmd) utils.info(vmi, "Current win name: %s", output) if pattern not in output: msg = "Can't find active window with pattern %s." % pattern raise utils.SpiceUtilsError(msg) # TODO utils.info(vmi, "Found active window: %s.", pattern) is_active()
def get_x_var(vmi, var_name): """Gets the env variable value by its name from X session. Info ---- It is no straight way to get variable value from X session. If you try to read var value from SSH session it could be different from X session var or absent. The strategy used in this function is: 1. Find nautilus process. 2. Read its /proc/$PID/environ Parameters ---------- var_name : str Spice test object. Returns ------- str Env variable value. """ pattern = "(?<=(?:^{0}=|(?<=\n){0}=))[^\n]+".format(var_name) pids = act.wait_for_prog(vmi, "nautilus") ret = "" for pid in pids: cmd1 = utils.Cmd("cat", "/proc/%s/environ" % pid) cmd2 = utils.Cmd("xargs", "-n", "1", "-0", "echo") cmd = utils.combine(cmd1, "|", cmd2) out = act.run(vmi, cmd) val = re.findall(pattern, out) if val: ret = val[0] utils.info(vmi, "export %s=%s", var_name, ret) return ret
def rv_chk_con(vmi): """Tests if connection is active. .. todo:: rewrte to test per session. Parameters ---------- test : SpiceTest Spice test object. Raises ------ RVSessionConnect RV session is not establised. Or established in unexpected way. RVSessionError Something goes wrong. """ test = vmi.test cfg = test.cfg proxy_port = None if vmi.cfg.ssltype == "invalid_implicit_hs" or \ "explicit" in vmi.cfg.ssltype: hostname = socket.gethostname() # See rv_url() function remote_ip = socket.gethostbyname(hostname) elif cfg.spice_proxy: proxy_port = "3128" if "http" in cfg.spice_proxy: split = cfg.spice_proxy.split('//')[1].split(':') else: split = cfg.spice_proxy.split(':') remote_ip = split[0] if len(split) > 1: proxy_port = split[1] logger.info("Proxy port to inspect: %s", proxy_port) else: remote_ip = utils.get_host_ip(test) rv_binary = os.path.basename(cfg.rv_binary) cmd1 = utils.Cmd("netstat", "-p", "-n") grep_regex = "^tcp.*:.*%s.*ESTABLISHED.*%s.*" % (remote_ip, rv_binary) cmd2 = utils.Cmd("grep", "-e", grep_regex) cmd = utils.combine(cmd1, "|", cmd2) time.sleep(5) # Wait all RV Spice links raise up. status, netstat_out = act.rstatus(vmi, cmd, admin=True) if status: raise utils.SpiceUtilsError("No active RV connections.") proxy_port_count = 0 if cfg.spice_proxy: proxy_port_count = netstat_out.count(proxy_port) test.vm_g.info("Active proxy ports %s: %s", proxy_port, proxy_port_count) port = test.kvm_g.spice_port tls_port = test.kvm_g.spice_tls_port port_count = netstat_out.count(port) test.vm_g.info("Active ports %s: %s", port, port_count) tls_port_count = 0 if tls_port: tls_port_count = netstat_out.count(tls_port) test.vm_g.info("Active TLS ports %s: %s", tls_port, tls_port_count) opened_ports = port_count + tls_port_count + proxy_port_count if opened_ports < 4: raise RVSessionConnect(test, "Total links per session is less then 4 (%s)." % opened_ports) if cfg.spice_secure_channels: tls_port_expected = len(cfg.spice_secure_channels.split(',')) if tls_port_count < tls_port_expected: msg = "Secure links per session is less then expected. %s (%s)" % ( tls_port_count, tls_port_expected) raise RVSessionConnect(test, msg) for line in netstat_out.split('\n'): for p in port, tls_port, proxy_port: if p and p in line and "ESTABLISHED" not in line: raise RVSessionConnect(test, "Missing active link at port %s", p) output = test.vm_g.monitor.cmd("info spice") logger.info(output) # Check to see if ipv6 address is reported back from qemu monitor if cfg.spice_info == "ipv6": # Remove brackets from ipv6 host ip host_ip = utils.get_host_ip(test) if host_ip[1:len(host_ip) - 1] in output: logger.info( "Reported ipv6 address found in output from 'info spice'") else: raise RVSessionConnect("ipv6 address not found from qemu monitor" " command: 'info spice'") logger.debug("RV connection checking pass")
def rv_chk_con(vmi): """Tests if connection is active. .. todo:: rewrte to test per session. Parameters ---------- test : SpiceTest Spice test object. Raises ------ RVSessionConnect RV session is not establised. Or established in unexpected way. RVSessionError Something goes wrong. """ test = vmi.test cfg = test.cfg proxy_port = None if vmi.cfg.ssltype == "invalid_implicit_hs" or \ "explicit" in vmi.cfg.ssltype: hostname = socket.gethostname() # See rv_url() function remote_ip = socket.gethostbyname(hostname) elif cfg.spice_proxy: remote_ip, proxy_port = utils.URL_parse(cfg.spice_proxy, cfg.http_proxy_port) logger.info("Proxy port to inspect: %s, proxy IP: %s", proxy_port, remote_ip) else: remote_ip = utils.get_host_ip(test) rv_binary = os.path.basename(cfg.rv_binary) cmd1 = utils.Cmd("ss", "-n", "-p", "-t", "state", "all") grep_regex = "%s.*%s" % (remote_ip, rv_binary) cmd2 = utils.Cmd("grep", "-e", grep_regex) cmd3 = utils.Cmd("grep", "-v", "CLOSE-WAIT") cmd = utils.combine(cmd1, "|", cmd2, "|", cmd3) status, ss_out = act.rstatus(vmi, cmd, admin=True) if status: logger.info("ss output: %s", ss_out) raise utils.SpiceUtilsError("No active RV connections.") proxy_port_count = 0 if cfg.spice_proxy: proxy_port_count = ss_out.count(proxy_port) test.vm_g.info("Active proxy ports %s: %s", proxy_port, proxy_port_count) port = test.kvm_g.spice_port tls_port = test.kvm_g.spice_tls_port if port == 'no': port_count = 0 else: port_count = ss_out.count(port) test.vm_g.info("Active ports %s: %s", port, port_count) tls_port_count = 0 if tls_port: tls_port_count = ss_out.count(tls_port) test.vm_g.info("Active TLS ports %s: %s", tls_port, tls_port_count) opened_ports = port_count + tls_port_count + proxy_port_count if opened_ports < 4: raise RVSessionConnect( test, "Total links per session is less then 4 (%s)." % opened_ports) if cfg.spice_secure_channels: tls_port_expected = len(cfg.spice_secure_channels.split(',')) if tls_port_count < tls_port_expected: msg = "Secure links per session is less then expected. %s (%s)" % ( tls_port_count, tls_port_expected) raise RVSessionConnect(test, msg) if cfg.spice_plaintext_channels: plaintext_port_expected = len(cfg.spice_plaintext_channels.split(',')) if port_count < plaintext_port_expected: msg = ( "Plaintext links per session is less then expected. %s (%s)" % (port_count, plaintext_port_expected)) raise RVSessionConnect(test, msg) for line in ss_out.split('\n'): for p in port, tls_port, proxy_port: if p and p in line and "ESTAB" not in line: raise RVSessionConnect(test, "Missing active link at port %s", p) output = test.vm_g.monitor.info("spice") logger.info(output) # Check to see if ipv6 address is reported back from qemu monitor if cfg.spice_info == "ipv6": # Remove brackets from ipv6 host ip host_ip = utils.get_host_ip(test) logger.info('host ip = %s', host_ip) if host_ip[1:len(host_ip) - 1] in str(output): logger.info( "Reported ipv6 address found in output from 'info spice'") else: raise RVSessionConnect("ipv6 address not found from qemu monitor" " command: 'info spice'") logger.debug("RV connection checking pass")
def get_ip(vmi): """Get IP for VM. Notes ----- * At this moment we use Ovirt ReST API. We need to know only VMs IP. If it is necessary to send more complex requests consider to switch to Ovirt Python SDK. * This function requires to installed and running a daemon from RPM rhevm-guest-agent-common or GuestTools for Windows.: 28236 ? Ssl 34:36 /usr/bin/python /usr/share/ovirt-guest-agent/ovirt-guest-agent.py * Will be called next command: curl \ --insecure \ --request GET \ --header "Filter: true" \ --header "Accept: application/xml" \ --user "[email protected]:redhat" \ 'https://rhevm36.spice.brq.redhat.com/ovirt-engine/api/vms/?search=auto_pool_06_rhel72' \ | xmllint --xpath 'string(/vms/vm/guest_info/ips/ip/@address)' - Returns ------- str String with IP address of a VM. Raises ------ Exception Cannot get IP for VM. """ cfg = vmi.cfg cmd1 = utils.Cmd("curl") cmd.append("--insecure") cmd.append("--request") cmd.append("GET") cmd.append("--header") cmd.append("Filter: true") cmd.append("--header") cmd.append("Accept: application/xml") cmd.append("--user") user = "******".format(user=cfg.ovirt_user, profile=cfg.ovirt_profile, passw=cfg.ovirt_password) cmd.append(user) if cfg.ovirt_vm_name: # The same syntax as in admin portal search bar. search = "name=%s" % cfg.ovirt_vm_name elif cfg.ovirt_pool_name: search = "pool=%s" % cfg.ovirt_pool_name else: raise Exception("Not defined: VM or pool name.") url = "{ovirt_engine}/api/vms/?search={search}".format( ovirt_engine=cfg.ovirt_engine_url, search=search) cmd.append(url) cmd2 = utils.Cmd("xmllint", "--xpath", "string(/vms/vm/guest_info/ips/ip/@address)", "-") cmd_get_ip = utils.combine(cmd1, "|", cmd2) out = subprocess.check_output(cmd_get_ip, shell=True) return out
def get_ip(vmi): """Get IP for VM. Notes ----- * At this moment we use Ovirt ReST API. We need to know only VMs IP. If it is necessary to send more complex requests consider to switch to Ovirt Python SDK. * This function requires to installed and running a daemon from RPM rhevm-guest-agent-common or GuestTools for Windows.: 28236 ? Ssl 34:36 /usr/bin/python /usr/share/ovirt-guest-agent/ovirt-guest-agent.py * Will be called next command: curl \ --insecure \ --request GET \ --header "Filter: true" \ --header "Accept: application/xml" \ --user "[email protected]:redhat" \ 'https://rhevm36.spice.brq.redhat.com/ovirt-engine/api/vms/?search=auto_pool_06_rhel72' \ | xmllint --xpath 'string(/vms/vm/guest_info/ips/ip/@address)' - Returns ------- str String with IP address of a VM. Raises ------ Exception Cannot get IP for VM. """ cfg = vmi.cfg cmd1 = utils.Cmd("curl") cmd1.append("--insecure") cmd1.append("--request") cmd1.append("GET") cmd1.append("--header") cmd1.append("Filter: true") cmd1.append("--header") cmd1.append("Accept: application/xml") cmd1.append("--user") user = "******".format(user=cfg.ovirt_user, profile=cfg.ovirt_profile, passw=cfg.ovirt_password) cmd1.append(user) if cfg.ovirt_vm_name: # The same syntax as in admin portal search bar. search = "name=%s" % cfg.ovirt_vm_name elif cfg.ovirt_pool_name: search = "pool=%s" % cfg.ovirt_pool_name else: raise Exception("Not defined: VM or pool name.") url = "{ovirt_engine}/api/vms/?search={search}".format( ovirt_engine=cfg.ovirt_engine_url, search=search) cmd1.append(url) cmd2 = utils.Cmd("xmllint", "--xpath", "string(/vms/vm/guest_info/ips/ip/@address)", "-") cmd_get_ip = utils.combine(cmd1, "|", cmd2) out = subprocess.check_output(cmd_get_ip, shell=True) return out
def run(vt_test, test_params, env): """Run remote-viewer at client VM. Parameters ---------- vt_test : avocado.core.plugins.vt.VirtTest QEMU test object. test_params : virttest.utils_params.Params Dictionary with the test parameters. env : virttest.utils_env.Env Dictionary with test environment. """ test = stest.ClientGuestTest(vt_test, test_params, env) cfg = test.cfg vmi_c = test.vmi_c vmi_g = test.vmi_g homedir_g = act.home_dir(vmi_g) success = False act.turn_accessibility(vmi_c) if utils.vm_is_rhel6(test.vm_c): # Activate accessibility for rhel6, BZ#1340160 for rhel7 act.reset_gui(vmi_c) act.x_active(vmi_c) act.x_active(vmi_g) ssn = act.new_ssn(vmi_c) act.rv_connect(vmi_c, ssn) # Nautilus cannot be docked to side when default resolution act.set_resolution(vmi_c, "1280x1024") if not utils.vm_is_rhel8(test.vm_c): act.install_rpm(vmi_c, vmi_c.cfg.dogtail_rpm) dst_script = act.chk_deps(vmi_c, cfg.helper_c) if cfg.locked: # enable screen lock cmd = utils.Cmd('rm', '-I', '/etc/dconf/db/local.d/screensaver') act.run(vmi_g, cmd, admin=True) cmd = utils.Cmd('dconf', 'update') act.run(vmi_g, cmd, admin=True) cmd = utils.Cmd('loginctl', 'lock-sessions') act.run(vmi_g, cmd, admin=True) logging.info('Locking gnome session on guest') if 'generate' in cfg.test_xfer_file: if cfg.copy_img: test_xfer_file = 'test.png' act.imggen(vmi_c, test_xfer_file, cfg.test_image_size) else: test_xfer_file = 'test.txt' act.gen_rnd_file(vmi_c, test_xfer_file, cfg.xfer_kbytes) elif 'http' in cfg.test_xfer_file: cmd = utils.Cmd('wget', cfg.test_xfer_file) act.run(vmi_c, cmd) test_xfer_file = os.path.basename(cfg.test_xfer_file) logger.info('Downloading %s', test_xfer_file) act.run(vmi_c, "nautilus 2>/dev/null &") if cfg.xfer_args: cmd = utils.Cmd(dst_script, cfg.xfer_args, test_xfer_file) else: cmd = utils.Cmd(dst_script, test_xfer_file) logger.info('Sending command to client: %s', cmd) try: act.run(vmi_c, cmd) except aexpect.exceptions.ShellCmdError: logger.info('Cannot transfer a file.') utils.SpiceTestFail(test, "Test failed.") md5src = act.md5sum(vmi_c, test_xfer_file) try: md5dst = act.md5sum( vmi_g, os.path.join(homedir_g, 'Downloads', test_xfer_file)) except aexpect.exceptions.ShellCmdError: logger.info('File is not transferred.') md5dst = None if md5src == md5dst: logger.info('%s transferred to guest VM', test_xfer_file) cmd1 = utils.Cmd('lsof') cmd2 = utils.Cmd('grep', '-q', '-s', test_xfer_file) cmd = utils.combine(cmd1, '|', cmd2) status, _ = act.rstatus(vmi_g, cmd) if status: logger.info('Transferred file %s is closed.', test_xfer_file) success = True elif cfg.xfer_args == '--negative': logger.info('File %s was not transferred.', test_xfer_file) success = True if not success: raise utils.SpiceTestFail(test, "Test failed.")