#kvm_iperf test - v0.3. by Alexey Eromenko - aeromenk@redhat.com
#31.05.2009. Add iperf_parallel_threads & iperf_dest_ip.
import time
import os

from autotest_lib.client.common_lib import utils, error

import kvm_log
import kvm_utils

def run_iperf(test, params, env):
    vm = kvm_utils.env_get_vm(env,  params.get("main_vm"))
    if not vm:
        message = "VM object not found in environment"
        kvm_log.error(message)
        raise error.TestError, message
    if not vm.is_alive():
        message = "VM seems to be dead; Test requires a living VM"
        kvm_log.error(message)
        raise error.TestError, message

    kvm_log.info("Waiting for guest to be up...")

    pxssh = kvm_utils.wait_for(vm.ssh_login, 240, 0, 2)
    if not pxssh:
        message = "Could not log into guest"
        kvm_log.error(message)
        raise error.TestFail, message

    kvm_log.info("Logged in")
    #----------------------------------------------------------------
    #Checking for GuestOS-compatible iPerf binary existence on host.
    iperf_binary = params.get("iperf_binary", "misc/iperf")
    iperf_duration = params.get("iperf_duration", 5)
    iperf_parallel_threads = params.get("iperf_parallel_threads", 1)
    iperf_dest_ip = params.get("iperf_dest_ip", "10.0.2.2")
    iperf_binary = os.path.join(test.bindir, iperf_binary)
    if not os.path.exists(iperf_binary):
        message = "iPerf binary: %s was not found on host" % iperf_binary
        kvm_log.error(message)
        raise error.TestError, message
    else:
        kvm_log.info("iPerf binary: %s was found on host" % iperf_binary)
    #----------------------------------------------------------------
    #Starting HostOS-compatible iPerf Server on host
    kvm_log.info('VM is up ... \n starting iPerf Server on host')
    kvm_utils.run_bg("iperf -s", timeout=5)
    #----------------------------------------------------------------
    #Detecting GuestOS
    if iperf_binary.__contains__("exe"):
        vm_type="win32"
    else:
        vm_type="linux32"
    #----------------------------------------------------------------
    #Copying GuestOS-compatible iPerf binary to guest.
    #Starting iPerf Client on guest, plus connect to host.
    if vm_type == "win32":
        win_dir = "/cygdrive/c/"
        kvm_log.info('starting copying %s to Windows VM to %s' % (iperf_binary, win_dir))
        if not vm.scp_to_remote(iperf_binary, win_dir):
            message = "Could not copy Win32 iPerf to guest"
            kvm_log.error(message)
            raise error.TestError, message
        print "Enabling file permissions of iPerf.exe on Windows VM..."
        pxssh.sendline('cacls C:\iperf.exe /P Administrator:F')
        # Debug section:
        #(match, output) = pxssh.read_until_last_line_matches(["Are you sure"], timeout=5)
        #print "match =", match
        #print "output =", output
        #if match == None:
        #    message = "No shell output from Windows File permissions"
        #    kvm_log.error(message)
        #    raise error.TestError, message
        pxssh.sendline('y')
        pxssh.sendline('')
        time.sleep(2)
        pxssh.sendline('')
        print "starting iPerf client on Windows VM, connecting to host"
        pxssh.sendline('C:\iperf -t %s -c %s -P %s' % (int(iperf_duration),iperf_dest_ip,int(iperf_parallel_threads)))
    else: #if vm_type == "linux":
        kvm_log.info('starting copying %s to Linux VM ' % iperf_binary)
        if not vm.scp_to_remote(iperf_binary, "/usr/local/bin"):
            message = "Could not copy Linux iPerf to guest"
            kvm_log.error(message)
            raise error.TestError, message
        print "starting iPerf client on VM, connecting to host"
        pxssh.sendline('iperf -t %s -c %s -P %s' % (int(iperf_duration),iperf_dest_ip,int(iperf_parallel_threads)))
    #----------------------------------------------------------------
    #Analyzing results
    iperf_result_match, iperf_result = pxssh.read_up_to_prompt()
    #print "iperf_result_match =", iperf_result_match
    print "iperf_result =", iperf_result

    if iperf_result.__contains__(" 0.00 bits/sec"):
        msg = 'guest returned 0.00 bits/sec during iperf test.'
        raise error.TestError(msg)
    elif iperf_result.__contains__("No route to host"):
        msg = 'SSH to guest returned: No route to host.'
        raise error.TestError(msg)
    elif iperf_result.__contains__("Access is denied"):
        msg = 'SSH to guest returned: Access is denied.'
        raise error.TestError(msg)
    elif not iperf_result.__contains__("bits/sec"):
        msg = 'SSH result unrecognizeble.'
        raise error.TestError(msg)

    pxssh.close()
