Home | History | Annotate | Download | only in camera_its
      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 inspect
     19 import logging
     20 import os
     21 import re
     22 import subprocess
     23 import sys
     24 
     25 from vts.runners.host import asserts
     26 from vts.runners.host import base_test
     27 from vts.runners.host import const
     28 from vts.runners.host import test_runner
     29 from vts.utils.python.controllers import android_device
     30 
     31 
     32 class CameraITSTest(base_test.BaseTestClass):
     33     """Running CameraITS tests in VTS"""
     34 
     35     # TODO: use config file to pass in:
     36     #          - serial for dut and screen
     37     #          - camera id
     38     #       so that we can run other test scenes with ITS-in-a-box
     39     def setUpClass(self):
     40         """Setup ITS running python environment and check for required python modules
     41         """
     42         self.dut = self.registerController(android_device)[0]
     43         self.device_arg = "device=%s" % (self.dut.serial)
     44         # data_file_path is unicode so convert it to ascii
     45         self.its_path = str(os.path.abspath(os.path.join(
     46             self.data_file_path, 'CameraITS')))
     47         logging.info("cwd: %s", os.getcwd())
     48         logging.info("its_path: %s", self.its_path)
     49         self.out_path = logging.log_path
     50         os.environ["CAMERA_ITS_TOP"] = self.its_path
     51         # Below module check code assumes tradefed is running python 2.7
     52         # If tradefed switches to python3, then we will be checking modules in python3 while ITS
     53         # scripts should be ran in 2.7.
     54         if sys.version_info[:2] != (2, 7):
     55             logging.warning(
     56                 "Python version %s found; "
     57                 "CameraITSTest only tested with Python 2.7." % (
     58                     str(sys.version_info[:3])))
     59         logging.info("===============================")
     60         logging.info("Python path is: %s" % (sys.executable))
     61         logging.info("PYTHONPATH env is: " + os.environ["PYTHONPATH"])
     62         import PIL
     63         logging.info("PIL version is " + PIL.__version__)
     64         logging.info("PIL path is " + inspect.getfile(PIL))
     65         from PIL import Image
     66         logging.info("Image path is " + inspect.getfile(Image))
     67         import numpy
     68         logging.info("numpy version is " + numpy.__version__)
     69         logging.info("numpy path is " + inspect.getfile(numpy))
     70         import scipy
     71         logging.info("scipy version is " + scipy.__version__)
     72         logging.info("scipy path is " + inspect.getfile(scipy))
     73         import matplotlib
     74         logging.info("matplotlib version is " + matplotlib.__version__)
     75         logging.info("matplotlib path is " + inspect.getfile(matplotlib))
     76         from matplotlib import pylab
     77         logging.info("pylab path is " + inspect.getfile(pylab))
     78         logging.info("===============================")
     79         modules = ["numpy", "PIL", "Image", "matplotlib", "pylab",
     80                    "scipy.stats", "scipy.spatial"]
     81         for m in modules:
     82             try:
     83                 if m == "Image":
     84                     # Image modules are now imported from PIL
     85                     exec ("from PIL import Image")
     86                 elif m == "pylab":
     87                     exec ("from matplotlib import pylab")
     88                 else:
     89                     exec ("import " + m)
     90             except ImportError as e:
     91                 asserts.fail("Cannot import python module %s: %s" % (m, str(e)))
     92 
     93         # Add ITS module path to path
     94         its_path = os.path.join(self.its_path, "pymodules")
     95         env_python_path = os.environ["PYTHONPATH"]
     96         self.pythonpath = env_python_path if its_path in env_python_path else \
     97                 "%s:%s" % (its_path, env_python_path)
     98         os.environ["PYTHONPATH"] = self.pythonpath
     99         logging.info("new PYTHONPATH: %s", self.pythonpath)
    100 
    101     def RunTestcase(self, testpath):
    102         """Runs the given testcase and asserts the result.
    103 
    104         Args:
    105             testpath: string, format tests/[scenename]/[testname].py
    106         """
    107         testname = re.split("/|\.", testpath)[-2]
    108         cmd = ['python', os.path.join(self.its_path, testpath),
    109                self.device_arg]
    110         outdir = self.out_path
    111         outpath = os.path.join(outdir, testname + "_stdout.txt")
    112         errpath = os.path.join(outdir, testname + "_stderr.txt")
    113         logging.info("cwd: %s", os.getcwd())
    114         logging.info("cmd: %s", cmd)
    115         logging.info("outpath: %s", outpath)
    116         logging.info("errpath: %s", errpath)
    117         with open(outpath, "w") as fout, open(errpath, "w") as ferr:
    118             retcode = subprocess.call(
    119                 cmd, stderr=ferr, stdout=fout, cwd=outdir)
    120         if retcode != 0 and retcode != 101:
    121             # Dump all logs to host log if the test failed
    122             with open(outpath, "r") as fout, open(errpath, "r") as ferr:
    123                 logging.info(fout.read())
    124                 logging.error(ferr.read())
    125 
    126         asserts.assertTrue(retcode == 0 or retcode == 101,
    127                            "ITS %s retcode %d" % (testname, retcode))
    128 
    129     def FetchTestPaths(self, scene):
    130         """Returns a list of test paths for a given test scene.
    131 
    132         Args:
    133             scnee: one of ITS test scene name.
    134         """
    135         its_path = self.its_path
    136         paths = [os.path.join("tests", scene, s)
    137                  for s in os.listdir(os.path.join(its_path, "tests", scene))
    138                  if s[-3:] == ".py" and s[:4] == "test"]
    139         paths.sort()
    140         return paths
    141 
    142     def generateScene0Test(self):
    143         testpaths = self.FetchTestPaths("scene0")
    144         self.runGeneratedTests(
    145             test_func=self.RunTestcase,
    146             settings=testpaths,
    147             name_func=lambda path: "%s_%s" % (re.split("/|\.", path)[-3], re.split("/|\.", path)[-2]))
    148 
    149 
    150 if __name__ == "__main__":
    151     test_runner.main()
    152