upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
89
android/system/core/libcutils/tests/Android.bp
Normal file
89
android/system/core/libcutils/tests/Android.bp
Normal file
|
@ -0,0 +1,89 @@
|
|||
// 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.
|
||||
|
||||
cc_defaults {
|
||||
name: "libcutils_test_default",
|
||||
srcs: ["sockets_test.cpp"],
|
||||
|
||||
target: {
|
||||
android: {
|
||||
srcs: [
|
||||
"AshmemTest.cpp",
|
||||
"MemsetTest.cpp",
|
||||
"PropertiesTest.cpp",
|
||||
"sched_policy_test.cpp",
|
||||
"trace-dev_test.cpp",
|
||||
"test_str_parms.cpp",
|
||||
"android_get_control_socket_test.cpp",
|
||||
"android_get_control_file_test.cpp",
|
||||
"multiuser_test.cpp",
|
||||
"fs_config.cpp",
|
||||
],
|
||||
},
|
||||
|
||||
not_windows: {
|
||||
srcs: [
|
||||
"test_str_parms.cpp",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
multilib: {
|
||||
lib32: {
|
||||
suffix: "32",
|
||||
},
|
||||
lib64: {
|
||||
suffix: "64",
|
||||
},
|
||||
},
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
}
|
||||
|
||||
test_libraries = [
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libbase",
|
||||
]
|
||||
|
||||
cc_test {
|
||||
name: "libcutils_test",
|
||||
test_suites: ["device-tests"],
|
||||
defaults: ["libcutils_test_default"],
|
||||
host_supported: true,
|
||||
shared_libs: test_libraries,
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "libcutils_test_static",
|
||||
test_suites: ["device-tests"],
|
||||
defaults: ["libcutils_test_default"],
|
||||
static_libs: ["libc"] + test_libraries,
|
||||
stl: "libc++_static",
|
||||
|
||||
target: {
|
||||
android: {
|
||||
static_executable: true,
|
||||
},
|
||||
windows: {
|
||||
host_ldlibs: ["-lws2_32"],
|
||||
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
26
android/system/core/libcutils/tests/AndroidTest.xml
Normal file
26
android/system/core/libcutils/tests/AndroidTest.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<configuration description="Config for libcutils_test">
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="libcutils_test->/data/local/tmp/libcutils_test" />
|
||||
</target_preparer>
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="libcutils_test" />
|
||||
</test>
|
||||
</configuration>
|
251
android/system/core/libcutils/tests/AshmemTest.cpp
Normal file
251
android/system/core/libcutils/tests/AshmemTest.cpp
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <cutils/ashmem.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <linux/fs.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
using android::base::unique_fd;
|
||||
|
||||
void TestCreateRegion(size_t size, unique_fd &fd, int prot) {
|
||||
fd = unique_fd(ashmem_create_region(nullptr, size));
|
||||
ASSERT_TRUE(fd >= 0);
|
||||
ASSERT_TRUE(ashmem_valid(fd));
|
||||
ASSERT_EQ(size, static_cast<size_t>(ashmem_get_size_region(fd)));
|
||||
ASSERT_EQ(0, ashmem_set_prot_region(fd, prot));
|
||||
}
|
||||
|
||||
void TestMmap(const unique_fd& fd, size_t size, int prot, void** region, off_t off = 0) {
|
||||
*region = mmap(nullptr, size, prot, MAP_SHARED, fd, off);
|
||||
ASSERT_NE(MAP_FAILED, *region);
|
||||
}
|
||||
|
||||
void TestProtDenied(const unique_fd &fd, size_t size, int prot) {
|
||||
EXPECT_EQ(MAP_FAILED, mmap(nullptr, size, prot, MAP_SHARED, fd, 0));
|
||||
}
|
||||
|
||||
void TestProtIs(const unique_fd& fd, int prot) {
|
||||
EXPECT_EQ(prot, ioctl(fd, ASHMEM_GET_PROT_MASK));
|
||||
}
|
||||
|
||||
void FillData(uint8_t* data, size_t dataLen) {
|
||||
for (size_t i = 0; i < dataLen; i++) {
|
||||
data[i] = i & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AshmemTest, BasicTest) {
|
||||
constexpr size_t size = PAGE_SIZE;
|
||||
uint8_t data[size];
|
||||
FillData(data, size);
|
||||
|
||||
unique_fd fd;
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
|
||||
|
||||
void *region1;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, ®ion1));
|
||||
|
||||
memcpy(region1, &data, size);
|
||||
ASSERT_EQ(0, memcmp(region1, &data, size));
|
||||
|
||||
EXPECT_EQ(0, munmap(region1, size));
|
||||
|
||||
void *region2;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ, ®ion2));
|
||||
ASSERT_EQ(0, memcmp(region2, &data, size));
|
||||
EXPECT_EQ(0, munmap(region2, size));
|
||||
}
|
||||
|
||||
TEST(AshmemTest, ForkTest) {
|
||||
constexpr size_t size = PAGE_SIZE;
|
||||
uint8_t data[size];
|
||||
FillData(data, size);
|
||||
|
||||
unique_fd fd;
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
|
||||
|
||||
void *region1;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, ®ion1));
|
||||
|
||||
memcpy(region1, &data, size);
|
||||
ASSERT_EQ(0, memcmp(region1, &data, size));
|
||||
EXPECT_EQ(0, munmap(region1, size));
|
||||
|
||||
ASSERT_EXIT({
|
||||
void *region2 = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (region2 == MAP_FAILED) {
|
||||
_exit(1);
|
||||
}
|
||||
if (memcmp(region2, &data, size) != 0) {
|
||||
_exit(2);
|
||||
}
|
||||
memset(region2, 0, size);
|
||||
munmap(region2, size);
|
||||
_exit(0);
|
||||
}, ::testing::ExitedWithCode(0),"");
|
||||
|
||||
memset(&data, 0, size);
|
||||
void *region2;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, ®ion2));
|
||||
ASSERT_EQ(0, memcmp(region2, &data, size));
|
||||
EXPECT_EQ(0, munmap(region2, size));
|
||||
}
|
||||
|
||||
TEST(AshmemTest, FileOperationsTest) {
|
||||
unique_fd fd;
|
||||
void* region;
|
||||
|
||||
// Allocate a 4-page buffer, but leave page-sized holes on either side
|
||||
constexpr size_t size = PAGE_SIZE * 4;
|
||||
constexpr size_t dataSize = PAGE_SIZE * 2;
|
||||
constexpr size_t holeSize = PAGE_SIZE;
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, dataSize, PROT_READ | PROT_WRITE, ®ion, holeSize));
|
||||
|
||||
uint8_t data[dataSize];
|
||||
FillData(data, dataSize);
|
||||
memcpy(region, data, dataSize);
|
||||
|
||||
constexpr off_t dataStart = holeSize;
|
||||
constexpr off_t dataEnd = dataStart + dataSize;
|
||||
|
||||
// The sequence of seeks below looks something like this:
|
||||
//
|
||||
// [ ][data][data][ ]
|
||||
// --^ lseek(99, SEEK_SET)
|
||||
// ------^ lseek(dataStart, SEEK_CUR)
|
||||
// ------^ lseek(0, SEEK_DATA)
|
||||
// ------------^ lseek(dataStart, SEEK_HOLE)
|
||||
// ^-- lseek(-99, SEEK_END)
|
||||
// ^------ lseek(-dataStart, SEEK_CUR)
|
||||
const struct {
|
||||
// lseek() parameters
|
||||
off_t offset;
|
||||
int whence;
|
||||
// Expected lseek() return value
|
||||
off_t ret;
|
||||
} seeks[] = {
|
||||
{99, SEEK_SET, 99}, {dataStart, SEEK_CUR, dataStart + 99},
|
||||
{0, SEEK_DATA, dataStart}, {dataStart, SEEK_HOLE, dataEnd},
|
||||
{-99, SEEK_END, size - 99}, {-dataStart, SEEK_CUR, dataEnd - 99},
|
||||
};
|
||||
for (const auto& cfg : seeks) {
|
||||
errno = 0;
|
||||
auto off = lseek(fd, cfg.offset, cfg.whence);
|
||||
ASSERT_EQ(cfg.ret, off) << "lseek(" << cfg.offset << ", " << cfg.whence << ") failed"
|
||||
<< (errno ? ": " : "") << (errno ? strerror(errno) : "");
|
||||
|
||||
if (off >= dataStart && off < dataEnd) {
|
||||
off_t dataOff = off - dataStart;
|
||||
ssize_t readSize = dataSize - dataOff;
|
||||
uint8_t buf[readSize];
|
||||
|
||||
ASSERT_EQ(readSize, TEMP_FAILURE_RETRY(read(fd, buf, readSize)));
|
||||
EXPECT_EQ(0, memcmp(buf, data + dataOff, readSize));
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, munmap(region, dataSize));
|
||||
}
|
||||
|
||||
TEST(AshmemTest, ProtTest) {
|
||||
unique_fd fd;
|
||||
constexpr size_t size = PAGE_SIZE;
|
||||
void *region;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ));
|
||||
TestProtDenied(fd, size, PROT_WRITE);
|
||||
TestProtIs(fd, PROT_READ);
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ, ®ion));
|
||||
EXPECT_EQ(0, munmap(region, size));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_WRITE));
|
||||
TestProtDenied(fd, size, PROT_READ);
|
||||
TestProtIs(fd, PROT_WRITE);
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_WRITE, ®ion));
|
||||
EXPECT_EQ(0, munmap(region, size));
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
|
||||
TestProtIs(fd, PROT_READ | PROT_WRITE);
|
||||
ASSERT_EQ(0, ashmem_set_prot_region(fd, PROT_READ));
|
||||
errno = 0;
|
||||
ASSERT_EQ(-1, ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE))
|
||||
<< "kernel shouldn't allow adding protection bits";
|
||||
EXPECT_EQ(EINVAL, errno);
|
||||
TestProtIs(fd, PROT_READ);
|
||||
TestProtDenied(fd, size, PROT_WRITE);
|
||||
}
|
||||
|
||||
TEST(AshmemTest, ForkProtTest) {
|
||||
unique_fd fd;
|
||||
constexpr size_t size = PAGE_SIZE;
|
||||
|
||||
int protFlags[] = { PROT_READ, PROT_WRITE };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
|
||||
ASSERT_EXIT({
|
||||
if (ashmem_set_prot_region(fd, protFlags[i]) >= 0) {
|
||||
_exit(0);
|
||||
} else {
|
||||
_exit(1);
|
||||
}
|
||||
}, ::testing::ExitedWithCode(0), "");
|
||||
ASSERT_NO_FATAL_FAILURE(TestProtDenied(fd, size, protFlags[1-i]));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(AshmemTest, ForkMultiRegionTest) {
|
||||
constexpr size_t size = PAGE_SIZE;
|
||||
uint8_t data[size];
|
||||
FillData(data, size);
|
||||
|
||||
constexpr int nRegions = 16;
|
||||
unique_fd fd[nRegions];
|
||||
for (int i = 0; i < nRegions; i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd[i], PROT_READ | PROT_WRITE));
|
||||
void *region;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd[i], size, PROT_READ | PROT_WRITE, ®ion));
|
||||
memcpy(region, &data, size);
|
||||
ASSERT_EQ(0, memcmp(region, &data, size));
|
||||
EXPECT_EQ(0, munmap(region, size));
|
||||
}
|
||||
|
||||
ASSERT_EXIT({
|
||||
for (int i = 0; i < nRegions; i++) {
|
||||
void *region = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd[i], 0);
|
||||
if (region == MAP_FAILED) {
|
||||
_exit(1);
|
||||
}
|
||||
if (memcmp(region, &data, size) != 0) {
|
||||
munmap(region, size);
|
||||
_exit(2);
|
||||
}
|
||||
memset(region, 0, size);
|
||||
munmap(region, size);
|
||||
}
|
||||
_exit(0);
|
||||
}, ::testing::ExitedWithCode(0), "");
|
||||
|
||||
memset(&data, 0, size);
|
||||
for (int i = 0; i < nRegions; i++) {
|
||||
void *region;
|
||||
ASSERT_NO_FATAL_FAILURE(TestMmap(fd[i], size, PROT_READ | PROT_WRITE, ®ion));
|
||||
ASSERT_EQ(0, memcmp(region, &data, size));
|
||||
EXPECT_EQ(0, munmap(region, size));
|
||||
}
|
||||
}
|
181
android/system/core/libcutils/tests/MemsetTest.cpp
Normal file
181
android/system/core/libcutils/tests/MemsetTest.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <cutils/memory.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define FENCEPOST_LENGTH 8
|
||||
|
||||
#define MAX_TEST_SIZE (64*1024)
|
||||
// Choose values that have no repeating byte values.
|
||||
#define MEMSET16_PATTERN 0xb139
|
||||
#define MEMSET32_PATTERN 0x48193a27
|
||||
|
||||
enum test_e {
|
||||
MEMSET16 = 0,
|
||||
MEMSET32,
|
||||
};
|
||||
|
||||
static int g_memset16_aligns[][2] = {
|
||||
{ 2, 0 },
|
||||
{ 4, 0 },
|
||||
{ 8, 0 },
|
||||
{ 16, 0 },
|
||||
{ 32, 0 },
|
||||
{ 64, 0 },
|
||||
{ 128, 0 },
|
||||
|
||||
{ 4, 2 },
|
||||
|
||||
{ 8, 2 },
|
||||
{ 8, 4 },
|
||||
{ 8, 6 },
|
||||
|
||||
{ 128, 2 },
|
||||
{ 128, 4 },
|
||||
{ 128, 6 },
|
||||
{ 128, 8 },
|
||||
{ 128, 10 },
|
||||
{ 128, 12 },
|
||||
{ 128, 14 },
|
||||
{ 128, 16 },
|
||||
};
|
||||
|
||||
static int g_memset32_aligns[][2] = {
|
||||
{ 4, 0 },
|
||||
{ 8, 0 },
|
||||
{ 16, 0 },
|
||||
{ 32, 0 },
|
||||
{ 64, 0 },
|
||||
{ 128, 0 },
|
||||
|
||||
{ 8, 4 },
|
||||
|
||||
{ 128, 4 },
|
||||
{ 128, 8 },
|
||||
{ 128, 12 },
|
||||
{ 128, 16 },
|
||||
};
|
||||
|
||||
static size_t GetIncrement(size_t len, size_t min_incr) {
|
||||
if (len >= 4096) {
|
||||
return 1024;
|
||||
} else if (len >= 1024) {
|
||||
return 256;
|
||||
}
|
||||
return min_incr;
|
||||
}
|
||||
|
||||
// Return a pointer into the current buffer with the specified alignment.
|
||||
static void *GetAlignedPtr(void *orig_ptr, int alignment, int or_mask) {
|
||||
uint64_t ptr = reinterpret_cast<uint64_t>(orig_ptr);
|
||||
if (alignment > 0) {
|
||||
// When setting the alignment, set it to exactly the alignment chosen.
|
||||
// The pointer returned will be guaranteed not to be aligned to anything
|
||||
// more than that.
|
||||
ptr += alignment - (ptr & (alignment - 1));
|
||||
ptr |= alignment | or_mask;
|
||||
}
|
||||
|
||||
return reinterpret_cast<void*>(ptr);
|
||||
}
|
||||
|
||||
static void SetFencepost(uint8_t *buffer) {
|
||||
for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {
|
||||
buffer[i] = 0xde;
|
||||
buffer[i+1] = 0xad;
|
||||
}
|
||||
}
|
||||
|
||||
static void VerifyFencepost(uint8_t *buffer) {
|
||||
for (int i = 0; i < FENCEPOST_LENGTH; i += 2) {
|
||||
if (buffer[i] != 0xde || buffer[i+1] != 0xad) {
|
||||
uint8_t expected_value;
|
||||
if (buffer[i] == 0xde) {
|
||||
i++;
|
||||
expected_value = 0xad;
|
||||
} else {
|
||||
expected_value = 0xde;
|
||||
}
|
||||
ASSERT_EQ(expected_value, buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunMemsetTests(test_e test_type, uint32_t value, int align[][2], size_t num_aligns) {
|
||||
size_t min_incr = 4;
|
||||
if (test_type == MEMSET16) {
|
||||
min_incr = 2;
|
||||
value |= value << 16;
|
||||
}
|
||||
std::unique_ptr<uint32_t[]> expected_buf(new uint32_t[MAX_TEST_SIZE/sizeof(uint32_t)]);
|
||||
for (size_t i = 0; i < MAX_TEST_SIZE/sizeof(uint32_t); i++) {
|
||||
expected_buf[i] = value;
|
||||
}
|
||||
|
||||
// Allocate one large buffer with lots of extra space so that we can
|
||||
// guarantee that all possible alignments will fit.
|
||||
std::unique_ptr<uint8_t[]> buf(new uint8_t[3*MAX_TEST_SIZE]);
|
||||
uint8_t *buf_align;
|
||||
for (size_t i = 0; i < num_aligns; i++) {
|
||||
size_t incr = min_incr;
|
||||
for (size_t len = incr; len <= MAX_TEST_SIZE; len += incr) {
|
||||
incr = GetIncrement(len, min_incr);
|
||||
|
||||
buf_align = reinterpret_cast<uint8_t*>(GetAlignedPtr(
|
||||
buf.get()+FENCEPOST_LENGTH, align[i][0], align[i][1]));
|
||||
|
||||
SetFencepost(&buf_align[-FENCEPOST_LENGTH]);
|
||||
SetFencepost(&buf_align[len]);
|
||||
|
||||
memset(buf_align, 0xff, len);
|
||||
if (test_type == MEMSET16) {
|
||||
android_memset16(reinterpret_cast<uint16_t*>(buf_align), value, len);
|
||||
} else {
|
||||
android_memset32(reinterpret_cast<uint32_t*>(buf_align), value, len);
|
||||
}
|
||||
ASSERT_EQ(0, memcmp(expected_buf.get(), buf_align, len))
|
||||
<< "Failed size " << len << " align " << align[i][0] << " " << align[i][1] << "\n";
|
||||
|
||||
VerifyFencepost(&buf_align[-FENCEPOST_LENGTH]);
|
||||
VerifyFencepost(&buf_align[len]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(libcutils, android_memset16_non_zero) {
|
||||
RunMemsetTests(MEMSET16, MEMSET16_PATTERN, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));
|
||||
}
|
||||
|
||||
TEST(libcutils, android_memset16_zero) {
|
||||
RunMemsetTests(MEMSET16, 0, g_memset16_aligns, sizeof(g_memset16_aligns)/sizeof(int[2]));
|
||||
}
|
||||
|
||||
TEST(libcutils, android_memset32_non_zero) {
|
||||
RunMemsetTests(MEMSET32, MEMSET32_PATTERN, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));
|
||||
}
|
||||
|
||||
TEST(libcutils, android_memset32_zero) {
|
||||
RunMemsetTests(MEMSET32, 0, g_memset32_aligns, sizeof(g_memset32_aligns)/sizeof(int[2]));
|
||||
}
|
360
android/system/core/libcutils/tests/PropertiesTest.cpp
Normal file
360
android/system/core/libcutils/tests/PropertiesTest.cpp
Normal file
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Properties_test"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <android/log.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
#define STRINGIFY_INNER(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_INNER(x)
|
||||
#define ASSERT_OK(x) ASSERT_EQ(0, (x))
|
||||
#define EXPECT_OK(x) EXPECT_EQ(0, (x))
|
||||
|
||||
#define PROPERTY_TEST_KEY "libcutils.test.key"
|
||||
#define PROPERTY_TEST_VALUE_DEFAULT "<<<default_value>>>"
|
||||
|
||||
template <typename T>
|
||||
static std::string HexString(T value) {
|
||||
std::stringstream ss;
|
||||
ss << "0x" << std::hex << std::uppercase << value;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static ::testing::AssertionResult AssertEqualHex(const char *mExpr,
|
||||
const char *nExpr,
|
||||
T m,
|
||||
T n) {
|
||||
if (m == n) {
|
||||
return ::testing::AssertionSuccess();
|
||||
}
|
||||
|
||||
return ::testing::AssertionFailure()
|
||||
<< mExpr << " and " << nExpr << " (expected: " << HexString(m) <<
|
||||
", actual: " << HexString(n) << ") are not equal";
|
||||
}
|
||||
|
||||
class PropertiesTest : public testing::Test {
|
||||
public:
|
||||
PropertiesTest() : mValue() {}
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
|
||||
}
|
||||
|
||||
char mValue[PROPERTY_VALUE_MAX];
|
||||
|
||||
template <typename T>
|
||||
static std::string ToString(T value) {
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Return length of property read; value is written into mValue
|
||||
int SetAndGetProperty(const char* value, const char* defaultValue = PROPERTY_TEST_VALUE_DEFAULT) {
|
||||
EXPECT_OK(property_set(PROPERTY_TEST_KEY, value)) << "value: '" << value << "'";
|
||||
return property_get(PROPERTY_TEST_KEY, mValue, defaultValue);
|
||||
}
|
||||
|
||||
void ResetValue(unsigned char c = 0xFF) {
|
||||
for (size_t i = 0; i < arraysize(mValue); ++i) {
|
||||
mValue[i] = (char) c;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(PropertiesTest, SetString) {
|
||||
|
||||
// Null key -> unsuccessful set
|
||||
{
|
||||
// Null key -> fails
|
||||
EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT));
|
||||
}
|
||||
|
||||
// Null value -> returns default value
|
||||
{
|
||||
// Null value -> OK , and it clears the value
|
||||
EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL));
|
||||
ResetValue();
|
||||
|
||||
// Since the value is null, default value will be returned
|
||||
size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
|
||||
EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len);
|
||||
EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue);
|
||||
}
|
||||
|
||||
// Trivial case => get returns what was set
|
||||
{
|
||||
size_t len = SetAndGetProperty("hello_world");
|
||||
EXPECT_EQ(strlen("hello_world"), len) << "hello_world key";
|
||||
EXPECT_STREQ("hello_world", mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Set to empty string => get returns default always
|
||||
{
|
||||
const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING";
|
||||
size_t len = SetAndGetProperty("", EMPTY_STRING_DEFAULT);
|
||||
EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key";
|
||||
EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Set to max length => get returns what was set
|
||||
{
|
||||
std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
|
||||
|
||||
int len = SetAndGetProperty(maxLengthString.c_str());
|
||||
EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << "max length key";
|
||||
EXPECT_STREQ(maxLengthString.c_str(), mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Set to max length + 1 => set fails
|
||||
{
|
||||
const char* VALID_TEST_VALUE = "VALID_VALUE";
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE));
|
||||
|
||||
std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
|
||||
|
||||
// Expect that the value set fails since it's too long
|
||||
EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str()));
|
||||
size_t len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT);
|
||||
|
||||
EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed";
|
||||
EXPECT_STREQ(VALID_TEST_VALUE, mValue);
|
||||
ResetValue();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PropertiesTest, GetString) {
|
||||
|
||||
// Try to use a default value that's too long => get truncates the value
|
||||
{
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
|
||||
|
||||
std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
|
||||
std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
|
||||
|
||||
// Expect that the value is truncated since it's too long (by 1)
|
||||
int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
|
||||
EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
|
||||
EXPECT_STREQ(maxLengthString.c_str(), mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Try to use a default value that's the max length => get succeeds
|
||||
{
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
|
||||
|
||||
std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'b');
|
||||
|
||||
// Expect that the value matches maxLengthString
|
||||
int len = property_get(PROPERTY_TEST_KEY, mValue, maxLengthString.c_str());
|
||||
EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
|
||||
EXPECT_STREQ(maxLengthString.c_str(), mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Try to use a default value of length one => get succeeds
|
||||
{
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
|
||||
|
||||
std::string oneCharString = std::string(1, 'c');
|
||||
|
||||
// Expect that the value matches oneCharString
|
||||
int len = property_get(PROPERTY_TEST_KEY, mValue, oneCharString.c_str());
|
||||
EXPECT_EQ(1, len);
|
||||
EXPECT_STREQ(oneCharString.c_str(), mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Try to use a default value of length zero => get succeeds
|
||||
{
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
|
||||
|
||||
std::string zeroCharString = std::string(0, 'd');
|
||||
|
||||
// Expect that the value matches oneCharString
|
||||
int len = property_get(PROPERTY_TEST_KEY, mValue, zeroCharString.c_str());
|
||||
EXPECT_EQ(0, len);
|
||||
EXPECT_STREQ(zeroCharString.c_str(), mValue);
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
// Try to use a NULL default value => get returns 0
|
||||
{
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
|
||||
|
||||
// Expect a return value of 0
|
||||
int len = property_get(PROPERTY_TEST_KEY, mValue, NULL);
|
||||
EXPECT_EQ(0, len);
|
||||
ResetValue();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PropertiesTest, GetBool) {
|
||||
/**
|
||||
* TRUE
|
||||
*/
|
||||
const char *valuesTrue[] = { "1", "true", "y", "yes", "on", };
|
||||
for (size_t i = 0; i < arraysize(valuesTrue); ++i) {
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i]));
|
||||
bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);
|
||||
EXPECT_TRUE(val) << "Property should've been TRUE for value: '" << valuesTrue[i] << "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* FALSE
|
||||
*/
|
||||
const char *valuesFalse[] = { "0", "false", "n", "no", "off", };
|
||||
for (size_t i = 0; i < arraysize(valuesFalse); ++i) {
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i]));
|
||||
bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);
|
||||
EXPECT_FALSE(val) << "Property shoud've been FALSE For string value: '" << valuesFalse[i] << "'";
|
||||
}
|
||||
|
||||
/**
|
||||
* NEITHER
|
||||
*/
|
||||
const char *valuesNeither[] = { "x0", "x1", "2", "-2", "True", "False", "garbage", "", " ",
|
||||
"+1", " 1 ", " true", " true ", " y ", " yes", "yes ",
|
||||
"+0", "-0", "00", " 00 ", " false", "false ",
|
||||
};
|
||||
for (size_t i = 0; i < arraysize(valuesNeither); ++i) {
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesNeither[i]));
|
||||
|
||||
// The default value should always be used
|
||||
bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true);
|
||||
EXPECT_TRUE(val) << "Property should've been NEITHER (true) for string value: '" << valuesNeither[i] << "'";
|
||||
|
||||
val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false);
|
||||
EXPECT_FALSE(val) << "Property should've been NEITHER (false) for string value: '" << valuesNeither[i] << "'";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PropertiesTest, GetInt64) {
|
||||
const int64_t DEFAULT_VALUE = INT64_C(0xDEADBEEFBEEFDEAD);
|
||||
|
||||
const std::string longMaxString = ToString(INT64_MAX);
|
||||
const std::string longStringOverflow = longMaxString + "0";
|
||||
|
||||
const std::string longMinString = ToString(INT64_MIN);
|
||||
const std::string longStringUnderflow = longMinString + "0";
|
||||
|
||||
const char* setValues[] = {
|
||||
// base 10
|
||||
"1", "2", "12345", "-1", "-2", "-12345",
|
||||
// base 16
|
||||
"0xFF", "0x0FF", "0xC0FFEE",
|
||||
// base 8
|
||||
"0", "01234", "07",
|
||||
// corner cases
|
||||
" 2", "2 ", "+0", "-0", " +0 ", longMaxString.c_str(), longMinString.c_str(),
|
||||
// failing cases
|
||||
NULL, "", " ", " ", "hello", " true ", "y",
|
||||
longStringOverflow.c_str(), longStringUnderflow.c_str(),
|
||||
};
|
||||
|
||||
int64_t getValues[] = {
|
||||
// base 10
|
||||
1, 2, 12345, -1, -2, -12345,
|
||||
// base 16
|
||||
0xFF, 0x0FF, 0xC0FFEE,
|
||||
// base 8
|
||||
0, 01234, 07,
|
||||
// corner cases
|
||||
2, 2, 0, 0, 0, INT64_MAX, INT64_MIN,
|
||||
// failing cases
|
||||
DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,
|
||||
DEFAULT_VALUE, DEFAULT_VALUE,
|
||||
};
|
||||
|
||||
ASSERT_EQ(arraysize(setValues), arraysize(getValues));
|
||||
|
||||
for (size_t i = 0; i < arraysize(setValues); ++i) {
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));
|
||||
|
||||
int64_t val = property_get_int64(PROPERTY_TEST_KEY, DEFAULT_VALUE);
|
||||
EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'";
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PropertiesTest, GetInt32) {
|
||||
const int32_t DEFAULT_VALUE = INT32_C(0xDEADBEEF);
|
||||
|
||||
const std::string intMaxString = ToString(INT32_MAX);
|
||||
const std::string intStringOverflow = intMaxString + "0";
|
||||
|
||||
const std::string intMinString = ToString(INT32_MIN);
|
||||
const std::string intStringUnderflow = intMinString + "0";
|
||||
|
||||
const char* setValues[] = {
|
||||
// base 10
|
||||
"1", "2", "12345", "-1", "-2", "-12345",
|
||||
// base 16
|
||||
"0xFF", "0x0FF", "0xC0FFEE", "0Xf00",
|
||||
// base 8
|
||||
"0", "01234", "07",
|
||||
// corner cases
|
||||
" 2", "2 ", "+0", "-0", " +0 ", intMaxString.c_str(), intMinString.c_str(),
|
||||
// failing cases
|
||||
NULL, "", " ", " ", "hello", " true ", "y",
|
||||
intStringOverflow.c_str(), intStringUnderflow.c_str(),
|
||||
};
|
||||
|
||||
int32_t getValues[] = {
|
||||
// base 10
|
||||
1, 2, 12345, -1, -2, -12345,
|
||||
// base 16
|
||||
0xFF, 0x0FF, 0xC0FFEE, 0Xf00,
|
||||
// base 8
|
||||
0, 01234, 07,
|
||||
// corner cases
|
||||
2, 2, 0, 0, 0, INT32_MAX, INT32_MIN,
|
||||
// failing cases
|
||||
DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE,
|
||||
DEFAULT_VALUE, DEFAULT_VALUE,
|
||||
};
|
||||
|
||||
ASSERT_EQ(arraysize(setValues), arraysize(getValues));
|
||||
|
||||
for (size_t i = 0; i < arraysize(setValues); ++i) {
|
||||
ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i]));
|
||||
|
||||
int32_t val = property_get_int32(PROPERTY_TEST_KEY, DEFAULT_VALUE);
|
||||
EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/test_utils.h>
|
||||
#include <cutils/android_get_control_file.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(FilesTest, android_get_control_file) {
|
||||
TemporaryFile tf;
|
||||
ASSERT_GE(tf.fd, 0);
|
||||
|
||||
std::string key(ANDROID_FILE_ENV_PREFIX);
|
||||
key += tf.path;
|
||||
|
||||
std::for_each(key.begin(), key.end(), [] (char& c) { c = isalnum(c) ? c : '_'; });
|
||||
|
||||
EXPECT_EQ(unsetenv(key.c_str()), 0);
|
||||
EXPECT_EQ(android_get_control_file(tf.path), -1);
|
||||
|
||||
EXPECT_EQ(setenv(key.c_str(), android::base::StringPrintf("%d", tf.fd).c_str(), true), 0);
|
||||
|
||||
EXPECT_EQ(android_get_control_file(tf.path), tf.fd);
|
||||
close(tf.fd);
|
||||
EXPECT_EQ(android_get_control_file(tf.path), -1);
|
||||
EXPECT_EQ(unsetenv(key.c_str()), 0);
|
||||
EXPECT_EQ(android_get_control_file(tf.path), -1);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <cutils/sockets.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#ifndef SOCK_NONBLOCK
|
||||
#define SOCK_NONBLOCK 0
|
||||
#endif
|
||||
|
||||
#ifndef SOCK_CLOEXEC
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
TEST(SocketsTest, android_get_control_socket) {
|
||||
static const char key[] = ANDROID_SOCKET_ENV_PREFIX "SocketsTest_android_get_control_socket";
|
||||
static const char* name = key + strlen(ANDROID_SOCKET_ENV_PREFIX);
|
||||
|
||||
EXPECT_EQ(unsetenv(key), 0);
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
|
||||
int fd;
|
||||
ASSERT_GE(fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0), 0);
|
||||
#ifdef F_GETFL
|
||||
int flags;
|
||||
ASSERT_GE(flags = fcntl(fd, F_GETFL), 0);
|
||||
ASSERT_GE(fcntl(fd, F_SETFL, flags | O_NONBLOCK), 0);
|
||||
#endif
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", name);
|
||||
unlink(addr.sun_path);
|
||||
|
||||
EXPECT_EQ(bind(fd, (struct sockaddr*)&addr, sizeof(addr)), 0);
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
|
||||
char val[32];
|
||||
snprintf(val, sizeof(val), "%d", fd);
|
||||
EXPECT_EQ(setenv(key, val, true), 0);
|
||||
|
||||
EXPECT_EQ(android_get_control_socket(name), fd);
|
||||
socket_close(fd);
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
EXPECT_EQ(unlink(addr.sun_path), 0);
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
EXPECT_EQ(unsetenv(key), 0);
|
||||
EXPECT_EQ(android_get_control_socket(name), -1);
|
||||
}
|
248
android/system/core/libcutils/tests/fs_config.cpp
Normal file
248
android/system/core/libcutils/tests/fs_config.cpp
Normal file
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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 <inttypes.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <private/fs_config.h>
|
||||
|
||||
extern const fs_path_config* __for_testing_only__android_dirs;
|
||||
extern const fs_path_config* __for_testing_only__android_files;
|
||||
extern bool (*__for_testing_only__fs_config_cmp)(bool, const char*, size_t, const char*, size_t);
|
||||
|
||||
// Maximum entries in system/core/libcutils/fs_config.cpp:android_* before we
|
||||
// hit a nullptr termination, before we declare the list is just too big or
|
||||
// could be missing the nullptr.
|
||||
static constexpr size_t max_idx = 4096;
|
||||
|
||||
static const struct fs_config_cmp_test {
|
||||
bool dir;
|
||||
const char* prefix;
|
||||
const char* path;
|
||||
bool match;
|
||||
} fs_config_cmp_tests[] = {
|
||||
// clang-format off
|
||||
{ true, "system/lib", "system/lib/hw", true },
|
||||
{ true, "vendor/lib", "system/vendor/lib/hw", true },
|
||||
{ true, "system/vendor/lib", "vendor/lib/hw", true },
|
||||
{ true, "system/vendor/lib", "system/vendor/lib/hw", true },
|
||||
{ false, "vendor/bin/wifi", "system/vendor/bin/w", false },
|
||||
{ false, "vendor/bin/wifi", "system/vendor/bin/wifi", true },
|
||||
{ false, "vendor/bin/wifi", "system/vendor/bin/wifi2", false },
|
||||
{ false, "system/vendor/bin/wifi", "system/vendor/bin/wifi", true, },
|
||||
{ false, "odm/bin/wifi", "system/odm/bin/wifi", true },
|
||||
{ false, "oem/bin/wifi", "system/oem/bin/wifi", true },
|
||||
{ false, "data/bin/wifi", "system/data/bin/wifi", false },
|
||||
{ false, "system/bin/*", "system/bin/wifi", true },
|
||||
{ false, "vendor/bin/*", "system/vendor/bin/wifi", true },
|
||||
{ false, "system/bin/*", "system/bin", false },
|
||||
{ false, "system/vendor/bin/*", "vendor/bin/wifi", true },
|
||||
{ false, NULL, NULL, false },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static bool check_unique(std::vector<const char*>& paths, const std::string& config_name,
|
||||
const std::string& prefix) {
|
||||
bool retval = false;
|
||||
|
||||
std::string alternate = "system/" + prefix;
|
||||
|
||||
for (size_t idx = 0; idx < paths.size(); ++idx) {
|
||||
size_t second;
|
||||
std::string path(paths[idx]);
|
||||
// check if there are multiple identical paths
|
||||
for (second = idx + 1; second < paths.size(); ++second) {
|
||||
if (path == paths[second]) {
|
||||
GTEST_LOG_(ERROR) << "duplicate paths in " << config_name << ": " << paths[idx];
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if path is <partition>/
|
||||
if (android::base::StartsWith(path, prefix.c_str())) {
|
||||
// rebuild path to be system/<partition>/... to check for alias
|
||||
path = alternate + path.substr(prefix.size());
|
||||
for (second = 0; second < paths.size(); ++second) {
|
||||
if (path == paths[second]) {
|
||||
GTEST_LOG_(ERROR) << "duplicate alias paths in " << config_name << ": "
|
||||
<< paths[idx] << " and " << paths[second]
|
||||
<< " (remove latter)";
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if path is system/<partition>/
|
||||
if (android::base::StartsWith(path, alternate.c_str())) {
|
||||
// rebuild path to be <partition>/... to check for alias
|
||||
path = prefix + path.substr(alternate.size());
|
||||
for (second = 0; second < paths.size(); ++second) {
|
||||
if (path == paths[second]) break;
|
||||
}
|
||||
if (second >= paths.size()) {
|
||||
GTEST_LOG_(ERROR) << "replace path in " << config_name << ": " << paths[idx]
|
||||
<< " with " << path;
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool check_unique(const fs_path_config* paths, const char* type_name,
|
||||
const std::string& prefix) {
|
||||
std::string config("system/core/libcutils/fs_config.cpp:android_");
|
||||
config += type_name;
|
||||
config += "[]";
|
||||
|
||||
bool retval = false;
|
||||
std::vector<const char*> paths_tmp;
|
||||
for (size_t idx = 0; paths[idx].prefix; ++idx) {
|
||||
if (idx > max_idx) {
|
||||
GTEST_LOG_(WARNING) << config << ": has no end (missing null prefix)";
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
paths_tmp.push_back(paths[idx].prefix);
|
||||
}
|
||||
|
||||
return check_unique(paths_tmp, config, prefix) || retval;
|
||||
}
|
||||
|
||||
static bool check_fs_config_cmp(const fs_config_cmp_test* tests) {
|
||||
bool match, retval = false;
|
||||
for (size_t idx = 0; tests[idx].prefix; ++idx) {
|
||||
match = __for_testing_only__fs_config_cmp(tests[idx].dir, tests[idx].prefix,
|
||||
strlen(tests[idx].prefix), tests[idx].path,
|
||||
strlen(tests[idx].path));
|
||||
if (match != tests[idx].match) {
|
||||
GTEST_LOG_(ERROR) << tests[idx].path << (match ? " matched " : " didn't match ")
|
||||
<< tests[idx].prefix;
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define endof(pointer, field) (offsetof(typeof(*(pointer)), field) + sizeof((pointer)->field))
|
||||
|
||||
static bool check_unique(const std::string& config, const std::string& prefix) {
|
||||
int retval = false;
|
||||
|
||||
std::string data;
|
||||
if (!android::base::ReadFileToString(config, &data)) return retval;
|
||||
|
||||
const fs_path_config_from_file* pc =
|
||||
reinterpret_cast<const fs_path_config_from_file*>(data.c_str());
|
||||
size_t len = data.size();
|
||||
|
||||
std::vector<const char*> paths_tmp;
|
||||
size_t entry_number = 0;
|
||||
while (len > 0) {
|
||||
uint16_t host_len = (len >= endof(pc, len)) ? pc->len : INT16_MAX;
|
||||
if (host_len > len) {
|
||||
GTEST_LOG_(WARNING) << config << ": truncated at entry " << entry_number << " ("
|
||||
<< host_len << " > " << len << ")";
|
||||
const std::string unknown("?");
|
||||
GTEST_LOG_(WARNING)
|
||||
<< config << ": entry[" << entry_number << "]={ "
|
||||
<< "len=" << ((len >= endof(pc, len))
|
||||
? android::base::StringPrintf("%" PRIu16, pc->len)
|
||||
: unknown)
|
||||
<< ", mode=" << ((len >= endof(pc, mode))
|
||||
? android::base::StringPrintf("0%" PRIo16, pc->mode)
|
||||
: unknown)
|
||||
<< ", uid=" << ((len >= endof(pc, uid))
|
||||
? android::base::StringPrintf("%" PRIu16, pc->uid)
|
||||
: unknown)
|
||||
<< ", gid=" << ((len >= endof(pc, gid))
|
||||
? android::base::StringPrintf("%" PRIu16, pc->gid)
|
||||
: unknown)
|
||||
<< ", capabilities="
|
||||
<< ((len >= endof(pc, capabilities))
|
||||
? android::base::StringPrintf("0x%" PRIx64, pc->capabilities)
|
||||
: unknown)
|
||||
<< ", prefix="
|
||||
<< ((len >= offsetof(fs_path_config_from_file, prefix))
|
||||
? android::base::StringPrintf(
|
||||
"\"%.*s...", (int)(len - offsetof(fs_path_config_from_file, prefix)),
|
||||
pc->prefix)
|
||||
: unknown)
|
||||
<< " }";
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
paths_tmp.push_back(pc->prefix);
|
||||
|
||||
pc = reinterpret_cast<const fs_path_config_from_file*>(reinterpret_cast<const char*>(pc) +
|
||||
host_len);
|
||||
len -= host_len;
|
||||
++entry_number;
|
||||
}
|
||||
|
||||
return check_unique(paths_tmp, config, prefix) || retval;
|
||||
}
|
||||
|
||||
void check_two(const fs_path_config* paths, const char* type_name, const char* prefix) {
|
||||
ASSERT_FALSE(paths == nullptr);
|
||||
ASSERT_FALSE(type_name == nullptr);
|
||||
ASSERT_FALSE(prefix == nullptr);
|
||||
bool check_internal = check_unique(paths, type_name, prefix);
|
||||
EXPECT_FALSE(check_internal);
|
||||
bool check_overrides =
|
||||
check_unique(std::string("/") + prefix + "etc/fs_config_" + type_name, prefix);
|
||||
EXPECT_FALSE(check_overrides);
|
||||
}
|
||||
|
||||
TEST(fs_config, vendor_dirs_alias) {
|
||||
check_two(__for_testing_only__android_dirs, "dirs", "vendor/");
|
||||
}
|
||||
|
||||
TEST(fs_config, vendor_files_alias) {
|
||||
check_two(__for_testing_only__android_files, "files", "vendor/");
|
||||
}
|
||||
|
||||
TEST(fs_config, oem_dirs_alias) {
|
||||
check_two(__for_testing_only__android_dirs, "dirs", "oem/");
|
||||
}
|
||||
|
||||
TEST(fs_config, oem_files_alias) {
|
||||
check_two(__for_testing_only__android_files, "files", "oem/");
|
||||
}
|
||||
|
||||
TEST(fs_config, odm_dirs_alias) {
|
||||
check_two(__for_testing_only__android_dirs, "dirs", "odm/");
|
||||
}
|
||||
|
||||
TEST(fs_config, odm_files_alias) {
|
||||
check_two(__for_testing_only__android_files, "files", "odm/");
|
||||
}
|
||||
|
||||
TEST(fs_config, system_alias) {
|
||||
EXPECT_FALSE(check_fs_config_cmp(fs_config_cmp_tests));
|
||||
}
|
91
android/system/core/libcutils/tests/multiuser_test.cpp
Normal file
91
android/system/core/libcutils/tests/multiuser_test.cpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cutils/multiuser.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
static constexpr auto ERR_GID = static_cast<gid_t>(-1);
|
||||
|
||||
TEST(MultiuserTest, TestMerge) {
|
||||
EXPECT_EQ(0U, multiuser_get_uid(0, 0));
|
||||
EXPECT_EQ(1000U, multiuser_get_uid(0, 1000));
|
||||
EXPECT_EQ(10000U, multiuser_get_uid(0, 10000));
|
||||
EXPECT_EQ(50000U, multiuser_get_uid(0, 50000));
|
||||
EXPECT_EQ(1000000U, multiuser_get_uid(10, 0));
|
||||
EXPECT_EQ(1001000U, multiuser_get_uid(10, 1000));
|
||||
EXPECT_EQ(1010000U, multiuser_get_uid(10, 10000));
|
||||
EXPECT_EQ(1050000U, multiuser_get_uid(10, 50000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestSplitUser) {
|
||||
EXPECT_EQ(0U, multiuser_get_user_id(0));
|
||||
EXPECT_EQ(0U, multiuser_get_user_id(1000));
|
||||
EXPECT_EQ(0U, multiuser_get_user_id(10000));
|
||||
EXPECT_EQ(0U, multiuser_get_user_id(50000));
|
||||
EXPECT_EQ(10U, multiuser_get_user_id(1000000));
|
||||
EXPECT_EQ(10U, multiuser_get_user_id(1001000));
|
||||
EXPECT_EQ(10U, multiuser_get_user_id(1010000));
|
||||
EXPECT_EQ(10U, multiuser_get_user_id(1050000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestSplitApp) {
|
||||
EXPECT_EQ(0U, multiuser_get_app_id(0));
|
||||
EXPECT_EQ(1000U, multiuser_get_app_id(1000));
|
||||
EXPECT_EQ(10000U, multiuser_get_app_id(10000));
|
||||
EXPECT_EQ(50000U, multiuser_get_app_id(50000));
|
||||
EXPECT_EQ(0U, multiuser_get_app_id(1000000));
|
||||
EXPECT_EQ(1000U, multiuser_get_app_id(1001000));
|
||||
EXPECT_EQ(10000U, multiuser_get_app_id(1010000));
|
||||
EXPECT_EQ(50000U, multiuser_get_app_id(1050000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestCache) {
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 0));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 1000));
|
||||
EXPECT_EQ(20000U, multiuser_get_cache_gid(0, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 50000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 0));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 1000));
|
||||
EXPECT_EQ(1020000U, multiuser_get_cache_gid(10, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 50000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestExt) {
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_gid(0, 0));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_gid(0, 1000));
|
||||
EXPECT_EQ(30000U, multiuser_get_ext_gid(0, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_gid(0, 50000));
|
||||
EXPECT_EQ(1030000U, multiuser_get_ext_gid(10, 10000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestExtCache) {
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_cache_gid(0, 0));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_cache_gid(0, 1000));
|
||||
EXPECT_EQ(40000U, multiuser_get_ext_cache_gid(0, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_ext_cache_gid(0, 50000));
|
||||
EXPECT_EQ(1040000U, multiuser_get_ext_cache_gid(10, 10000));
|
||||
}
|
||||
|
||||
TEST(MultiuserTest, TestShared) {
|
||||
EXPECT_EQ(0U, multiuser_get_shared_gid(0, 0));
|
||||
EXPECT_EQ(1000U, multiuser_get_shared_gid(0, 1000));
|
||||
EXPECT_EQ(50000U, multiuser_get_shared_gid(0, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 50000));
|
||||
EXPECT_EQ(0U, multiuser_get_shared_gid(10, 0));
|
||||
EXPECT_EQ(1000U, multiuser_get_shared_gid(10, 1000));
|
||||
EXPECT_EQ(50000U, multiuser_get_shared_gid(10, 10000));
|
||||
EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(10, 50000));
|
||||
}
|
98
android/system/core/libcutils/tests/sched_policy_test.cpp
Normal file
98
android/system/core/libcutils/tests/sched_policy_test.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/capability.h>
|
||||
|
||||
#include <cutils/sched_policy.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
bool hasCapSysNice() {
|
||||
__user_cap_header_struct header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.version = _LINUX_CAPABILITY_VERSION_3;
|
||||
|
||||
__user_cap_data_struct caps[_LINUX_CAPABILITY_U32S_3];
|
||||
if (capget(&header, &caps[0])) {
|
||||
GTEST_LOG_(WARNING) << "failed to get process capabilities";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto nice_idx = CAP_TO_INDEX(CAP_SYS_NICE);
|
||||
auto nice_mask = CAP_TO_MASK(CAP_SYS_NICE);
|
||||
return caps[nice_idx].effective & nice_mask;
|
||||
}
|
||||
|
||||
long long medianSleepTime() {
|
||||
std::vector<long long> sleepTimes;
|
||||
constexpr size_t numSamples = 100;
|
||||
|
||||
for (size_t i = 0; i < numSamples; i++) {
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(1));
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
|
||||
auto diff = end - start;
|
||||
sleepTimes.push_back(diff.count());
|
||||
}
|
||||
|
||||
constexpr auto median = numSamples / 2;
|
||||
std::nth_element(sleepTimes.begin(), sleepTimes.begin() + median,
|
||||
sleepTimes.end());
|
||||
return sleepTimes[median];
|
||||
}
|
||||
|
||||
TEST(SchedPolicy, set_sched_policy) {
|
||||
if (!hasCapSysNice()) {
|
||||
GTEST_LOG_(INFO) << "skipping test that requires CAP_SYS_NICE";
|
||||
return;
|
||||
}
|
||||
|
||||
// A measureable effect of scheduling policy is that the kernel has 800x
|
||||
// greater slack time in waking up a sleeping background thread.
|
||||
//
|
||||
// Look for 100x difference in how long FB and BG threads actually sleep
|
||||
// when trying to sleep for 1 ns. This difference is large enough not
|
||||
// to happen by chance, but small enough (compared to 800x) to keep inherent
|
||||
// fuzziness in scheduler behavior from causing false negatives.
|
||||
const unsigned int BG_FG_SLACK_FACTOR = 100;
|
||||
|
||||
ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
|
||||
auto bgSleepTime = medianSleepTime();
|
||||
|
||||
ASSERT_EQ(0, set_sched_policy(0, SP_FOREGROUND));
|
||||
auto fgSleepTime = medianSleepTime();
|
||||
ASSERT_GT(bgSleepTime, fgSleepTime * BG_FG_SLACK_FACTOR);
|
||||
}
|
||||
|
||||
TEST(SchedPolicy, get_sched_policy) {
|
||||
SchedPolicy policy;
|
||||
ASSERT_EQ(0, get_sched_policy(0, &policy));
|
||||
|
||||
const char *policyName = get_sched_policy_name(policy);
|
||||
EXPECT_NE(nullptr, policyName);
|
||||
EXPECT_STRNE("error", policyName);
|
||||
|
||||
ASSERT_EQ(0, set_sched_policy(0, SP_BACKGROUND));
|
||||
SchedPolicy newPolicy;
|
||||
ASSERT_EQ(0, get_sched_policy(0, &newPolicy));
|
||||
EXPECT_EQ(SP_BACKGROUND, newPolicy);
|
||||
}
|
189
android/system/core/libcutils/tests/sockets_test.cpp
Normal file
189
android/system/core/libcutils/tests/sockets_test.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (C) 2015 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.
|
||||
*/
|
||||
|
||||
// Tests socket functionality using loopback connections. Requires IPv4 and
|
||||
// IPv6 capabilities. These tests assume that no UDP packets are lost, which
|
||||
// should be the case for loopback communication, but is not guaranteed.
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <cutils/sockets.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
// Makes sure the passed sockets are valid, sends data between them, and closes
|
||||
// them. Any failures are logged with gtest.
|
||||
//
|
||||
// On Mac recvfrom() will not fill in the address for TCP sockets, so we need
|
||||
// separate logic paths depending on socket type.
|
||||
static void TestConnectedSockets(cutils_socket_t server, cutils_socket_t client,
|
||||
int type) {
|
||||
ASSERT_NE(INVALID_SOCKET, server);
|
||||
ASSERT_NE(INVALID_SOCKET, client);
|
||||
|
||||
char buffer[128];
|
||||
sockaddr_storage addr;
|
||||
socklen_t addr_size = sizeof(addr);
|
||||
|
||||
// Send client -> server first to get the UDP client's address.
|
||||
ASSERT_EQ(3, send(client, "foo", 3, 0));
|
||||
if (type == SOCK_DGRAM) {
|
||||
EXPECT_EQ(3, recvfrom(server, buffer, sizeof(buffer), 0,
|
||||
reinterpret_cast<sockaddr*>(&addr), &addr_size));
|
||||
} else {
|
||||
EXPECT_EQ(3, recv(server, buffer, sizeof(buffer), 0));
|
||||
}
|
||||
EXPECT_EQ(0, memcmp(buffer, "foo", 3));
|
||||
|
||||
// Now send server -> client.
|
||||
if (type == SOCK_DGRAM) {
|
||||
ASSERT_EQ(3, sendto(server, "bar", 3, 0,
|
||||
reinterpret_cast<sockaddr*>(&addr), addr_size));
|
||||
} else {
|
||||
ASSERT_EQ(3, send(server, "bar", 3, 0));
|
||||
}
|
||||
EXPECT_EQ(3, recv(client, buffer, sizeof(buffer), 0));
|
||||
EXPECT_EQ(0, memcmp(buffer, "bar", 3));
|
||||
|
||||
// Send multiple buffers using socket_send_buffers().
|
||||
std::string data[] = {"foo", "bar", "12345"};
|
||||
cutils_socket_buffer_t socket_buffers[] = { {data[0].data(), data[0].length()},
|
||||
{data[1].data(), data[1].length()},
|
||||
{data[2].data(), data[2].length()} };
|
||||
EXPECT_EQ(11, socket_send_buffers(client, socket_buffers, 3));
|
||||
EXPECT_EQ(11, recv(server, buffer, sizeof(buffer), 0));
|
||||
EXPECT_EQ(0, memcmp(buffer, "foobar12345", 11));
|
||||
|
||||
EXPECT_EQ(0, socket_close(server));
|
||||
EXPECT_EQ(0, socket_close(client));
|
||||
}
|
||||
|
||||
// Tests receive timeout. The timing verification logic must be very coarse to
|
||||
// make sure different systems can all pass these tests.
|
||||
void TestReceiveTimeout(cutils_socket_t sock) {
|
||||
time_t start_time;
|
||||
char buffer[32];
|
||||
|
||||
// Make sure a 20ms timeout completes in 1 second or less.
|
||||
EXPECT_EQ(0, socket_set_receive_timeout(sock, 20));
|
||||
start_time = time(nullptr);
|
||||
EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
|
||||
EXPECT_LE(difftime(time(nullptr), start_time), 1.0);
|
||||
|
||||
// Make sure a 1250ms timeout takes 1 second or more.
|
||||
EXPECT_EQ(0, socket_set_receive_timeout(sock, 1250));
|
||||
start_time = time(nullptr);
|
||||
EXPECT_EQ(-1, recv(sock, buffer, sizeof(buffer), 0));
|
||||
EXPECT_LE(1.0, difftime(time(nullptr), start_time));
|
||||
}
|
||||
|
||||
// Tests socket_get_local_port().
|
||||
TEST(SocketsTest, TestGetLocalPort) {
|
||||
cutils_socket_t server;
|
||||
|
||||
// Check a bunch of ports so that we can ignore any conflicts in case
|
||||
// of ports already being taken, but if a server is able to start up we
|
||||
// should always be able to read its port.
|
||||
for (int port : {10000, 12345, 15999, 20202, 25000}) {
|
||||
for (int type : {SOCK_DGRAM, SOCK_STREAM}) {
|
||||
server = socket_inaddr_any_server(port, type);
|
||||
if (server != INVALID_SOCKET) {
|
||||
EXPECT_EQ(port, socket_get_local_port(server));
|
||||
}
|
||||
socket_close(server);
|
||||
}
|
||||
}
|
||||
|
||||
// Check expected failure for an invalid socket.
|
||||
EXPECT_EQ(-1, socket_get_local_port(INVALID_SOCKET));
|
||||
}
|
||||
|
||||
// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 UDP.
|
||||
TEST(SocketsTest, TestIpv4UdpLoopback) {
|
||||
cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
|
||||
cutils_socket_t client = socket_network_client(
|
||||
"127.0.0.1", socket_get_local_port(server), SOCK_DGRAM);
|
||||
|
||||
TestConnectedSockets(server, client, SOCK_DGRAM);
|
||||
}
|
||||
|
||||
// Tests socket_inaddr_any_server() and socket_network_client() for IPv4 TCP.
|
||||
TEST(SocketsTest, TestIpv4TcpLoopback) {
|
||||
cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
|
||||
ASSERT_NE(INVALID_SOCKET, server);
|
||||
|
||||
cutils_socket_t client = socket_network_client(
|
||||
"127.0.0.1", socket_get_local_port(server), SOCK_STREAM);
|
||||
cutils_socket_t handler = accept(server, nullptr, nullptr);
|
||||
EXPECT_EQ(0, socket_close(server));
|
||||
|
||||
TestConnectedSockets(handler, client, SOCK_STREAM);
|
||||
}
|
||||
|
||||
// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 UDP.
|
||||
TEST(SocketsTest, TestIpv6UdpLoopback) {
|
||||
cutils_socket_t server = socket_inaddr_any_server(0, SOCK_DGRAM);
|
||||
cutils_socket_t client = socket_network_client(
|
||||
"::1", socket_get_local_port(server), SOCK_DGRAM);
|
||||
|
||||
TestConnectedSockets(server, client, SOCK_DGRAM);
|
||||
}
|
||||
|
||||
// Tests socket_inaddr_any_server() and socket_network_client() for IPv6 TCP.
|
||||
TEST(SocketsTest, TestIpv6TcpLoopback) {
|
||||
cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
|
||||
ASSERT_NE(INVALID_SOCKET, server);
|
||||
|
||||
cutils_socket_t client = socket_network_client(
|
||||
"::1", socket_get_local_port(server), SOCK_STREAM);
|
||||
cutils_socket_t handler = accept(server, nullptr, nullptr);
|
||||
EXPECT_EQ(0, socket_close(server));
|
||||
|
||||
TestConnectedSockets(handler, client, SOCK_STREAM);
|
||||
}
|
||||
|
||||
// Tests setting a receive timeout for UDP sockets.
|
||||
TEST(SocketsTest, TestUdpReceiveTimeout) {
|
||||
cutils_socket_t sock = socket_inaddr_any_server(0, SOCK_DGRAM);
|
||||
ASSERT_NE(INVALID_SOCKET, sock);
|
||||
|
||||
TestReceiveTimeout(sock);
|
||||
|
||||
EXPECT_EQ(0, socket_close(sock));
|
||||
}
|
||||
|
||||
// Tests setting a receive timeout for TCP sockets.
|
||||
TEST(SocketsTest, TestTcpReceiveTimeout) {
|
||||
cutils_socket_t server = socket_inaddr_any_server(0, SOCK_STREAM);
|
||||
ASSERT_NE(INVALID_SOCKET, server);
|
||||
|
||||
cutils_socket_t client = socket_network_client(
|
||||
"localhost", socket_get_local_port(server), SOCK_STREAM);
|
||||
cutils_socket_t handler = accept(server, nullptr, nullptr);
|
||||
EXPECT_EQ(0, socket_close(server));
|
||||
|
||||
TestReceiveTimeout(handler);
|
||||
|
||||
EXPECT_EQ(0, socket_close(client));
|
||||
EXPECT_EQ(0, socket_close(handler));
|
||||
}
|
||||
|
||||
// Tests socket_send_buffers() failure.
|
||||
TEST(SocketsTest, TestSocketSendBuffersFailure) {
|
||||
EXPECT_EQ(-1, socket_send_buffers(INVALID_SOCKET, nullptr, 0));
|
||||
}
|
57
android/system/core/libcutils/tests/test_str_parms.cpp
Normal file
57
android/system/core/libcutils/tests/test_str_parms.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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 <cutils/str_parms.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
static void test_str_parms_str(const char* str, const char* expected) {
|
||||
str_parms* str_parms = str_parms_create_str(str);
|
||||
str_parms_add_str(str_parms, "dude", "woah");
|
||||
str_parms_add_str(str_parms, "dude", "woah");
|
||||
str_parms_del(str_parms, "dude");
|
||||
str_parms_dump(str_parms);
|
||||
char* out_str = str_parms_to_str(str_parms);
|
||||
str_parms_destroy(str_parms);
|
||||
ASSERT_STREQ(expected, out_str) << str;
|
||||
free(out_str);
|
||||
}
|
||||
|
||||
TEST(str_parms, smoke) {
|
||||
test_str_parms_str("", "");
|
||||
test_str_parms_str(";", "");
|
||||
test_str_parms_str("=", "");
|
||||
test_str_parms_str("=;", "");
|
||||
test_str_parms_str("=bar", "");
|
||||
test_str_parms_str("=bar;", "");
|
||||
test_str_parms_str("foo=", "foo=");
|
||||
test_str_parms_str("foo=;", "foo=");
|
||||
test_str_parms_str("foo=bar", "foo=bar");
|
||||
test_str_parms_str("foo=bar;", "foo=bar");
|
||||
test_str_parms_str("foo=bar;baz", "foo=bar;baz=");
|
||||
test_str_parms_str("foo=bar;baz=", "foo=bar;baz=");
|
||||
test_str_parms_str("foo=bar;baz=bat", "foo=bar;baz=bat");
|
||||
test_str_parms_str("foo=bar;baz=bat;", "foo=bar;baz=bat");
|
||||
test_str_parms_str("foo=bar1;baz=bat;foo=bar2", "foo=bar2;baz=bat");
|
||||
}
|
||||
|
||||
TEST(str_parms, put_ENOMEM) {
|
||||
// hashmapPut reports errors by setting errno to ENOMEM.
|
||||
// Test that we're not confused by running in an environment where this is already true.
|
||||
errno = ENOMEM;
|
||||
test_str_parms_str("foo=bar;baz=", "foo=bar;baz=");
|
||||
ASSERT_EQ(ENOMEM, errno);
|
||||
test_str_parms_str("foo=bar;baz=", "foo=bar;baz=");
|
||||
}
|
295
android/system/core/libcutils/tests/trace-dev_test.cpp
Normal file
295
android/system/core/libcutils/tests/trace-dev_test.cpp
Normal file
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/test_utils.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../trace-dev.c"
|
||||
|
||||
class TraceDevTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
lseek(tmp_file_.fd, 0, SEEK_SET);
|
||||
atrace_marker_fd = tmp_file_.fd;
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
atrace_marker_fd = -1;
|
||||
}
|
||||
|
||||
TemporaryFile tmp_file_;
|
||||
|
||||
static std::string MakeName(size_t length) {
|
||||
std::string name;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
name += '0' + (i % 10);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TraceDevTest, atrace_begin_body_normal) {
|
||||
atrace_begin_body("fake_name");
|
||||
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
std::string expected = android::base::StringPrintf("B|%d|fake_name", getpid());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_begin_body_exact) {
|
||||
std::string expected = android::base::StringPrintf("B|%d|", getpid());
|
||||
std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1);
|
||||
atrace_begin_body(name.c_str());
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
expected += name;
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
|
||||
// Add a single character and verify we get the exact same value as before.
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
name += '*';
|
||||
atrace_begin_body(name.c_str());
|
||||
EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_begin_body_truncated) {
|
||||
std::string expected = android::base::StringPrintf("B|%d|", getpid());
|
||||
std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
|
||||
atrace_begin_body(name.c_str());
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1;
|
||||
expected += android::base::StringPrintf("%.*s", expected_len, name.c_str());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_begin_body_normal) {
|
||||
atrace_async_begin_body("fake_name", 12345);
|
||||
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
std::string expected = android::base::StringPrintf("S|%d|fake_name|12345", getpid());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_begin_body_exact) {
|
||||
std::string expected = android::base::StringPrintf("S|%d|", getpid());
|
||||
std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
|
||||
atrace_async_begin_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
expected += name + "|12345";
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
|
||||
// Add a single character and verify we get the exact same value as before.
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
name += '*';
|
||||
atrace_async_begin_body(name.c_str(), 12345);
|
||||
EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_begin_body_truncated) {
|
||||
std::string expected = android::base::StringPrintf("S|%d|", getpid());
|
||||
std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
|
||||
atrace_async_begin_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
|
||||
expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_end_body_normal) {
|
||||
atrace_async_end_body("fake_name", 12345);
|
||||
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
std::string expected = android::base::StringPrintf("F|%d|fake_name|12345", getpid());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_end_body_exact) {
|
||||
std::string expected = android::base::StringPrintf("F|%d|", getpid());
|
||||
std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
|
||||
atrace_async_end_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
expected += name + "|12345";
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
|
||||
// Add a single character and verify we get the exact same value as before.
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
name += '*';
|
||||
atrace_async_end_body(name.c_str(), 12345);
|
||||
EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_async_end_body_truncated) {
|
||||
std::string expected = android::base::StringPrintf("F|%d|", getpid());
|
||||
std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
|
||||
atrace_async_end_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
|
||||
expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int_body_normal) {
|
||||
atrace_int_body("fake_name", 12345);
|
||||
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
std::string expected = android::base::StringPrintf("C|%d|fake_name|12345", getpid());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int_body_exact) {
|
||||
std::string expected = android::base::StringPrintf("C|%d|", getpid());
|
||||
std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
|
||||
atrace_int_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
expected += name + "|12345";
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
|
||||
// Add a single character and verify we get the exact same value as before.
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
name += '*';
|
||||
atrace_int_body(name.c_str(), 12345);
|
||||
EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int_body_truncated) {
|
||||
std::string expected = android::base::StringPrintf("C|%d|", getpid());
|
||||
std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
|
||||
atrace_int_body(name.c_str(), 12345);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
|
||||
expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int64_body_normal) {
|
||||
atrace_int64_body("fake_name", 17179869183L);
|
||||
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
std::string expected = android::base::StringPrintf("C|%d|fake_name|17179869183", getpid());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int64_body_exact) {
|
||||
std::string expected = android::base::StringPrintf("C|%d|", getpid());
|
||||
std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 13);
|
||||
atrace_int64_body(name.c_str(), 17179869183L);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
expected += name + "|17179869183";
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
|
||||
// Add a single character and verify we get the exact same value as before.
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
name += '*';
|
||||
atrace_int64_body(name.c_str(), 17179869183L);
|
||||
EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
||||
|
||||
TEST_F(TraceDevTest, atrace_int64_body_truncated) {
|
||||
std::string expected = android::base::StringPrintf("C|%d|", getpid());
|
||||
std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
|
||||
atrace_int64_body(name.c_str(), 17179869183L);
|
||||
|
||||
ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
|
||||
ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
|
||||
|
||||
std::string actual;
|
||||
ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
|
||||
int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 13;
|
||||
expected += android::base::StringPrintf("%.*s|17179869183", expected_len, name.c_str());
|
||||
ASSERT_STREQ(expected.c_str(), actual.c_str());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue