Home | History | Annotate | Download | only in linux_kselftest
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2016 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 import logging
     19 
     20 from vts.runners.host import asserts
     21 from vts.runners.host import base_test
     22 from vts.runners.host import const
     23 from vts.runners.host import keys
     24 from vts.runners.host import test_runner
     25 from vts.utils.python.controllers import android_device
     26 from vts.utils.python.os import path_utils
     27 
     28 from vts.testcases.kernel.linux_kselftest import kselftest_config as config
     29 
     30 class LinuxKselftestTest(base_test.BaseTestClass):
     31     """Runs Linux Kselftest test cases against Android OS kernel.
     32 
     33     Attributes:
     34         _dut: AndroidDevice, the device under test as config
     35         _shell: ShellMirrorObject, shell mirror
     36         _testcases: string list, list of testcases to run
     37     """
     38     _32BIT = 32
     39     _64BIT = 64
     40 
     41     def setUpClass(self):
     42         """Creates a remote shell instance, and copies data files."""
     43         required_params = [
     44             keys.ConfigKeys.IKEY_DATA_FILE_PATH,
     45             config.ConfigKeys.TEST_TYPE
     46         ]
     47         self.getUserParams(required_params)
     48 
     49         logging.info("%s: %s", keys.ConfigKeys.IKEY_DATA_FILE_PATH,
     50             self.data_file_path)
     51 
     52         self._dut = self.registerController(android_device)[0]
     53         self._dut.shell.InvokeTerminal("one")
     54         self._shell = self._dut.shell.one
     55 
     56         if self.test_type == "presubmit":
     57             self._testcases = config.KSFT_CASES_PRESUBMIT
     58         elif self.test_type == "stable":
     59             self._testcases = config.KSFT_CASES_STABLE
     60         elif self.test_type == "staging":
     61             self._testcases = config.KSFT_CASES_STAGING
     62         else:
     63             asserts.fail("Test config is incorrect!")
     64 
     65     def tearDownClass(self):
     66         """Deletes all copied data."""
     67         self._shell.Execute("rm -rf %s" % config.KSFT_DIR)
     68 
     69     def PushFiles(self, n_bit):
     70         """adb pushes related file to target.
     71 
     72         Args:
     73             n_bit: _32BIT or 32 for 32-bit tests;
     74                 _64BIT or 64 for 64-bit tests;
     75         """
     76         self._shell.Execute("mkdir %s -p" % config.KSFT_DIR)
     77         test_bit = 'nativetest'
     78         if n_bit == self._64BIT:
     79             test_bit += '64'
     80         self._dut.adb.push("%s/DATA/%s/linux-kselftest/. %s" %
     81             (self.data_file_path, test_bit, config.KSFT_DIR))
     82 
     83     def PreTestSetup(self):
     84         """Sets up test before running."""
     85         # This sed command makes shell scripts compatible wiht android shell.
     86         sed_pattern = [
     87             's?/bin/echo?echo?',
     88             's?#!/bin/sh?#!/system/bin/sh?',
     89             's?#!/bin/bash?#!/system/bin/sh?'
     90         ]
     91         sed_cmd = 'sed %s' % ' '.join(
     92             ['-i -e ' + ('"%s"' % p) for p in sed_pattern])
     93 
     94         # This grep command is used to identify shell scripts.
     95         grep_pattern = [
     96            'bin/sh',
     97            'bin/bash'
     98         ]
     99         grep_cmd = 'grep -l %s' % ' '.join(
    100             ['-e ' + ('"%s"' % p) for p in grep_pattern])
    101 
    102         # This applies sed_cmd to every shell script.
    103         cmd = 'find %s -type f | xargs %s | xargs %s' % (
    104             config.KSFT_DIR, grep_cmd, sed_cmd)
    105         result = self._shell.Execute(cmd)
    106 
    107         asserts.assertFalse(
    108             any(result[const.EXIT_CODE]),
    109             "Error: pre-test setup failed.")
    110 
    111     def RunTestcase(self, testcase):
    112         """Runs the given testcase and asserts the result.
    113 
    114         Args:
    115             testcase: string, format testsuite/testname, specifies which
    116                 test case to run.
    117         """
    118         if not testcase:
    119             asserts.skip("Test is not supported on this abi.")
    120 
    121         chmod_cmd = "chmod -R 755 %s" % path_utils.JoinTargetPath(
    122             config.KSFT_DIR, testcase.testsuite)
    123         cd_cmd = "cd %s" % path_utils.JoinTargetPath(
    124             config.KSFT_DIR, testcase.testsuite)
    125 
    126         cmd = [
    127             chmod_cmd,
    128             "%s && %s" % (cd_cmd, testcase.test_cmd)
    129         ]
    130         logging.info("Executing: %s", cmd)
    131 
    132         result = self._shell.Execute(cmd)
    133         logging.info("EXIT_CODE: %s:", result[const.EXIT_CODE])
    134 
    135         asserts.assertFalse(
    136             any(result[const.EXIT_CODE]),
    137             "%s failed." % testcase.testname)
    138 
    139     def TestNBits(self, n_bit):
    140         """Runs all 32-bit or all 64-bit tests.
    141 
    142         Args:
    143             n_bit: _32BIT or 32 for 32-bit tests;
    144                 _64BIT or 64 for 64-bit tests;
    145         """
    146         self.PushFiles(n_bit)
    147         self.PreTestSetup()
    148 
    149         cpu_abi = self._dut.cpu_abi
    150         relevant_testcases = filter(
    151             lambda x: x.IsRelevant(cpu_abi, n_bit),
    152             self._testcases)
    153 
    154         self.runGeneratedTests(
    155             test_func=self.RunTestcase,
    156             settings=relevant_testcases,
    157             name_func=lambda testcase: "%s_%sbit" % (
    158                 testcase.testname.replace('/','_'), n_bit))
    159 
    160     def generate32BitTests(self):
    161         """Runs all 32-bit tests."""
    162         self.TestNBits(self._32BIT)
    163 
    164     def generate64BitTests(self):
    165         """Runs all 64-bit tests."""
    166         if self._dut.is64Bit:
    167             self.TestNBits(self._64BIT)
    168 
    169 if __name__ == "__main__":
    170     test_runner.main()
    171