blob: 3e0fcc99f365e0b8d606ea5c361d56011bfe2e24 [file] [log] [blame]
Dennis Kempin22c7c4d2012-07-26 13:04:24 -07001# Copyright (c) 2012 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# This module is the main module for the console interface. It takes care
6# of parsing the command line arguments and formating the output
7from os import path
Dennis Kempin725ee5b2012-08-10 14:17:15 -07008import json
9import math
10import os
11import pprint
12import sys
13
14from table import Table
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070015from test_case import TestCase
Dennis Kempin31c0fbd2012-07-30 13:20:37 -070016from test_factory import TestFactory
Dennis Kempin963fb152013-01-11 15:40:19 -080017from test_runner import ParallelTestRunner as TestRunner
Dennis Kempin1479e742012-07-31 17:31:01 -070018from test_verifier import TestVerifier
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070019
20_help_text = """\
21Available Commands:
22-------------------
23$ touchtests run [all|testname]
24Executes tests. Either all of them and presents a resulting overall score.
25Or just a single named test.
26
Andrew de los Reyesb2d1c8a2012-08-17 18:40:28 -070027$ touchtests get [--from filename] gestures-log|evdev-log|activity-log testname
Dennis Kempin64f513f2012-08-10 15:09:18 -070028Runs a test and prints the requested log of a specific test. In case the
29--from option is used, the test will not be run, but the log will be loaded from
30the test results stored in file at 'filename'.
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070031
Dennis Kempin7a2f40b2012-08-10 15:13:54 -070032$ touchtests add [name] [activity_log] [cmt_log]
33Adds a new test case. The name has to include the platform and can optionally
34specify a subfolder where the test should be stored.
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070035activity_log and cmt_log should point to the file names of log files collected
36from the device.
37You can trim activity_log in tp_view, touchtests will automatically trim the
38cmt_log accordingly.
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070039
40General Info:
41-------------
42testname arguments:
43Tests are always names as [platform]/[name of test case]. You can find the tests
44available in the tests folder.
45For example: lumpy/scroll_test
46
47Tests Folder:
48The tests folder contains a folder for each platform and all the test cases.
49Each test case is made up of 3 files:
50[testcase].py which contains the validation script
51[testcase].log which contains the input_event log
52[testcase].props which contains user_defined properties passed to gestures lib.
53
54Platform folders:
55To add a new platform you need to add a new folder to the Tests folder, and
56generate a platform.dat file. This can be done using the evemu-describe tool
57on the target platform:
58
59$ gmerge utouch-evemu
60$ evemu-describe /path/to/device > platform.dat
61"""
62
63
64def HelpExit():
65 """
66 Print help text and exit
67 """
68 print _help_text
69 exit()
70
Dennis Kempin1479e742012-07-31 17:31:01 -070071def Verify(device, glob):
72 verifier = TestVerifier(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"],
73 device)
74 runner = TestRunner(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
75 cases = runner.DiscoverTestCases(glob)
76
77 for case in cases:
78 print "###", case.name
79 report = verifier.Verify(case)
80 print report
81
Dennis Kempin12968302012-08-09 15:37:09 -070082def Run(glob, out_file=None, ref_file=None):
Dennis Kempin4bc397b2012-08-08 16:51:47 -070083 print "Running tests..."
Dennis Kempin725ee5b2012-08-10 14:17:15 -070084 runner = TestRunner(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070085 results = runner.RunAll(glob)
Dennis Kempin22c7c4d2012-07-26 13:04:24 -070086
Dennis Kempin725ee5b2012-08-10 14:17:15 -070087 # print reports
Andrew de los Reyesbf5fa422012-10-17 16:45:45 -070088 sorted_results_items = sorted(results.items())
89 for key, value in sorted_results_items:
Dennis Kempin4bc397b2012-08-08 16:51:47 -070090 print "### Validation report for", key
91 print value["logs"]["validation"]
Dennis Kempin725ee5b2012-08-10 14:17:15 -070092 print value["error"]
Dennis Kempin4bc397b2012-08-08 16:51:47 -070093
Dennis Kempin725ee5b2012-08-10 14:17:15 -070094 # load reference
Dennis Kempin12968302012-08-09 15:37:09 -070095 ref = {}
96 if ref_file:
97 ref = json.load(open(ref_file))
98
Dennis Kempin725ee5b2012-08-10 14:17:15 -070099 # format result table
100 table = Table()
101 table.title = "Test Results"
102 table.header("Test", "reference score", "new score", "delta")
103
Andrew de los Reyesbf5fa422012-10-17 16:45:45 -0700104 for key, value in sorted_results_items:
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700105 def ResultStr(value):
106 # format result to string
107 if value["result"] == "success":
108 return "%s (%.4f)" % (value["result"], value["score"])
109 else:
110 return value["result"]
111
112 # format reference and delta column
113 ref_score = ""
114 delta_str = ""
115 regression = False
Dennis Kempin12968302012-08-09 15:37:09 -0700116 if key in ref:
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700117 ref_score = ResultStr(ref[key])
118 delta = value["score"] - ref[key]["score"]
119 if math.fabs(delta) < 1e-10:
120 # don't color, but line up with other values
121 delta_str = " %.4f " % delta
122 elif delta < 0:
123 regression = True
124 # color red
125 delta_str = "\x1b[91m%+.4f\x1b[0m" % delta
126 else:
127 # color green
128 delta_str = "\x1b[92m%+.4f\x1b[0m" % delta
129 table.row(key, ref_score, ResultStr(value), delta_str)
130
131 print table
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700132
Dennis Kempin12968302012-08-09 15:37:09 -0700133 if out_file:
134 json.dump(results, open(out_file, "w"), indent=2)
135 print "results stored in:", out_file
136
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700137 if regression:
138 print "\x1b[91mThere are regressions present in this test run!\x1b[0m"
139 exit(-1)
140
Dennis Kempin64f513f2012-08-10 15:09:18 -0700141def Get(test_name, what, file=None):
142 if file:
143 data = json.load(open(file))
144 results = data[test_name]
145 else:
146 runner = TestRunner(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
147 data = runner.RunAll(test_name)
148 results = data[test_name]
149
150 if what == "gestures-log":
151 print results["logs"]["gestures"]
152 elif what == "evdev-log":
153 print results["logs"]["evdev"]
154 elif what == "activity-log":
155 print results["logs"]["activity"]
156 elif what == "gestures":
157 print results["gestures"]
158 elif what == "events":
159 print results["events"]
160
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700161def Add(testname, activity_log, event_log):
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700162 """
163 Adds a new test case.
164 """
165 # determine test name from activity_log name
Dennis Kempin31c0fbd2012-07-30 13:20:37 -0700166 factory = TestFactory(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
167 case = factory.CreateTest(testname, activity_log, event_log)
168
Dennis Kempin49fe8a52012-08-03 11:27:40 -0700169 print "Test \"" + case.name + "\" created"
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700170
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700171def Main():
172 """
173 Main entry point for the console interface
174 """
175
176 # setup paths from environment variables
177 if "TESTS_DIR" not in os.environ:
178 print "Require TESTS_DIR environment variable"
179 exit(-1)
180
181 if "REPLAY_TOOL" not in os.environ:
182 print "Require REPLAY_TOOL environment variable"
183 exit(-1)
184
185 TestCase.tests_path = os.environ["TESTS_DIR"]
186 TestCase.replay_tool = os.environ["REPLAY_TOOL"]
187
188 # parse arguments and call command methods
189 if len(sys.argv) < 2:
190 HelpExit()
191
192 # call command method according to command line arguments
Dennis Kempin12968302012-08-09 15:37:09 -0700193 # todo: use an option parser library
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700194 cmd = sys.argv[1]
195
Dennis Kempin12968302012-08-09 15:37:09 -0700196 if cmd == "run":
197 if len(sys.argv) == 3:
198 test_name = sys.argv[2]
199 Run(test_name)
200 elif len(sys.argv) == 5 and sys.argv[2] == "--out":
201 test_name = sys.argv[4]
202 out = sys.argv[3]
203 Run(test_name, out)
204 elif len(sys.argv) == 5 and sys.argv[2] == "--ref":
205 test_name = sys.argv[4]
206 ref_file = sys.argv[3]
207 Run(test_name, None, ref_file)
208 else:
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700209 HelpExit()
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700210
Dennis Kempin64f513f2012-08-10 15:09:18 -0700211 elif cmd == "get":
212 if len(sys.argv) == 4:
213 test_name = sys.argv[3]
214 what = sys.argv[2]
215 Get(test_name, what)
216 elif len(sys.argv) == 6 and sys.argv[2] == "--from":
217 test_name = sys.argv[5]
218 what = sys.argv[4]
219 file = sys.argv[3]
220 Get(test_name, what, file)
221 else:
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700222 HelpExit()
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700223
Dennis Kempin1479e742012-07-31 17:31:01 -0700224 elif cmd == "verify":
225 if len(sys.argv) < 4:
226 HelpExit()
227 device_name = sys.argv[2]
228 test_name = sys.argv[3]
229 Verify(device_name, test_name)
230
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700231 elif cmd == "add":
232 if len(sys.argv) < 5:
233 HelpExit()
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700234 testname = sys.argv[2]
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700235 activity_log = sys.argv[3]
236 event_log = sys.argv[4]
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700237 Add(testname, activity_log, event_log)
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700238
239 else:
240 HelpExit()
241
242if __name__ == "__main__":
243 Main()