• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18import inspect
19import logging
20import os
21import re
22import subprocess
23import sys
24
25from vts.runners.host import asserts
26from vts.runners.host import base_test
27from vts.runners.host import const
28from vts.runners.host import test_runner
29from vts.utils.python.controllers import android_device
30
31
32class 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
150if __name__ == "__main__":
151    test_runner.main()
152