1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import argparse
18import json
19
20
21def read_acts_results(acts_summary_filename):
22    """Opens the ACTS results file and returns the pass/fail/unknown counters.
23
24    Args:
25        acts_summary_filename: The ACTS results file name.
26
27    Returns:
28        master_results_data: A list of all the test results, including the
29            result of each test.
30        master_results_pass: A list of all pass test results.
31        master_results_fail: A list of all fail test results.
32        master_results_unknown: A list of all unknown test results.
33        pass_counter: A counter of how many tests pass.
34        fail_counter: A counter of how many tests fail.
35        unknown_counter: A counter of how many tests are unknown.
36    """
37    with open(acts_summary_filename) as json_file:
38        data = json.load(json_file)
39
40    master_results_data = [['Test', 'Result']]
41    master_results_pass = [['Test', 'Result']]
42    master_results_fail = [['Test', 'Result']]
43    master_results_unknown = [['Test', 'Result']]
44    pass_counter = 0
45    fail_counter = 0
46    unknown_counter = 0
47
48    for result in data['Results']:
49        results_data = []
50        results_pass = []
51        results_fail = []
52        results_unknown = []
53        if result['Result'] == 'PASS':
54            results_pass.append(result['Test Name'])
55            results_pass.append(result['Result'])
56            master_results_pass.append(results_pass)
57            pass_counter += 1
58        if result['Result'] == 'FAIL':
59            results_fail.append(result['Test Name'])
60            results_fail.append(result['Result'])
61            master_results_fail.append(results_fail)
62            fail_counter += 1
63        if result['Result'] == 'UNKNOWN':
64            results_unknown.append(result['Test Name'])
65            results_unknown.append(result['Result'])
66            master_results_unknown.append(results_unknown)
67            unknown_counter += 1
68        results_data.append(result['Test Name'])
69        results_data.append(result['Result'])
70        master_results_data.append(results_data)
71    return (master_results_data,
72            master_results_pass,
73            master_results_fail,
74            master_results_unknown,
75            pass_counter,
76            fail_counter,
77            unknown_counter)
78
79
80def print_acts_summary(master_results_data,
81                       master_results_pass,
82                       master_results_fail,
83                       master_results_unknown,
84                       pass_counter,
85                       fail_counter,
86                       unknown_counter,
87                       split_results=False,
88                       ):
89    """Prints the ACTS test results as either all of the tests together, or
90    split into pass, fail, and unknown.
91
92    Args:
93        master_results_data: A list of all the test results, including the
94            result of each test.
95        master_results_pass: A list of all pass test results.
96        master_results_fail: A list of all fail test results.
97        master_results_unknown: A list of all unknown test results.
98        pass_counter: A counter of how many tests pass.
99        fail_counter: A counter of how many tests fail.
100        unknown_counter: A counter of how many tests are unknown.
101        split_results: Whether to split the results into pass/fail/unknown or
102            display the results in the order the tests were run.
103    """
104    widths = [max(map(len, col)) for col in zip(*master_results_data)]
105    if not split_results:
106        for row in master_results_data:
107            print('  '.join((val.ljust(width) for val, width in zip(row,
108                                                                    widths))))
109        print('')
110        print('Pass: %s     '
111              'Fail: %s     '
112              'Unknown: %s  '
113              'Total: %s' % (pass_counter,
114                             fail_counter,
115                             unknown_counter,
116                             pass_counter+fail_counter+unknown_counter))
117    else:
118        print('')
119        for row in master_results_pass:
120            print('  '.join((val.ljust(width) for val, width in zip(row,
121                                                                    widths))))
122        print('Pass: %s' % pass_counter)
123
124        print('')
125        for row in master_results_fail:
126            print('  '.join((val.ljust(width) for val, width in zip(row,
127                                                                    widths))))
128        print('Fail: %s' % fail_counter)
129        if unknown_counter is not 0:
130            print('')
131            for row in master_results_unknown:
132                print('  '.join((val.ljust(width)
133                                 for val, width in zip(row, widths))))
134            print('Unknown: %s' % unknown_counter)
135
136
137def main():
138    parser = argparse.ArgumentParser()
139    parser.add_argument('-f',
140                        '--results_file',
141                        help='ACTS results file')
142    parser.add_argument('--split_results',
143                        help='separate passing and failing results',
144                        action='store_true')
145
146    args = parser.parse_args()
147    if not args.results_file:
148        parser.error('Use --results_file or -f to specify the ACTS '
149                     'results file you want to parse.')
150
151    (master_results_data,
152     master_results_pass,
153     master_results_fail,
154     master_results_unknown,
155     pass_counter,
156     fail_counter,
157     unknown_counter) = read_acts_results(args.results_file)
158    print_acts_summary(master_results_data,
159                       master_results_pass,
160                       master_results_fail,
161                       master_results_unknown,
162                       pass_counter,
163                       fail_counter,
164                       unknown_counter,
165                       split_results=args.split_results)
166
167
168if __name__ == '__main__':
169    main()
170