xref: /aosp_15_r20/cts/hostsidetests/edi/src/android/edi/cts/NativeDeviceInfo.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.edi.cts;
17 
18 import com.android.compatibility.common.util.DeviceInfo;
19 import com.android.compatibility.common.util.HostInfoStore;
20 import com.android.tradefed.device.ITestDevice;
21 import com.android.tradefed.log.LogUtil.CLog;
22 import com.android.tradefed.util.CommandResult;
23 
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 
27 /**
28  * System native device info collector.
29  */
30 public class NativeDeviceInfo extends DeviceInfo {
31 
collectMemCG(ITestDevice device, HostInfoStore store)32     private void collectMemCG(ITestDevice device, HostInfoStore store) throws Exception {
33         CommandResult commandResult = device.executeShellV2Command("grep memory /proc/cgroups");
34 
35         store.startGroup("memcg");
36         if (commandResult.getExitCode() == 0) {
37             String[] tokens = commandResult.getStdout().split("\\s+");
38             boolean memcg_enabled = tokens[3].equals("1");
39             store.addResult("enabled", memcg_enabled);
40             if (memcg_enabled) store.addResult("version", tokens[1].equals("0") ? "2" : "1");
41         } else if (commandResult.getExitCode() == 1) { // "memory" not found by grep
42             store.addResult("version", -3);
43         } else if (commandResult.getStderr().contains("No such file")) {
44             store.addResult("version", -1);
45         } else if (commandResult.getStderr().contains("Permission denied")) {
46             store.addResult("version", -2);
47         }
48         store.endGroup();
49     }
50 
collectMGLRU(ITestDevice device, HostInfoStore store)51     private void collectMGLRU(ITestDevice device, HostInfoStore store) throws Exception {
52         CommandResult commandResult = device.executeShellV2Command(
53                 "cat /sys/kernel/mm/lru_gen/enabled");
54 
55         if (commandResult.getExitCode() == 0) {
56             store.addResult("mglru_enabled", Integer.decode(commandResult.getStdout().trim()));
57         } else if (commandResult.getStderr().contains("No such file")) {
58             store.addResult("mglru_enabled", -1);
59         } else if (commandResult.getStderr().contains("Permission denied")) {
60             store.addResult("mglru_enabled", -2);
61         }
62     }
63 
64     @Override
collectDeviceInfo(HostInfoStore store)65     protected void collectDeviceInfo(HostInfoStore store) throws Exception {
66         ITestDevice device = getDevice();
67         CommandResult commandResult = device.executeShellV2Command("cat /proc/self/maps");
68         if (!commandResult.getStderr().isEmpty()) {
69             CLog.w("Warnings occurred when running cat:\n%s", commandResult.getStderr());
70         }
71         if (commandResult.getExitCode() == null) {
72             throw new NullPointerException("cat command exit code is null");
73         }
74         if (commandResult.getExitCode() != 0) {
75             throw new IllegalStateException(
76                 String.format("cat commaned returned %d: %s", commandResult.getExitCode(),
77                               commandResult.getStderr()));
78         }
79         String stdout = commandResult.getStdout();
80         if (stdout == null) {
81             throw new NullPointerException("cat command resulted in no output");
82         }
83 
84         String allocatorName;
85         if (stdout.indexOf(":scudo:") != -1) {
86             allocatorName = "scudo";
87         } else {
88             allocatorName = "jemalloc";
89         }
90 
91         // Check for the bitness of the device. A device that supports
92         // both 32 bits and 64 bits is assumed to be whatever the shell
93         // user runs as.
94         // On 32 bit devices, the format of the entries is:
95         //   beace000-beaf0000 rw-p 00000000 00:00 0          [stack]
96         // On 64 bit devices, the format of the entries is:
97         //   7ffdc13000-7ffdc35000 rw-p 00000000 00:00 0      [stack]
98         // This pattern looks for an entry that contains only 8 hex digits
99         // in the first and second map address to indicate 32 bit devices.
100         Pattern mapPattern = Pattern.compile("^[0-9a-f]{8,8}-[0-9a-f]{8,8} ");
101         Matcher matcher = mapPattern.matcher(stdout);
102         if (matcher.find()) {
103             allocatorName += "32";
104         } else {
105             allocatorName += "64";
106         }
107 
108         if (device.getBooleanProperty("ro.config.low_ram", false)) {
109             allocatorName += "_lowmemory";
110         }
111         store.addResult("allocator", allocatorName);
112 
113         collectMemCG(device, store);
114         collectMGLRU(device, store);
115     }
116 }
117