1 # Copyright 2014 The Chromium 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.
7 from devil
.android
import device_errors
8 from pylib
import valgrind_tools
9 from pylib
.base
import base_test_result
10 from pylib
.base
import test_run
11 from pylib
.base
import test_collection
14 class LocalDeviceTestRun(test_run
.TestRun
):
16 def __init__(self
, env
, test_instance
):
17 super(LocalDeviceTestRun
, self
).__init
__(env
, test_instance
)
22 tests
= self
._GetTests
()
24 def run_tests_on_device(dev
, tests
, results
):
27 result
= self
._RunTest
(dev
, test
)
28 if isinstance(result
, base_test_result
.BaseTestResult
):
29 results
.AddResult(result
)
30 elif isinstance(result
, list):
31 results
.AddResults(result
)
34 'Unexpected result type: %s' % type(result
).__name
__)
36 if isinstance(tests
, test_collection
.TestCollection
):
40 if isinstance(tests
, test_collection
.TestCollection
):
41 tests
.test_completed()
42 logging
.info('Finished running tests on this device.')
45 results
= base_test_result
.TestRunResults()
47 while tries
< self
._env
.max_tries
and tests
:
48 logging
.info('STARTING TRY #%d/%d', tries
+ 1, self
._env
.max_tries
)
49 logging
.info('Will run %d tests on %d devices: %s',
50 len(tests
), len(self
._env
.devices
),
51 ', '.join(str(d
) for d
in self
._env
.devices
))
53 logging
.debug(' %s', t
)
56 try_results
= base_test_result
.TestRunResults()
57 if self
._ShouldShard
():
58 tc
= test_collection
.TestCollection(self
._CreateShards
(tests
))
59 self
._env
.parallel_devices
.pMap(
60 run_tests_on_device
, tc
, try_results
).pGet(None)
62 self
._env
.parallel_devices
.pMap(
63 run_tests_on_device
, tests
, try_results
).pGet(None)
64 except device_errors
.CommandFailedError
:
65 logging
.exception('Shard terminated: command failed')
66 except device_errors
.CommandTimeoutError
:
67 logging
.exception('Shard terminated: command timed out')
68 except device_errors
.DeviceUnreachableError
:
69 logging
.exception('Shard terminated: device became unreachable')
71 for result
in try_results
.GetAll():
72 if result
.GetType() in (base_test_result
.ResultType
.PASS
,
73 base_test_result
.ResultType
.SKIP
):
74 results
.AddResult(result
)
76 all_fail_results
[result
.GetName()] = result
78 results_names
= set(r
.GetName() for r
in results
.GetAll())
79 tests
= [t
for t
in tests
if self
._GetTestName
(t
) not in results_names
]
81 logging
.info('FINISHED TRY #%d/%d', tries
, self
._env
.max_tries
)
83 logging
.info('%d failed tests remain.', len(tests
))
85 logging
.info('All tests completed.')
87 all_unknown_test_names
= set(self
._GetTestName
(t
) for t
in tests
)
88 all_failed_test_names
= set(all_fail_results
.iterkeys())
90 unknown_tests
= all_unknown_test_names
.difference(all_failed_test_names
)
91 failed_tests
= all_failed_test_names
.intersection(all_unknown_test_names
)
95 base_test_result
.BaseTestResult(
96 u
, base_test_result
.ResultType
.UNKNOWN
)
97 for u
in unknown_tests
)
99 results
.AddResults(all_fail_results
[f
] for f
in failed_tests
)
103 def GetTool(self
, device
):
104 if not str(device
) in self
._tools
:
105 self
._tools
[str(device
)] = valgrind_tools
.CreateTool(
106 self
._env
.tool
, device
)
107 return self
._tools
[str(device
)]
109 def _CreateShards(self
, tests
):
110 raise NotImplementedError
112 # pylint: disable=no-self-use
113 def _GetTestName(self
, test
):
117 raise NotImplementedError
119 def _RunTest(self
, device
, test
):
120 raise NotImplementedError
122 def _ShouldShard(self
):
123 raise NotImplementedError