Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 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 | |
| 15 | import os |
| 16 | import os.path |
| 17 | import tempfile |
| 18 | import subprocess |
| 19 | import time |
| 20 | import sys |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 21 | import textwrap |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 22 | import its.device |
| 23 | |
| 24 | def 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 Chen | bad96ca | 2014-10-20 17:30:56 -0700 | [diff] [blame] | 31 | SKIP_RET_CODE = 101 |
| 32 | |
Yin-Chia Yeh | 665dda4 | 2014-10-20 11:23:48 -0700 | [diff] [blame] | 33 | # Not yet mandated tests |
| 34 | NOT_YET_MANDATED = { |
| 35 | "scene0":[ |
| 36 | "test_jitter" |
| 37 | ], |
| 38 | "scene1":[ |
| 39 | "test_ae_precapture_trigger", |
Yin-Chia Yeh | 665dda4 | 2014-10-20 11:23:48 -0700 | [diff] [blame] | 40 | "test_crop_region_raw", |
Zhijun He | 6137f21 | 2014-11-20 13:47:11 -0800 | [diff] [blame] | 41 | "test_ev_compensation_advanced", |
| 42 | "test_ev_compensation_basic", |
Yin-Chia Yeh | 3b1763a | 2014-10-22 10:59:13 -0700 | [diff] [blame] | 43 | "test_yuv_plus_jpeg" |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 44 | ], |
Chien-Yu Chen | f07d5c2 | 2015-07-09 15:37:33 -0700 | [diff] [blame] | 45 | "scene2":[], |
Lu | 7c6f52e | 2015-12-15 14:42:18 -0800 | [diff] [blame] | 46 | "scene3":[], |
| 47 | "scene4":[] |
Yin-Chia Yeh | 665dda4 | 2014-10-20 11:23:48 -0700 | [diff] [blame] | 48 | } |
| 49 | |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 50 | # Get all the scene0 and scene1 tests, which can be run using the same |
| 51 | # physical setup. |
Lu | 7c6f52e | 2015-12-15 14:42:18 -0800 | [diff] [blame] | 52 | scenes = ["scene0", "scene1", "scene2", "scene3", "scene4"] |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 53 | scene_req = { |
| 54 | "scene0" : None, |
| 55 | "scene1" : "A grey card covering at least the middle 30% of the scene", |
Chien-Yu Chen | f07d5c2 | 2015-07-09 15:37:33 -0700 | [diff] [blame] | 56 | "scene2" : "A picture containing human faces", |
Lu | 7c6f52e | 2015-12-15 14:42:18 -0800 | [diff] [blame] | 57 | "scene3" : "A chart containing sharp edges like ISO 12233", |
| 58 | "scene4" : "A specific test page of a circle covering at least the " |
| 59 | "middle 50% of the scene. See CameraITS.pdf section 2.3.4 " |
| 60 | "for more detail" |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 61 | } |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 62 | tests = [] |
| 63 | for d in scenes: |
| 64 | tests += [(d,s[:-3],os.path.join("tests", d, s)) |
| 65 | for s in os.listdir(os.path.join("tests",d)) |
| 66 | if s[-3:] == ".py"] |
| 67 | tests.sort() |
| 68 | |
| 69 | # Make output directories to hold the generated files. |
| 70 | topdir = tempfile.mkdtemp() |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 71 | print "Saving output files to:", topdir, "\n" |
| 72 | |
Chien-Yu Chen | 1da2313 | 2015-07-22 15:24:41 -0700 | [diff] [blame] | 73 | device_id = its.device.get_device_id() |
| 74 | device_id_arg = "device=" + device_id |
| 75 | print "Testing device " + device_id |
| 76 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 77 | camera_ids = [] |
Yin-Chia Yeh | a2277d0 | 2014-10-20 15:50:23 -0700 | [diff] [blame] | 78 | for s in sys.argv[1:]: |
| 79 | if s[:7] == "camera=" and len(s) > 7: |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 80 | camera_ids.append(s[7:]) |
Yin-Chia Yeh | a2277d0 | 2014-10-20 15:50:23 -0700 | [diff] [blame] | 81 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 82 | # user doesn't specify camera id, run through all cameras |
| 83 | if not camera_ids: |
| 84 | camera_ids_path = os.path.join(topdir, "camera_ids.txt") |
| 85 | out_arg = "out=" + camera_ids_path |
| 86 | cmd = ['python', |
Chien-Yu Chen | 1da2313 | 2015-07-22 15:24:41 -0700 | [diff] [blame] | 87 | os.path.join(os.getcwd(),"tools/get_camera_ids.py"), out_arg, |
| 88 | device_id_arg] |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 89 | retcode = subprocess.call(cmd,cwd=topdir) |
| 90 | assert(retcode == 0) |
| 91 | with open(camera_ids_path, "r") as f: |
| 92 | for line in f: |
| 93 | camera_ids.append(line.replace('\n', '')) |
Yin-Chia Yeh | 665dda4 | 2014-10-20 11:23:48 -0700 | [diff] [blame] | 94 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 95 | print "Running ITS on the following cameras:", camera_ids |
| 96 | |
| 97 | for camera_id in camera_ids: |
| 98 | # Loop capturing images until user confirm test scene is correct |
| 99 | camera_id_arg = "camera=" + camera_id |
| 100 | print "Preparing to run ITS on camera", camera_id |
| 101 | |
| 102 | os.mkdir(os.path.join(topdir, camera_id)) |
| 103 | for d in scenes: |
| 104 | os.mkdir(os.path.join(topdir, camera_id, d)) |
| 105 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 106 | print "Start running ITS on camera: ", camera_id |
| 107 | # Run each test, capturing stdout and stderr. |
| 108 | summary = "ITS test result summary for camera " + camera_id + "\n" |
| 109 | numpass = 0 |
| 110 | numskip = 0 |
| 111 | numnotmandatedfail = 0 |
| 112 | numfail = 0 |
| 113 | |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 114 | prev_scene = "" |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 115 | for (scene,testname,testpath) in tests: |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 116 | if scene != prev_scene and scene_req[scene] != None: |
| 117 | out_path = os.path.join(topdir, camera_id, scene+".jpg") |
| 118 | out_arg = "out=" + out_path |
| 119 | scene_arg = "scene=" + scene_req[scene] |
| 120 | cmd = ['python', |
| 121 | os.path.join(os.getcwd(),"tools/validate_scene.py"), |
Chien-Yu Chen | 1da2313 | 2015-07-22 15:24:41 -0700 | [diff] [blame] | 122 | camera_id_arg, out_arg, scene_arg, device_id_arg] |
Yin-Chia Yeh | 0e0276f | 2015-06-03 15:27:06 -0700 | [diff] [blame] | 123 | retcode = subprocess.call(cmd,cwd=topdir) |
| 124 | assert(retcode == 0) |
| 125 | print "Start running tests for", scene |
| 126 | prev_scene = scene |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 127 | cmd = ['python', os.path.join(os.getcwd(),testpath)] + \ |
| 128 | sys.argv[1:] + [camera_id_arg] |
| 129 | outdir = os.path.join(topdir,camera_id,scene) |
| 130 | outpath = os.path.join(outdir,testname+"_stdout.txt") |
| 131 | errpath = os.path.join(outdir,testname+"_stderr.txt") |
| 132 | t0 = time.time() |
| 133 | with open(outpath,"w") as fout, open(errpath,"w") as ferr: |
| 134 | retcode = subprocess.call(cmd,stderr=ferr,stdout=fout,cwd=outdir) |
| 135 | t1 = time.time() |
| 136 | |
| 137 | if retcode == 0: |
| 138 | retstr = "PASS " |
| 139 | numpass += 1 |
| 140 | elif retcode == SKIP_RET_CODE: |
| 141 | retstr = "SKIP " |
| 142 | numskip += 1 |
| 143 | elif retcode != 0 and testname in NOT_YET_MANDATED[scene]: |
| 144 | retstr = "FAIL*" |
| 145 | numnotmandatedfail += 1 |
| 146 | else: |
| 147 | retstr = "FAIL " |
| 148 | numfail += 1 |
| 149 | |
| 150 | msg = "%s %s/%s [%.1fs]" % (retstr, scene, testname, t1-t0) |
| 151 | print msg |
| 152 | summary += msg + "\n" |
| 153 | if retcode != 0 and retcode != SKIP_RET_CODE: |
| 154 | # Dump the stderr if the test fails |
| 155 | with open (errpath, "r") as error_file: |
| 156 | errors = error_file.read() |
| 157 | summary += errors + "\n" |
| 158 | |
| 159 | if numskip > 0: |
| 160 | skipstr = ", %d test%s skipped" % (numskip, "s" if numskip > 1 else "") |
Chien-Yu Chen | bad96ca | 2014-10-20 17:30:56 -0700 | [diff] [blame] | 161 | else: |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 162 | skipstr = "" |
Yin-Chia Yeh | 665dda4 | 2014-10-20 11:23:48 -0700 | [diff] [blame] | 163 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 164 | test_result = "\n%d / %d tests passed (%.1f%%)%s" % ( |
| 165 | numpass + numnotmandatedfail, len(tests) - numskip, |
| 166 | 100.0 * float(numpass + numnotmandatedfail) / (len(tests) - numskip) |
| 167 | if len(tests) != numskip else 100.0, |
| 168 | skipstr) |
| 169 | print test_result |
| 170 | summary += test_result + "\n" |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 171 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 172 | if numnotmandatedfail > 0: |
| 173 | msg = "(*) tests are not yet mandated" |
| 174 | print msg |
| 175 | summary += msg + "\n" |
Chien-Yu Chen | bad96ca | 2014-10-20 17:30:56 -0700 | [diff] [blame] | 176 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 177 | result = numfail == 0 |
| 178 | print "Reporting ITS result to CtsVerifier" |
| 179 | summary_path = os.path.join(topdir, camera_id, "summary.txt") |
| 180 | with open(summary_path, "w") as f: |
| 181 | f.write(summary) |
Chien-Yu Chen | 1da2313 | 2015-07-22 15:24:41 -0700 | [diff] [blame] | 182 | its.device.report_result(device_id, camera_id, result, summary_path) |
Chien-Yu Chen | bad96ca | 2014-10-20 17:30:56 -0700 | [diff] [blame] | 183 | |
Yin-Chia Yeh | ab98ada | 2015-03-05 13:28:53 -0800 | [diff] [blame] | 184 | print "ITS tests finished. Please go back to CtsVerifier and proceed" |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 185 | |
| 186 | if __name__ == '__main__': |
| 187 | main() |