• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import os
16import os.path
17import tempfile
18import subprocess
19import time
20import sys
21import textwrap
22import its.device
23
24def main():
25    """Run all the automated tests, saving intermediate files, and producing
26    a summary/report of the results.
27
28    Script should be run from the top-level CameraITS directory.
29    """
30
31    SKIP_RET_CODE = 101
32
33    # Not yet mandated tests
34    NOT_YET_MANDATED = {
35        "scene0":[
36            "test_jitter"
37        ],
38        "scene1":[
39            "test_ae_precapture_trigger",
40            "test_crop_region_raw",
41            "test_ev_compensation_advanced",
42            "test_ev_compensation_basic",
43            "test_yuv_plus_jpeg"
44        ],
45        "scene2":[],
46        "scene3":[],
47        "scene4":[],
48        "scene5":[],
49        "sensor_fusion":[]
50    }
51
52    # Get all the scene0 and scene1 tests, which can be run using the same
53    # physical setup.
54    scenes = ["scene0", "scene1", "scene2", "scene3", "scene4", "scene5",
55              "sensor_fusion"]
56
57    scene_req = {
58        "scene0" : None,
59        "scene1" : "A grey card covering at least the middle 30% of the scene",
60        "scene2" : "A picture containing human faces",
61        "scene3" : "A chart containing sharp edges like ISO 12233",
62        "scene4" : "A specific test page of a circle covering at least the "
63                   "middle 50% of the scene. See CameraITS.pdf section 2.3.4 "
64                   "for more details",
65        "scene5" : "Capture images with a diffuser attached to the camera. See "
66                   "CameraITS.pdf section 2.3.4 for more details",
67        "sensor_fusion" : "Rotating checkboard pattern. See "
68                          "sensor_fusion/SensorFusion.pdf for detailed "
69                          "instructions. Note that this test will be skipped "
70                          "on devices not supporting REALTIME camera timestamp."
71                          "If that is the case, no scene setup is required and "
72                          "you can just answer Y when being asked if the scene "
73                          "is okay"
74    }
75    scene_extra_args = {
76        "scene5" : ["doAF=False"]
77    }
78    tests = []
79    for d in scenes:
80        tests += [(d,s[:-3],os.path.join("tests", d, s))
81                  for s in os.listdir(os.path.join("tests",d))
82                  if s[-3:] == ".py"]
83    tests.sort()
84
85    # Make output directories to hold the generated files.
86    topdir = tempfile.mkdtemp()
87    print "Saving output files to:", topdir, "\n"
88
89    device_id = its.device.get_device_id()
90    device_id_arg = "device=" + device_id
91    print "Testing device " + device_id
92
93    camera_ids = []
94    for s in sys.argv[1:]:
95        if s[:7] == "camera=" and len(s) > 7:
96            camera_ids.append(s[7:])
97
98    # user doesn't specify camera id, run through all cameras
99    if not camera_ids:
100        camera_ids_path = os.path.join(topdir, "camera_ids.txt")
101        out_arg = "out=" + camera_ids_path
102        cmd = ['python',
103               os.path.join(os.getcwd(),"tools/get_camera_ids.py"), out_arg,
104               device_id_arg]
105        retcode = subprocess.call(cmd,cwd=topdir)
106        assert(retcode == 0)
107        with open(camera_ids_path, "r") as f:
108            for line in f:
109                camera_ids.append(line.replace('\n', ''))
110
111    print "Running ITS on the following cameras:", camera_ids
112
113    for camera_id in camera_ids:
114        # Loop capturing images until user confirm test scene is correct
115        camera_id_arg = "camera=" + camera_id
116        print "Preparing to run ITS on camera", camera_id
117
118        os.mkdir(os.path.join(topdir, camera_id))
119        for d in scenes:
120            os.mkdir(os.path.join(topdir, camera_id, d))
121
122        print "Start running ITS on camera: ", camera_id
123        # Run each test, capturing stdout and stderr.
124        summary = "ITS test result summary for camera " + camera_id + "\n"
125        numpass = 0
126        numskip = 0
127        numnotmandatedfail = 0
128        numfail = 0
129
130        prev_scene = ""
131        for (scene,testname,testpath) in tests:
132            if scene != prev_scene and scene_req[scene] != None:
133                out_path = os.path.join(topdir, camera_id, scene+".jpg")
134                out_arg = "out=" + out_path
135                scene_arg = "scene=" + scene_req[scene]
136                extra_args = scene_extra_args.get(scene, [])
137                cmd = ['python',
138                        os.path.join(os.getcwd(),"tools/validate_scene.py"),
139                        camera_id_arg, out_arg, scene_arg, device_id_arg] + \
140                        extra_args
141                retcode = subprocess.call(cmd,cwd=topdir)
142                assert(retcode == 0)
143                print "Start running tests for", scene
144            prev_scene = scene
145            cmd = ['python', os.path.join(os.getcwd(),testpath)] + \
146                  sys.argv[1:] + [camera_id_arg]
147            outdir = os.path.join(topdir,camera_id,scene)
148            outpath = os.path.join(outdir,testname+"_stdout.txt")
149            errpath = os.path.join(outdir,testname+"_stderr.txt")
150            t0 = time.time()
151            with open(outpath,"w") as fout, open(errpath,"w") as ferr:
152                retcode = subprocess.call(cmd,stderr=ferr,stdout=fout,cwd=outdir)
153            t1 = time.time()
154
155            if retcode == 0:
156                retstr = "PASS "
157                numpass += 1
158            elif retcode == SKIP_RET_CODE:
159                retstr = "SKIP "
160                numskip += 1
161            elif retcode != 0 and testname in NOT_YET_MANDATED[scene]:
162                retstr = "FAIL*"
163                numnotmandatedfail += 1
164            else:
165                retstr = "FAIL "
166                numfail += 1
167
168            msg = "%s %s/%s [%.1fs]" % (retstr, scene, testname, t1-t0)
169            print msg
170            summary += msg + "\n"
171            if retcode != 0 and retcode != SKIP_RET_CODE:
172                # Dump the stderr if the test fails
173                with open (errpath, "r") as error_file:
174                    errors = error_file.read()
175                    summary += errors + "\n"
176
177        if numskip > 0:
178            skipstr = ", %d test%s skipped" % (numskip, "s" if numskip > 1 else "")
179        else:
180            skipstr = ""
181
182        test_result = "\n%d / %d tests passed (%.1f%%)%s" % (
183                numpass + numnotmandatedfail, len(tests) - numskip,
184                100.0 * float(numpass + numnotmandatedfail) / (len(tests) - numskip)
185                    if len(tests) != numskip else 100.0,
186                skipstr)
187        print test_result
188        summary += test_result + "\n"
189
190        if numnotmandatedfail > 0:
191            msg = "(*) tests are not yet mandated"
192            print msg
193            summary += msg + "\n"
194
195        result = numfail == 0
196        print "Reporting ITS result to CtsVerifier"
197        summary_path = os.path.join(topdir, camera_id, "summary.txt")
198        with open(summary_path, "w") as f:
199            f.write(summary)
200        its.device.report_result(device_id, camera_id, result, summary_path)
201
202    print "ITS tests finished. Please go back to CtsVerifier and proceed"
203
204if __name__ == '__main__':
205    main()
206