| # Copyright (c) 2014 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging |
| from autotest_lib.client.cros.video import method_logger |
| from autotest_lib.client.cros.image_comparison import comparison_result |
| |
| # TODO (mussa): We will use data generated by running tests using this class. |
| # If we can do with one comparer we may not need this class. |
| |
| class UploadOnFailComparer(object): |
| """ |
| Compares a test image against a golden image. |
| |
| Uses a local comparer first to do the comparison, for every comparison |
| that return fail, it uses remote comparer. |
| |
| """ |
| |
| |
| @method_logger.log |
| def __init__(self, local_comparer, remote_comparer, threshold=0): |
| """ |
| @param local_comparer: object impementing compare(), local comparer. |
| @param remote_comparer: object implementing compare(), remote comparer. |
| @param threshold: int, a value which the pixel difference between test |
| image and golden image has to exceed before the |
| remote comparer is used. |
| |
| """ |
| self.local_comparer = local_comparer |
| self.remote_comparer = remote_comparer |
| self.threshold = threshold |
| |
| |
| def __enter__(self): |
| return self |
| |
| |
| @method_logger.log |
| def compare(self, golden_image_path, test_image_path, box=None): |
| """ |
| Compares a test image against a golden image using up to two comparers. |
| |
| If the local comparer reports a fail, use the remote comparer to |
| compare the same images. |
| |
| E.g of use case: You have two comparers, one is local and another is |
| web-based. Web-based comparer has the advantage of storing information |
| you need to look at the results later. |
| Local comparer is fast and reduces the load on the web-based comparer. |
| |
| Use local comparer as primary comparer and only invoke the web-based |
| comparer on test images that differ from their golden counterparts. |
| |
| @param golden_image_path: path, complete path to the golden image. |
| @param test_image_path: path, complete path to the test image. |
| @param box: int tuple, left, upper, right, lower pixel coordinates |
| defining a box region within which the comparison is made. |
| |
| @return: int, differing pixels as per double check comparer. |
| |
| """ |
| logging.debug('Using primary comparer..') |
| |
| with self.local_comparer: |
| res = self.local_comparer.compare(golden_image_path, |
| test_image_path, |
| box) |
| diffpx = res.diff_pixel_count |
| logging.debug('Primary comparison complete. Diff pixels = %d', diffpx) |
| |
| diffpx2 = -1 |
| comp_res = res.comparison_url |
| |
| if (diffpx > self.threshold): |
| logging.debug('Threshold diff pixels is %d', self.threshold) |
| logging.debug('Diff pxls > threshold. Using remote comparer.') |
| |
| with self.remote_comparer: |
| res_remote = self.remote_comparer.compare(golden_image_path, |
| test_image_path, |
| box) |
| diffpx2 = res_remote.diff_pixel_count |
| |
| if not comp_res: |
| comp_res = res_remote.comparison_url |
| |
| logging.debug('Secondary comparison complete. Diff pixels = %d', |
| diffpx2) |
| |
| diffpx_return = diffpx2 if diffpx2 != -1 else diffpx |
| |
| |
| return comparison_result.ComparisonResult(diffpx_return, |
| comp_res) |
| |
| |
| def __exit__(self, exc_type, exc_val, exc_tb): |
| pass |