Merge changes Ie4b641cd,I5502b71d,I68086ce4

* changes:
  libion: add apache license header to ion_test.c
  libion: initial unit tests
  libion: update ion_test.h
This commit is contained in:
Colin Cross 2013-12-27 00:22:54 +00:00 committed by Gerrit Code Review
commit c3e314a93c
13 changed files with 1526 additions and 1 deletions

View File

@ -16,3 +16,5 @@ LOCAL_MODULE_TAGS := optional tests
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_EXECUTABLE)
include $(call first-makefiles-under,$(LOCAL_PATH))

View File

@ -1,3 +1,19 @@
/*
* Copyright 2013 Google, Inc
*
* 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 <errno.h>
#include <fcntl.h>
#include <getopt.h>

View File

@ -27,10 +27,12 @@ struct ion_test_rw_data {
__u64 size;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
int write;
int __padding;
};
#define ION_IOC_MAGIC 'I'
#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define ION_IOC_TEST_SET_FD _IO(ION_IOC_MAGIC, 0xf0)
#define ION_IOC_TEST_DMA_MAPPING _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data)
#define ION_IOC_TEST_KERNEL_MAPPING _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data)
#endif
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */

View File

@ -32,6 +32,7 @@ struct ion_test_rw_data {
__u64 offset;
__u64 size;
int write;
int __padding;
};
#define ION_IOC_MAGIC 'I'

34
libion/tests/Android.mk Normal file
View File

@ -0,0 +1,34 @@
#
# Copyright (C) 2013 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)
include $(CLEAR_VARS)
LOCAL_MODULE := ion-unit-tests
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_CFLAGS += -g -Wall -Werror -std=gnu++11 -Wno-missing-field-initializers
LOCAL_SHARED_LIBRARIES += libion
LOCAL_STATIC_LIBRARIES += libgtest_main
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../kernel-headers
LOCAL_SRC_FILES := \
ion_test_fixture.cpp \
allocate_test.cpp \
formerly_valid_handle_test.cpp \
invalid_values_test.cpp \
map_test.cpp \
device_test.cpp \
exit_test.cpp
include $(BUILD_NATIVE_TEST)

View File

@ -0,0 +1,145 @@
/*
* Copyright (C) 2013 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/mman.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
class Allocate : public IonAllHeapsTest {
};
TEST_F(Allocate, Allocate)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ion_user_handle_t handle = 0;
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
ASSERT_TRUE(handle != 0);
ASSERT_EQ(0, ion_free(m_ionFd, handle));
}
}
}
TEST_F(Allocate, AllocateCached)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ion_user_handle_t handle = 0;
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &handle));
ASSERT_TRUE(handle != 0);
ASSERT_EQ(0, ion_free(m_ionFd, handle));
}
}
}
TEST_F(Allocate, AllocateCachedNeedsSync)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ion_user_handle_t handle = 0;
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED_NEEDS_SYNC, &handle));
ASSERT_TRUE(handle != 0);
ASSERT_EQ(0, ion_free(m_ionFd, handle));
}
}
}
TEST_F(Allocate, RepeatedAllocate)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ion_user_handle_t handle = 0;
for (unsigned int i = 0; i < 1024; i++) {
SCOPED_TRACE(::testing::Message() << "iteration " << i);
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
ASSERT_TRUE(handle != 0);
ASSERT_EQ(0, ion_free(m_ionFd, handle));
}
}
}
}
TEST_F(Allocate, Zeroed)
{
void *zeroes = calloc(4096, 1);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int fds[16];
for (unsigned int i = 0; i < 16; i++) {
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr = NULL;
ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
memset(ptr, 0xaa, 4096);
ASSERT_EQ(0, munmap(ptr, 4096));
fds[i] = map_fd;
}
for (unsigned int i = 0; i < 16; i++) {
ASSERT_EQ(0, close(fds[i]));
}
int newIonFd = ion_open();
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(newIonFd, 4096, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr = NULL;
ptr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, memcmp(ptr, zeroes, 4096));
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(zeroes);
}
TEST_F(Allocate, Large)
{
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
ion_user_handle_t handle = 0;
ASSERT_EQ(-ENOMEM, ion_alloc(m_ionFd, 3UL*1024*1024*1024, 0, heapMask, 0, &handle));
}
}

View File

@ -0,0 +1,568 @@
/*
* Copyright (C) 2013 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 <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/ion_test.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
#define ALIGN(x,y) (((x) + ((y) - 1)) & ~((y) - 1))
class Device : public IonAllHeapsTest {
public:
virtual void SetUp();
virtual void TearDown();
int m_deviceFd;
void readDMA(int fd, void *buf, size_t size);
void writeDMA(int fd, void *buf, size_t size);
void readKernel(int fd, void *buf, size_t size);
void writeKernel(int fd, void *buf, size_t size);
void blowCache();
void dirtyCache(void *ptr, size_t size);
};
void Device::SetUp()
{
IonAllHeapsTest::SetUp();
m_deviceFd = open("/dev/ion-test", O_RDWR);
ASSERT_GE(m_deviceFd, 0);
}
void Device::TearDown()
{
ASSERT_EQ(0, close(m_deviceFd));
IonAllHeapsTest::TearDown();
}
void Device::readDMA(int fd, void *buf, size_t size)
{
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
struct ion_test_rw_data ion_test_rw_data = {
.ptr = (uint64_t)buf,
.offset = 0,
.size = size,
.write = 0,
};
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data));
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
}
void Device::writeDMA(int fd, void *buf, size_t size)
{
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
struct ion_test_rw_data ion_test_rw_data = {
.ptr = (uint64_t)buf,
.offset = 0,
.size = size,
.write = 1,
};
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data));
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
}
void Device::readKernel(int fd, void *buf, size_t size)
{
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
struct ion_test_rw_data ion_test_rw_data = {
.ptr = (uint64_t)buf,
.offset = 0,
.size = size,
.write = 0,
};
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data));
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
}
void Device::writeKernel(int fd, void *buf, size_t size)
{
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd));
struct ion_test_rw_data ion_test_rw_data = {
.ptr = (uint64_t)buf,
.offset = 0,
.size = size,
.write = 1,
};
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data));
ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1));
}
void Device::blowCache()
{
const size_t bigger_than_cache = 8*1024*1024;
void *buf1 = malloc(bigger_than_cache);
void *buf2 = malloc(bigger_than_cache);
memset(buf1, 0xaa, bigger_than_cache);
memcpy(buf2, buf1, bigger_than_cache);
free(buf1);
free(buf2);
}
void Device::dirtyCache(void *ptr, size_t size)
{
/* try to dirty cache lines */
for (size_t i = size-1; i > 0; i--) {
((volatile char *)ptr)[i];
((char *)ptr)[i] = i;
}
}
TEST_F(Device, KernelReadCached)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
((char*)buf)[4096] = 0x12;
readKernel(map_fd, buf, 4096);
ASSERT_EQ(((char*)buf)[4096], 0x12);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, KernelWriteCached)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeKernel(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMAReadCached)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
readDMA(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMAWriteCached)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeDMA(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, KernelReadCachedNeedsSync)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
((char*)buf)[4096] = 0x12;
readKernel(map_fd, buf, 4096);
ASSERT_EQ(((char*)buf)[4096], 0x12);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, KernelWriteCachedNeedsSync)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeKernel(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMAReadCachedNeedsSync)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
ion_sync_fd(m_ionFd, map_fd);
readDMA(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMAWriteCachedNeedsSync)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeDMA(map_fd, buf, 4096);
ion_sync_fd(m_ionFd, map_fd);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, KernelRead)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = 0;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
((char*)buf)[4096] = 0x12;
readKernel(map_fd, buf, 4096);
ASSERT_EQ(((char*)buf)[4096], 0x12);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, KernelWrite)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = 0;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeKernel(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMARead)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = 0;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
for (int i = 0; i < 4096; i++)
((char *)ptr)[i] = i;
readDMA(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)buf)[i]);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, DMAWrite)
{
void *alloc = malloc(8192 + 1024);
void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024);
for (int i = 0; i < 4096; i++)
((char *)buf)[i] = i;
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = 0;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
writeDMA(map_fd, buf, 4096);
for (int i = 0; i < 4096; i++)
ASSERT_EQ((char)i, ((char *)ptr)[i]) << i;
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
free(alloc);
}
TEST_F(Device, IsCached)
{
void *buf = malloc(4096);
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
dirtyCache(ptr, 4096);
readDMA(map_fd, buf, 4096);
bool same = true;
for (int i = 4096-16; i >= 0; i -= 16)
if (((char *)buf)[i] != i)
same = false;
ASSERT_FALSE(same);
ASSERT_EQ(0, munmap(ptr, 4096));
ASSERT_EQ(0, close(map_fd));
}
}

227
libion/tests/exit_test.cpp Normal file
View File

@ -0,0 +1,227 @@
/*
* Copyright (C) 2013 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/mman.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
class Exit : public IonAllHeapsTest {
};
TEST_F(Exit, WithAlloc)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
ion_user_handle_t handle = 0;
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
ASSERT_TRUE(handle != 0);
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithAllocFd)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int handle_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &handle_fd));
ASSERT_NE(-1, handle_fd);
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithRepeatedAllocFd)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
for (unsigned int i = 0; i < 1024; i++) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ASSERT_EXIT({
int handle_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &handle_fd));
ASSERT_NE(-1, handle_fd);
exit(0);
}, ::testing::ExitedWithCode(0), "")
<< "failed on heap " << heapMask
<< " and size " << size
<< " on iteration " << i;
}
}
}
}
TEST_F(Exit, WithMapping)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithPartialMapping)
{
static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, munmap(ptr, size / 2));
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithMappingCached)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithPartialMappingCached)
{
static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, munmap(ptr, size / 2));
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithMappingNeedsSync)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}
TEST_F(Exit, WithPartialMappingNeedsSync)
{
static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
EXPECT_EXIT({
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, munmap(ptr, size / 2));
exit(0);
}, ::testing::ExitedWithCode(0), "");
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2013 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/mman.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
class FormerlyValidHandle : public IonTest {
public:
virtual void SetUp();
virtual void TearDown();
ion_user_handle_t m_handle;
};
void FormerlyValidHandle::SetUp()
{
IonTest::SetUp();
ASSERT_EQ(0, ion_alloc(m_ionFd, 4096, 0, 1/* ion_env->m_firstHeap */, 0, &m_handle));
ASSERT_TRUE(m_handle != 0);
ASSERT_EQ(0, ion_free(m_ionFd, m_handle));
}
void FormerlyValidHandle::TearDown()
{
m_handle = 0;
}
TEST_F(FormerlyValidHandle, free)
{
ASSERT_EQ(-EINVAL, ion_free(m_ionFd, m_handle));
}
TEST_F(FormerlyValidHandle, map)
{
int map_fd;
unsigned char *ptr;
ASSERT_EQ(-EINVAL, ion_map(m_ionFd, m_handle, 4096, PROT_READ, 0, 0, &ptr, &map_fd));
}
TEST_F(FormerlyValidHandle, share)
{
int share_fd;
ASSERT_EQ(-EINVAL, ion_share(m_ionFd, m_handle, &share_fd));
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (C) 2013 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/mman.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
class InvalidValues : public IonAllHeapsTest {
public:
virtual void SetUp();
virtual void TearDown();
ion_user_handle_t m_validHandle;
int m_validShareFd;
ion_user_handle_t const m_badHandle = -1;
};
void InvalidValues::SetUp()
{
IonAllHeapsTest::SetUp();
ASSERT_EQ(0, ion_alloc(m_ionFd, 4096, 0, m_firstHeap, 0, &m_validHandle))
<< m_ionFd << " " << m_firstHeap;
ASSERT_TRUE(m_validHandle != 0);
ASSERT_EQ(0, ion_share(m_ionFd, m_validHandle, &m_validShareFd));
}
void InvalidValues::TearDown()
{
ASSERT_EQ(0, ion_free(m_ionFd, m_validHandle));
ASSERT_EQ(0, close(m_validShareFd));
m_validHandle = 0;
IonAllHeapsTest::TearDown();
}
TEST_F(InvalidValues, ion_close)
{
EXPECT_EQ(-EBADF, ion_close(-1));
}
TEST_F(InvalidValues, ion_alloc)
{
ion_user_handle_t handle;
/* invalid ion_fd */
int ret = ion_alloc(0, 4096, 0, m_firstHeap, 0, &handle);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion_fd */
EXPECT_EQ(-EBADF, ion_alloc(-1, 4096, 0, m_firstHeap, 0, &handle));
/* no heaps */
EXPECT_EQ(-ENODEV, ion_alloc(m_ionFd, 4096, 0, 0, 0, &handle));
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
/* zero size */
EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 0, 0, heapMask, 0, &handle));
/* too large size */
EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, -1, 0, heapMask, 0, &handle));
/* bad alignment */
EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 4096, -1, heapMask, 0, &handle));
/* NULL handle */
EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 4096, 0, heapMask, 0, NULL));
}
}
TEST_F(InvalidValues, ion_alloc_fd)
{
int fd;
/* invalid ion_fd */
int ret = ion_alloc_fd(0, 4096, 0, m_firstHeap, 0, &fd);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion_fd */
EXPECT_EQ(-EBADF, ion_alloc_fd(-1, 4096, 0, m_firstHeap, 0, &fd));
/* no heaps */
EXPECT_EQ(-ENODEV, ion_alloc_fd(m_ionFd, 4096, 0, 0, 0, &fd));
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
/* zero size */
EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 0, 0, heapMask, 0, &fd));
/* too large size */
EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, -1, 0, heapMask, 0, &fd));
/* bad alignment */
EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 4096, -1, heapMask, 0, &fd));
/* NULL handle */
EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, 0, NULL));
}
}
TEST_F(InvalidValues, ion_free)
{
/* invalid ion fd */
int ret = ion_free(0, m_validHandle);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion fd */
EXPECT_EQ(-EBADF, ion_free(-1, m_validHandle));
/* zero handle */
EXPECT_EQ(-EINVAL, ion_free(m_ionFd, 0));
/* bad handle */
EXPECT_EQ(-EINVAL, ion_free(m_ionFd, m_badHandle));
}
TEST_F(InvalidValues, ion_map)
{
int map_fd;
unsigned char *ptr;
/* invalid ion fd */
int ret = ion_map(0, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion fd */
EXPECT_EQ(-EBADF, ion_map(-1, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd));
/* zero handle */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, 0, 4096, PROT_READ, 0, 0, &ptr, &map_fd));
/* bad handle */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_badHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd));
/* zero length */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 0, PROT_READ, 0, 0, &ptr, &map_fd));
/* bad prot */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, -1, 0, 0, &ptr, &map_fd));
/* bad offset */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, -1, &ptr, &map_fd));
/* NULL ptr */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, 0, NULL, &map_fd));
/* NULL map_fd */
EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, NULL));
}
TEST_F(InvalidValues, ion_share)
{
int share_fd;
/* invalid ion fd */
int ret = ion_share(0, m_validHandle, &share_fd);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion fd */
EXPECT_EQ(-EBADF, ion_share(-1, m_validHandle, &share_fd));
/* zero handle */
EXPECT_EQ(-EINVAL, ion_share(m_ionFd, 0, &share_fd));
/* bad handle */
EXPECT_EQ(-EINVAL, ion_share(m_ionFd, m_badHandle, &share_fd));
/* NULL share_fd */
EXPECT_EQ(-EINVAL, ion_share(m_ionFd, m_validHandle, NULL));
}
TEST_F(InvalidValues, ion_import)
{
ion_user_handle_t handle;
/* invalid ion fd */
int ret = ion_import(0, m_validShareFd, &handle);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion fd */
EXPECT_EQ(-EBADF, ion_import(-1, m_validShareFd, &handle));
/* bad share_fd */
EXPECT_EQ(-EINVAL, ion_import(m_ionFd, 0, &handle));
/* invalid share_fd */
EXPECT_EQ(-EBADF, ion_import(m_ionFd, -1, &handle));
/* NULL handle */
EXPECT_EQ(-EINVAL, ion_import(m_ionFd, m_validShareFd, NULL));
}
TEST_F(InvalidValues, ion_sync_fd)
{
/* invalid ion fd */
int ret = ion_sync_fd(0, m_validShareFd);
EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY);
/* invalid ion fd */
EXPECT_EQ(-EBADF, ion_sync_fd(-1, m_validShareFd));
/* bad share_fd */
EXPECT_EQ(-EINVAL, ion_sync_fd(m_ionFd, 0));
/* invalid share_fd */
EXPECT_EQ(-EBADF, ion_sync_fd(m_ionFd, -1));
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2013 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 <ion/ion.h>
#include "ion_test_fixture.h"
IonTest::IonTest() : m_ionFd(-1)
{
}
void IonTest::SetUp() {
m_ionFd = ion_open();
ASSERT_GE(m_ionFd, 0);
}
void IonTest::TearDown() {
ion_close(m_ionFd);
}
IonAllHeapsTest::IonAllHeapsTest() :
m_firstHeap(0),
m_lastHeap(0),
m_allHeaps()
{
}
void IonAllHeapsTest::SetUp() {
int fd = ion_open();
ASSERT_GE(fd, 0);
for (int i = 1; i != 0; i <<= 1) {
ion_user_handle_t handle = 0;
int ret;
ret = ion_alloc(fd, 4096, 0, i, 0, &handle);
if (ret == 0 && handle != 0) {
ion_free(fd, handle);
if (!m_firstHeap) {
m_firstHeap = i;
}
m_lastHeap = i;
m_allHeaps.push_back(i);
} else {
ASSERT_EQ(-ENODEV, ret);
}
}
ion_close(fd);
EXPECT_NE(0U, m_firstHeap);
EXPECT_NE(0U, m_lastHeap);
RecordProperty("Heaps", m_allHeaps.size());
IonTest::SetUp();
}
void IonAllHeapsTest::TearDown() {
IonTest::TearDown();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2013 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.
*/
#ifndef ION_TEST_FIXTURE_H_
#define ION_TEST_FIXTURE_H_
#include <gtest/gtest.h>
using ::testing::Test;
class IonTest : public virtual Test {
public:
IonTest();
virtual ~IonTest() {};
virtual void SetUp();
virtual void TearDown();
int m_ionFd;
};
class IonAllHeapsTest : public IonTest {
public:
IonAllHeapsTest();
virtual ~IonAllHeapsTest() {};
virtual void SetUp();
virtual void TearDown();
unsigned int m_firstHeap;
unsigned int m_lastHeap;
std::vector<unsigned int> m_allHeaps;
};
#endif /* ION_TEST_FIXTURE_H_ */

162
libion/tests/map_test.cpp Normal file
View File

@ -0,0 +1,162 @@
/*
* Copyright (C) 2013 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/mman.h>
#include <gtest/gtest.h>
#include <ion/ion.h>
#include "ion_test_fixture.h"
class Map : public IonAllHeapsTest {
};
TEST_F(Map, MapHandle)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
ion_user_handle_t handle = 0;
ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle));
ASSERT_TRUE(handle != 0);
int map_fd = -1;
unsigned char *ptr = NULL;
ASSERT_EQ(0, ion_map(m_ionFd, handle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, &ptr, &map_fd));
ASSERT_TRUE(ptr != NULL);
ASSERT_GE(map_fd, 0);
ASSERT_EQ(0, close(map_fd));
ASSERT_EQ(0, ion_free(m_ionFd, handle));
memset(ptr, 0xaa, size);
ASSERT_EQ(0, munmap(ptr, size));
}
}
}
TEST_F(Map, MapFd)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, close(map_fd));
memset(ptr, 0xaa, size);
ASSERT_EQ(0, munmap(ptr, size));
}
}
}
TEST_F(Map, MapOffset)
{
for (unsigned int heapMask : m_allHeaps) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
int map_fd = -1;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, PAGE_SIZE * 2, 0, heapMask, 0, &map_fd));
ASSERT_GE(map_fd, 0);
unsigned char *ptr;
ptr = (unsigned char *)mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
memset(ptr, 0, PAGE_SIZE);
memset(ptr + PAGE_SIZE, 0xaa, PAGE_SIZE);
ASSERT_EQ(0, munmap(ptr, PAGE_SIZE * 2));
ptr = (unsigned char *)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, PAGE_SIZE);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(ptr[0], 0xaa);
ASSERT_EQ(ptr[PAGE_SIZE - 1], 0xaa);
ASSERT_EQ(0, munmap(ptr, PAGE_SIZE));
ASSERT_EQ(0, close(map_fd));
}
}
TEST_F(Map, MapCached)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, close(map_fd));
memset(ptr, 0xaa, size);
ASSERT_EQ(0, munmap(ptr, size));
}
}
}
TEST_F(Map, MapCachedNeedsSync)
{
static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024};
for (unsigned int heapMask : m_allHeaps) {
for (size_t size : allocationSizes) {
SCOPED_TRACE(::testing::Message() << "heap " << heapMask);
SCOPED_TRACE(::testing::Message() << "size " << size);
int map_fd = -1;
unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, flags, &map_fd));
ASSERT_GE(map_fd, 0);
void *ptr;
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0);
ASSERT_TRUE(ptr != NULL);
ASSERT_EQ(0, close(map_fd));
memset(ptr, 0xaa, size);
ASSERT_EQ(0, munmap(ptr, size));
}
}
}