Home | History | Annotate | Download | only in cheets_AppCompatTest
      1 # Copyright 2018 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 import logging
      6 import os
      7 
      8 from autotest_lib.client.bin import utils
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.client.common_lib.cros import arc
     11 from autotest_lib.client.cros.graphics import graphics_utils
     12 
     13 
     14 class cheets_AppCompatTest(arc.ArcTest):
     15     """
     16     Autotest wrapper class for the AppCompat's team UIAutomator test cases.
     17 
     18     It is used to call the apk that runs the test. It then copies logcat,
     19     bugreport and screenshots to the autotest resultsdir.
     20 
     21     It parses logcat to get the test results.
     22 
     23     """
     24     version = 1
     25 
     26     _PLAY_STORE_ACTIVITY = 'com.android.vending'
     27     _TEST_FILES_LOCATION = ('https://storage.googleapis.com/chromeos-throw'
     28                             '-away-bucket/app_compat/')
     29     _TEST_FILES = ['app-debug.apk', 'app-debug-androidTest.apk',
     30                    'autresources.xml']
     31     _TMP_LOCATION = '/tmp/app_compat/'
     32     _LOG_TAG = '~APPCOM_TEST_AUTO~'
     33 
     34 
     35     def initialize(self, pkg_name, touch_view_mode):
     36         self._pkg_name = pkg_name
     37         browser_args = None
     38         self._touch_view_mode = touch_view_mode
     39         if self._touch_view_mode:
     40             browser_args = ['--force-tablet-mode=touch_view']
     41 
     42         super(cheets_AppCompatTest, self).initialize(
     43             disable_arc_opt_in=False, extra_browser_args=browser_args,
     44             disable_app_sync=True, disable_play_auto_install=True,
     45             username='crosarcappcompat (at] gmail.com',
     46             password='appcompatautotest')
     47 
     48 
     49     def arc_setup(self):
     50         super(cheets_AppCompatTest, self).arc_setup()
     51 
     52 
     53     def cleanup(self):
     54         arc.adb_cmd('uninstall com.hcl.actframework')
     55         arc.adb_cmd('uninstall com.hcl.actframework.test')
     56         arc.adb_cmd('uninstall %s' % self._pkg_name)
     57         arc.adb_shell('rm -f /sdcard/autresources.xml > /dev/null')
     58         arc.adb_shell('rm -f /sdcard/touchView.txt > /dev/null',
     59                       ignore_status=True)
     60         utils.run('rm -rf %s' % self._TMP_LOCATION)
     61         super(cheets_AppCompatTest, self).cleanup()
     62 
     63 
     64     def _grant_storage_permission(self):
     65         """Grant the UIAutomator tests storage permission."""
     66         arc.adb_shell('am instrument -w -r -e debug false -e '
     67                       '"grant_permissions_only" "Y" '
     68                       'com.hcl.actframework.test/android.support.test.runner'
     69                       '.AndroidJUnitRunner')
     70 
     71     def _start_test(self):
     72         """Kick off the UIAutomator tests."""
     73         arc.adb_shell('am instrument -w -r -e debug false -e '
     74                       '"device_model" "Google~Pixelbook" -e '
     75                       '"app_packagename" %s -e "app_version" "TBD" -e '
     76                       '"device_os_build_version" 7.1.1 -e '
     77                       '"clear_recents" "N" -e "check_wifi_connection" '
     78                       '"N" -e "check_location_on" "N" -e '
     79                       '"check_auto_rotate_off" "N" '
     80                       'com.hcl.actframework.test/android.support.test'
     81                       '.runner.AndroidJUnitRunner' % self._pkg_name)
     82 
     83 
     84     def _copy_resources_to_dut(self):
     85         """Copy the apks & xml file needed for the UIAutomator tests."""
     86         if not os.path.exists(self._TMP_LOCATION):
     87             os.mkdir(self._TMP_LOCATION)
     88         for test_file in self._TEST_FILES:
     89             uri = self._TEST_FILES_LOCATION + test_file
     90             utils.run('wget -O %s %s' % (os.path.join(self._TMP_LOCATION,
     91                                                       test_file), uri))
     92 
     93         for test_file in os.listdir(self._TMP_LOCATION):
     94             if test_file == 'app-debug.apk':
     95                 arc.adb_cmd('push %s /data/local/tmp/com.hcl.actframework' %
     96                             os.path.join(self._TMP_LOCATION, test_file))
     97                 arc.adb_shell('pm install -t -r '
     98                               '"/data/local/tmp/com.hcl.actframework"')
     99             elif test_file == 'app-debug-androidTest.apk':
    100                 arc.adb_cmd('push %s '
    101                             '/data/local/tmp/com.hcl.actframework.test' %
    102                             os.path.join(self._TMP_LOCATION, test_file))
    103                 arc.adb_shell('pm install -t -r '
    104                               '"/data/local/tmp/com.hcl.actframework.test"')
    105             else:
    106                 arc.adb_cmd('push %s /sdcard/' % os.path.join(
    107                             self._TMP_LOCATION, test_file))
    108         if self._touch_view_mode:
    109             arc.adb_shell('touch /sdcard/touchView.txt')
    110 
    111 
    112     def _capture_bugreport(self):
    113         """Captures a bugreport and saves into resultsdir."""
    114         arc.adb_cmd('bugreport > %s' % os.path.join(self.resultsdir,
    115                                                     'bugreport.txt'))
    116 
    117 
    118     def _grab_screenshots(self):
    119         """Captures screenshots that are created by the UIAutomator tests."""
    120         for screenshot in arc.adb_shell('find /sdcard/*.png').splitlines():
    121             logging.debug('Screenshot is %s.', screenshot)
    122             arc.adb_cmd('pull %s %s' % (screenshot, self.resultsdir),
    123                         ignore_status=True)
    124             arc.adb_shell('rm -r %s' % screenshot, ignore_status=True)
    125 
    126 
    127     def _save_logcat(self, iteration):
    128         """Saves the logcat for the test run to the resultsdir."""
    129         self._logcat = 'logcat%d.txt' % iteration
    130         arc.adb_cmd('logcat -d > %s' % os.path.join(self.resultsdir,
    131                                                     self._logcat))
    132 
    133 
    134     def _parse_results(self):
    135         """Parse the pass/fail/skipped entries from logcat. """
    136         passed = self._get_log_entry_count(",PASS,")
    137         failed = self._get_log_entry_count(",FAIL,")
    138         nt = self._get_log_entry_count(",NT,")
    139         blocked = self._get_log_entry_count(",BLOCKED,")
    140         skipped = self._get_log_entry_count(",SKIPPED,")
    141         ft = self._get_failed_test_cases()
    142 
    143         result = ('Test results for %s(%s): Passed %s, Failed %s, Not Tested '
    144                   '%s, Blocked %s, Skipped %s. Failed tests: [%s]' % (
    145                   self._pkg_name, self._app_version, passed, failed, nt,
    146                   blocked, skipped, ft))
    147         logging.info(result)
    148         pass_status = int(failed) == 0 and int(passed) > 0
    149         return pass_status, result
    150 
    151 
    152     def _get_log_entry_count(self, entry):
    153         """Get the total number of times a string appears in logcat."""
    154         logcat = os.path.join(self.resultsdir, self._logcat)
    155         return utils.run('grep "%s" %s | grep -c "%s"' %
    156                         (self._LOG_TAG, logcat, entry),
    157                          ignore_status=True).stdout.strip()
    158 
    159 
    160     def _get_failed_test_cases(self):
    161         """Get the list of test cases that failed from logcat."""
    162         logcat = os.path.join(self.resultsdir, self._logcat)
    163         failed_tests = []
    164         failed_tests_list = utils.run('grep "%s" %s | grep ",FAIL,"' %
    165                             (self._LOG_TAG, logcat),
    166                             ignore_status=True).stdout.strip().splitlines()
    167         for line in failed_tests_list:
    168             failed_tests.append(line.split(',')[-4:])
    169         return failed_tests
    170 
    171 
    172     def _increase_logcat_buffer(self):
    173         """Increase logcat buffer so all UIAutomator test entries appear."""
    174         arc.adb_cmd('logcat -G 16M')
    175 
    176 
    177     def _clear_logcat_buffer(self):
    178         """Clear logcat buffer between runs."""
    179         arc.adb_cmd('logcat -c')
    180 
    181 
    182     def _get_app_version(self):
    183         """Grab the version of the application we are testing."""
    184         self._app_version = arc.adb_shell('dumpsys package %s | grep '
    185                                           'versionName| cut -d"=" -f2' %
    186                                           self._pkg_name)
    187 
    188 
    189     def _take_screenshot(self, name):
    190         try:
    191             graphics_utils.take_screenshot(self.resultsdir, name)
    192         except:
    193             logging.info('Failed to take screenshot')
    194 
    195 
    196     def run_once(self, retries=3):
    197         self._increase_logcat_buffer()
    198         self._copy_resources_to_dut()
    199         self._grant_storage_permission()
    200 
    201         for trial in range(retries):
    202             logging.info('Iteration %d: Trying to launch play store' % trial)
    203 
    204             # Bring Play Store to front.
    205             arc.adb_shell('am start %s' % self._PLAY_STORE_ACTIVITY)
    206             self._take_screenshot('test_start')
    207             self._start_test()
    208             logging.info('Iteration %d: Test finished' % trial)
    209             self._take_screenshot('test_end')
    210             self._get_app_version()
    211             self._capture_bugreport()
    212             self._grab_screenshots()
    213             self._save_logcat(trial)
    214             passed, result = self._parse_results()
    215             if passed:
    216                 return
    217             elif trial + 1 >= retries:
    218                 raise error.TestFail(result)
    219 
    220             # Kill playstore and clear logcat for next iteration.
    221             arc.adb_shell('am force-stop %s' % self._PLAY_STORE_ACTIVITY)
    222             self._clear_logcat_buffer()
    223