Beispiel #1
0
 def test_tabular_output(self):
     matrix = [('foo', 'bar'),
               ('/bin/bar/sbrubles', '/home/myuser/sbrubles')]
     self.assertEqual(astring.tabular_output(matrix),
                      ('foo               bar\n'
                       '/bin/bar/sbrubles /home/myuser/sbrubles'))
     header = ['id', 'path']
     self.assertEqual(astring.tabular_output(matrix, header),
                      ('id                path\n'
                       'foo               bar\n'
                       '/bin/bar/sbrubles /home/myuser/sbrubles'))
Beispiel #2
0
 def test_tabular_output(self):
     matrix = [('foo', 'bar'), ('/bin/bar/sbrubles',
                                '/home/myuser/sbrubles')]
     self.assertEqual(astring.tabular_output(matrix),
                      ('foo               bar\n'
                       '/bin/bar/sbrubles /home/myuser/sbrubles'))
     header = ['id', 'path']
     self.assertEqual(astring.tabular_output(matrix, header),
                      ('id                path\n'
                       'foo               bar\n'
                       '/bin/bar/sbrubles /home/myuser/sbrubles'))
    def report_comparison(self, record, files):
        """
        Generates comparison data for 2 IOZone runs.

        It compares 2 sets of nxm results and outputs a table with differences.
        If a difference higher or smaller than 5% is found, a warning is
        triggered.

        :param record: Tuple with 4 elements containing results for record
        size.
        :param file: Tuple with 4 elements containing results for file size.
        """
        (record_size, record_improvements, record_regressions,
         record_total) = record
        (file_size, file_improvements, file_regressions,
         file_total) = files
        header_list = ['RECORD SIZE (KB)', 'INIT WRITE', 'RE WRITE', 'READ',
                       'RE READ', 'RANDOM READ', 'RANDOM WRITE', 'BACKWD READ',
                       'RECRE WRITE', 'STRIDE READ', 'F WRITE', 'FRE WRITE',
                       'F READ', 'FRE READ']
        self.log.info("\n%s", astring.tabular_output(
            record_size, header=header_list))

        self.log.info("ANALYSIS of DRILLED DATA:")

        self.log.info("")
        self.log.info("TABLE:  RECsize Difference between runs              "
                      "Results are % DIFF")
        self.log.info("")
        self.log.info("REGRESSIONS: %d (%.2f%%)    Improvements: %d (%.2f%%)",
                      record_regressions,
                      (100 * record_regressions / float(record_total)),
                      record_improvements,
                      (100 * record_improvements / float(record_total)))
        self.log.info("")

        self.log.info("")
        self.log.info("TABLE:  FILEsize Difference between runs               "
                      "Results are % DIFF")
        self.log.info("")

        self.log.info("\n%s", astring.tabular_output(
            file_size, header=header_list))
        self.log.info("REGRESSIONS: %d (%.2f%%)    Improvements: %d (%.2f%%)",
                      file_regressions,
                      (100 * file_regressions / float(file_total)),
                      file_improvements,
                      (100 * file_improvements / float(file_total)))
        self.log.info("")
Beispiel #4
0
 def test_tabular_output_different_no_cols(self):
     matrix = [[], [1], [2, 2], [333, 333, 333], [4, 4, 4, 4444]]
     self.assertEqual(astring.tabular_output(matrix),
                      "1\n"
                      "2   2\n"
                      "333 333 333\n"
                      "4   4   4   4444")
Beispiel #5
0
 def __str__(self):
     headers = ("|_REQUESTED_|", "|_TRIAGING__|",
                "|___READY___|", "|__STARTED__|",
                "|______FINISHED_______|")
     data = itertools.zip_longest(self._requested, self._triaging, self._ready,
                                  self._started, self._finished, fillvalue="")
     matrix = [_ for _ in data]
     return tabular_output(matrix, headers)
Beispiel #6
0
    def test_tabular_output(self):

        self.assertEqual(astring.tabular_output([]), "")
        self.assertEqual(astring.tabular_output([], header=('C1', 'C2', 'C3')),
                         "C1 C2 C3")
        self.assertEqual(astring.tabular_output([['v11', 'v12', 'v13']]),
                         "v11 v12 v13")
        self.assertEqual(
            astring.tabular_output(
                [['v11', 'v12', 'v13'], ['v21', 'v22', 'v23']],
                header=('C1', 'C2', 'C3')),
            "C1  C2  C3" + "\n" + "v11 v12 v13" + "\n" + "v21 v22 v23")
        self.assertEqual(
            astring.tabular_output([['v11', 'v12', ''], ['v21', 'v22', 'v23']],
                                   header=('C1', 'C2', 'C3')),
            "C1  C2  C3" + "\n" + "v11 v12 " + "\n" + "v21 v22 v23")
        self.assertEqual(
            astring.tabular_output([['v11', 'v12', ''], ['v21', 'v22', 'v23']],
                                   header=('C1', 'C2', 'C3'),
                                   strip=True),
            "C1  C2  C3" + "\n" + "v11 v12" + "\n" + "v21 v22 v23")

        self.assertEqual(
            astring.tabular_output(
                [['v11', 'v12', ''], ['v2100', 'v22', 'v23'],
                 ['v31', 'v320', 'v33']],
                header=('C1', 'C02', 'COL3')), "C1    C02  COL3" + "\n" +
            "v11   v12  " + "\n" + "v2100 v22  v23" + "\n" + "v31   v320 v33")
Beispiel #7
0
 def test_tabular_output_different_no_cols(self):
     matrix = [[], [1], [2, 2], [333, 333, 333], [4, 4, 4, 4444]]
     self.assertEqual(
         astring.tabular_output(matrix),
         "1\n"
         "2   2\n"
         "333 333 333\n"
         "4   4   4   4444",
     )
Beispiel #8
0
 def test_tabular_with_console_codes(self):
     matrix = [("a", "an", "dog", "word", "last"),
               ("\x1b[94ma",             # {BLUE}a
                "\033[0man",             # {END}an
                "cc\033[91mc",   # cc{RED}c
                # {RED}d{GREEN}d{BLUE}d{GRAY}d{END}
                "\033[91md\033[92md\033[94md\033[90md\033[0m",
                "last")]
     header = ['0', '1', '2', '3', '4']
     self.assertEqual(astring.tabular_output(matrix, header),
                      "0 1  2   3    4\n"
                      "a an dog word last\n"
                      "a an ccc "
                      "dddd last")
Beispiel #9
0
 def testTabularWithConsoleCodes(self):
     matrix = [("a", "bb", "ccc", "dddd", "last"),
               ("\x1b[94ma",             # {BLUE}a
                "\033[0mbb",             # {END}bb
                "cc\033[91mc",   # cc{RED}c
                # {RED}d{GREEN}d{BLUE}d{GREY}d{END}
                "\033[91md\033[92md\033[94md\033[90md\033[0m",
                "last")]
     header = ['0', '1', '2', '3', '4']
     self.assertEqual(astring.tabular_output(matrix, header),
                      "0 1  2   3    4\n"
                      "a bb ccc dddd last\n"
                      "\x1b[94ma \x1b[0mbb cc\033[91mc "
                      "\033[91md\033[92md\033[94md\033[90md\033[0m last")
Beispiel #10
0
 def test_tabular_with_console_codes(self):
     matrix = [
         ("a", "an", "dog", "word", "last"),
         (
             "\x1b[94ma",  # {BLUE}a
             "\033[0man",  # {END}an
             "cc\033[91mc",  # cc{RED}c
             # {RED}d{GREEN}d{BLUE}d{GRAY}d{END}
             "\033[91md\033[92md\033[94md\033[90md\033[0m",
             "last")
     ]
     header = ['0', '1', '2', '3', '4']
     self.assertEqual(
         astring.tabular_output(matrix, header), "0 1  2   3    4\n"
         "a an dog word last\n"
         "a an ccc "
         "dddd last")
Beispiel #11
0
    def test_unicode_tabular(self):
        """
        Verifies tabular can handle utf-8 chars properly

        It tries valid encoded utf-8 string as well as unicode ones of
        various lengths and verifies calculates the right length and reports
        the correct results. (the string_safe_encode function is in use here)
        """

        matrix = [("\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4\xff",
                   123), (u'\u0430\u0432\u043e\u043a\u0430\u0434\xff', 123),
                  ("avok\xc3\xa1do", 123), ("a\u0430", 123)]
        str_matrix = ("\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4"
                      "\xef\xbf\xbd 123\n"
                      "\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4"
                      "\xc3\xbf 123\n"
                      "avok\xc3\xa1do 123\n"
                      "a\u0430 123")
        self.assertEqual(astring.tabular_output(matrix), str_matrix)
Beispiel #12
0
 def test_tabular_with_console_codes(self):
     matrix = [
         ("a", "an", "dog", "word", "last"),
         (
             "\x1b[94ma",  # {BLUE}a
             "\033[0man",  # {END}an
             "cc\033[91mc",  # cc{RED}c
             # {RED}d{GREEN}d{BLUE}d{GRAY}d{END}
             "\033[91md\033[92md\033[94md\033[90md\033[0m",
             "last",
         ),
     ]
     header = ["0", "1", "2", "3", "4"]
     self.assertEqual(
         astring.tabular_output(matrix, header),
         "0 1  2   3    4\n"
         "a an dog word last\n"
         "\x1B[94ma \x1B[0man cc\x1B[91mc "
         "\x1B[91md\x1B[92md\x1B[94md\x1B[90md\x1B[0m last",
     )
Beispiel #13
0
    def test_unicode_tabular(self):
        """
        Verifies tabular can handle utf-8 chars properly

        It tries valid encoded utf-8 string as well as unicode ones of
        various lengths and verifies calculates the right length and reports
        the correct results. (the string_safe_encode function is in use here)
        """

        matrix = [("\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4\xff",
                   123),
                  (u'\u0430\u0432\u043e\u043a\u0430\u0434\xff', 123),
                  ("avok\xc3\xa1do", 123),
                  ("a\u0430", 123)]
        str_matrix = ("\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4"
                      "\xef\xbf\xbd 123\n"
                      "\xd0\xb0\xd0\xb2\xd0\xbe\xd0\xba\xd0\xb0\xd0\xb4"
                      "\xc3\xbf 123\n"
                      "avok\xc3\xa1do 123\n"
                      "a\u0430 123")
        self.assertEqual(astring.tabular_output(matrix), str_matrix)
Beispiel #14
0
    def test_tabular_output(self):

        self.assertEqual(astring.tabular_output([]), "")
        self.assertEqual(astring.tabular_output([], header=("C1", "C2", "C3")),
                         "C1 C2 C3")
        self.assertEqual(astring.tabular_output([["v11", "v12", "v13"]]),
                         "v11 v12 v13")
        self.assertEqual(
            astring.tabular_output(
                [["v11", "v12", "v13"], ["v21", "v22", "v23"]],
                header=("C1", "C2", "C3"),
            ),
            "C1  C2  C3" + "\n" + "v11 v12 v13" + "\n" + "v21 v22 v23",
        )
        self.assertEqual(
            astring.tabular_output([["v11", "v12", ""], ["v21", "v22", "v23"]],
                                   header=("C1", "C2", "C3")),
            "C1  C2  C3" + "\n" + "v11 v12 " + "\n" + "v21 v22 v23",
        )
        self.assertEqual(
            astring.tabular_output(
                [["v11", "v12", ""], ["v21", "v22", "v23"]],
                header=("C1", "C2", "C3"),
                strip=True,
            ),
            "C1  C2  C3" + "\n" + "v11 v12" + "\n" + "v21 v22 v23",
        )

        self.assertEqual(
            astring.tabular_output(
                [["v11", "v12", ""], ["v2100", "v22", "v23"],
                 ["v31", "v320", "v33"]],
                header=("C1", "C02", "COL3"),
            ),
            "C1    C02  COL3" + "\n" + "v11   v12  " + "\n" +
            "v2100 v22  v23" + "\n" + "v31   v320 v33",
        )
Beispiel #15
0
 def testTabularOutputDifferentNOCols(self):
     matrix = [[], [1], [2, 2], [333, 333, 333], [4, 4, 4, 4444]]
     self.assertEqual(astring.tabular_output(matrix), "1\n"
                      "2   2\n"
                      "333 333 333\n"
                      "4   4   4   4444")
Beispiel #16
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params["file_system"].split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    black_list = params["black_list"].split()
    drive_letters = int(params.get("drive_letters", "26"))
    stg_image_size = params["stg_image_size"]
    dd_test = params.get("dd_test", "no")
    labeltype = params.get("labeltype", "gpt")

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying qtree vs."
                      " params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return
    try:
        err_msg = "Set disks num: %d" % stg_image_num
        err_msg += ", Get disks num in guest: %d"
        ostype = params["os_type"]
        if ostype == "windows":
            error_context.context("Get windows disk index that to "
                                  "be formatted", logging.info)
            disks = utils_disk.get_windows_disks_index(session, stg_image_size)
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
            if len(disks) > drive_letters:
                black_list.extend(utils_misc.get_winutils_vol(session))
                disks = random.sample(disks, drive_letters - len(black_list))
            error_context.context("Clear readonly for all disks and online "
                                  "them in windows guest.", logging.info)
            if not utils_disk.update_windows_disk_attributes(session, disks):
                test.fail("Failed to update windows disk attributes.")
            dd_test = "no"
        else:
            error_context.context("Get linux disk that to be "
                                  "formatted", logging.info)
            disks = sorted(utils_disk.get_linux_disks(session).keys())
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
    except Exception:
        _do_post_cmd(session)
        raise
    try:
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            for disk in disks:
                error_context.context("Format disk in guest: '%s'" % disk,
                                      logging.info)
                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fstype = file_system[index].strip()
                partitions = utils_disk.configure_empty_disk(
                    session, disk, stg_image_size, ostype,
                    fstype=fstype, labeltype=labeltype)
                if not partitions:
                    test.fail("Fail to format disks.")
                cmd_list = params["cmd_list"]
                for partition in partitions:
                    if "/" not in partition:
                        partition += ":"
                    else:
                        partition = partition.split("/")[-1]
                    error_context.context("Copy file into / out of partition:"
                                          " %s..." % partition, logging.info)
                    for cmd_l in cmd_list.split():
                        cmd = params.get(cmd_l)
                        if cmd:
                            session.cmd(cmd % partition, timeout=cmd_timeout)
                    cmd = params["compare_command"]
                    key_word = params["check_result_key_word"]
                    output = session.cmd_output(cmd)
                    if key_word not in output:
                        test.fail("Files on guest os root fs and disk differ")
                    if dd_test != "no":
                        error_context.context("dd test on partition: %s..."
                                              % partition, logging.info)
                        status, output = session.cmd_status_output(
                            dd_test % (partition, partition), timeout=cmd_timeout)
                        if status != 0:
                            test.fail("dd test fail: %s" % output)
            need_reboot = params.get("need_reboot", "no")
            need_shutdown = params.get("need_shutdown", "no")
            if need_reboot == "yes":
                error_context.context("Rebooting guest ...", logging.info)
                session = vm.reboot(session=session, timeout=login_timeout)
            if need_shutdown == "yes":
                error_context.context("Shutting down guest ...", logging.info)
                vm.graceful_shutdown(timeout=login_timeout)
                if vm.is_alive():
                    test.fail("Fail to shut down guest.")
                error_context.context("Start the guest again.", logging.info)
                vm = env.get_vm(params["main_vm"])
                vm.create(params=params)
                session = vm.wait_for_login(timeout=login_timeout)
            error_context.context("Delete partitions in guest.", logging.info)
            for disk in disks:
                utils_disk.clean_partition(session, disk, ostype)
    finally:
        _do_post_cmd(session)
Beispiel #17
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    def _get_disk_index(session, image_size, disk_indexs):
        list_disk_cmd = "echo list disk > disk && "
        list_disk_cmd += "echo exit >> disk && diskpart /s disk"
        disks = session.cmd_output(list_disk_cmd)
        size_type = image_size[-1] + "B"
        disk_size = ""

        if size_type == "MB":
            disk_size = image_size[:-1] + " MB"
        elif size_type == "GB" and int(image_size[:-1]) < 8:
            disk_size = str(int(image_size[:-1])*1024) + " MB"
        else:
            disk_size = image_size[:-1] + " GB"

        regex_str = r'Disk (\d+).*?%s.*?%s' % (disk_size, disk_size)
        for disk in disks.splitlines():
            if disk.startswith("  Disk"):
                o = re.findall(regex_str, disk, re.I | re.M)
                if o:
                    disk_indexs.append(o[0])

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params.get("file_system").split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    re_str = params["re_str"]
    black_list = params["black_list"].split()
    stg_image_size = params.get("stg_image_size")
    disk_indexs = []

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying"
                      " qtree vs. params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return

    try:
        cmd = params.get("clean_cmd")
        if cmd:
            session.cmd_status_output(cmd)

        if params.get("os_type") == "windows":
            error_context.context("Create partition on those disks", logging.info)
            # Get the disk index
            _get_disk_index(session, stg_image_size, disk_indexs)
            if len(disk_indexs) < stg_image_num:
                err_msg = "Set disks num: %d" % stg_image_num
                err_msg += ", Get disks num in guest: %d" % len(disk_indexs)
                test.fail("Fail to list all the volumes, %s" % err_msg)

            # Random select one file system from file_system
            index = random.randint(0, (len(file_system) - 1))
            fs_type = file_system[index].strip()
            for i in range(stg_image_num):
                utils_misc.format_windows_disk(session, disk_indexs[i], None,
                                               None, fs_type)

        error_context.context("Get disks dev filenames in guest", logging.info)
        cmd = params["list_volume_command"]
        s, output = session.cmd_status_output(cmd, timeout=cmd_timeout)
        if s != 0:
            test.fail("List volume command failed with cmd '%s'.\n"
                      "Output is: %s\n" % (cmd, output))

        output = session.cmd_output(cmd, timeout=cmd_timeout)
        disks = re.findall(re_str, output)
        disks = [item.strip() for item in disks]
        disks.sort()
        logging.debug("Volume list that meet regular expressions: %s",
                      " ".join(disks))

        images = params.get("images").split()
        if len(disks) < len(images):
            logging.debug("disks: %s , images: %s", len(disks), len(images))
            test.fail("Fail to list all the volumes!")

        if params.get("os_type") == "linux":
            output = session.cmd_output("mount")
            li = re.findall(r"^/dev/(%s)\d*" % re_str, output, re.M)
            if li:
                black_list.extend(li)
        else:
            black_list.extend(utils_misc.get_winutils_vol(session))
        disks = set(disks)
        black_list = set(black_list)
        logging.info("No need to check volume '%s'", (disks & black_list))
        disks = disks - black_list
    except Exception:
        _do_post_cmd(session)
        raise

    try:
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            error_context.context("Format those disks in guest", logging.info)
            for disk in disks:
                disk = disk.strip()
                error_context.context("Preparing disk: %s..." % disk)

                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fs = file_system[index].strip()
                cmd = params["format_command"] % (fs, disk)
                error_context.context("formatting test disk")
                session.cmd(cmd, timeout=cmd_timeout)
                cmd = params.get("mount_command")
                if cmd:
                    cmd = cmd % (disk, disk, disk)
                    session.cmd(cmd)

            error_context.context("Cope file into / out of those disks", logging.info)
            for disk in disks:
                disk = disk.strip()

                error_context.context("Performing I/O on disk: %s..." % disk)
                cmd_list = params["cmd_list"].split()
                for cmd_l in cmd_list:
                    cmd = params.get(cmd_l)
                    if cmd:
                        session.cmd(cmd % disk, timeout=cmd_timeout)

                cmd = params["compare_command"]
                key_word = params["check_result_key_word"]
                output = session.cmd_output(cmd)
                if key_word not in output:
                    test.fail("Files on guest os root fs and disk differ")

            if params.get("umount_command"):
                cmd = params.get("show_mount_cmd")
                output = session.cmd_output(cmd)
                disks = re.findall(re_str, output)
                disks.sort()
                for disk in disks:
                    disk = disk.strip()
                    error_context.context("Unmounting disk: %s..." % disk)
                    cmd = params.get("umount_command") % (disk, disk)
                    session.cmd(cmd)
    finally:
        cmd = params.get("show_mount_cmd")
        if cmd:
            try:
                output = session.cmd_output(cmd)
                disks = re.findall(re_str, output)
                disks.sort()
                for disk in disks:
                    error_context.context("Unmounting disk: %s..." % disk)
                    cmd = params["umount_command"] % (disk, disk)
                    session.cmd(cmd)
            except Exception as err:
                logging.warn("Get error when cleanup, '%s'", err)

        _do_post_cmd(session)
Beispiel #18
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    def _get_disk_index(session, image_size, disk_indexs):
        list_disk_cmd = "echo list disk > disk && "
        list_disk_cmd += "echo exit >> disk && diskpart /s disk"
        disks = session.cmd_output(list_disk_cmd)
        size_type = image_size[-1] + "B"
        disk_size = ""

        if size_type == "MB":
            disk_size = image_size[:-1] + " MB"
        elif size_type == "GB" and int(image_size[:-1]) < 8:
            disk_size = str(int(image_size[:-1])*1024) + " MB"
        else:
            disk_size = image_size[:-1] + " GB"

        regex_str = r'Disk (\d+).*?%s.*?%s' % (disk_size, disk_size)
        for disk in disks.splitlines():
            if disk.startswith("  Disk"):
                o = re.findall(regex_str, disk, re.I | re.M)
                if o:
                    disk_indexs.append(o[0])

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params.get("file_system").split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    re_str = params["re_str"]
    black_list = params["black_list"].split()
    stg_image_size = params.get("stg_image_size")
    disk_indexs = []

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying"
                      " qtree vs. params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return

    try:
        cmd = params.get("clean_cmd")
        if cmd:
            session.cmd_status_output(cmd)

        if params.get("os_type") == "windows":
            error_context.context("Create partition on those disks", logging.info)
            # Get the disk index
            _get_disk_index(session, stg_image_size, disk_indexs)
            if len(disk_indexs) < stg_image_num:
                err_msg = "Set disks num: %d" % stg_image_num
                err_msg += ", Get disks num in guest: %d" % len(disk_indexs)
                test.fail("Fail to list all the volumes, %s" % err_msg)

            # Random select one file system from file_system
            index = random.randint(0, (len(file_system) - 1))
            fs_type = file_system[index].strip()
            for i in range(stg_image_num):
                utils_misc.format_windows_disk(session, disk_indexs[i], None,
                                               None, fs_type)

        error_context.context("Get disks dev filenames in guest", logging.info)
        cmd = params["list_volume_command"]
        s, output = session.cmd_status_output(cmd, timeout=cmd_timeout)
        if s != 0:
            test.fail("List volume command failed with cmd '%s'.\n"
                      "Output is: %s\n" % (cmd, output))

        output = session.cmd_output(cmd, timeout=cmd_timeout)
        disks = re.findall(re_str, output)
        disks = list(map(string.strip, disks))
        disks.sort()
        logging.debug("Volume list that meet regular expressions: %s",
                      " ".join(disks))

        images = params.get("images").split()
        if len(disks) < len(images):
            logging.debug("disks: %s , images: %s", len(disks), len(images))
            test.fail("Fail to list all the volumes!")

        if params.get("os_type") == "linux":
            output = session.cmd_output("mount")
            li = re.findall(r"^/dev/(%s)\d*" % re_str, output, re.M)
            if li:
                black_list.extend(li)
        else:
            black_list.extend(utils_misc.get_winutils_vol(session))
        disks = set(disks)
        black_list = set(black_list)
        logging.info("No need to check volume '%s'", (disks & black_list))
        disks = disks - black_list
    except Exception:
        _do_post_cmd(session)
        raise

    try:
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            error_context.context("Format those disks in guest", logging.info)
            for disk in disks:
                disk = disk.strip()
                error_context.context("Preparing disk: %s..." % disk)

                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fs = file_system[index].strip()
                cmd = params["format_command"] % (fs, disk)
                error_context.context("formatting test disk")
                session.cmd(cmd, timeout=cmd_timeout)
                cmd = params.get("mount_command")
                if cmd:
                    cmd = cmd % (disk, disk, disk)
                    session.cmd(cmd)

            error_context.context("Cope file into / out of those disks", logging.info)
            for disk in disks:
                disk = disk.strip()

                error_context.context("Performing I/O on disk: %s..." % disk)
                cmd_list = params["cmd_list"].split()
                for cmd_l in cmd_list:
                    cmd = params.get(cmd_l)
                    if cmd:
                        session.cmd(cmd % disk, timeout=cmd_timeout)

                cmd = params["compare_command"]
                key_word = params["check_result_key_word"]
                output = session.cmd_output(cmd)
                if key_word not in output:
                    test.fail("Files on guest os root fs and disk differ")

            if params.get("umount_command"):
                cmd = params.get("show_mount_cmd")
                output = session.cmd_output(cmd)
                disks = re.findall(re_str, output)
                disks.sort()
                for disk in disks:
                    disk = disk.strip()
                    error_context.context("Unmounting disk: %s..." % disk)
                    cmd = params.get("umount_command") % (disk, disk)
                    session.cmd(cmd)
    finally:
        cmd = params.get("show_mount_cmd")
        if cmd:
            try:
                output = session.cmd_output(cmd)
                disks = re.findall(re_str, output)
                disks.sort()
                for disk in disks:
                    error_context.context("Unmounting disk: %s..." % disk)
                    cmd = params["umount_command"] % (disk, disk)
                    session.cmd(cmd)
            except Exception as err:
                logging.warn("Get error when cleanup, '%s'", err)

        _do_post_cmd(session)
Beispiel #19
0
    def _run(self, args):
        """
        List available test modules.

        :param args: Command line args received from the list subparser.
        """
        self.view = output.View(app_args=args,
                                use_paginator=args.paginator == 'on')

        paths = [data_dir.get_test_dir()]
        if args.paths:
            paths = args.paths
        params_list = self.test_loader.discover_urls(paths)
        for params in params_list:
            params['omit_non_tests'] = False
        test_suite = self.test_loader.discover(params_list)
        error_msg_parts = self.test_loader.validate_ui(test_suite,
                                                       ignore_not_test=True,
                                                       ignore_access_denied=True,
                                                       ignore_broken_symlinks=True)
        if error_msg_parts:
            for error_msg in error_msg_parts:
                self.view.notify(event='error', msg=error_msg)
            self.view.cleanup()
            sys.exit(exit_codes.AVOCADO_FAIL)

        test_matrix = []
        stats = {'simple': 0,
                 'instrumented': 0,
                 'buggy': 0,
                 'missing': 0,
                 'not_a_test': 0,
                 'broken_symlink': 0,
                 'access_denied': 0}
        for cls, params in test_suite:
            id_label = ''
            type_label = cls.__name__

            if 'params' in params:
                id_label = params['params']['id']
            else:
                if 'name' in params:
                    id_label = params['name']
                elif 'path' in params:
                    id_label = params['path']

            if cls == test.SimpleTest:
                stats['simple'] += 1
                type_label = self.term_support.healthy_str('SIMPLE')
            elif cls == test.BuggyTest:
                stats['buggy'] += 1
                type_label = self.term_support.fail_header_str('BUGGY')
            elif cls == test.NotATest:
                if not args.verbose:
                    continue
                stats['not_a_test'] += 1
                type_label = self.term_support.warn_header_str('NOT_A_TEST')
            elif cls == test.MissingTest:
                stats['missing'] += 1
                type_label = self.term_support.fail_header_str('MISSING')
            elif cls == loader.BrokenSymlink:
                stats['broken_symlink'] += 1
                type_label = self.term_support.fail_header_str('BROKEN_SYMLINK')
            elif cls == loader.AccessDeniedPath:
                stats['access_denied'] += 1
                type_label = self.term_support.fail_header_str('ACCESS_DENIED')
            else:
                if issubclass(cls, test.Test):
                    stats['instrumented'] += 1
                    type_label = self.term_support.healthy_str('INSTRUMENTED')

            test_matrix.append((type_label, id_label))

        header = None
        if args.verbose:
            header = (self.term_support.header_str('Type'),
                      self.term_support.header_str('file'))
        for line in astring.tabular_output(test_matrix,
                                           header=header).splitlines():
            self.view.notify(event='minor', msg="%s" % line)

        if args.verbose:
            self.view.notify(event='minor', msg='')

            self.view.notify(event='message', msg=("SIMPLE: %s" %
                                                   stats['simple']))
            self.view.notify(event='message', msg=("INSTRUMENTED: %s" %
                                                   stats['instrumented']))
            self.view.notify(event='message', msg=("BUGGY: %s" %
                                                   stats['buggy']))
            self.view.notify(event='message', msg=("MISSING: %s" %
                                                   stats['missing']))
            self.view.notify(event='message', msg=("NOT_A_TEST: %s" %
                                                   stats['not_a_test']))
            self.view.notify(event='message', msg=("ACCESS_DENIED: %s" %
                                                   stats['access_denied']))
            self.view.notify(event='message', msg=("BROKEN_SYMLINK: %s" %
                                                   stats['broken_symlink']))
Beispiel #20
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params["file_system"].split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    black_list = params["black_list"].split()
    drive_letters = int(params.get("drive_letters", "26"))
    stg_image_size = params["stg_image_size"]
    dd_test = params.get("dd_test", "no")
    pre_command = params.get("pre_command", "")
    labeltype = params.get("labeltype", "gpt")
    iozone_target_num = int(params.get('iozone_target_num', '5'))
    iozone_options = params.get('iozone_options')
    iozone_timeout = float(params.get('iozone_timeout', '7200'))

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying qtree vs."
                      " params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return
    try:
        err_msg = "Set disks num: %d" % stg_image_num
        err_msg += ", Get disks num in guest: %d"
        ostype = params["os_type"]
        if ostype == "windows":
            error_context.context(
                "Get windows disk index that to "
                "be formatted", logging.info)
            disks = utils_disk.get_windows_disks_index(session, stg_image_size)
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
            if len(disks) > drive_letters:
                black_list.extend(utils_misc.get_winutils_vol(session))
                disks = random.sample(disks, drive_letters - len(black_list))
            error_context.context(
                "Clear readonly for all disks and online "
                "them in windows guest.", logging.info)
            if not utils_disk.update_windows_disk_attributes(session, disks):
                test.fail("Failed to update windows disk attributes.")
            dd_test = "no"
        else:
            error_context.context("Get linux disk that to be "
                                  "formatted", logging.info)
            disks = sorted(utils_disk.get_linux_disks(session).keys())
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
    except Exception:
        _do_post_cmd(session)
        raise
    try:
        if iozone_options:
            iozone = generate_instance(params, session, 'iozone')
            random.shuffle(disks)
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            for n, disk in enumerate(disks):
                error_context.context("Format disk in guest: '%s'" % disk,
                                      logging.info)
                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fstype = file_system[index].strip()
                partitions = utils_disk.configure_empty_disk(
                    session,
                    disk,
                    stg_image_size,
                    ostype,
                    fstype=fstype,
                    labeltype=labeltype)
                if not partitions:
                    test.fail("Fail to format disks.")
                cmd_list = params["cmd_list"]
                for partition in partitions:
                    orig_partition = partition
                    if "/" not in partition:
                        partition += ":"
                    else:
                        partition = partition.split("/")[-1]
                    error_context.context(
                        "Copy file into / out of partition:"
                        " %s..." % partition, logging.info)
                    for cmd_l in cmd_list.split():
                        cmd = params.get(cmd_l)
                        if cmd:
                            session.cmd(cmd % partition, timeout=cmd_timeout)
                    cmd = params["compare_command"]
                    key_word = params["check_result_key_word"]
                    output = session.cmd_output(cmd)
                    if iozone_options and n < iozone_target_num:
                        iozone.run(iozone_options.format(orig_partition),
                                   iozone_timeout)
                    if key_word not in output:
                        test.fail("Files on guest os root fs and disk differ")
                    if dd_test != "no":
                        error_context.context(
                            "dd test on partition: %s..." % partition,
                            logging.info)
                        status, output = session.cmd_status_output(
                            dd_test % (partition, partition),
                            timeout=cmd_timeout)
                        if status != 0:
                            test.fail("dd test fail: %s" % output)
                    # When multiple SCSI disks are simulated by scsi_debug,
                    # they could be viewed as multiple paths to the same
                    # storage device. So need umount partition before operate
                    # next disk, in order to avoid corrupting the filesystem
                    # (xfs integrity checks error).
                    if ostype == "linux" and "scsi_debug add_host" in pre_command:
                        status, output = session.cmd_status_output(
                            "umount /dev/%s" % partition, timeout=cmd_timeout)
                        if status != 0:
                            test.fail("Failed to umount partition '%s': %s" %
                                      (partition, output))
            need_reboot = params.get("need_reboot", "no")
            need_shutdown = params.get("need_shutdown", "no")
            if need_reboot == "yes":
                error_context.context("Rebooting guest ...", logging.info)
                session = vm.reboot(session=session, timeout=login_timeout)
            if need_shutdown == "yes":
                error_context.context("Shutting down guest ...", logging.info)
                vm.graceful_shutdown(timeout=login_timeout)
                if vm.is_alive():
                    test.fail("Fail to shut down guest.")
                error_context.context("Start the guest again.", logging.info)
                vm = env.get_vm(params["main_vm"])
                vm.create(params=params)
                session = vm.wait_for_login(timeout=login_timeout)
            error_context.context("Delete partitions in guest.", logging.info)
            for disk in disks:
                utils_disk.clean_partition(session, disk, ostype)
    finally:
        if iozone_options:
            iozone.clean()
        _do_post_cmd(session)
    def report(self, overall_results, record_size_results, file_size_results):
        """
        Generates analysis data for IOZone run.

        Generates a report to both logs (where it goes with nice headers) and
        output files for further processing (graph generation).

        :param overall_results: 1x15 Matrix containing IOzone results for all
                file sizes
        :param record_size_results: nx15 Matrix containing IOzone results for
                each record size tested.
        :param file_size_results: nx15 Matrix containing file size results
                for each file size tested.
        """

        formatter = logging.Formatter("")

        self.log.info("")
        self.log.info("TABLE:  SUMMARY of ALL FILE and RECORD SIZES           "
                      "Results in MB/sec")
        self.log.info("")
        overall_results[0].insert(0, "ALL")
        header_list = ['FILE & RECORD SIZES (KB)', 'INIT WRITE', 'RE WRITE',
                       'READ', 'RE READ', 'RANDOM READ', 'RANDOM WRITE',
                       'BACKWD READ', 'RECRE WRITE', 'STRIDE READ', 'F WRITE',
                       'FRE WRITE', 'F READ', 'FRE READ']
        self.log.info("\n%s", astring.tabular_output(
            overall_results, header=header_list))
        self.log.info("")

        self.log.info("DRILLED DATA:")

        self.log.info("")
        self.log.info("TABLE:  RECORD Size against all FILE Sizes             "
                      "Results in MB/sec")
        self.log.info("")
        foutput_path = os.path.join(self.output_dir, '2d-datasource-file')
        if os.path.isfile(foutput_path):
            os.unlink(foutput_path)
        foutput = logging.FileHandler(foutput_path)
        foutput.setFormatter(formatter)
        self.log.addHandler(foutput)

        header_list = ['RECORD SIZE (KB)', 'INIT WRITE', 'RE WRITE', 'READ',
                       'RE READ', 'RANDOM READ', 'RANDOM WRITE', 'BACKWD READ',
                       'RECRE WRITE', 'STRIDE READ', 'F WRITE', 'FRE WRITE',
                       'F READ', 'FRE READ']
        self.log.info("\n%s", astring.tabular_output(
            record_size_results, header=header_list))
        self.log.removeHandler(foutput)

        self.log.info("")
        self.log.info("TABLE:  FILE Size against all RECORD Sizes             "
                      "Results in MB/sec")
        self.log.info("")
        routput_path = os.path.join(self.output_dir, '2d-datasource-record')
        if os.path.isfile(routput_path):
            os.unlink(routput_path)
        routput = logging.FileHandler(routput_path)
        routput.setFormatter(formatter)
        self.log.addHandler(routput)

        self.log.info("\n%s", astring.tabular_output(
            file_size_results, header=header_list))
        self.log.removeHandler(routput)

        self.log.info("")