• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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