1# Copyright (c) 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.
4
5import errno
6import hashlib
7import logging
8import os
9
10from autotest_lib.client.bin import utils
11from autotest_lib.client.common_lib import error
12from autotest_lib.client.common_lib import file_utils
13from autotest_lib.client.cros import chrome_binary_test
14
15DOWNLOAD_BASE = 'http://commondatastorage.googleapis.com/chromiumos-test-assets-public/'
16BINARY = 'video_encode_accelerator_unittest'
17
18def _remove_if_exists(filepath):
19    try:
20        os.remove(filepath)
21    except OSError, e:
22        if e.errno != errno.ENOENT: # no such file
23            raise
24
25
26def _download_video(download_path, local_file):
27    url = '%s%s' % (DOWNLOAD_BASE, download_path)
28    logging.info('download "%s" to "%s"', url, local_file)
29
30    file_utils.download_file(url, local_file)
31
32    with open(local_file, 'r') as r:
33        md5sum = hashlib.md5(r.read()).hexdigest()
34        if md5sum not in download_path:
35            raise error.TestError('unmatched md5 sum: %s' % md5sum)
36
37
38class video_VideoEncodeAccelerator(chrome_binary_test.ChromeBinaryTest):
39    """
40    This test is a wrapper of the chrome unittest binary:
41    video_encode_accelerator_unittest.
42    """
43
44    version = 1
45
46    def get_filter_option(self):
47        """Get option of filtering test
48        """
49
50        blacklist = {
51                # board: [tests to skip...]
52
53                # Kevin doesn't support HW encode for plane sizes not multiple
54                # of cache line
55                'kevin': ['CacheLineUnalignedInputTest/*']
56                }
57
58        board = utils.get_current_board()
59        if board in blacklist:
60            return ' --gtest_filter=-' + ':'.join(blacklist[board])
61
62        return ''
63
64    @chrome_binary_test.nuke_chrome
65    def run_once(self, in_cloud, streams, profile):
66        """Runs video_encode_accelerator_unittest on the streams.
67
68        @param in_cloud: Input file needs to be downloaded first.
69        @param streams: The test streams for video_encode_accelerator_unittest.
70        @param profile: The profile to encode into.
71
72        @raises error.TestFail for video_encode_accelerator_unittest failures.
73        """
74
75        last_test_failure = None
76        for path, width, height, bit_rate in streams:
77            if in_cloud:
78                input_path = os.path.join(self.tmpdir, path.split('/')[-1])
79                _download_video(path, input_path)
80            else:
81                input_path = os.path.join(self.cr_source_dir, path)
82
83            output_path = os.path.join(self.tmpdir,
84                    '%s.out' % input_path.split('/')[-1])
85
86            cmd_line = '--test_stream_data="%s:%s:%s:%s:%s:%s"' % (
87                    input_path, width, height, profile, output_path, bit_rate)
88            if utils.is_freon():
89                cmd_line += ' --ozone-platform=gbm'
90            cmd_line += self.get_filter_option()
91            try:
92                self.run_chrome_test_binary(BINARY, cmd_line, as_chronos=False)
93            except error.TestFail as test_failure:
94                # Continue to run the remaining test streams and raise
95                # the last failure after finishing all streams.
96                logging.exception('error while encoding %s', input_path)
97                last_test_failure = test_failure
98            finally:
99                # Remove the downloaded video
100                if in_cloud:
101                    _remove_if_exists(input_path)
102                _remove_if_exists(output_path)
103
104        if last_test_failure:
105            raise last_test_failure
106