1# Copyright (c) 2014 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"""Mock out test results for puppylab. 6""" 7 8 9import logging 10import os 11import time 12 13import common 14from autotest_lib.client.common_lib import time_utils 15from autotest_lib.puppylab import templates 16 17 18class ResultsMocker(object): 19 """Class to mock out the results of a test.""" 20 21 def _make_dirs(self): 22 """Create essential directories needed for faking test results. 23 24 @raises ValueError: If the directories crucial to reporting 25 test status already exist. 26 @raises OSError: If we cannot make one of the directories for 27 an os related reason (eg: permissions). 28 @raises AssertionError: If one of the directories silently failed 29 creation. 30 """ 31 logging.info("creating dir %s, %s, %s", 32 self.results_dir, self.test_results, self.host_keyval_dir) 33 if not os.path.exists(self.results_dir): 34 os.makedirs(self.results_dir) 35 if not os.path.exists(self.test_results): 36 os.makedirs(self.test_results) 37 if not os.path.exists(self.host_keyval_dir): 38 os.makedirs(self.host_keyval_dir) 39 assert(os.path.exists(self.test_results) and 40 os.path.exists(self.results_dir) and 41 os.path.exists(self.host_keyval_dir)) 42 43 44 def __init__(self, test_name, results_dir, machine_name): 45 """Initialize a results mocker. 46 47 @param test_name: The name of the test, eg: dummy_Pass. 48 @param results_dir: The results directory this test will use. 49 @param machine_name: A string representing the hostname the test will 50 run on. 51 """ 52 self.results_dir = results_dir 53 self.test_results = os.path.join(results_dir, test_name) 54 self.host_keyval_dir = os.path.join(self.results_dir, 'host_keyvals') 55 self.machine_name = machine_name 56 self.test_name = test_name 57 58 self._make_dirs() 59 60 # Status logs are used by the parser to declare a test as pass/fail. 61 self.job_status = os.path.join(self.results_dir, 'status') 62 self.job_status_log = os.path.join(self.results_dir, 'status.log') 63 self.test_status = os.path.join(self.test_results, 'status') 64 65 # keyvals are used by the parser to figure out fine grained information 66 # about a test. Only job_keyvals are crucial to parsing. 67 self.test_keyvals = os.path.join(self.test_results, 'keyval') 68 self.job_keyvals = os.path.join(self.results_dir, 'keyval') 69 self.host_keyvals = os.path.join(self.results_dir, machine_name) 70 71 72 def _write(self, results_path, results): 73 """Write the content in results to the file in results_path. 74 75 @param results_path: The path to the results file. 76 @param results: The content to write to the file. 77 """ 78 logging.info('Writing results to %s', results_path) 79 with open(results_path, 'w') as results_file: 80 results_file.write(results) 81 82 83 def generate_keyvals(self): 84 """Apply templates to keyval files. 85 86 There are 3 important keyvals files, only one of which is actually 87 crucial to results parsing: 88 host_keyvals - information about the DUT 89 job_keyvals - information about the server_job 90 test_keyvals - information about the test 91 92 Parsing cannot complete without the job_keyvals. Everything else is 93 optional. Keyvals are parsed into tko tables. 94 """ 95 #TODO(beeps): Include other keyvals. 96 self._write( 97 self.job_keyvals, 98 templates.job_keyvals_template % 99 {'hostname': self.machine_name}) 100 101 102 def generate_status(self): 103 """Generate status logs. 104 105 3 important status logs are required for successful parsing: 106 test_name/status - core test status 107 results_dir/status - server job status (has test status in it) 108 status.log - compiled final status log 109 """ 110 current_timestamp = int(time.time()) 111 test_info = { 112 'test_name': self.test_name, 113 'timestamp': current_timestamp, 114 'date': time_utils.epoch_time_to_date_string( 115 current_timestamp, fmt_string='%b %d %H:%M:%S'), 116 } 117 self._write( 118 self.job_status, 119 templates.success_job_template % test_info) 120 self._write( 121 self.job_status_log, 122 templates.success_job_template % test_info) 123 self._write( 124 self.test_status, 125 templates.success_test_template % test_info) 126 127 128 def mock_results(self): 129 """Create mock results in the directories used to init the instance.""" 130 self.generate_status() 131 self.generate_keyvals() 132 133 134