upload android base code part6

This commit is contained in:
August 2018-08-08 17:48:24 +08:00
parent 421e214c7d
commit 4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions

View file

@ -0,0 +1,117 @@
#
# Copyright (C) 2013-2014 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.
#
LOCAL_PATH := $(call my-dir)
# -----------------------------------------------------------------------------
# Benchmarks.
# -----------------------------------------------------------------------------
test_module_prefix := liblog-
test_tags := tests
benchmark_c_flags := \
-Ibionic/tests \
-Wall -Wextra \
-Werror \
-fno-builtin \
benchmark_src_files := \
benchmark_main.cpp \
liblog_benchmark.cpp
# Build benchmarks for the device. Run with:
# adb shell liblog-benchmarks
include $(CLEAR_VARS)
LOCAL_MODULE := $(test_module_prefix)benchmarks
LOCAL_MODULE_TAGS := $(test_tags)
LOCAL_CFLAGS += $(benchmark_c_flags)
LOCAL_SHARED_LIBRARIES += liblog libm libbase
LOCAL_SRC_FILES := $(benchmark_src_files)
include $(BUILD_NATIVE_TEST)
# -----------------------------------------------------------------------------
# Unit tests.
# -----------------------------------------------------------------------------
test_c_flags := \
-fstack-protector-all \
-g \
-Wall -Wextra \
-Werror \
-fno-builtin \
cts_src_files := \
libc_test.cpp \
liblog_test_default.cpp \
liblog_test_local.cpp \
liblog_test_stderr.cpp \
liblog_test_stderr_local.cpp \
log_id_test.cpp \
log_radio_test.cpp \
log_read_test.cpp \
log_system_test.cpp \
log_time_test.cpp \
log_wrap_test.cpp
test_src_files := \
$(cts_src_files) \
# Build tests for the device (with .so). Run with:
# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
include $(CLEAR_VARS)
LOCAL_MODULE := $(test_module_prefix)unit-tests
LOCAL_MODULE_TAGS := $(test_tags)
LOCAL_CFLAGS += $(test_c_flags)
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
LOCAL_SRC_FILES := $(test_src_files)
include $(BUILD_NATIVE_TEST)
cts_executable := CtsLiblogTestCases
include $(CLEAR_VARS)
LOCAL_MODULE := $(cts_executable)
LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE
LOCAL_SRC_FILES := $(cts_src_files)
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
LOCAL_COMPATIBILITY_SUITE := cts vts
LOCAL_CTS_TEST_PACKAGE := android.core.liblog
include $(BUILD_CTS_EXECUTABLE)
ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
include $(CLEAR_VARS)
LOCAL_MODULE := $(cts_executable)_list
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := $(test_c_flags) -DHOST
LOCAL_C_INCLUDES := external/gtest/include
LOCAL_SRC_FILES := $(test_src_files)
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_CXX_STL := libc++
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_LDLIBS_linux := -lrt
include $(BUILD_HOST_NATIVE_TEST)
endif # ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<configuration description="Config for CTS Logging Library test cases">
<option name="config-descriptor:metadata" key="component" value="systems" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
<option name="push" value="CtsLiblogTestCases->/data/local/tmp/CtsLiblogTestCases" />
<option name="append-bitness" value="true" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="CtsLiblogTestCases" />
<option name="runtime-hint" value="65s" />
</test>
</configuration>

View file

@ -0,0 +1,147 @@
/*
* Copyright (C) 2012-2014 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#ifndef BIONIC_BENCHMARK_H_
#define BIONIC_BENCHMARK_H_
namespace testing {
class Benchmark;
template <typename T> class BenchmarkWantsArg;
template <typename T> class BenchmarkWithArg;
void BenchmarkRegister(Benchmark* bm);
int PrettyPrintInt(char* str, int len, unsigned int arg);
class Benchmark {
public:
Benchmark(const char* name, void (*fn)(int)) : name_(strdup(name)), fn_(fn) {
BenchmarkRegister(this);
}
explicit Benchmark(const char* name) : name_(strdup(name)), fn_(NULL) {}
virtual ~Benchmark() {
free(name_);
}
const char* Name() { return name_; }
virtual const char* ArgName() { return NULL; }
virtual void RunFn(int iterations) { fn_(iterations); }
protected:
char* name_;
private:
void (*fn_)(int);
};
template <typename T>
class BenchmarkWantsArgBase : public Benchmark {
public:
BenchmarkWantsArgBase(const char* name, void (*fn)(int, T)) : Benchmark(name) {
fn_arg_ = fn;
}
BenchmarkWantsArgBase<T>* Arg(const char* arg_name, T arg) {
BenchmarkRegister(new BenchmarkWithArg<T>(name_, fn_arg_, arg_name, arg));
return this;
}
protected:
virtual void RunFn(int) { printf("can't run arg benchmark %s without arg\n", Name()); }
void (*fn_arg_)(int, T);
};
template <typename T>
class BenchmarkWithArg : public BenchmarkWantsArg<T> {
public:
BenchmarkWithArg(const char* name, void (*fn)(int, T), const char* arg_name, T arg) :
BenchmarkWantsArg<T>(name, fn), arg_(arg) {
arg_name_ = strdup(arg_name);
}
virtual ~BenchmarkWithArg() {
free(arg_name_);
}
virtual const char* ArgName() { return arg_name_; }
protected:
virtual void RunFn(int iterations) { BenchmarkWantsArg<T>::fn_arg_(iterations, arg_); }
private:
T arg_;
char* arg_name_;
};
template <typename T>
class BenchmarkWantsArg : public BenchmarkWantsArgBase<T> {
public:
BenchmarkWantsArg<T>(const char* name, void (*fn)(int, T)) :
BenchmarkWantsArgBase<T>(name, fn) { }
};
template <>
class BenchmarkWantsArg<int> : public BenchmarkWantsArgBase<int> {
public:
BenchmarkWantsArg<int>(const char* name, void (*fn)(int, int)) :
BenchmarkWantsArgBase<int>(name, fn) { }
BenchmarkWantsArg<int>* Arg(int arg) {
char arg_name[100];
PrettyPrintInt(arg_name, sizeof(arg_name), arg);
BenchmarkRegister(new BenchmarkWithArg<int>(name_, fn_arg_, arg_name, arg));
return this;
}
};
static inline Benchmark* BenchmarkFactory(const char* name, void (*fn)(int)) {
return new Benchmark(name, fn);
}
template <typename T>
static inline BenchmarkWantsArg<T>* BenchmarkFactory(const char* name, void (*fn)(int, T)) {
return new BenchmarkWantsArg<T>(name, fn);
}
} // namespace testing
template <typename T>
static inline void BenchmarkAddArg(::testing::Benchmark* b, const char* name, T arg) {
::testing::BenchmarkWantsArg<T>* ba;
ba = static_cast< ::testing::BenchmarkWantsArg<T>* >(b);
ba->Arg(name, arg);
}
void SetBenchmarkBytesProcessed(uint64_t);
void ResetBenchmarkTiming(void);
void StopBenchmarkTiming(void);
void StartBenchmarkTiming(void);
void StartBenchmarkTiming(uint64_t);
void StopBenchmarkTiming(uint64_t);
#define BENCHMARK(f) \
static ::testing::Benchmark* _benchmark_##f __attribute__((unused)) = /* NOLINT */ \
(::testing::Benchmark*)::testing::BenchmarkFactory(#f, f) /* NOLINT */
#endif // BIONIC_BENCHMARK_H_

View file

@ -0,0 +1,247 @@
/*
* Copyright (C) 2012-2014 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 <benchmark.h>
#include <inttypes.h>
#include <math.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <string>
#include <vector>
static uint64_t gBytesProcessed;
static uint64_t gBenchmarkTotalTimeNs;
static uint64_t gBenchmarkTotalTimeNsSquared;
static uint64_t gBenchmarkNum;
static uint64_t gBenchmarkStartTimeNs;
typedef std::vector< ::testing::Benchmark*> BenchmarkList;
static BenchmarkList* gBenchmarks;
static int Round(int n) {
int base = 1;
while (base * 10 < n) {
base *= 10;
}
if (n < 2 * base) {
return 2 * base;
}
if (n < 5 * base) {
return 5 * base;
}
return 10 * base;
}
static uint64_t NanoTime() {
struct timespec t;
t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_MONOTONIC, &t);
return static_cast<uint64_t>(t.tv_sec) * 1000000000ULL + t.tv_nsec;
}
namespace testing {
int PrettyPrintInt(char* str, int len, unsigned int arg) {
if (arg >= (1 << 30) && arg % (1 << 30) == 0) {
return snprintf(str, len, "%uGi", arg / (1 << 30));
} else if (arg >= (1 << 20) && arg % (1 << 20) == 0) {
return snprintf(str, len, "%uMi", arg / (1 << 20));
} else if (arg >= (1 << 10) && arg % (1 << 10) == 0) {
return snprintf(str, len, "%uKi", arg / (1 << 10));
} else if (arg >= 1000000000 && arg % 1000000000 == 0) {
return snprintf(str, len, "%uG", arg / 1000000000);
} else if (arg >= 1000000 && arg % 1000000 == 0) {
return snprintf(str, len, "%uM", arg / 1000000);
} else if (arg >= 1000 && arg % 1000 == 0) {
return snprintf(str, len, "%uK", arg / 1000);
} else {
return snprintf(str, len, "%u", arg);
}
}
bool ShouldRun(Benchmark* b, int argc, char* argv[]) {
if (argc == 1) {
return true; // With no arguments, we run all benchmarks.
}
// Otherwise, we interpret each argument as a regular expression and
// see if any of our benchmarks match.
for (int i = 1; i < argc; i++) {
regex_t re;
if (regcomp(&re, argv[i], 0) != 0) {
fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n",
argv[i]);
exit(EXIT_FAILURE);
}
int match = regexec(&re, b->Name(), 0, NULL, 0);
regfree(&re);
if (match != REG_NOMATCH) {
return true;
}
}
return false;
}
void BenchmarkRegister(Benchmark* b) {
if (gBenchmarks == NULL) {
gBenchmarks = new BenchmarkList;
}
gBenchmarks->push_back(b);
}
void RunRepeatedly(Benchmark* b, int iterations) {
gBytesProcessed = 0;
ResetBenchmarkTiming();
uint64_t StartTimeNs = NanoTime();
b->RunFn(iterations);
// Catch us if we fail to log anything.
if ((gBenchmarkTotalTimeNs == 0) && (StartTimeNs != 0) &&
(gBenchmarkStartTimeNs == 0)) {
gBenchmarkTotalTimeNs = NanoTime() - StartTimeNs;
}
}
void Run(Benchmark* b) {
// run once in case it's expensive
unsigned iterations = 1;
uint64_t s = NanoTime();
RunRepeatedly(b, iterations);
s = NanoTime() - s;
while (s < 2e9 && gBenchmarkTotalTimeNs < 1e9 && iterations < 1e9) {
unsigned last = iterations;
if (gBenchmarkTotalTimeNs / iterations == 0) {
iterations = 1e9;
} else {
iterations = 1e9 / (gBenchmarkTotalTimeNs / iterations);
}
iterations =
std::max(last + 1, std::min(iterations + iterations / 2, 100 * last));
iterations = Round(iterations);
s = NanoTime();
RunRepeatedly(b, iterations);
s = NanoTime() - s;
}
char throughput[100];
throughput[0] = '\0';
if (gBenchmarkTotalTimeNs > 0 && gBytesProcessed > 0) {
double mib_processed = static_cast<double>(gBytesProcessed) / 1e6;
double seconds = static_cast<double>(gBenchmarkTotalTimeNs) / 1e9;
snprintf(throughput, sizeof(throughput), " %8.2f MiB/s",
mib_processed / seconds);
}
char full_name[100];
snprintf(full_name, sizeof(full_name), "%s%s%s", b->Name(),
b->ArgName() ? "/" : "", b->ArgName() ? b->ArgName() : "");
uint64_t mean = gBenchmarkTotalTimeNs / iterations;
uint64_t sdev = 0;
if (gBenchmarkNum == iterations) {
mean = gBenchmarkTotalTimeNs / gBenchmarkNum;
uint64_t nXvariance = gBenchmarkTotalTimeNsSquared * gBenchmarkNum -
(gBenchmarkTotalTimeNs * gBenchmarkTotalTimeNs);
sdev = (sqrt((double)nXvariance) / gBenchmarkNum / gBenchmarkNum) + 0.5;
}
if (mean > (10000 * sdev)) {
printf("%-25s %10" PRIu64 " %10" PRIu64 "%s\n", full_name,
static_cast<uint64_t>(iterations), mean, throughput);
} else {
printf("%-25s %10" PRIu64 " %10" PRIu64 "(\317\203%" PRIu64 ")%s\n",
full_name, static_cast<uint64_t>(iterations), mean, sdev, throughput);
}
fflush(stdout);
}
} // namespace testing
void SetBenchmarkBytesProcessed(uint64_t x) {
gBytesProcessed = x;
}
void ResetBenchmarkTiming() {
gBenchmarkStartTimeNs = 0;
gBenchmarkTotalTimeNs = 0;
gBenchmarkTotalTimeNsSquared = 0;
gBenchmarkNum = 0;
}
void StopBenchmarkTiming(void) {
if (gBenchmarkStartTimeNs != 0) {
int64_t diff = NanoTime() - gBenchmarkStartTimeNs;
gBenchmarkTotalTimeNs += diff;
gBenchmarkTotalTimeNsSquared += diff * diff;
++gBenchmarkNum;
}
gBenchmarkStartTimeNs = 0;
}
void StartBenchmarkTiming(void) {
if (gBenchmarkStartTimeNs == 0) {
gBenchmarkStartTimeNs = NanoTime();
}
}
void StopBenchmarkTiming(uint64_t NanoTime) {
if (gBenchmarkStartTimeNs != 0) {
int64_t diff = NanoTime - gBenchmarkStartTimeNs;
gBenchmarkTotalTimeNs += diff;
gBenchmarkTotalTimeNsSquared += diff * diff;
if (NanoTime != 0) {
++gBenchmarkNum;
}
}
gBenchmarkStartTimeNs = 0;
}
void StartBenchmarkTiming(uint64_t NanoTime) {
if (gBenchmarkStartTimeNs == 0) {
gBenchmarkStartTimeNs = NanoTime;
}
}
int main(int argc, char* argv[]) {
if (gBenchmarks->empty()) {
fprintf(stderr, "No benchmarks registered!\n");
exit(EXIT_FAILURE);
}
bool need_header = true;
for (auto b : *gBenchmarks) {
if (ShouldRun(b, argc, argv)) {
if (need_header) {
printf("%-25s %10s %10s\n", "", "iterations", "ns/op");
fflush(stdout);
need_header = false;
}
Run(b);
}
}
if (need_header) {
fprintf(stderr, "No matching benchmarks!\n");
fprintf(stderr, "Available benchmarks:\n");
for (auto b : *gBenchmarks) {
fprintf(stderr, " %s\n", b->Name());
}
exit(EXIT_FAILURE);
}
return 0;
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2014 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 <gtest/gtest.h>
#include <errno.h>
#include <stdio.h>
TEST(libc, __pstore_append) {
#ifdef __ANDROID__
FILE* fp;
ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a")));
static const char message[] = "libc.__pstore_append\n";
ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));
int fflushReturn = fflush(fp);
int fflushErrno = fflushReturn ? errno : 0;
ASSERT_EQ(0, fflushReturn);
ASSERT_EQ(0, fflushErrno);
int fcloseReturn = fclose(fp);
int fcloseErrno = fcloseReturn ? errno : 0;
ASSERT_EQ(0, fcloseReturn);
ASSERT_EQ(0, fcloseErrno);
if ((fcloseErrno == ENOMEM) || (fflushErrno == ENOMEM)) {
fprintf(stderr,
"Kernel does not have space allocated to pmsg pstore driver "
"configured\n");
}
if (!fcloseReturn && !fcloseErrno && !fflushReturn && !fflushReturn) {
fprintf(stderr,
"Reboot, ensure string libc.__pstore_append is in "
"/sys/fs/pstore/pmsg-ramoops-0\n");
}
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#ifdef __ANDROID__
#include <log/log_transport.h>
#define TEST_LOGGER LOGGER_DEFAULT
#endif
#include "liblog_test.cpp"

View file

@ -0,0 +1,4 @@
#include <log/log_transport.h>
#define liblog liblog_local
#define TEST_LOGGER LOGGER_LOCAL
#include "liblog_test.cpp"

View file

@ -0,0 +1,5 @@
#include <log/log_transport.h>
#define liblog liblog_stderr
#define TEST_LOGGER LOGGER_STDERR
#define USING_LOGGER_STDERR
#include "liblog_test.cpp"

View file

@ -0,0 +1,4 @@
#include <log/log_transport.h>
#define liblog liblog_stderr_local
#define TEST_LOGGER (LOGGER_LOCAL | LOGGER_STDERR)
#include "liblog_test.cpp"

View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2013-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 <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <gtest/gtest.h>
// Test the APIs in this standalone include file
#include <log/log_id.h>
// We do not want to include <android/log.h> to acquire ANDROID_LOG_INFO for
// include file API purity. We do however want to allow the _option_ that
// log/log_id.h could include this file, or related content, in the future.
#ifndef __android_LogPriority_defined
#define ANDROID_LOG_INFO 4
#endif
TEST(liblog, log_id) {
int count = 0;
for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char* name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
++count;
fprintf(stderr, "log buffer %s\r", name);
}
ASSERT_EQ(LOG_ID_MAX, count);
}
TEST(liblog, __android_log_buf_print) {
EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "radio"));
usleep(1000);
EXPECT_LT(0,
__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "main"));
usleep(1000);
}
TEST(liblog, __android_log_buf_write) {
EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "radio"));
usleep(1000);
EXPECT_LT(0,
__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "main"));
usleep(1000);
}
static void* ConcurrentPrintFn(void* arg) {
int ret = __android_log_buf_print(
LOG_ID_MAIN, ANDROID_LOG_INFO, "TEST__android_log_print",
"Concurrent %" PRIuPTR, reinterpret_cast<uintptr_t>(arg));
return reinterpret_cast<void*>(ret);
}
#define NUM_CONCURRENT 64
#define _concurrent_name(a, n) a##__concurrent##n
#define concurrent_name(a, n) _concurrent_name(a, n)
TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
pthread_t t[NUM_CONCURRENT];
int i;
for (i = 0; i < NUM_CONCURRENT; i++) {
ASSERT_EQ(0, pthread_create(&t[i], NULL, ConcurrentPrintFn,
reinterpret_cast<void*>(i)));
}
int ret = 0;
for (i = 0; i < NUM_CONCURRENT; i++) {
void* result;
ASSERT_EQ(0, pthread_join(t[i], &result));
int this_result = reinterpret_cast<uintptr_t>(result);
if ((0 == ret) && (0 != this_result)) {
ret = this_result;
}
}
ASSERT_LT(0, ret);
}

View file

@ -0,0 +1,119 @@
/*
* 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 <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <gtest/gtest.h>
// Test the APIs in this standalone include file
#include <log/log_radio.h>
TEST(liblog, RLOG) {
static const char content[] = "log_radio.h";
static const char content_false[] = "log_radio.h false";
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGV"
RLOGV(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGD"
RLOGD(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGI"
RLOGI(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGW"
RLOGW(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGE"
RLOGE(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGV"
RLOGV_IF(true, content);
usleep(100000);
RLOGV_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGD"
RLOGD_IF(true, content);
usleep(100000);
RLOGD_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGI"
RLOGI_IF(true, content);
usleep(100000);
RLOGI_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGW"
RLOGW_IF(true, content);
usleep(100000);
RLOGW_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGE"
RLOGE_IF(true, content);
usleep(100000);
RLOGE_IF(false, content_false);
#ifdef __ANDROID__
// give time for content to long-path through logger
sleep(1);
std::string buf = android::base::StringPrintf(
"logcat -b radio --pid=%u -d -s"
" TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
++pos) {
++count;
}
for (size_t pos = 0;
(pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
}
EXPECT_EQ(0, count_false);
#if LOG_NDEBUG
ASSERT_EQ(8, count);
#else
ASSERT_EQ(10, count);
#endif
#else
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
#endif
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2013-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 <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <string>
#include <android-base/stringprintf.h>
#include <android/log.h> // minimal logging API
#include <gtest/gtest.h>
#include <log/log_properties.h>
// Test the APIs in this standalone include file
#include <log/log_read.h>
// Do not use anything in log/log_time.h despite side effects of the above.
TEST(liblog, __android_log_write__android_logger_list_read) {
#ifdef __ANDROID__
pid_t pid = getpid();
struct logger_list* logger_list;
ASSERT_TRUE(
NULL !=
(logger_list = android_logger_list_open(
LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid,
ts.tv_sec, ts.tv_nsec);
static const char tag[] =
"liblog.__android_log_write__android_logger_list_read";
static const char prio = ANDROID_LOG_DEBUG;
ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str()));
usleep(1000000);
buf = std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf +
std::string("", 1);
int count = 0;
for (;;) {
log_msg log_msg;
if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
EXPECT_EQ(log_msg.entry.pid, pid);
// There may be a future where we leak "liblog" tagged LOG_ID_EVENT
// binary messages through so that logger losses can be correlated?
EXPECT_EQ(log_msg.id(), LOG_ID_MAIN);
if (log_msg.entry.len != buf.length()) continue;
if (buf != std::string(log_msg.msg(), log_msg.entry.len)) continue;
++count;
}
android_logger_list_close(logger_list);
EXPECT_EQ(1, count);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
TEST(liblog, android_logger_get_) {
#ifdef __ANDROID__
// This test assumes the log buffers are filled with noise from
// normal operations. It will fail if done immediately after a
// logcat -c.
struct logger_list* logger_list =
android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char* name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
fprintf(stderr, "log buffer %s\r", name);
struct logger* logger;
EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
EXPECT_EQ(id, android_logger_get_id(logger));
ssize_t get_log_size = android_logger_get_log_size(logger);
/* security buffer is allowed to be denied */
if (strcmp("security", name)) {
EXPECT_LT(0, get_log_size);
// crash buffer is allowed to be empty, that is actually healthy!
// kernel buffer is allowed to be empty on "user" builds
EXPECT_LE( // boolean 1 or 0 depending on expected content or empty
!!((strcmp("crash", name) != 0) &&
((strcmp("kernel", name) != 0) || __android_log_is_debuggable())),
android_logger_get_log_readable_size(logger));
} else {
EXPECT_NE(0, get_log_size);
if (get_log_size < 0) {
EXPECT_GT(0, android_logger_get_log_readable_size(logger));
} else {
EXPECT_LE(0, android_logger_get_log_readable_size(logger));
}
}
EXPECT_LT(0, android_logger_get_log_version(logger));
}
android_logger_list_close(logger_list);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}

View file

@ -0,0 +1,119 @@
/*
* 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 <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <gtest/gtest.h>
// Test the APIs in this standalone include file
#include <log/log_system.h>
TEST(liblog, SLOG) {
static const char content[] = "log_system.h";
static const char content_false[] = "log_system.h false";
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGV"
SLOGV(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGD"
SLOGD(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGI"
SLOGI(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGW"
SLOGW(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGE"
SLOGE(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGV"
SLOGV_IF(true, content);
usleep(100000);
SLOGV_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGD"
SLOGD_IF(true, content);
usleep(100000);
SLOGD_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGI"
SLOGI_IF(true, content);
usleep(100000);
SLOGI_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGW"
SLOGW_IF(true, content);
usleep(100000);
SLOGW_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGE"
SLOGE_IF(true, content);
usleep(100000);
SLOGE_IF(false, content_false);
#ifdef __ANDROID__
// give time for content to long-path through logger
sleep(1);
std::string buf = android::base::StringPrintf(
"logcat -b system --pid=%u -d -s"
" TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
++pos) {
++count;
}
for (size_t pos = 0;
(pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
}
EXPECT_EQ(0, count_false);
#if LOG_NDEBUG
ASSERT_EQ(8, count);
#else
ASSERT_EQ(10, count);
#endif
#else
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
#endif
}

View file

@ -0,0 +1,37 @@
/*
* 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 <time.h>
#include <gtest/gtest.h>
// Test the APIs in this standalone include file
#include <log/log_time.h>
TEST(liblog, log_time) {
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
log_time(CLOCK_MONOTONIC);
EXPECT_EQ(log_time, log_time::EPOCH);
#endif
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
log_time tl(ts);
EXPECT_EQ(tl, ts);
EXPECT_GE(tl, ts);
EXPECT_LE(tl, ts);
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (C) 2013-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 <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <string>
#include <android-base/chrono_utils.h>
#include <android-base/stringprintf.h>
#include <android/log.h> // minimal logging API
#include <gtest/gtest.h>
#include <log/log_properties.h>
#include <log/log_read.h>
#include <log/log_time.h>
#include <log/log_transport.h>
#ifdef __ANDROID__
static void read_with_wrap() {
android_set_log_transport(LOGGER_LOGD);
// Read the last line in the log to get a starting timestamp. We're assuming
// the log is not empty.
const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
struct logger_list* logger_list =
android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0);
ASSERT_NE(logger_list, nullptr);
log_msg log_msg;
int ret = android_logger_list_read(logger_list, &log_msg);
android_logger_list_close(logger_list);
ASSERT_GT(ret, 0);
log_time start(log_msg.entry.sec, log_msg.entry.nsec);
ASSERT_NE(start, log_time());
logger_list =
android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0);
ASSERT_NE(logger_list, nullptr);
struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN);
EXPECT_NE(logger, nullptr);
if (logger) {
android_logger_list_read(logger_list, &log_msg);
}
android_logger_list_close(logger_list);
}
static void caught_signal(int /* signum */) {
}
#endif
// b/64143705 confirm fixed
TEST(liblog, wrap_mode_blocks) {
#ifdef __ANDROID__
android::base::Timer timer;
// The read call is expected to take up to 2 hours in the happy case.
// We only want to make sure it waits for longer than 30s, but we can't
// use an alarm as the implementation uses it. So we run the test in
// a separate process.
pid_t pid = fork();
if (pid == 0) {
// child
read_with_wrap();
_exit(0);
}
struct sigaction ignore, old_sigaction;
memset(&ignore, 0, sizeof(ignore));
ignore.sa_handler = caught_signal;
sigemptyset(&ignore.sa_mask);
sigaction(SIGALRM, &ignore, &old_sigaction);
alarm(45);
bool killed = false;
for (;;) {
siginfo_t info = {};
// This wait will succeed if the child exits, or fail with EINTR if the
// alarm goes off first - a loose approximation to a timed wait.
int ret = waitid(P_PID, pid, &info, WEXITED);
if (ret >= 0 || errno != EINTR) {
EXPECT_EQ(ret, 0);
if (!killed) {
EXPECT_EQ(info.si_status, 0);
}
break;
}
unsigned int alarm_left = alarm(0);
if (alarm_left > 0) {
alarm(alarm_left);
} else {
kill(pid, SIGTERM);
killed = true;
}
}
alarm(0);
EXPECT_GT(timer.duration(), std::chrono::seconds(40));
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}