Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c227b21f authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4511918 from 90516bc4 to pi-release

Change-Id: Ic1a660e23df7732a212e54a327c5d64b68300bce
parents 3a14d4be 90516bc4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ cc_test {
        "stringprintf_test.cpp",
        "strings_test.cpp",
        "test_main.cpp",
        "test_utils_test.cpp",
    ],
    target: {
        android: {
+29 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_BASE_TEST_UTILS_H
#define ANDROID_BASE_TEST_UTILS_H

#include <regex>
#include <string>

#include <android-base/macros.h>
@@ -70,4 +71,32 @@ class CapturedStderr {
  DISALLOW_COPY_AND_ASSIGN(CapturedStderr);
};

#define ASSERT_MATCH(str, pattern)                                             \
  do {                                                                         \
    if (!std::regex_search((str), std::regex((pattern)))) {                    \
      FAIL() << "regex mismatch: expected " << (pattern) << " in:\n" << (str); \
    }                                                                          \
  } while (0)

#define ASSERT_NOT_MATCH(str, pattern)                                                     \
  do {                                                                                     \
    if (std::regex_search((str), std::regex((pattern)))) {                                 \
      FAIL() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << (str); \
    }                                                                                      \
  } while (0)

#define EXPECT_MATCH(str, pattern)                                                    \
  do {                                                                                \
    if (!std::regex_search((str), std::regex((pattern)))) {                           \
      ADD_FAILURE() << "regex mismatch: expected " << (pattern) << " in:\n" << (str); \
    }                                                                                 \
  } while (0)

#define EXPECT_NOT_MATCH(str, pattern)                                                            \
  do {                                                                                            \
    if (std::regex_search((str), std::regex((pattern)))) {                                        \
      ADD_FAILURE() << "regex mismatch: expected to not find " << (pattern) << " in:\n" << (str); \
    }                                                                                             \
  } while (0)

#endif  // ANDROID_BASE_TEST_UTILS_H
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 "android-base/test_utils.h"

#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>

namespace android {
namespace base {

TEST(TestUtilsTest, AssertMatch) {
  ASSERT_MATCH("foobar", R"(fo+baz?r)");
  EXPECT_FATAL_FAILURE(ASSERT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
}

TEST(TestUtilsTest, AssertNotMatch) {
  ASSERT_NOT_MATCH("foobar", R"(foobaz)");
  EXPECT_FATAL_FAILURE(ASSERT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
}

TEST(TestUtilsTest, ExpectMatch) {
  EXPECT_MATCH("foobar", R"(fo+baz?r)");
  EXPECT_NONFATAL_FAILURE(EXPECT_MATCH("foobar", R"(foobaz)"), "regex mismatch");
}

TEST(TestUtilsTest, ExpectNotMatch) {
  EXPECT_NOT_MATCH("foobar", R"(foobaz)");
  EXPECT_NONFATAL_FAILURE(EXPECT_NOT_MATCH("foobar", R"(foobar)"), "regex mismatch");
}

}  // namespace base
}  // namespace android
+10 −0
Original line number Diff line number Diff line
@@ -218,6 +218,16 @@ cc_test {
    },
}

cc_benchmark {
    name: "debuggerd_benchmark",
    defaults: ["debuggerd_defaults"],
    srcs: ["debuggerd_benchmark.cpp"],
    shared_libs: [
        "libbase",
        "libdebuggerd_client",
    ],
}

cc_binary {
    name: "crash_dump",
    srcs: [
+128 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017, 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 <err.h>
#include <errno.h>
#include <sched.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include <chrono>
#include <thread>

#include <benchmark/benchmark.h>
#include <debuggerd/client.h>

using namespace std::chrono_literals;

static_assert(std::chrono::high_resolution_clock::is_steady);

enum class ThreadState { Starting, Started, Stopping };

static void SetScheduler() {
  struct sched_param param {
    .sched_priority = 1,
  };

  if (sched_setscheduler(getpid(), SCHED_FIFO, &param) != 0) {
    fprintf(stderr, "failed to set scheduler to SCHED_FIFO: %s", strerror(errno));
  }
}

static std::chrono::duration<double> GetMaximumPause(std::atomic<ThreadState>& state) {
  std::chrono::duration<double> max_diff(0);

  const auto begin = std::chrono::high_resolution_clock::now();
  auto last = begin;
  state.store(ThreadState::Started);
  while (state.load() != ThreadState::Stopping) {
    auto now = std::chrono::high_resolution_clock::now();

    auto diff = now - last;
    if (diff > max_diff) {
      max_diff = diff;
    }

    last = now;
  }

  return max_diff;
}

static void PerformDump() {
  pid_t target = getpid();
  pid_t forkpid = fork();
  if (forkpid == -1) {
    err(1, "fork failed");
  } else if (forkpid != 0) {
    int status;
    pid_t pid = waitpid(forkpid, &status, 0);
    if (pid == -1) {
      err(1, "waitpid failed");
    } else if (!WIFEXITED(status)) {
      err(1, "child didn't exit");
    } else if (WEXITSTATUS(status) != 0) {
      errx(1, "child exited with non-zero status %d", WEXITSTATUS(status));
    }
  } else {
    android::base::unique_fd output_fd(open("/dev/null", O_WRONLY | O_CLOEXEC));
    if (output_fd == -1) {
      err(1, "failed to open /dev/null");
    }

    if (!debuggerd_trigger_dump(target, kDebuggerdNativeBacktrace, 1000, std::move(output_fd))) {
      errx(1, "failed to trigger dump");
    }

    _exit(0);
  }
}

template <typename Fn>
static void BM_maximum_pause_impl(benchmark::State& state, const Fn& function) {
  SetScheduler();

  for (auto _ : state) {
    std::chrono::duration<double> max_pause;
    std::atomic<ThreadState> thread_state(ThreadState::Starting);
    auto thread = std::thread([&]() { max_pause = GetMaximumPause(thread_state); });

    while (thread_state != ThreadState::Started) {
      std::this_thread::sleep_for(1ms);
    }

    function();

    thread_state = ThreadState::Stopping;
    thread.join();

    state.SetIterationTime(max_pause.count());
  }
}

static void BM_maximum_pause_noop(benchmark::State& state) {
  BM_maximum_pause_impl(state, []() {});
}

static void BM_maximum_pause_debuggerd(benchmark::State& state) {
  BM_maximum_pause_impl(state, []() { PerformDump(); });
}

BENCHMARK(BM_maximum_pause_noop)->Iterations(128)->UseManualTime();
BENCHMARK(BM_maximum_pause_debuggerd)->Iterations(128)->UseManualTime();

BENCHMARK_MAIN();
Loading