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 logging
19
20from vts.runners.host import asserts
21from vts.runners.host import base_test
22from vts.runners.host import test_runner
23from vts.utils.python.controllers import android_device
24from vts.runners.host import const
25
26
27class ShellBinaryCrashTest(base_test.BaseTestClass):
28    """A binary crash test case for the shell driver."""
29
30    EXIT_CODE_CRASH = 133
31    EXIT_CODE_SEGFAULT = 139
32
33    def setUpClass(self):
34        self.dut = self.registerController(android_device)[0]
35
36    def testCrashBinary(self):
37        """Tests whether the agent survives when a called binary crashes."""
38        self.dut.shell.InvokeTerminal("my_shell1")
39        target = "/data/local/tmp/64/vts_test_binary_crash_app"
40        results = self.dut.shell.my_shell1.Execute(
41            ["chmod 755 %s" % target, target])
42        logging.info(str(results[const.STDOUT]))
43        asserts.assertEqual(len(results[const.STDOUT]), 2)
44        asserts.assertEqual(results[const.STDOUT][1].strip(), "")
45        # "crash_app: start" is also valid output.
46        asserts.assertEqual(results[const.EXIT_CODE][1], self.EXIT_CODE_CRASH)
47
48        self.CheckShellDriver("my_shell1")
49        self.CheckShellDriver("my_shell2")
50
51    def testSegmentFaultBinary(self):
52        """Tests whether the agent survives when a binary leads to segfault."""
53        self.dut.shell.InvokeTerminal("my_shell1")
54        target = "/data/local/tmp/32/connect01"
55        results = self.dut.shell.my_shell1.Execute(
56            ["chmod 755 %s" % target, target])
57        logging.info(str(results[const.STDOUT]))
58        asserts.assertEqual(len(results[const.STDOUT]), 2)
59        asserts.assertEqual(results[const.STDOUT][1].strip(), "")
60        # TODO: currently the agent doesn't return the stdout log emitted
61        # before a failure.
62        asserts.assertEqual(results[const.EXIT_CODE][1],
63                            self.EXIT_CODE_SEGFAULT)
64
65        self.CheckShellDriver("my_shell1")
66        self.CheckShellDriver("my_shell2")
67
68    def CheckShellDriver(self, shell_name):
69        """Checks whether the shell driver sevice is available.
70
71        Args:
72            shell_name: string, the name of a shell service to create.
73        """
74        self.dut.shell.InvokeTerminal(shell_name)
75        results = getattr(self.dut.shell, shell_name).Execute("which ls")
76        logging.info(str(results[const.STDOUT]))
77        asserts.assertEqual(len(results[const.STDOUT]), 1)
78        asserts.assertEqual(results[const.STDOUT][0].strip(),
79                            "/system/bin/ls")
80        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
81
82
83if __name__ == "__main__":
84    test_runner.main()
85