Camera App Stress Test

Requires a proper camera app and ffmpeg bin path

Test: run the test using VTS
Bug: 36233082
Change-Id: I9621f69256081e76496270fae4328865576817de
diff --git a/camera/app/stress_test/Android.mk b/camera/app/stress_test/Android.mk
new file mode 100644
index 0000000..a1ce05f
--- /dev/null
+++ b/camera/app/stress_test/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsAppCameraStressTest
+VTS_CONFIG_SRC_DIR := testcases/performance/camera/app/stress_test
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/camera/app/stress_test/AndroidTest.xml b/camera/app/stress_test/AndroidTest.xml
new file mode 100644
index 0000000..dd7a6db
--- /dev/null
+++ b/camera/app/stress_test/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS Google camera app's stress test case">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="push-group" value="HostDrivenTest.push" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="test-file-name" value="DATA/app/GoogleCameraTests/GoogleCameraTests.apk" />
+        <option name="cleanup-apks" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-case-path" value="vts/testcases/performance/camera/app/stress_test/CameraAppStressTest" />
+    </test>
+</configuration>
diff --git a/camera/app/stress_test/CameraAppStressTest.py b/camera/app/stress_test/CameraAppStressTest.py
new file mode 100644
index 0000000..6a0b939
--- /dev/null
+++ b/camera/app/stress_test/CameraAppStressTest.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import logging
+import os
+
+from vts.runners.host import asserts
+from vts.runners.host import base_test
+from vts.runners.host import const
+from vts.runners.host import keys
+from vts.runners.host import test_runner
+from vts.testcases.performance.camera.app.stress_test import FrameDropRate
+from vts.utils.python.controllers import android_device
+
+import shutil
+import tempfile
+
+class VtsAppCameraStressTest(base_test.BaseTestClass):
+    """A stress test of Google camera app."""
+
+    _TESTS = [
+        {"apk": "CameraAppStressTest.apk",
+         "opt": "-e videoCount 7 "
+                "-e screenshotOnFailure true "
+                "-e timeout_msec 21600000 "
+                "-e class com.android.camera.stress.CameraStressTest#testBackCameraHFR240FPSVideoCaptureLongDuration "
+                "com.android.camera2/android.test.InstrumentationTestRunner"},
+        ]
+    CAMERA_DATA_DIR_ON_TARGET = "/sdcard/DCIM/Camera"
+    RESULT_PREFIX_TEST = "Total framedrop: "
+
+    def setUpClass(self):
+        self.getUserParams(
+            req_param_names=[keys.ConfigKeys.IKEY_FFMPEG_BINARY_PATH])
+        self._ffmpeg_binary_path = getattr(self, keys.ConfigKeys.IKEY_FFMPEG_BINARY_PATH)
+        logging.info("ffmpeg_binary_path: %s", self._ffmpeg_binary_path)
+        self.dut = self.registerController(android_device)[0]
+
+    def setUpTest(self):
+        self._tmpdir = tempfile.mkdtemp()
+
+    def tearDownTest(self):
+        shutil.rmtree(self._tmpdir)
+
+    def testFrameDropRate(self):
+        """Runs all test cases listed in self._TESTS."""
+        for test in self._TESTS:
+            logging.info("Run %s", test["apk"])
+            self.dut.adb.shell(
+                "rm -rf %s/*" % self.CAMERA_DATA_DIR_ON_TARGET)
+            self.dut.adb.shell(
+                "am instrument -w -r %s" % (test["opt"]))
+            self.dut.adb.pull("%s %s" % (self.CAMERA_DATA_DIR_ON_TARGET,
+                                         self._tmpdir))
+            report = FrameDropRate.Analyze(
+                os.path.join(self._tmpdir, "Camera"),
+                ffmpeg_binary_path=self._ffmpeg_binary_path)
+            logging.info("Frame drop rate report: %s", report)
+            for line in report.split("\n"):
+                if line.startswith(self.RESULT_PREFIX_TEST):
+                    droped_frames, all_frames = line.replace(
+                        self.RESULT_PREFIX_TEST, "").split()[0].split("/")
+                    fdr = float(droped_frames) / float(all_frames) * 100
+                    logging.info("fdr %s", fdr)
+                    break
+            asserts.assertLess(fdr, 0.4)
+
+
+if __name__ == "__main__":
+    test_runner.main()