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