xref: /aosp_15_r20/art/libartpalette/apex/palette_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "palette/palette.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <jni.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/mman.h>
21*795d594fSAndroid Build Coastguard Worker #include <sys/syscall.h>
22*795d594fSAndroid Build Coastguard Worker #include <unistd.h>
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include <cstring>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "base/common_art_test.h"
27*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
30*795d594fSAndroid Build Coastguard Worker #include "android-modules-utils/sdk_level.h"
31*795d594fSAndroid Build Coastguard Worker #include "android/api-level.h"
32*795d594fSAndroid Build Coastguard Worker #endif
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker namespace {
35*795d594fSAndroid Build Coastguard Worker 
GetTid()36*795d594fSAndroid Build Coastguard Worker pid_t GetTid() {
37*795d594fSAndroid Build Coastguard Worker #ifdef __BIONIC__
38*795d594fSAndroid Build Coastguard Worker   return gettid();
39*795d594fSAndroid Build Coastguard Worker #else  // __BIONIC__
40*795d594fSAndroid Build Coastguard Worker   return syscall(__NR_gettid);
41*795d594fSAndroid Build Coastguard Worker #endif  // __BIONIC__
42*795d594fSAndroid Build Coastguard Worker }
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
PaletteSetTaskProfilesIsSupported(palette_status_t res)45*795d594fSAndroid Build Coastguard Worker bool PaletteSetTaskProfilesIsSupported(palette_status_t res) {
46*795d594fSAndroid Build Coastguard Worker   if (android::modules::sdklevel::IsAtLeastU()) {
47*795d594fSAndroid Build Coastguard Worker     return true;
48*795d594fSAndroid Build Coastguard Worker   }
49*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_NOT_SUPPORTED, res)
50*795d594fSAndroid Build Coastguard Worker       << "Device API level: " << android_get_device_api_level();
51*795d594fSAndroid Build Coastguard Worker   return false;
52*795d594fSAndroid Build Coastguard Worker }
PaletteDebugStoreIsSupported()53*795d594fSAndroid Build Coastguard Worker bool PaletteDebugStoreIsSupported() {
54*795d594fSAndroid Build Coastguard Worker   // TODO(b/345433959): Switch to android::modules::sdklevel::IsAtLeastW
55*795d594fSAndroid Build Coastguard Worker   return android_get_device_api_level() >= 36;
56*795d594fSAndroid Build Coastguard Worker }
57*795d594fSAndroid Build Coastguard Worker #endif
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker }  // namespace
60*795d594fSAndroid Build Coastguard Worker 
61*795d594fSAndroid Build Coastguard Worker class PaletteClientTest : public testing::Test {};
62*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,SchedPriority)63*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, SchedPriority) {
64*795d594fSAndroid Build Coastguard Worker   int32_t tid = GetTid();
65*795d594fSAndroid Build Coastguard Worker   int32_t saved_priority;
66*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedGetPriority(tid, &saved_priority));
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ 0));
69*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ -1));
70*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ 11));
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedSetPriority(tid, /*java_priority=*/ 1));
73*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedSetPriority(tid, saved_priority));
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,Trace)76*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, Trace) {
77*795d594fSAndroid Build Coastguard Worker   bool enabled = false;
78*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceEnabled(&enabled));
79*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceBegin("Hello world!"));
80*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceEnd());
81*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceIntegerValue("Beans", /*value=*/ 3));
82*795d594fSAndroid Build Coastguard Worker }
83*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,Ashmem)84*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, Ashmem) {
85*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
86*795d594fSAndroid Build Coastguard Worker   GTEST_SKIP() << "ashmem is only supported on Android";
87*795d594fSAndroid Build Coastguard Worker #else
88*795d594fSAndroid Build Coastguard Worker   int fd;
89*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteAshmemCreateRegion("ashmem-test", 4096, &fd));
90*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteAshmemSetProtRegion(fd, PROT_READ | PROT_EXEC));
91*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0, close(fd));
92*795d594fSAndroid Build Coastguard Worker #endif
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker class PaletteClientJniTest : public art::CommonArtTest {};
96*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientJniTest,JniInvocation)97*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientJniTest, JniInvocation) {
98*795d594fSAndroid Build Coastguard Worker   bool enabled;
99*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, PaletteShouldReportJniInvocations(&enabled));
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker   std::string boot_class_path_string =
102*795d594fSAndroid Build Coastguard Worker       GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames());
103*795d594fSAndroid Build Coastguard Worker   std::string boot_class_path_locations_string =
104*795d594fSAndroid Build Coastguard Worker       GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations());
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker   JavaVMOption options[] = {
107*795d594fSAndroid Build Coastguard Worker       {.optionString = boot_class_path_string.c_str(), .extraInfo = nullptr},
108*795d594fSAndroid Build Coastguard Worker       {.optionString = boot_class_path_locations_string.c_str(), .extraInfo = nullptr},
109*795d594fSAndroid Build Coastguard Worker   };
110*795d594fSAndroid Build Coastguard Worker   JavaVMInitArgs vm_args = {
111*795d594fSAndroid Build Coastguard Worker       .version = JNI_VERSION_1_6,
112*795d594fSAndroid Build Coastguard Worker       .nOptions = std::size(options),
113*795d594fSAndroid Build Coastguard Worker       .options = options,
114*795d594fSAndroid Build Coastguard Worker       .ignoreUnrecognized = JNI_TRUE,
115*795d594fSAndroid Build Coastguard Worker   };
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   JavaVM* jvm = nullptr;
118*795d594fSAndroid Build Coastguard Worker   JNIEnv* env = nullptr;
119*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(JNI_OK, JNI_CreateJavaVM(&jvm, &env, &vm_args));
120*795d594fSAndroid Build Coastguard Worker   ASSERT_NE(nullptr, env);
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   PaletteNotifyBeginJniInvocation(env);
123*795d594fSAndroid Build Coastguard Worker   PaletteNotifyEndJniInvocation(env);
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(JNI_OK, jvm->DestroyJavaVM());
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,SetTaskProfiles)128*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, SetTaskProfiles) {
129*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
130*795d594fSAndroid Build Coastguard Worker   GTEST_SKIP() << "SetTaskProfiles is only supported on Android";
131*795d594fSAndroid Build Coastguard Worker #else
132*795d594fSAndroid Build Coastguard Worker   const char* profiles[] = {"ProcessCapacityHigh", "TimerSlackNormal"};
133*795d594fSAndroid Build Coastguard Worker   palette_status_t res = PaletteSetTaskProfiles(GetTid(), &profiles[0], 2);
134*795d594fSAndroid Build Coastguard Worker   if (PaletteSetTaskProfilesIsSupported(res)) {
135*795d594fSAndroid Build Coastguard Worker     // SetTaskProfiles will only work fully if we run as root. Otherwise it'll
136*795d594fSAndroid Build Coastguard Worker     // return false which is mapped to PALETTE_STATUS_FAILED_CHECK_LOG.
137*795d594fSAndroid Build Coastguard Worker     if (getuid() == 0) {
138*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(PALETTE_STATUS_OK, res);
139*795d594fSAndroid Build Coastguard Worker     } else {
140*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(PALETTE_STATUS_FAILED_CHECK_LOG, res);
141*795d594fSAndroid Build Coastguard Worker     }
142*795d594fSAndroid Build Coastguard Worker   }
143*795d594fSAndroid Build Coastguard Worker #endif
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,SetTaskProfilesCpp)146*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, SetTaskProfilesCpp) {
147*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
148*795d594fSAndroid Build Coastguard Worker   GTEST_SKIP() << "SetTaskProfiles is only supported on Android";
149*795d594fSAndroid Build Coastguard Worker #else
150*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> profiles = {"ProcessCapacityHigh", "TimerSlackNormal"};
151*795d594fSAndroid Build Coastguard Worker   palette_status_t res = PaletteSetTaskProfiles(GetTid(), profiles);
152*795d594fSAndroid Build Coastguard Worker   if (PaletteSetTaskProfilesIsSupported(res)) {
153*795d594fSAndroid Build Coastguard Worker     // SetTaskProfiles will only work fully if we run as root. Otherwise it'll
154*795d594fSAndroid Build Coastguard Worker     // return false which is mapped to PALETTE_STATUS_FAILED_CHECK_LOG.
155*795d594fSAndroid Build Coastguard Worker     if (getuid() == 0) {
156*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(PALETTE_STATUS_OK, res);
157*795d594fSAndroid Build Coastguard Worker     } else {
158*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(PALETTE_STATUS_FAILED_CHECK_LOG, res);
159*795d594fSAndroid Build Coastguard Worker     }
160*795d594fSAndroid Build Coastguard Worker   }
161*795d594fSAndroid Build Coastguard Worker #endif
162*795d594fSAndroid Build Coastguard Worker }
163*795d594fSAndroid Build Coastguard Worker 
TEST_F(PaletteClientTest,DebugStore)164*795d594fSAndroid Build Coastguard Worker TEST_F(PaletteClientTest, DebugStore) {
165*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
166*795d594fSAndroid Build Coastguard Worker   GTEST_SKIP() << "DebugStore is only supported on Android";
167*795d594fSAndroid Build Coastguard Worker #else
168*795d594fSAndroid Build Coastguard Worker   std::array<char, 20> result{};
169*795d594fSAndroid Build Coastguard Worker   // Make sure the we are on a correct API level.
170*795d594fSAndroid Build Coastguard Worker   if (!PaletteDebugStoreIsSupported()) {
171*795d594fSAndroid Build Coastguard Worker     GTEST_SKIP() << "DebugStore is only supported on API 36+";
172*795d594fSAndroid Build Coastguard Worker   }
173*795d594fSAndroid Build Coastguard Worker   palette_status_t pstatus = PaletteDebugStoreGetString(result.data(), result.size());
174*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(PALETTE_STATUS_OK, pstatus);
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker   size_t len = strnlen(result.data(), result.size());
177*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(len < result.size());
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker   const char* start = "1,0,";
180*795d594fSAndroid Build Coastguard Worker   const char* end = "::";
181*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(len > strlen(start) + strlen(end));
182*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(strncmp(result.data() + len - strlen(end), end, strlen(end)), 0);
183*795d594fSAndroid Build Coastguard Worker #endif
184*795d594fSAndroid Build Coastguard Worker }
185