Home | History | Annotate | Download | only in result_tools
      1 # Copyright 2017 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Shared constants and methods for result utilities."""
      6 
      7 import collections
      8 import logging
      9 import math
     10 
     11 
     12 # Logging method, default to logging.debug. TKO parser use a different logger,
     13 # so it can overwrite the logging method here.
     14 LOG = logging.debug
     15 
     16 # Following are key names for directory summaries. The keys are started with /
     17 # so it can be differentiated with a valid file name. The short keys are
     18 # designed for smaller file size of the directory summary.
     19 
     20 # Original size of the directory or file
     21 ORIGINAL_SIZE_BYTES = '/S'
     22 # Size of the directory or file after trimming
     23 TRIMMED_SIZE_BYTES = '/T'
     24 # Size of the directory or file being collected from client side
     25 COLLECTED_SIZE_BYTES = '/C'
     26 # A dictionary of sub-directories' summary: name: {directory_summary}
     27 DIRS = '/D'
     28 # Default root directory name. To allow summaries to be merged effectively, all
     29 # summaries are collected with root directory of ''
     30 ROOT_DIR = ''
     31 
     32 # Information of test result sizes to be stored in tko_job_keyvals.
     33 # The total size (in kB) of test results that generated during the test,
     34 # including:
     35 #  * server side test logs and result files.
     36 #  * client side test logs, sysinfo, system logs and crash dumps.
     37 # Note that a test can collect the same test result files from DUT multiple
     38 # times during the test, before and after each iteration/test. So the value of
     39 # client_result_collected_KB could be larger than the value of
     40 # result_uploaded_KB, which is the size of result directory on the server side,
     41 # even if the test result throttling is not applied.
     42 #
     43 # Attributes of the named tuple includes:
     44 # client_result_collected_KB: The total size (in KB) of test results collected
     45 #         from test device.
     46 # original_result_total_KB: The original size (in KB) of test results before
     47 #         being trimmed.
     48 # result_uploaded_KB: The total size (in KB) of test results to be uploaded by
     49 #         gs_offloader.
     50 # result_throttled: Flag to indicate if test results collection is throttled.
     51 ResultSizeInfo = collections.namedtuple(
     52         'ResultSizeInfo',
     53         ['client_result_collected_KB',
     54          'original_result_total_KB',
     55          'result_uploaded_KB',
     56          'result_throttled'])
     57 
     58 
     59 class NotEnoughDiskError(Exception):
     60     """Exception to raise when the target directory doesn't have enough free
     61     disk space.
     62     """
     63 
     64 
     65 def get_result_size_info(client_collected_bytes, summary):
     66     """Get the result size information.
     67 
     68     @param client_collected_bytes: Size in bytes of results collected from the
     69             test device.
     70     @param summary: A dictionary of directory summary.
     71     @return: A namedtuple of result size informations, including:
     72             client_result_collected_KB: The total size (in KB) of test results
     73                     collected from test device.
     74             original_result_total_KB: The original size (in KB) of test results
     75                     before being trimmed.
     76             result_uploaded_KB: The total size (in KB) of test results to be
     77                     uploaded.
     78             result_throttled: True if test results collection is throttled.
     79     """
     80     client_result_collected_KB= client_collected_bytes / 1024
     81     original_result_total_KB = summary.original_size / 1024
     82     result_uploaded_KB = summary.trimmed_size / 1024
     83     # Test results are considered to be throttled if the total size of
     84     # results collected is different from the total size of trimmed results
     85     # from the client side.
     86     result_throttled = (summary.original_size > summary.trimmed_size)
     87 
     88     return ResultSizeInfo(client_result_collected_KB=client_result_collected_KB,
     89                           original_result_total_KB=original_result_total_KB,
     90                           result_uploaded_KB=result_uploaded_KB,
     91                           result_throttled=result_throttled)
     92 
     93 
     94 def get_size_string(size_bytes):
     95     """Get a string of the given bytes.
     96 
     97     Convert the number of bytes to the closest integer of file size measure,
     98     i.e., KB, MB etc. If the size is less than 10, round to one decimal place of
     99     the size value.
    100 
    101     @param size_bytes: Number of bytes.
    102     @return: A string representing `size_bytes` in KB, MB etc.
    103     """
    104     if size_bytes == 0:
    105         return '0 B'
    106     size_name = ('B', 'KB', 'MB', 'GB', 'TB', 'PB')
    107     i = int(math.log(size_bytes, 1024))
    108     p = math.pow(1024, i)
    109     s = size_bytes / p
    110     if s >= 10:
    111         return '%d %s' % (int(s), size_name[i])
    112     else:
    113         # Round to one decimal place if the size is less than 10.
    114         return '%0.1f %s' % (s, size_name[i])