def ParseDiskSpdResults()

in perfkitbenchmarker/windows_packages/diskspd.py [0:0]


def ParseDiskSpdResults(result_xml, metadata, main_metric):
  """Parses the xml output from DiskSpd and returns a list of samples.

  each list of sample only have one sample with read speed as value
  all the other information is stored in the meta data

  Args:
    result_xml: diskspd output
    metadata: the running info of vm
    main_metric: the main metric to test, for example 'ReadSpeed'

  Returns:
    list of samples from the results of the diskspd tests.
  """
  xml_root = xml.etree.ElementTree.fromstring(result_xml)
  metadata = metadata.copy()

  # Get the parameters from the sender XML output. Add all the
  # information of diskspd result to metadata
  for item in list(xml_root):
    if item.tag == 'TimeSpan':
      for subitem in list(item):
        if subitem.tag == 'Thread':
          target_item = subitem.find('Target')
          for read_write_info in list(target_item):
            if read_write_info.tag not in ['Path', 'FileSize']:
              if read_write_info.tag not in metadata:
                metadata[read_write_info.tag] = 0
              try:
                metadata[read_write_info.tag] += int(read_write_info.text)
              except ValueError:
                metadata[read_write_info.tag] += float(read_write_info.text)
        elif subitem.tag == 'CpuUtilization':
          target_item = subitem.find('Average')
          for cpu_info in list(target_item):
            metadata[cpu_info.tag] = cpu_info.text
        elif subitem.tag == 'Latency':
          # Latency data is added at the top level of the xml data, so no need
          # to add it again here.
          pass
        else:
          metadata[subitem.tag] = subitem.text
    if item.tag == 'Profile':
      for subitem in list(item):
        if subitem.tag == 'TimeSpans':
          timespan_info = subitem.find('TimeSpan')
          for timespan_item in list(timespan_info):
            if timespan_item.tag == 'Targets':
              target_info = timespan_item.find('Target')
              for target_item in list(target_info):
                if target_item.tag == 'WriteBufferContent':
                  pattern_item = target_item.find('Pattern')
                  metadata[pattern_item.tag] = pattern_item.text
                else:
                  metadata[target_item.tag] = target_item.text
            else:
              metadata[timespan_item.tag] = timespan_item.text

  read_bytes = int(metadata['ReadBytes'])
  write_bytes = int(metadata['WriteBytes'])
  read_count = int(metadata['ReadCount'])
  write_count = int(metadata['WriteCount'])
  total_byte = int(metadata['BytesCount'])
  total_count = int(metadata['IOCount'])
  testtime = float(metadata['TestTimeSeconds'])

  # calculate the read and write speed (Byte -> MB)
  read_speed = int(read_bytes / testtime / 1024 / 1024)
  write_speed = int(write_bytes / testtime / 1024 / 1024)
  total_speed = int(total_byte / testtime / 1024 / 1024)

  # calculate the read write times per second
  read_iops = int(read_count / testtime)
  write_iops = int(write_count / testtime)
  total_iops = int(total_count / testtime)

  # store the speed and iops information in metadata
  metadata['ReadSpeed'] = read_speed
  metadata['WriteSpeed'] = write_speed
  metadata['ReadIops'] = read_iops
  metadata['WriteIops'] = write_iops
  metadata['TotalSpeed'] = total_speed
  metadata['TotalIops'] = total_iops

  return sample.Sample(main_metric, metadata[main_metric], 'MB/s', metadata)