blob: 9075686157e2787961e79beadce09f32a1938397 [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 Kempin22c7c4d2012-07-26 13:04:24 -070017from test_runner import 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
Dennis Kempin64f513f2012-08-10 15:09:18 -070027$ touchtests get [--from filename] testname gestures-log|evdev-log|activity-log
28Runs 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
Dennis Kempin4bc397b2012-08-08 16:51:47 -070088 for key, value in results.items():
89 print "### Validation report for", key
90 print value["logs"]["validation"]
Dennis Kempin725ee5b2012-08-10 14:17:15 -070091 print value["error"]
Dennis Kempin4bc397b2012-08-08 16:51:47 -070092
Dennis Kempin725ee5b2012-08-10 14:17:15 -070093 # load reference
Dennis Kempin12968302012-08-09 15:37:09 -070094 ref = {}
95 if ref_file:
96 ref = json.load(open(ref_file))
97
Dennis Kempin725ee5b2012-08-10 14:17:15 -070098 # format result table
99 table = Table()
100 table.title = "Test Results"
101 table.header("Test", "reference score", "new score", "delta")
102
Dennis Kempin8cb1a892012-08-06 15:19:17 -0700103 for key, value in results.items():
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700104 def ResultStr(value):
105 # format result to string
106 if value["result"] == "success":
107 return "%s (%.4f)" % (value["result"], value["score"])
108 else:
109 return value["result"]
110
111 # format reference and delta column
112 ref_score = ""
113 delta_str = ""
114 regression = False
Dennis Kempin12968302012-08-09 15:37:09 -0700115 if key in ref:
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700116 ref_score = ResultStr(ref[key])
117 delta = value["score"] - ref[key]["score"]
118 if math.fabs(delta) < 1e-10:
119 # don't color, but line up with other values
120 delta_str = " %.4f " % delta
121 elif delta < 0:
122 regression = True
123 # color red
124 delta_str = "\x1b[91m%+.4f\x1b[0m" % delta
125 else:
126 # color green
127 delta_str = "\x1b[92m%+.4f\x1b[0m" % delta
128 table.row(key, ref_score, ResultStr(value), delta_str)
129
130 print table
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700131
Dennis Kempin12968302012-08-09 15:37:09 -0700132 if out_file:
133 json.dump(results, open(out_file, "w"), indent=2)
134 print "results stored in:", out_file
135
Dennis Kempin725ee5b2012-08-10 14:17:15 -0700136 if regression:
137 print "\x1b[91mThere are regressions present in this test run!\x1b[0m"
138 exit(-1)
139
Dennis Kempin64f513f2012-08-10 15:09:18 -0700140def Get(test_name, what, file=None):
141 if file:
142 data = json.load(open(file))
143 results = data[test_name]
144 else:
145 runner = TestRunner(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
146 data = runner.RunAll(test_name)
147 results = data[test_name]
148
149 if what == "gestures-log":
150 print results["logs"]["gestures"]
151 elif what == "evdev-log":
152 print results["logs"]["evdev"]
153 elif what == "activity-log":
154 print results["logs"]["activity"]
155 elif what == "gestures":
156 print results["gestures"]
157 elif what == "events":
158 print results["events"]
159
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700160def Add(testname, activity_log, event_log):
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700161 """
162 Adds a new test case.
163 """
164 # determine test name from activity_log name
Dennis Kempin31c0fbd2012-07-30 13:20:37 -0700165 factory = TestFactory(os.environ["TESTS_DIR"], os.environ["REPLAY_TOOL"])
166 case = factory.CreateTest(testname, activity_log, event_log)
167
Dennis Kempin49fe8a52012-08-03 11:27:40 -0700168 print "Test \"" + case.name + "\" created"
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700169
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700170def Main():
171 """
172 Main entry point for the console interface
173 """
174
175 # setup paths from environment variables
176 if "TESTS_DIR" not in os.environ:
177 print "Require TESTS_DIR environment variable"
178 exit(-1)
179
180 if "REPLAY_TOOL" not in os.environ:
181 print "Require REPLAY_TOOL environment variable"
182 exit(-1)
183
184 TestCase.tests_path = os.environ["TESTS_DIR"]
185 TestCase.replay_tool = os.environ["REPLAY_TOOL"]
186
187 # parse arguments and call command methods
188 if len(sys.argv) < 2:
189 HelpExit()
190
191 # call command method according to command line arguments
Dennis Kempin12968302012-08-09 15:37:09 -0700192 # todo: use an option parser library
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700193 cmd = sys.argv[1]
194
Dennis Kempin12968302012-08-09 15:37:09 -0700195 if cmd == "run":
196 if len(sys.argv) == 3:
197 test_name = sys.argv[2]
198 Run(test_name)
199 elif len(sys.argv) == 5 and sys.argv[2] == "--out":
200 test_name = sys.argv[4]
201 out = sys.argv[3]
202 Run(test_name, out)
203 elif len(sys.argv) == 5 and sys.argv[2] == "--ref":
204 test_name = sys.argv[4]
205 ref_file = sys.argv[3]
206 Run(test_name, None, ref_file)
207 else:
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700208 HelpExit()
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700209
Dennis Kempin64f513f2012-08-10 15:09:18 -0700210 elif cmd == "get":
211 if len(sys.argv) == 4:
212 test_name = sys.argv[3]
213 what = sys.argv[2]
214 Get(test_name, what)
215 elif len(sys.argv) == 6 and sys.argv[2] == "--from":
216 test_name = sys.argv[5]
217 what = sys.argv[4]
218 file = sys.argv[3]
219 Get(test_name, what, file)
220 else:
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700221 HelpExit()
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700222
Dennis Kempin1479e742012-07-31 17:31:01 -0700223 elif cmd == "verify":
224 if len(sys.argv) < 4:
225 HelpExit()
226 device_name = sys.argv[2]
227 test_name = sys.argv[3]
228 Verify(device_name, test_name)
229
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700230 elif cmd == "add":
231 if len(sys.argv) < 5:
232 HelpExit()
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700233 testname = sys.argv[2]
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700234 activity_log = sys.argv[3]
235 event_log = sys.argv[4]
Dennis Kempin7a2f40b2012-08-10 15:13:54 -0700236 Add(testname, activity_log, event_log)
Dennis Kempin22c7c4d2012-07-26 13:04:24 -0700237
238 else:
239 HelpExit()
240
241if __name__ == "__main__":
242 Main()