github.com/greenplum-db/gpbackup@v0.0.0-20240517212602-89daab1885b3/ci/scripts/analyze_run.py (about)

     1  #!/usr/bin/python2
     2  
     3  import os
     4  import sys
     5  from datetime import datetime
     6  from pygresql import pg
     7  
     8  ## Constants for interacting with refdb
     9  RESULTS_LOG_FILE = os.environ.get('RESULTS_LOG_FILE')
    10  RESULTS_DATABASE_HOST = os.environ.get('RESULTS_DATABASE_HOST')
    11  RESULTS_DATABASE_USER = os.environ.get('RESULTS_DATABASE_USER')
    12  RESULTS_DATABASE_NAME = os.environ.get('RESULTS_DATABASE_NAME')
    13  RESULTS_DATABASE_PASSWORD = os.environ.get('RESULTS_DATABASE_PASSWORD')
    14  GPDB_VERSION = os.environ.get('GPDB_VERSION').replace("gpstart version ", "")
    15  GPB_VERSION = os.environ.get('GPB_VERSION').replace("gpbackup version ", "")
    16  
    17  
    18  def parse_runtime(logline):
    19      runtime = int(float(logline.replace("TEST RUNTIME: ", "").replace("\n", "").replace("\r", "")))
    20      return runtime
    21  
    22  def parse_log():
    23      """Extract required info from log file"""
    24      log_dict = {}
    25      with open(RESULTS_LOG_FILE, 'r') as fp:
    26          log_lines = fp.readlines()
    27  
    28      for line in log_lines:
    29          if line.startswith('TEST RUNTIME'):
    30              runtime = parse_runtime(line)
    31              log_dict['test_runtime'] = runtime
    32      return log_dict
    33  
    34  def get_test_id(test_name):
    35      conn = pg.connect(
    36          dbname=RESULTS_DATABASE_NAME,
    37          host=RESULTS_DATABASE_HOST,
    38          user=RESULTS_DATABASE_USER,
    39          passwd=RESULTS_DATABASE_PASSWORD
    40      )
    41  
    42      select_string = """
    43          SELECT
    44              tn.test_id
    45          FROM 
    46              prod.test_names tn
    47          WHERE
    48              tn.test_name = '{}'
    49          ;
    50      """.format(test_name)
    51  
    52      query = conn.query(select_string)
    53      result = query.getresult()
    54      result = result[0] # unpack list of single tuple
    55      conn.close()
    56  
    57      test_id = result[0]
    58  
    59      return test_id
    60  
    61  
    62  def get_stats(test_name):
    63      """Retrieve stats for given test name from provided postgres database"""
    64      stats_dict = {}
    65      conn = pg.connect(
    66          dbname=RESULTS_DATABASE_NAME,
    67          host=RESULTS_DATABASE_HOST,
    68          user=RESULTS_DATABASE_USER,
    69          passwd=RESULTS_DATABASE_PASSWORD
    70      )
    71  
    72      select_string = """
    73          SELECT
    74              tn.test_id,
    75              tn.test_name,
    76              ts.test_runs_included,
    77              ts.test_runtime_avg,
    78              ts.test_runtime_var,
    79              ts.test_limit_report,
    80              ts.test_limit_fail
    81          FROM 
    82              prod.test_names tn
    83              LEFT JOIN prod.test_stats ts
    84                  ON ts.test_id = tn.test_id
    85          WHERE
    86              tn.test_name = '{}'
    87          ;
    88      """.format(test_name)
    89  
    90      query = conn.query(select_string)
    91      result = query.getresult()
    92      conn.close()
    93  
    94      if result:
    95          result = result[0] # unpack list of single tuple
    96          stats_dict['test_id'] = result[0]
    97          stats_dict['test_name'] = result[1]
    98          stats_dict['test_runs_included'] = result[2] or 0
    99          stats_dict['test_runtime_avg'] = result[3] or 0
   100          stats_dict['test_runtime_var'] = result[4] or 0
   101          stats_dict['test_limit_report'] = result[5] or 99999
   102          stats_dict['test_limit_fail'] = result[6] or 99999
   103  
   104      return stats_dict
   105  
   106  def analyze_stats(run_stats, summary_stats, test_name):
   107      """
   108      Possible result values are: "pass" "fail" "report"
   109      """
   110      run_stats['was_failed'] = "false"
   111      run_stats['was_reported'] = "false"
   112  
   113      if (
   114          summary_stats.get('test_runs_included', 0) >= 10
   115          and run_stats.get('test_runtime') >= summary_stats.get('test_limit_fail')
   116          ):
   117          run_stats['was_failed'] = "true"
   118  
   119      if run_stats.get('was_failed') == "true":
   120          result_string = "Failed"
   121      else:
   122          result_string = "Passed"
   123  
   124      report_string = """
   125      ############################################################
   126      Test Name: {test_name}
   127      Runtime: {run_time}
   128      Compared against: {summary_stats}
   129      Comparison result: {comp_result}
   130      ############################################################
   131      """.format(
   132          test_name = test_name,
   133          run_time = run_stats.get('test_runtime'),
   134          summary_stats = summary_stats,
   135          comp_result = result_string
   136      )
   137      print report_string
   138      return
   139  
   140  def store_stats(run_stats, test_id, test_name):
   141      now_ts = datetime.now()
   142      now_ts_str = datetime.strftime(now_ts, "%Y-%m-%d-%H-%M-%S")
   143      conn = pg.connect(
   144          dbname=RESULTS_DATABASE_NAME,
   145          host=RESULTS_DATABASE_HOST,
   146          user=RESULTS_DATABASE_USER,
   147          passwd=RESULTS_DATABASE_PASSWORD
   148      )
   149  
   150      insert_qry_string = """
   151      INSERT INTO prod.test_runs(test_id, run_timestamp, test_runtime, gpbackup_version, gpdb_version, was_reported, was_failed)
   152      VALUES
   153          ({id}, '{ts}', {runtime}, '{gpbver}', '{gpdbver}', {reported}, {failed})
   154      ;
   155      """.format(
   156          id=test_id, 
   157          ts=now_ts_str,
   158          gpbver=GPB_VERSION,
   159          gpdbver=GPDB_VERSION,
   160          runtime=run_stats.get('test_runtime', 0),
   161          reported=run_stats.get('was_reported', False),
   162          failed=run_stats.get('was_failed', True)
   163      )
   164  
   165      summ_func_qry_string = """
   166      SELECT prod.summarize_runs('{}');
   167      """.format(test_name)
   168  
   169      conn.query(insert_qry_string)
   170      conn.query(summ_func_qry_string)
   171      # conn.commit()
   172      conn.close()
   173      return
   174  
   175  def main():
   176      try:
   177          TEST_NAME = sys.argv[1]
   178          run_stats = parse_log()
   179          test_id = get_test_id(TEST_NAME)
   180          summary_stats = get_stats(TEST_NAME)
   181          analyze_stats(run_stats, summary_stats, TEST_NAME)
   182          store_stats(run_stats, test_id, TEST_NAME)
   183          return
   184      except Exception as e:
   185          print "Python script errored: {}".format(e)
   186          return
   187  
   188  if __name__ == "__main__":
   189      main()