blob: 52780eb9c84bee158a919240458b81b377ace7e6 [file] [log] [blame]
Ruben Brunk370e2432014-10-14 18:33:23 -07001# 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
Yin-Chia Yehab98ada2015-03-05 13:28:53 -080021import textwrap
Ruben Brunk370e2432014-10-14 18:33:23 -070022import 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
Chien-Yu Chenbad96ca2014-10-20 17:30:56 -070031 SKIP_RET_CODE = 101
32
Yin-Chia Yeh665dda42014-10-20 11:23:48 -070033 # Not yet mandated tests
34 NOT_YET_MANDATED = {
35 "scene0":[
36 "test_jitter"
37 ],
38 "scene1":[
39 "test_ae_precapture_trigger",
Yin-Chia Yeh665dda42014-10-20 11:23:48 -070040 "test_crop_region_raw",
Zhijun He6137f212014-11-20 13:47:11 -080041 "test_ev_compensation_advanced",
42 "test_ev_compensation_basic",
Yin-Chia Yeh3b1763a2014-10-22 10:59:13 -070043 "test_yuv_plus_jpeg"
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070044 ],
Chien-Yu Chenf07d5c22015-07-09 15:37:33 -070045 "scene2":[],
Lu7c6f52e2015-12-15 14:42:18 -080046 "scene3":[],
Lu75f22fc2016-02-19 10:54:07 -080047 "scene4":[],
Yin-Chia Yehf16d6872016-06-06 13:54:42 -070048 "scene5":[],
49 "sensor_fusion":[]
Yin-Chia Yeh665dda42014-10-20 11:23:48 -070050 }
51
Ruben Brunk370e2432014-10-14 18:33:23 -070052 # Get all the scene0 and scene1 tests, which can be run using the same
53 # physical setup.
Yin-Chia Yehf16d6872016-06-06 13:54:42 -070054 scenes = ["scene0", "scene1", "scene2", "scene3", "scene4", "scene5",
55 "sensor_fusion"]
56
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070057 scene_req = {
58 "scene0" : None,
59 "scene1" : "A grey card covering at least the middle 30% of the scene",
Chien-Yu Chenf07d5c22015-07-09 15:37:33 -070060 "scene2" : "A picture containing human faces",
Lu7c6f52e2015-12-15 14:42:18 -080061 "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 "
Lu75f22fc2016-02-19 10:54:07 -080064 "for more details",
65 "scene5" : "Capture images with a diffuser attached to the camera. See "
Yin-Chia Yehf16d6872016-06-06 13:54:42 -070066 "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"
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -070074 }
Yin-Chia Yeh143612d2016-04-27 15:44:08 -070075 scene_extra_args = {
76 "scene5" : ["doAF=False"]
77 }
Ruben Brunk370e2432014-10-14 18:33:23 -070078 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()
Ruben Brunk370e2432014-10-14 18:33:23 -070087 print "Saving output files to:", topdir, "\n"
88
Chien-Yu Chen1da23132015-07-22 15:24:41 -070089 device_id = its.device.get_device_id()
90 device_id_arg = "device=" + device_id
91 print "Testing device " + device_id
92
Yin-Chia Yehab98ada2015-03-05 13:28:53 -080093 camera_ids = []
Yin-Chia Yeha2277d02014-10-20 15:50:23 -070094 for s in sys.argv[1:]:
95 if s[:7] == "camera=" and len(s) > 7:
Yin-Chia Yehab98ada2015-03-05 13:28:53 -080096 camera_ids.append(s[7:])
Yin-Chia Yeha2277d02014-10-20 15:50:23 -070097
Yin-Chia Yehab98ada2015-03-05 13:28:53 -080098 # 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',
Chien-Yu Chen1da23132015-07-22 15:24:41 -0700103 os.path.join(os.getcwd(),"tools/get_camera_ids.py"), out_arg,
104 device_id_arg]
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800105 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', ''))
Yin-Chia Yeh665dda42014-10-20 11:23:48 -0700110
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800111 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
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800122 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
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -0700130 prev_scene = ""
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800131 for (scene,testname,testpath) in tests:
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -0700132 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]
Yin-Chia Yeh143612d2016-04-27 15:44:08 -0700136 extra_args = scene_extra_args.get(scene, [])
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -0700137 cmd = ['python',
138 os.path.join(os.getcwd(),"tools/validate_scene.py"),
Yin-Chia Yeh143612d2016-04-27 15:44:08 -0700139 camera_id_arg, out_arg, scene_arg, device_id_arg] + \
140 extra_args
Yin-Chia Yeh0e0276f2015-06-03 15:27:06 -0700141 retcode = subprocess.call(cmd,cwd=topdir)
142 assert(retcode == 0)
143 print "Start running tests for", scene
144 prev_scene = scene
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800145 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 "")
Chien-Yu Chenbad96ca2014-10-20 17:30:56 -0700179 else:
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800180 skipstr = ""
Yin-Chia Yeh665dda42014-10-20 11:23:48 -0700181
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800182 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"
Ruben Brunk370e2432014-10-14 18:33:23 -0700189
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800190 if numnotmandatedfail > 0:
191 msg = "(*) tests are not yet mandated"
192 print msg
193 summary += msg + "\n"
Chien-Yu Chenbad96ca2014-10-20 17:30:56 -0700194
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800195 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)
Chien-Yu Chen1da23132015-07-22 15:24:41 -0700200 its.device.report_result(device_id, camera_id, result, summary_path)
Chien-Yu Chenbad96ca2014-10-20 17:30:56 -0700201
Yin-Chia Yehab98ada2015-03-05 13:28:53 -0800202 print "ITS tests finished. Please go back to CtsVerifier and proceed"
Ruben Brunk370e2432014-10-14 18:33:23 -0700203
204if __name__ == '__main__':
205 main()