• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright (C) 2017 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 const
23from vts.runners.host import test_runner
24
25from vts.testcases.kernel.api.proc import ProcAsoundTests
26from vts.testcases.kernel.api.proc import ProcCmdlineTest
27from vts.testcases.kernel.api.proc import ProcCpuFileTests
28from vts.testcases.kernel.api.proc import ProcFsFileTests
29from vts.testcases.kernel.api.proc import ProcKmsgTest
30from vts.testcases.kernel.api.proc import ProcMapsTest
31from vts.testcases.kernel.api.proc import ProcMiscTest
32from vts.testcases.kernel.api.proc import ProcMemInfoTest
33from vts.testcases.kernel.api.proc import ProcModulesTest
34from vts.testcases.kernel.api.proc import ProcQtaguidCtrlTest
35from vts.testcases.kernel.api.proc import ProcRemoveUidRangeTest
36from vts.testcases.kernel.api.proc import ProcSimpleFileTests
37from vts.testcases.kernel.api.proc import ProcShowUidStatTest
38from vts.testcases.kernel.api.proc import ProcStatTest
39from vts.testcases.kernel.api.proc import ProcUidIoStatsTest
40from vts.testcases.kernel.api.proc import ProcUidTimeInStateTest
41from vts.testcases.kernel.api.proc import ProcUidConcurrentTimeTests
42from vts.testcases.kernel.api.proc import ProcUidCpuPowerTests
43from vts.testcases.kernel.api.proc import ProcVersionTest
44from vts.testcases.kernel.api.proc import ProcVmallocInfoTest
45from vts.testcases.kernel.api.proc import ProcVmstatTest
46from vts.testcases.kernel.api.proc import ProcZoneInfoTest
47
48from vts.utils.python.controllers import android_device
49from vts.utils.python.file import target_file_utils
50
51TEST_OBJECTS = {
52    ProcAsoundTests.ProcAsoundCardsTest(),
53    ProcCmdlineTest.ProcCmdlineTest(),
54    ProcCpuFileTests.ProcCpuInfoTest(),
55    ProcCpuFileTests.ProcLoadavgTest(),
56    ProcFsFileTests.ProcDiskstatsTest(),
57    ProcFsFileTests.ProcFilesystemsTest(),
58    ProcFsFileTests.ProcMountsTest(),
59    ProcFsFileTests.ProcSwapsTest(),
60    ProcKmsgTest.ProcKmsgTest(),
61    ProcMapsTest.ProcMapsTest(),
62    ProcMiscTest.ProcMisc(),
63    ProcMemInfoTest.ProcMemInfoTest(),
64    ProcModulesTest.ProcModulesTest(),
65    ProcQtaguidCtrlTest.ProcQtaguidCtrlTest(),
66    ProcRemoveUidRangeTest.ProcRemoveUidRangeTest(),
67    ProcSimpleFileTests.ProcCorePattern(),
68    ProcSimpleFileTests.ProcCorePipeLimit(),
69    ProcSimpleFileTests.ProcDirtyBackgroundBytes(),
70    ProcSimpleFileTests.ProcDirtyBackgroundRatio(),
71    ProcSimpleFileTests.ProcDirtyExpireCentisecs(),
72    ProcSimpleFileTests.ProcDmesgRestrict(),
73    ProcSimpleFileTests.ProcDomainname(),
74    ProcSimpleFileTests.ProcDropCaches(),
75    ProcSimpleFileTests.ProcExtraFreeKbytes(),
76    ProcSimpleFileTests.ProcHostname(),
77    ProcSimpleFileTests.ProcHungTaskTimeoutSecs(),
78    ProcSimpleFileTests.ProcKptrRestrictTest(),
79    ProcSimpleFileTests.ProcMaxMapCount(),
80    ProcSimpleFileTests.ProcMmapMinAddrTest(),
81    ProcSimpleFileTests.ProcMmapRndBitsTest(),
82    ProcSimpleFileTests.ProcModulesDisabled(),
83    ProcSimpleFileTests.ProcOverCommitMemoryTest(),
84    ProcSimpleFileTests.ProcPageCluster(),
85    ProcSimpleFileTests.ProcPanicOnOops(),
86    ProcSimpleFileTests.ProcPerfEventMaxSampleRate(),
87    ProcSimpleFileTests.ProcPerfEventParanoid(),
88    ProcSimpleFileTests.ProcPidMax(),
89    ProcSimpleFileTests.ProcPipeMaxSize(),
90    ProcSimpleFileTests.ProcProtectedHardlinks(),
91    ProcSimpleFileTests.ProcProtectedSymlinks(),
92    ProcSimpleFileTests.ProcRandomizeVaSpaceTest(),
93    ProcSimpleFileTests.ProcSchedChildRunsFirst(),
94    ProcSimpleFileTests.ProcSchedLatencyNS(),
95    ProcSimpleFileTests.ProcSchedRTPeriodUS(),
96    ProcSimpleFileTests.ProcSchedRTRuntimeUS(),
97    ProcSimpleFileTests.ProcSchedTunableScaling(),
98    ProcSimpleFileTests.ProcSchedWakeupGranularityNS(),
99    ProcShowUidStatTest.ProcShowUidStatTest(),
100    ProcSimpleFileTests.ProcSuidDumpable(),
101    ProcSimpleFileTests.ProcSysKernelRandomBootId(),
102    ProcSimpleFileTests.ProcSysRqTest(),
103    ProcSimpleFileTests.ProcUptime(),
104    ProcStatTest.ProcStatTest(),
105    ProcUidIoStatsTest.ProcUidIoStatsTest(),
106    ProcUidTimeInStateTest.ProcUidTimeInStateTest(),
107    ProcUidConcurrentTimeTests.ProcUidConcurrentActiveTimeTest(),
108    ProcUidConcurrentTimeTests.ProcUidConcurrentPolicyTimeTest(),
109    ProcUidCpuPowerTests.ProcUidCpuPowerTimeInStateTest(),
110    ProcUidCpuPowerTests.ProcUidCpuPowerConcurrentActiveTimeTest(),
111    ProcUidCpuPowerTests.ProcUidCpuPowerConcurrentPolicyTimeTest(),
112    ProcVersionTest.ProcVersionTest(),
113    ProcVmallocInfoTest.ProcVmallocInfoTest(),
114    ProcVmstatTest.ProcVmstat(),
115    ProcZoneInfoTest.ProcZoneInfoTest(),
116}
117
118TEST_OBJECTS_64 = {
119    ProcSimpleFileTests.ProcMmapRndCompatBitsTest(),
120}
121
122
123class VtsKernelProcFileApiTest(base_test.BaseTestClass):
124    """Test cases which check content of proc files.
125
126    Attributes:
127        _PROC_SYS_ABI_SWP_FILE_PATH: the path of a file which decides behaviour of SWP instruction.
128    """
129
130    _PROC_SYS_ABI_SWP_FILE_PATH = "/proc/sys/abi/swp"
131
132    def setUpClass(self):
133        self.dut = self.android_devices[0]
134        self.shell = self.dut.shell
135
136    def runProcFileTest(self, test_object):
137        """Reads from the file and checks that it parses and the content is valid.
138
139        Args:
140            test_object: inherits KernelProcFileTestBase, contains the test functions
141        """
142        asserts.skipIf(test_object in TEST_OBJECTS_64 and not self.dut.is64Bit,
143                       "Skip test for 64-bit kernel.")
144        filepath = test_object.get_path()
145        asserts.skipIf(not target_file_utils.Exists(filepath, self.shell) and
146                       test_object.file_optional(shell=self.shell, dut=self.dut),
147                       "%s does not exist and is optional." % filepath)
148        target_file_utils.assertPermissionsAndExistence(
149            self.shell, filepath, test_object.get_permission_checker())
150
151        logging.info("Testing format of %s", filepath)
152
153        asserts.assertTrue(
154            test_object.prepare_test(self.shell, self.dut), "Setup failed!")
155
156        if not test_object.test_format():
157            return
158
159        file_content = self.ReadFileContent(filepath)
160        try:
161            parse_result = test_object.parse_contents(file_content)
162        except (SyntaxError, ValueError, IndexError) as e:
163            asserts.fail("Failed to parse! " + str(e))
164        asserts.assertTrue(
165            test_object.result_correct(parse_result), "Results not valid!")
166
167    def generateProcFileTests(self):
168        """Run all proc file tests."""
169        self.runGeneratedTests(
170            test_func=self.runProcFileTest,
171            settings=TEST_OBJECTS.union(TEST_OBJECTS_64),
172            name_func=lambda test_obj: "test" + test_obj.__class__.__name__)
173
174    def ReadFileContent(self, filepath):
175        """Read the content of a file and perform assertions.
176
177        Args:
178            filepath: string, path to file
179
180        Returns:
181            string, content of file
182        """
183        cmd = "cat %s" % filepath
184        results = self.shell.Execute(cmd)
185
186        # checks the exit code
187        asserts.assertEqual(
188            results[const.EXIT_CODE][0], 0,
189            "%s: Error happened while reading the file." % filepath)
190
191        return results[const.STDOUT][0]
192
193    def testProcPagetypeinfo(self):
194        # TODO(b/109884074): make mandatory once incident_helper is in AOSP.
195        try:
196            self.dut.adb.shell("which incident_helper")
197        except:
198            asserts.skip("incident_helper not present")
199
200        filepath = "/proc/pagetypeinfo"
201        # Check that incident_helper can parse /proc/pagetypeinfo.
202        result = self.shell.Execute("cat %s | incident_helper -s 2001" % filepath)
203        asserts.assertEqual(
204            result[const.EXIT_CODE][0], 0,
205            "Failed to parse %s." % filepath)
206
207    def testProcSysrqTrigger(self):
208        filepath = "/proc/sysrq-trigger"
209
210        # This command only performs a best effort attempt to remount all
211        # filesystems. Check that it doesn't throw an error.
212        self.dut.adb.shell("echo u > %s" % filepath)
213
214        # Reboot the device.
215        self.dut.adb.shell("echo b > %s" % filepath)
216        asserts.assertFalse(self.dut.hasBooted(), "Device is still alive.")
217        self.dut.waitForBootCompletion()
218        self.dut.rootAdb()
219
220    def testProcUidProcstatSet(self):
221        def UidIOStats(uid):
222            """Returns I/O stats for a given uid.
223
224            Args:
225                uid, uid number.
226
227            Returns:
228                list of I/O numbers.
229            """
230            stats_path = "/proc/uid_io/stats"
231            result = self.dut.adb.shell(
232                    "cat %s | grep '^%d'" % (stats_path, uid),
233                    no_except=True)
234            return result[const.STDOUT].split()
235
236        def CheckStatsInState(state):
237            """Sets VTS (root uid) into a given state and checks the stats.
238
239            Args:
240                state, boolean. Use False for foreground,
241                and True for background.
242            """
243            state = 1 if state else 0
244            filepath = "/proc/uid_procstat/set"
245            root_uid = 0
246
247            # fg write chars are at index 2, and bg write chars are at 6.
248            wchar_index = 6 if state else 2
249            old_wchar = UidIOStats(root_uid)[wchar_index]
250            self.dut.adb.shell("echo %d %s > %s" % (root_uid, state, filepath))
251            # This should increase the number of write syscalls.
252            self.dut.adb.shell("echo foo")
253            asserts.assertLess(
254                old_wchar,
255                UidIOStats(root_uid)[wchar_index],
256                "Number of write syscalls has not increased.")
257
258        CheckStatsInState(False)
259        CheckStatsInState(True)
260
261    def testProcPerUidTimes(self):
262        # TODO: make these files mandatory once they're in AOSP
263        try:
264            filepaths = self.dut.adb.shell("find /proc/uid -name time_in_state")
265        except:
266            asserts.skip("/proc/uid/ directory does not exist and is optional")
267
268        asserts.skipIf(not filepaths,
269                       "per-UID time_in_state files do not exist and are optional")
270
271        filepaths = filepaths.splitlines()
272        for filepath in filepaths:
273            target_file_utils.assertPermissionsAndExistence(
274                self.shell, filepath, target_file_utils.IsReadOnly
275            )
276            file_content = self.ReadFileContent(filepath)
277
278    def testProcSysAbiSwpInstruction(self):
279        """Tests /proc/sys/abi/swp.
280
281        /proc/sys/abi/swp sets the execution behaviour for the obsoleted ARM instruction
282        SWP. As per the setting in /proc/sys/abi/swp, the usage of SWP{B}
283        can either generate an undefined instruction abort or use software emulation
284        or hardware execution.
285        """
286
287        asserts.skipIf(not ("arm" in self.dut.cpu_abi and self.dut.is64Bit),
288                       "file not present on non-ARM64 device")
289        target_file_utils.assertPermissionsAndExistence(
290            self.shell, self._PROC_SYS_ABI_SWP_FILE_PATH, target_file_utils.IsReadWrite)
291        file_content = self.ReadFileContent(self._PROC_SYS_ABI_SWP_FILE_PATH)
292        try:
293            swp_state = int(file_content)
294        except ValueError as e:
295            asserts.fail("Failed to parse %s" % self._PROC_SYS_ABI_SWP_FILE_PATH)
296        asserts.assertTrue(swp_state >= 0 and swp_state <= 2,
297                           "%s contains incorrect value: %d" % (self._PROC_SYS_ABI_SWP_FILE_PATH,
298                                                                swp_state))
299
300if __name__ == "__main__":
301    test_runner.main()
302