blob: d02f26d5e9370c7d88a8e9fe3db4778ad7d38771 [file] [log] [blame]
Charlie Mooney3cca6ba2014-11-19 16:15:28 -08001# Copyright (c) 2014 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
5import colorama as color
6
Charlie Mooneye0d06c42015-01-27 11:32:51 -08007import mt
Charlie Mooney3cca6ba2014-11-19 16:15:28 -08008import tests
Charlie Mooney86b5cf12014-12-04 09:34:09 -08009from plotter import TouchPlotter
Charlie Mooney985cf402015-01-08 15:15:59 -080010from report import Report
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080011
12
13class TestSuite:
14 """ This class represents a collection of tests and is used to run them
15
16 A TestSuite object will set up a connection to the DUT, robot, etc, and
17 determine which tests can be run. Once the object is instantiated,
18 RunNextTestAndVariation() can be run repeatedly to work your way through
19 the entire suite.
20 """
21
Charlie Mooneyda8e13f2015-02-24 11:32:05 -080022 NO_EVENTS_DETECTED_TIMEOUT_MANUAL_S = 60
23 NO_EVENTS_DETECTED_TIMEOUT_ROBOT_S = 5
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080024
Charlie Mooneyd5712b82015-02-23 12:06:59 -080025 def __init__(self, touch_dev, options, args):
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080026 color.init(autoreset=True)
27
28 self.options = options
Charlie Mooneyd5712b82015-02-23 12:06:59 -080029 self.touch_dev = touch_dev
Charlie Mooneyaf9d5122014-12-04 15:15:52 -080030 tests.validator.BaseValidator._device = self.touch_dev
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080031
Charlie Mooneydaaaa242015-02-03 14:20:23 -080032 # Connect to the function generator if the operator says they have one
33 self.fn_generator = None
34 if options.has_fn_gen:
35 self.fn_generator = tests.noise.HP33120A()
36 if not self.fn_generator.IsValid():
37 self.fn_generator = None
38 options.has_fn_gen = False
39 print 'Error: Unable to connect to function generator!'
40
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080041 # Compute the list of tests to run
42 self.tests = tests.generate_test_list(options)
Charlie Mooney73051762015-02-06 11:52:38 -080043 if not self.tests:
44 print color.Fore.RED + 'Warning: No tests selected!'
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080045 self.curr_test = 0
46 self.curr_variation = 0
Charlie Mooneyaf9d5122014-12-04 15:15:52 -080047 self.curr_iteration = 1
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080048
Charlie Mooneyda8e13f2015-02-24 11:32:05 -080049 self.no_events_timeout = TestSuite.NO_EVENTS_DETECTED_TIMEOUT_MANUAL_S
50 if options.has_robot:
51 self.no_events_timeout = TestSuite.NO_EVENTS_DETECTED_TIMEOUT_ROBOT_S
52
Charlie Mooney985cf402015-01-08 15:15:59 -080053 # Create a new Report that will store all the test Results
54 self.report = Report()
55
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080056 def RunNextTestAndVariation(self):
57 """ Run the next test.
58
59 This function runs the next test/variation combination in the test suite
60 and advances the internal state to the next one automatically. When
61 finished, this function return True if there are more tests to run, and
62 False if the whole test suite is done.
63
64 After a TestSuite is instantiated, this function should be called
65 repeatedly until it returns False to go through all tests, variations,
66 and iterations.
67 """
Charlie Mooney73051762015-02-06 11:52:38 -080068 if self.curr_test >= len(self.tests):
69 return False
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080070 test = self.tests[self.curr_test]
71
72 # Print the header for this new test and variation
73 prompt = test.PromptForVariation(self.curr_variation)
74 print color.Fore.WHITE + '-' * 80
75 print color.Fore.BLUE + test.name
76 print color.Fore.GREEN + prompt
77
Charlie Mooneydaaaa242015-02-03 14:20:23 -080078 # Start the function generator (if applicable)
79 if self.fn_generator:
80 waveform = test.WaveformForVariation(self.curr_variation)
81 if waveform:
82 self.fn_generator.GenerateFunction(*waveform)
83 else:
84 self.fn_generator.Off()
85
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080086 # Start collecting data
87 print 'Opening connection with DUT... ',
88 self.touch_dev.BeginEventStream()
89 print 'Connection established!'
90
91 # Wait a long time for the first event, then have a much shorter
92 # timeout on subsequent incoming events
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080093 events = []
Charlie Mooneyd5712b82015-02-23 12:06:59 -080094 plotter = TouchPlotter(self.touch_dev)
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080095 print 'Waiting for 1st event...',
Charlie Mooneyda8e13f2015-02-24 11:32:05 -080096 event = self.touch_dev.NextEvent(self.no_events_timeout)
Charlie Mooney3cca6ba2014-11-19 16:15:28 -080097 if not event:
Charlie Mooneye0d06c42015-01-27 11:32:51 -080098 print ('\rNo MT events collected before timeout (%d seconds)!' %
Charlie Mooneyda8e13f2015-02-24 11:32:05 -080099 self.no_events_timeout),
Charlie Mooney3cca6ba2014-11-19 16:15:28 -0800100 while event:
Charlie Mooney86b5cf12014-12-04 09:34:09 -0800101 plotter.add_event(event)
Charlie Mooneye0d06c42015-01-27 11:32:51 -0800102 print '\rCollected %d MT events' % len(events),
Charlie Mooney3cca6ba2014-11-19 16:15:28 -0800103 events.append(event)
104 event = self.touch_dev.NextEvent(test.timeout)
105 print
Charlie Mooney97d73c12015-01-09 08:57:03 -0800106 plot_image_png = plotter.end()
Charlie Mooney3cca6ba2014-11-19 16:15:28 -0800107
Charlie Mooney754992b2015-03-05 08:54:26 -0800108 print 'Closing connection with DUT... ',
109 self.touch_dev.EndEventStream()
110
Charlie Mooney3cca6ba2014-11-19 16:15:28 -0800111 # Run the validators on these events
Charlie Mooneye0d06c42015-01-27 11:32:51 -0800112 snapshots = mt.process(events, protocol=self.touch_dev.protocol)
Charlie Mooneyaf9d5122014-12-04 15:15:52 -0800113 results = test.RunAllValidators(snapshots)
Charlie Mooney985cf402015-01-08 15:15:59 -0800114
Charlie Mooney5e9a10f2015-01-13 14:54:27 -0800115 # Bundle the Validator results with some details of which gesture was used
116 # during the test for easier debugging.
117 test_result = tests.TestResult(results, prompt, plot_image_png)
118
Charlie Mooney985cf402015-01-08 15:15:59 -0800119 # Add the results into our report (And have it print them to stdout, too)
Charlie Mooney5e9a10f2015-01-13 14:54:27 -0800120 self.report.AddTestResult(test_result, verbose=True)
Charlie Mooney3cca6ba2014-11-19 16:15:28 -0800121
122 # Advance the test suite to the next test and variation and return an
123 # indicator as to whether this was the last thing to do or not.
124 next_test, next_var = self._Advance()
125 return (next_test is not None)
126
127 def _Advance(self):
128 """ Move on to the next test/variation pair
129
130 This function increments all the interal counters, according to the
131 number of tests, their variations, and the selected number of iterations
132 and returns the test object and the variation number that should be
133 done next.
134
135 When the TestSuite is complete, this function will return None, None
136 otherwise it will return the next Test object and the variation number
137 the test suite is on.
138 """
139 if self.curr_test >= len(self.tests):
140 return None, None
141 test = self.tests[self.curr_test]
142
143 if self.curr_variation >= len(test.variations):
144 self.curr_test += 1
145 self.curr_variation = 0
146 self.curr_iteration = 0
147 return self._Advance()
148
149 if self.curr_iteration >= self.options.num_iterations:
150 self.curr_variation += 1
151 self.curr_iteration = 0
152 return self._Advance()
153
154 self.curr_iteration += 1
155 return test, self.curr_variation