Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/libartpalette/apex/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 8 kB image not shown  

Quelle  palette_test.cc

  Sprache: C
 

/*
 * Copyright (C) 2019 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.
 */


#include "palette/palette.h"

#include <jni.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <unistd.h>

#include <cstring>

#include "base/testing.h"
#include "gtest/gtest.h"
#include "system/palette_system.h"

#ifdef ART_TARGET_ANDROID
#include "android-modules-utils/sdk_level.h"
#include "android/api-level.h"
#include "nativehelper/JniInvocation.h"
#endif

namespace {

pid_t GetTid() {
#ifdef __BIONIC__
  return gettid();
#else  // __BIONIC__
  return syscall(__NR_gettid);
#endif  // __BIONIC__
}

#ifdef ART_TARGET_ANDROID

bool PaletteSetTaskProfilesIsSupported(palette_status_t res) {
  if (android::modules::sdklevel::IsAtLeastU()) {
    return true;
  }
  EXPECT_EQ(PALETTE_STATUS_NOT_SUPPORTED, res)
      << "Device API level: " << android_get_device_api_level();
  return false;
}
bool PaletteDebugStoreIsSupported() { return android::modules::sdklevel::IsAtLeastB(); }

bool PaletteMapPriorityIsSupported() {
  if (android::modules::sdklevel::IsAtLeastC()) {
    return true;
  }
  int dummy_result;
  return PaletteMapPriority(6, &dummy_result) != PALETTE_STATUS_NOT_SUPPORTED;
}

#else  // !ART_TARGET_ANDROID

bool PaletteMapPriorityIsSupported() {
  return true;  // Safe?
}

#endif

}  // namespace

class PaletteClientTest : public ::testing::Test {};

TEST_F(PaletteClientTest, SchedPriority) {
  int32_t tid = GetTid();
  int32_t saved_priority;
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedGetPriority(tid, &saved_priority));

  EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ 0));
  EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ -1));
  EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, PaletteSchedSetPriority(tid, /*java_priority=*/ 11));

  EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedSetPriority(tid, /*java_priority=*/ 1));
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteSchedSetPriority(tid, saved_priority));
}

TEST_F(PaletteClientTest, Trace) {
  bool enabled = false;
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceEnabled(&enabled));
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceBegin("Hello world!"));
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceEnd());
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteTraceIntegerValue("Beans"/*value=*/ 3));
}

TEST_F(PaletteClientTest, Ashmem) {
#ifndef ART_TARGET_ANDROID
  GTEST_SKIP() << "ashmem is only supported on Android";
#else
  int fd;
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteAshmemCreateRegion("ashmem-test"4096, &fd));
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteAshmemSetProtRegion(fd, PROT_READ | PROT_EXEC));
  EXPECT_EQ(0, close(fd));
#endif
}

TEST_F(PaletteClientTest, JniInvocation) {
#ifndef ART_TARGET_ANDROID
  // On host we need to use the runtime linked into the test to start a VM (e.g.
  // by inheriting CommonArtTest), while on device it needs to launch the
  // runtime through libnativehelper. Let's not bother on host since this test
  // is only for native API coverage on device.
  GTEST_SKIP() << "Will only spin up a VM on Android";
#else
  bool enabled;
  EXPECT_EQ(PALETTE_STATUS_OK, PaletteShouldReportJniInvocations(&enabled));

  // Load the default JNI_CreateJavaVM implementation, i.e., libart.so.
  JniInvocation jni_invocation;
  ASSERT_TRUE(jni_invocation.Init(/*library=*/ nullptr));

  std::string boot_class_path_string =
      art::testing::GetClassPathOption("-Xbootclasspath:", art::testing::GetLibCoreDexFileNames());
  std::string boot_class_path_locations_string = art::testing::GetClassPathOption(
      "-Xbootclasspath-locations:", art::testing::GetLibCoreDexLocations());

  JavaVMOption options[] = {
      {.optionString = boot_class_path_string.c_str(), .extraInfo = nullptr},
      {.optionString = boot_class_path_locations_string.c_str(), .extraInfo = nullptr},
  };
  JavaVMInitArgs vm_args = {
      .version = JNI_VERSION_1_6,
      .nOptions = std::size(options),
      .options = options,
      .ignoreUnrecognized = JNI_TRUE,
  };

  JavaVM* jvm = nullptr;
  JNIEnv* env = nullptr;
  EXPECT_EQ(JNI_OK, JNI_CreateJavaVM(&jvm, &env, &vm_args));
  ASSERT_NE(nullptr, env);

  PaletteNotifyBeginJniInvocation(env);
  PaletteNotifyEndJniInvocation(env);

  EXPECT_EQ(JNI_OK, jvm->DestroyJavaVM());
#endif
}

// Run with the expectation to be both root and non-root, skipping the
// inapplicable one. Useful when expected results depend on rootness, to make it
// clear in test results which variant was executed.
class PaletteClientRootParamTest : public ::testing::TestWithParam<bool> {
 protected:
  bool TestAsRoot() { return GetParam(); }
  bool RunningAsRoot() { return getuid() == 0; }
  bool ShouldSkip() { return TestAsRoot() != RunningAsRoot(); }
};

TEST_P(PaletteClientRootParamTest, SetTaskProfiles) {
#ifndef ART_TARGET_ANDROID
  GTEST_SKIP() << "SetTaskProfiles is only supported on Android";
#else
  if (ShouldSkip()) {
    GTEST_SKIP() << (RunningAsRoot() ? "Running as root" : "Not running as root");
  }
  const char* profiles[] = {"ProcessCapacityHigh""TimerSlackNormal"};
  palette_status_t res = PaletteSetTaskProfiles(GetTid(), &profiles[0]2);
  if (PaletteSetTaskProfilesIsSupported(res)) {
    // SetTaskProfiles will only work fully if we run as root. Otherwise it'll
    // return false which is mapped to PALETTE_STATUS_FAILED_CHECK_LOG.
    if (TestAsRoot()) {
      EXPECT_EQ(PALETTE_STATUS_OK, res);
    } else {
      EXPECT_EQ(PALETTE_STATUS_FAILED_CHECK_LOG, res);
    }
  }
#endif
}

TEST_P(PaletteClientRootParamTest, SetTaskProfilesCpp) {
#ifndef ART_TARGET_ANDROID
  GTEST_SKIP() << "SetTaskProfiles is only supported on Android";
#else
  if (ShouldSkip()) {
    GTEST_SKIP() << (RunningAsRoot() ? "Running as root" : "Not running as root");
  }
  std::vector<std::string> profiles = {"ProcessCapacityHigh""TimerSlackNormal"};
  palette_status_t res = PaletteSetTaskProfiles(GetTid(), profiles);
  if (PaletteSetTaskProfilesIsSupported(res)) {
    // SetTaskProfiles will only work fully if we run as root. Otherwise it'll
    // return false which is mapped to PALETTE_STATUS_FAILED_CHECK_LOG.
    if (TestAsRoot()) {
      EXPECT_EQ(PALETTE_STATUS_OK, res);
    } else {
      EXPECT_EQ(PALETTE_STATUS_FAILED_CHECK_LOG, res);
    }
  }
#endif
}

INSTANTIATE_TEST_SUITE_P(
    Rootness,
    PaletteClientRootParamTest,
    ::testing::Bool(),
    [](const ::testing::TestParamInfo<PaletteClientRootParamTest::ParamType>& info) {
      return info.param ? "Root" : "NonRoot";
    });

TEST_F(PaletteClientTest, DebugStore) {
#ifndef ART_TARGET_ANDROID
  GTEST_SKIP() << "DebugStore is only supported on Android";
#else
  std::array<char20> result{};
  // Make sure the we are on a correct API level.
  if (!PaletteDebugStoreIsSupported()) {
    GTEST_SKIP() << "DebugStore is only supported on API 36+";
  }
  palette_status_t pstatus = PaletteDebugStoreGetString(result.data(), result.size());
  EXPECT_EQ(PALETTE_STATUS_OK, pstatus);

  size_t len = strnlen(result.data(), result.size());
  EXPECT_TRUE(len < result.size());

  const char* start = "1,0,";
  const char* end = "::;;";
  EXPECT_TRUE(len > strlen(start) + strlen(end));
  EXPECT_EQ(strncmp(result.data() + len - strlen(end), end, strlen(end)), 0);
#endif
}

TEST_F(PaletteClientTest, MapPriority) {
  // Make sure the we are on a correct API level.
  if (!PaletteMapPriorityIsSupported()) {
    GTEST_SKIP() << "GetPriorityMapping is only supported on API 36.1+";
  }
  int result;
  int last_result = 100;  // > any plausible niceness value.
  palette_status_t pstatus;
  for (int32_t i = art::palette::kMinManagedThreadPriority;
       i <= art::palette::kMaxManagedThreadPriority;
       ++i) {
    pstatus = PaletteMapPriority(i, &result);
    EXPECT_EQ(PALETTE_STATUS_OK, pstatus);
    if (i == art::palette::kMinManagedThreadPriority) {
      EXPECT_GT(result, 0);
    }
    if (i == art::palette::kMaxManagedThreadPriority) {
      EXPECT_LT(result, 0);
    }
    EXPECT_LT(result, last_result);
    last_result = result;
  }

  // This time with invalid Java priorities.
  pstatus = PaletteMapPriority(art::palette::kMinManagedThreadPriority - 1, &result);
  EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, pstatus);
  pstatus = PaletteMapPriority(art::palette::kMaxManagedThreadPriority + 1, &result);
  EXPECT_EQ(PALETTE_STATUS_INVALID_ARGUMENT, pstatus);
}

Messung V0.5 in Prozent
C=90 H=97 G=93

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.