weekly_report.py revision 8a68b2d90fdafdd45c636cf48375c944107d5062
1#!/usr/bin/python
2#
3# Copyright Google Inc. 2014
4
5import datetime
6import optparse
7import os
8import sys
9import time
10
11from utils import constants
12from utils import command_executer
13
14WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
15
16DATA_ROOT_DIR = os.path.join(constants.CROSTC_WORKSPACE,
17                             'weekly_test_data')
18
19EXPERIMENT_FILE = os.path.join(DATA_ROOT_DIR, 'weekly_report')
20
21
22def Generate_Vanilla_Report_File(vanilla_image_paths, board, remote,
23                                 chromeos_root, cmd_executer):
24
25    experiment_header = """
26name: weekly_vanilla_report
27cache_only: True
28same_specs: False
29board: %s
30remote: %s
31""" % (board, remote)
32
33
34    experiment_tests = """
35benchmark: all_perfv2 {
36  suite: telemetry_Crosperf
37  iterations: 3
38}
39"""
40
41    filename = "%s_%s_vanilla.exp" % (EXPERIMENT_FILE, board)
42    if os.path.exists(filename):
43        cmd = "rm %s" % filename
44        cmd_executer.RunCommand(cmd)
45
46    with open(filename, "w") as f:
47        print >>f, experiment_header
48        print >>f, experiment_tests
49
50        # Add each vanilla image
51        for test_path in vanilla_image_paths:
52            pieces = test_path.split("/")
53            test_name = pieces[-1]
54            test_image = """
55%s {
56  chromeos_root: %s
57  chromeos_image: %s
58}
59""" % (test_name, chromeos_root, os.path.join (test_path,
60                                               "chromiumos_test_image.bin"))
61            print >>f, test_image
62
63    return filename
64
65def Generate_Test_File(test_image_paths, vanilla_image_path, board, remote,
66                       chromeos_root, cmd_executer):
67
68    experiment_header = """
69name: weekly_report
70cache_only: True
71same_specs: False
72board: %s
73remote: %s
74""" % (board, remote)
75
76
77    experiment_tests = """
78benchmark: all_perfv2 {
79  suite: telemetry_Crosperf
80  iterations: 3
81}
82"""
83
84    filename = "%s_%s.exp" % (EXPERIMENT_FILE, board)
85    if os.path.exists(filename):
86        cmd = "rm %s" % filename
87        cmd_executer.RunCommand(cmd)
88
89    with open(filename, "w") as f:
90        print >>f, experiment_header
91        print >>f, experiment_tests
92
93        # Add vanilla image (first)
94        vanilla_image = """
95%s {
96  chromeos_root: %s
97  chromeos_image: %s
98}
99""" % (vanilla_image_path.split("/")[-1],
100       chromeos_root, os.path.join(vanilla_image_path,
101                                   "chromiumos_test_image.bin"))
102
103        print >>f, vanilla_image
104
105        # Add each test image
106        for test_path in test_image_paths:
107            pieces = test_path.split("/")
108            test_name = pieces[-1]
109            test_image = """
110%s {
111  chromeos_root: %s
112  chromeos_image: %s
113}
114""" % (test_name, chromeos_root, os.path.join (test_path,
115                                               "chromiumos_test_image.bin"))
116            print >>f, test_image
117
118    return filename
119
120
121
122def Main(argv):
123
124    parser = optparse.OptionParser()
125    parser.add_option('-b', '--board', dest='board',
126                      help='Target board.')
127    parser.add_option("-r", "--remote", dest="remote",
128                    help="Target device.")
129    parser.add_option("-v", "--vanilla_only", dest="vanilla_only",
130                    action="store_true",
131                    default=False,
132                    help="Generate a report comparing only the vanilla images.")
133
134    options = parser.parse_args(argv[1:])[0]
135
136    if not options.board:
137        print "Must specify a board."
138        return 1
139
140    if not options.remote:
141        print "Must specify at least one remote."
142        return 1
143
144    cmd_executer = command_executer.GetCommandExecuter(log_level="average")
145
146    # Find starting index, for cycling through days of week, generating
147    # reports starting 6 days ago from today. Generate list of indices for
148    # order in which to look at weekdays for report:
149    todays_index = datetime.datetime.today().isoweekday()
150    indices = []
151    start = todays_index + 1
152    end = start + 7
153    for i in range(start,end):
154      indices.append(i % 7)
155    # E.g. if today is Sunday, then start report with last Monday, so
156    # indices = [1, 2, 3, 4, 5, 6, 0].
157
158
159
160    # Find all the test image tar files, untar them and add them to
161    # the list. Also find and untar vanilla image tar files, and keep
162    # track of the first vanilla image.
163    report_image_paths = []
164    vanilla_image_paths = []
165    first_vanilla_image = None
166    for i in indices:
167        day = WEEKDAYS[i]
168        data_path = os.path.join(DATA_ROOT_DIR, options.board, day)
169        if os.path.exists(data_path):
170            # First, untar the test image.
171            tar_file_name = "%s_test_image.tar" % day
172            tar_file_path = os.path.join(data_path, tar_file_name)
173            image_dir = "%s_test_image" % day
174            image_path = os.path.join(data_path, image_dir)
175            if os.path.exists(tar_file_path):
176                if not os.path.exists(image_path):
177                    os.makedirs(image_path)
178                cmd = ("cd %s; tar -xvf %s -C %s --strip-components 1" %
179                       (data_path, tar_file_path, image_path))
180                ret = cmd_executer.RunCommand(cmd)
181                if not ret:
182                    report_image_paths.append(image_path)
183            # Next, untar the vanilla image.
184            vanilla_file = "%s_vanilla_image.tar" % day
185            v_file_path = os.path.join(data_path, vanilla_file)
186            image_dir = "%s_vanilla_image" % day
187            image_path = os.path.join(data_path, image_dir)
188            if os.path.exists(v_file_path):
189                if not os.path.exists(image_path):
190                    os.makedirs(image_path)
191                cmd = ("cd %s; tar -xvf %s -C %s --strip-components 1" %
192                       (data_path, v_file_path, image_path))
193                ret = cmd_executer.RunCommand(cmd)
194                if not ret:
195                    vanilla_image_paths.append(image_path)
196                if not first_vanilla_image:
197                    first_vanilla_image = image_path
198
199    # Find a chroot we can use.  Look for a directory containing both
200    # an experiment file and a chromeos directory (the experiment file will
201    # only be created if both images built successfully, i.e. the chroot is
202    # good).
203    chromeos_root = None
204    for day in WEEKDAYS:
205        startdir = os.path.join(constants.CROSTC_WORKSPACE, day)
206        num_dirs = os.listdir(startdir)
207        for d in num_dirs:
208            exp_file = os.path.join(startdir, d, "toolchain_experiment.txt")
209            chroot = os.path.join(startdir, d, "chromeos")
210            if os.path.exists(chroot) and os.path.exists(exp_file):
211                chromeos_root = chroot
212            if chromeos_root:
213                break;
214        if chromeos_root:
215            break;
216
217    if not chromeos_root:
218        print "Unable to locate a usable chroot. Exiting without report."
219        return 1
220
221
222    # Create the Crosperf experiment file for generating the weekly report.
223    if not options.vanilla_only:
224        filename = Generate_Test_File (report_image_paths, first_vanilla_image,
225                                       options.board, options.remote,
226                                       chromeos_root, cmd_executer)
227    else:
228        filename = Generate_Vanilla_Report_File (vanilla_image_paths,
229                                                 options.board, options.remote,
230                                                 chromeos_root, cmd_executer)
231
232    # Run Crosperf on the file to generate the weekly report.
233    cmd = ("%s/toolchain-utils/crosperf/crosperf "
234           "%s --email=c-compiler-chrome@google.com" %
235           (constants.CROSTC_WORKSPACE, filename))
236    retval = cmd_executer.RunCommand(cmd)
237    return retval
238
239
240
241if __name__ == '__main__':
242    retval = Main(sys.argv)
243    sys.exit(retval)
244