diff options
author | Colin Cross | 2013-11-08 01:06:58 -0600 |
---|---|---|
committer | Colin Cross | 2013-12-19 21:31:46 -0600 |
commit | 363441b120aa7ff4ec7c639bac099e775c2ace69 (patch) | |
tree | 4aef851bb4d982f88748694f9e67baf6e480ed84 /libion | |
parent | b04f75ab129e471eb0b45571f0c319c516de0c02 (diff) | |
download | platform-system-core-363441b120aa7ff4ec7c639bac099e775c2ace69.tar.gz platform-system-core-363441b120aa7ff4ec7c639bac099e775c2ace69.tar.xz platform-system-core-363441b120aa7ff4ec7c639bac099e775c2ace69.zip |
libion: initial unit tests
Change-Id: I5502b71d0c7c24d7fd59e4880033657f840b341a
Diffstat (limited to 'libion')
-rw-r--r-- | libion/Android.mk | 2 | ||||
-rw-r--r-- | libion/tests/Android.mk | 34 | ||||
-rw-r--r-- | libion/tests/allocate_test.cpp | 145 | ||||
-rw-r--r-- | libion/tests/device_test.cpp | 568 | ||||
-rw-r--r-- | libion/tests/exit_test.cpp | 227 | ||||
-rw-r--r-- | libion/tests/formerly_valid_handle_test.cpp | 63 | ||||
-rw-r--r-- | libion/tests/invalid_values_test.cpp | 186 | ||||
-rw-r--r-- | libion/tests/ion_test_fixture.cpp | 73 | ||||
-rw-r--r-- | libion/tests/ion_test_fixture.h | 46 | ||||
-rw-r--r-- | libion/tests/map_test.cpp | 162 |
10 files changed, 1506 insertions, 0 deletions
diff --git a/libion/Android.mk b/libion/Android.mk index 42e6f0710..e5d495b2f 100644 --- a/libion/Android.mk +++ b/libion/Android.mk | |||
@@ -16,3 +16,5 @@ LOCAL_MODULE_TAGS := optional tests | |||
16 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers | 16 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers |
17 | LOCAL_SHARED_LIBRARIES := liblog | 17 | LOCAL_SHARED_LIBRARIES := liblog |
18 | include $(BUILD_EXECUTABLE) | 18 | include $(BUILD_EXECUTABLE) |
19 | |||
20 | include $(call first-makefiles-under,$(LOCAL_PATH)) | ||
diff --git a/libion/tests/Android.mk b/libion/tests/Android.mk new file mode 100644 index 000000000..8dc7f9d1d --- /dev/null +++ b/libion/tests/Android.mk | |||
@@ -0,0 +1,34 @@ | |||
1 | # | ||
2 | # Copyright (C) 2013 The Android Open Source Project | ||
3 | # | ||
4 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | # you may not use this file except in compliance with the License. | ||
6 | # You may obtain a copy of the License at | ||
7 | # | ||
8 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | # | ||
10 | # Unless required by applicable law or agreed to in writing, software | ||
11 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | # See the License for the specific language governing permissions and | ||
14 | # limitations under the License. | ||
15 | # | ||
16 | |||
17 | LOCAL_PATH:= $(call my-dir) | ||
18 | |||
19 | include $(CLEAR_VARS) | ||
20 | LOCAL_MODULE := ion-unit-tests | ||
21 | LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk | ||
22 | LOCAL_CFLAGS += -g -Wall -Werror -std=gnu++11 -Wno-missing-field-initializers | ||
23 | LOCAL_SHARED_LIBRARIES += libion | ||
24 | LOCAL_STATIC_LIBRARIES += libgtest_main | ||
25 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/../kernel-headers | ||
26 | LOCAL_SRC_FILES := \ | ||
27 | ion_test_fixture.cpp \ | ||
28 | allocate_test.cpp \ | ||
29 | formerly_valid_handle_test.cpp \ | ||
30 | invalid_values_test.cpp \ | ||
31 | map_test.cpp \ | ||
32 | device_test.cpp \ | ||
33 | exit_test.cpp | ||
34 | include $(BUILD_NATIVE_TEST) | ||
diff --git a/libion/tests/allocate_test.cpp b/libion/tests/allocate_test.cpp new file mode 100644 index 000000000..e26b30205 --- /dev/null +++ b/libion/tests/allocate_test.cpp | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <sys/mman.h> | ||
18 | |||
19 | #include <gtest/gtest.h> | ||
20 | |||
21 | #include <ion/ion.h> | ||
22 | #include "ion_test_fixture.h" | ||
23 | |||
24 | class Allocate : public IonAllHeapsTest { | ||
25 | }; | ||
26 | |||
27 | TEST_F(Allocate, Allocate) | ||
28 | { | ||
29 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
30 | for (unsigned int heapMask : m_allHeaps) { | ||
31 | for (size_t size : allocationSizes) { | ||
32 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
33 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
34 | ion_user_handle_t handle = 0; | ||
35 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle)); | ||
36 | ASSERT_TRUE(handle != 0); | ||
37 | ASSERT_EQ(0, ion_free(m_ionFd, handle)); | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | |||
42 | TEST_F(Allocate, AllocateCached) | ||
43 | { | ||
44 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
45 | for (unsigned int heapMask : m_allHeaps) { | ||
46 | for (size_t size : allocationSizes) { | ||
47 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
48 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
49 | ion_user_handle_t handle = 0; | ||
50 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &handle)); | ||
51 | ASSERT_TRUE(handle != 0); | ||
52 | ASSERT_EQ(0, ion_free(m_ionFd, handle)); | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | |||
57 | TEST_F(Allocate, AllocateCachedNeedsSync) | ||
58 | { | ||
59 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
60 | for (unsigned int heapMask : m_allHeaps) { | ||
61 | for (size_t size : allocationSizes) { | ||
62 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
63 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
64 | ion_user_handle_t handle = 0; | ||
65 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED_NEEDS_SYNC, &handle)); | ||
66 | ASSERT_TRUE(handle != 0); | ||
67 | ASSERT_EQ(0, ion_free(m_ionFd, handle)); | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | TEST_F(Allocate, RepeatedAllocate) | ||
73 | { | ||
74 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
75 | for (unsigned int heapMask : m_allHeaps) { | ||
76 | for (size_t size : allocationSizes) { | ||
77 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
78 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
79 | ion_user_handle_t handle = 0; | ||
80 | |||
81 | for (unsigned int i = 0; i < 1024; i++) { | ||
82 | SCOPED_TRACE(::testing::Message() << "iteration " << i); | ||
83 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle)); | ||
84 | ASSERT_TRUE(handle != 0); | ||
85 | ASSERT_EQ(0, ion_free(m_ionFd, handle)); | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | |||
91 | TEST_F(Allocate, Zeroed) | ||
92 | { | ||
93 | void *zeroes = calloc(4096, 1); | ||
94 | |||
95 | for (unsigned int heapMask : m_allHeaps) { | ||
96 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
97 | int fds[16]; | ||
98 | for (unsigned int i = 0; i < 16; i++) { | ||
99 | int map_fd = -1; | ||
100 | |||
101 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, 0, &map_fd)); | ||
102 | ASSERT_GE(map_fd, 0); | ||
103 | |||
104 | void *ptr = NULL; | ||
105 | ptr = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
106 | ASSERT_TRUE(ptr != NULL); | ||
107 | |||
108 | memset(ptr, 0xaa, 4096); | ||
109 | |||
110 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
111 | fds[i] = map_fd; | ||
112 | } | ||
113 | |||
114 | for (unsigned int i = 0; i < 16; i++) { | ||
115 | ASSERT_EQ(0, close(fds[i])); | ||
116 | } | ||
117 | |||
118 | int newIonFd = ion_open(); | ||
119 | int map_fd = -1; | ||
120 | |||
121 | ASSERT_EQ(0, ion_alloc_fd(newIonFd, 4096, 0, heapMask, 0, &map_fd)); | ||
122 | ASSERT_GE(map_fd, 0); | ||
123 | |||
124 | void *ptr = NULL; | ||
125 | ptr = mmap(NULL, 4096, PROT_READ, MAP_SHARED, map_fd, 0); | ||
126 | ASSERT_TRUE(ptr != NULL); | ||
127 | |||
128 | ASSERT_EQ(0, memcmp(ptr, zeroes, 4096)); | ||
129 | |||
130 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
131 | ASSERT_EQ(0, close(map_fd)); | ||
132 | } | ||
133 | |||
134 | free(zeroes); | ||
135 | |||
136 | } | ||
137 | |||
138 | TEST_F(Allocate, Large) | ||
139 | { | ||
140 | for (unsigned int heapMask : m_allHeaps) { | ||
141 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
142 | ion_user_handle_t handle = 0; | ||
143 | ASSERT_EQ(-ENOMEM, ion_alloc(m_ionFd, 3UL*1024*1024*1024, 0, heapMask, 0, &handle)); | ||
144 | } | ||
145 | } | ||
diff --git a/libion/tests/device_test.cpp b/libion/tests/device_test.cpp new file mode 100644 index 000000000..6f6e1bdcf --- /dev/null +++ b/libion/tests/device_test.cpp | |||
@@ -0,0 +1,568 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <fcntl.h> | ||
18 | #include <sys/mman.h> | ||
19 | #include <sys/stat.h> | ||
20 | #include <sys/types.h> | ||
21 | |||
22 | #include <linux/ion_test.h> | ||
23 | |||
24 | #include <gtest/gtest.h> | ||
25 | |||
26 | #include <ion/ion.h> | ||
27 | |||
28 | #include "ion_test_fixture.h" | ||
29 | |||
30 | #define ALIGN(x,y) (((x) + ((y) - 1)) & ~((y) - 1)) | ||
31 | |||
32 | class Device : public IonAllHeapsTest { | ||
33 | public: | ||
34 | virtual void SetUp(); | ||
35 | virtual void TearDown(); | ||
36 | int m_deviceFd; | ||
37 | void readDMA(int fd, void *buf, size_t size); | ||
38 | void writeDMA(int fd, void *buf, size_t size); | ||
39 | void readKernel(int fd, void *buf, size_t size); | ||
40 | void writeKernel(int fd, void *buf, size_t size); | ||
41 | void blowCache(); | ||
42 | void dirtyCache(void *ptr, size_t size); | ||
43 | }; | ||
44 | |||
45 | void Device::SetUp() | ||
46 | { | ||
47 | IonAllHeapsTest::SetUp(); | ||
48 | m_deviceFd = open("/dev/ion-test", O_RDWR); | ||
49 | ASSERT_GE(m_deviceFd, 0); | ||
50 | } | ||
51 | |||
52 | void Device::TearDown() | ||
53 | { | ||
54 | ASSERT_EQ(0, close(m_deviceFd)); | ||
55 | IonAllHeapsTest::TearDown(); | ||
56 | } | ||
57 | |||
58 | void Device::readDMA(int fd, void *buf, size_t size) | ||
59 | { | ||
60 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd)); | ||
61 | struct ion_test_rw_data ion_test_rw_data = { | ||
62 | .ptr = (uint64_t)buf, | ||
63 | .offset = 0, | ||
64 | .size = size, | ||
65 | .write = 0, | ||
66 | }; | ||
67 | |||
68 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data)); | ||
69 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1)); | ||
70 | } | ||
71 | |||
72 | void Device::writeDMA(int fd, void *buf, size_t size) | ||
73 | { | ||
74 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd)); | ||
75 | struct ion_test_rw_data ion_test_rw_data = { | ||
76 | .ptr = (uint64_t)buf, | ||
77 | .offset = 0, | ||
78 | .size = size, | ||
79 | .write = 1, | ||
80 | }; | ||
81 | |||
82 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_DMA_MAPPING, &ion_test_rw_data)); | ||
83 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1)); | ||
84 | } | ||
85 | |||
86 | void Device::readKernel(int fd, void *buf, size_t size) | ||
87 | { | ||
88 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd)); | ||
89 | struct ion_test_rw_data ion_test_rw_data = { | ||
90 | .ptr = (uint64_t)buf, | ||
91 | .offset = 0, | ||
92 | .size = size, | ||
93 | .write = 0, | ||
94 | }; | ||
95 | |||
96 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data)); | ||
97 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1)); | ||
98 | } | ||
99 | |||
100 | void Device::writeKernel(int fd, void *buf, size_t size) | ||
101 | { | ||
102 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, fd)); | ||
103 | struct ion_test_rw_data ion_test_rw_data = { | ||
104 | .ptr = (uint64_t)buf, | ||
105 | .offset = 0, | ||
106 | .size = size, | ||
107 | .write = 1, | ||
108 | }; | ||
109 | |||
110 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_KERNEL_MAPPING, &ion_test_rw_data)); | ||
111 | ASSERT_EQ(0, ioctl(m_deviceFd, ION_IOC_TEST_SET_FD, -1)); | ||
112 | } | ||
113 | |||
114 | void Device::blowCache() | ||
115 | { | ||
116 | const size_t bigger_than_cache = 8*1024*1024; | ||
117 | void *buf1 = malloc(bigger_than_cache); | ||
118 | void *buf2 = malloc(bigger_than_cache); | ||
119 | memset(buf1, 0xaa, bigger_than_cache); | ||
120 | memcpy(buf2, buf1, bigger_than_cache); | ||
121 | free(buf1); | ||
122 | free(buf2); | ||
123 | } | ||
124 | |||
125 | void Device::dirtyCache(void *ptr, size_t size) | ||
126 | { | ||
127 | /* try to dirty cache lines */ | ||
128 | for (size_t i = size-1; i > 0; i--) { | ||
129 | ((volatile char *)ptr)[i]; | ||
130 | ((char *)ptr)[i] = i; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | TEST_F(Device, KernelReadCached) | ||
135 | { | ||
136 | void *alloc = malloc(8192 + 1024); | ||
137 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
138 | |||
139 | for (unsigned int heapMask : m_allHeaps) { | ||
140 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
141 | int map_fd = -1; | ||
142 | unsigned int flags = ION_FLAG_CACHED; | ||
143 | |||
144 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
145 | ASSERT_GE(map_fd, 0); | ||
146 | |||
147 | void *ptr; | ||
148 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
149 | ASSERT_TRUE(ptr != NULL); | ||
150 | |||
151 | for (int i = 0; i < 4096; i++) | ||
152 | ((char *)ptr)[i] = i; | ||
153 | |||
154 | ((char*)buf)[4096] = 0x12; | ||
155 | readKernel(map_fd, buf, 4096); | ||
156 | ASSERT_EQ(((char*)buf)[4096], 0x12); | ||
157 | |||
158 | for (int i = 0; i < 4096; i++) | ||
159 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
160 | |||
161 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
162 | ASSERT_EQ(0, close(map_fd)); | ||
163 | } | ||
164 | |||
165 | free(alloc); | ||
166 | } | ||
167 | |||
168 | TEST_F(Device, KernelWriteCached) | ||
169 | { | ||
170 | void *alloc = malloc(8192 + 1024); | ||
171 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
172 | |||
173 | for (int i = 0; i < 4096; i++) | ||
174 | ((char *)buf)[i] = i; | ||
175 | |||
176 | for (unsigned int heapMask : m_allHeaps) { | ||
177 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
178 | int map_fd = -1; | ||
179 | unsigned int flags = ION_FLAG_CACHED; | ||
180 | |||
181 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
182 | ASSERT_GE(map_fd, 0); | ||
183 | |||
184 | void *ptr; | ||
185 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
186 | ASSERT_TRUE(ptr != NULL); | ||
187 | |||
188 | dirtyCache(ptr, 4096); | ||
189 | |||
190 | writeKernel(map_fd, buf, 4096); | ||
191 | |||
192 | for (int i = 0; i < 4096; i++) | ||
193 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
194 | |||
195 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
196 | ASSERT_EQ(0, close(map_fd)); | ||
197 | } | ||
198 | |||
199 | free(alloc); | ||
200 | } | ||
201 | |||
202 | TEST_F(Device, DMAReadCached) | ||
203 | { | ||
204 | void *alloc = malloc(8192 + 1024); | ||
205 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
206 | |||
207 | for (unsigned int heapMask : m_allHeaps) { | ||
208 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
209 | int map_fd = -1; | ||
210 | unsigned int flags = ION_FLAG_CACHED; | ||
211 | |||
212 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
213 | ASSERT_GE(map_fd, 0); | ||
214 | |||
215 | void *ptr; | ||
216 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
217 | ASSERT_TRUE(ptr != NULL); | ||
218 | |||
219 | for (int i = 0; i < 4096; i++) | ||
220 | ((char *)ptr)[i] = i; | ||
221 | |||
222 | readDMA(map_fd, buf, 4096); | ||
223 | |||
224 | for (int i = 0; i < 4096; i++) | ||
225 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
226 | |||
227 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
228 | ASSERT_EQ(0, close(map_fd)); | ||
229 | } | ||
230 | |||
231 | free(alloc); | ||
232 | } | ||
233 | |||
234 | TEST_F(Device, DMAWriteCached) | ||
235 | { | ||
236 | void *alloc = malloc(8192 + 1024); | ||
237 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
238 | |||
239 | for (int i = 0; i < 4096; i++) | ||
240 | ((char *)buf)[i] = i; | ||
241 | |||
242 | for (unsigned int heapMask : m_allHeaps) { | ||
243 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
244 | int map_fd = -1; | ||
245 | unsigned int flags = ION_FLAG_CACHED; | ||
246 | |||
247 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
248 | ASSERT_GE(map_fd, 0); | ||
249 | |||
250 | void *ptr; | ||
251 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
252 | ASSERT_TRUE(ptr != NULL); | ||
253 | |||
254 | dirtyCache(ptr, 4096); | ||
255 | |||
256 | writeDMA(map_fd, buf, 4096); | ||
257 | |||
258 | for (int i = 0; i < 4096; i++) | ||
259 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
260 | |||
261 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
262 | ASSERT_EQ(0, close(map_fd)); | ||
263 | } | ||
264 | |||
265 | free(alloc); | ||
266 | } | ||
267 | |||
268 | TEST_F(Device, KernelReadCachedNeedsSync) | ||
269 | { | ||
270 | void *alloc = malloc(8192 + 1024); | ||
271 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
272 | |||
273 | for (unsigned int heapMask : m_allHeaps) { | ||
274 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
275 | int map_fd = -1; | ||
276 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
277 | |||
278 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
279 | ASSERT_GE(map_fd, 0); | ||
280 | |||
281 | void *ptr; | ||
282 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
283 | ASSERT_TRUE(ptr != NULL); | ||
284 | |||
285 | for (int i = 0; i < 4096; i++) | ||
286 | ((char *)ptr)[i] = i; | ||
287 | |||
288 | ((char*)buf)[4096] = 0x12; | ||
289 | readKernel(map_fd, buf, 4096); | ||
290 | ASSERT_EQ(((char*)buf)[4096], 0x12); | ||
291 | |||
292 | for (int i = 0; i < 4096; i++) | ||
293 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
294 | |||
295 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
296 | ASSERT_EQ(0, close(map_fd)); | ||
297 | } | ||
298 | |||
299 | free(alloc); | ||
300 | } | ||
301 | |||
302 | TEST_F(Device, KernelWriteCachedNeedsSync) | ||
303 | { | ||
304 | void *alloc = malloc(8192 + 1024); | ||
305 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
306 | |||
307 | for (int i = 0; i < 4096; i++) | ||
308 | ((char *)buf)[i] = i; | ||
309 | |||
310 | for (unsigned int heapMask : m_allHeaps) { | ||
311 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
312 | int map_fd = -1; | ||
313 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
314 | |||
315 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
316 | ASSERT_GE(map_fd, 0); | ||
317 | |||
318 | void *ptr; | ||
319 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
320 | ASSERT_TRUE(ptr != NULL); | ||
321 | |||
322 | dirtyCache(ptr, 4096); | ||
323 | |||
324 | writeKernel(map_fd, buf, 4096); | ||
325 | |||
326 | for (int i = 0; i < 4096; i++) | ||
327 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
328 | |||
329 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
330 | ASSERT_EQ(0, close(map_fd)); | ||
331 | } | ||
332 | |||
333 | free(alloc); | ||
334 | } | ||
335 | |||
336 | TEST_F(Device, DMAReadCachedNeedsSync) | ||
337 | { | ||
338 | void *alloc = malloc(8192 + 1024); | ||
339 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
340 | |||
341 | for (unsigned int heapMask : m_allHeaps) { | ||
342 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
343 | int map_fd = -1; | ||
344 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
345 | |||
346 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
347 | ASSERT_GE(map_fd, 0); | ||
348 | |||
349 | void *ptr; | ||
350 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
351 | ASSERT_TRUE(ptr != NULL); | ||
352 | |||
353 | for (int i = 0; i < 4096; i++) | ||
354 | ((char *)ptr)[i] = i; | ||
355 | |||
356 | ion_sync_fd(m_ionFd, map_fd); | ||
357 | |||
358 | readDMA(map_fd, buf, 4096); | ||
359 | |||
360 | for (int i = 0; i < 4096; i++) | ||
361 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
362 | |||
363 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
364 | ASSERT_EQ(0, close(map_fd)); | ||
365 | } | ||
366 | |||
367 | free(alloc); | ||
368 | } | ||
369 | |||
370 | TEST_F(Device, DMAWriteCachedNeedsSync) | ||
371 | { | ||
372 | void *alloc = malloc(8192 + 1024); | ||
373 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
374 | |||
375 | for (int i = 0; i < 4096; i++) | ||
376 | ((char *)buf)[i] = i; | ||
377 | |||
378 | for (unsigned int heapMask : m_allHeaps) { | ||
379 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
380 | int map_fd = -1; | ||
381 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
382 | |||
383 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
384 | ASSERT_GE(map_fd, 0); | ||
385 | |||
386 | void *ptr; | ||
387 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
388 | ASSERT_TRUE(ptr != NULL); | ||
389 | |||
390 | dirtyCache(ptr, 4096); | ||
391 | |||
392 | writeDMA(map_fd, buf, 4096); | ||
393 | |||
394 | ion_sync_fd(m_ionFd, map_fd); | ||
395 | |||
396 | for (int i = 0; i < 4096; i++) | ||
397 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
398 | |||
399 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
400 | ASSERT_EQ(0, close(map_fd)); | ||
401 | } | ||
402 | |||
403 | free(alloc); | ||
404 | } | ||
405 | TEST_F(Device, KernelRead) | ||
406 | { | ||
407 | void *alloc = malloc(8192 + 1024); | ||
408 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
409 | |||
410 | for (unsigned int heapMask : m_allHeaps) { | ||
411 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
412 | int map_fd = -1; | ||
413 | unsigned int flags = 0; | ||
414 | |||
415 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
416 | ASSERT_GE(map_fd, 0); | ||
417 | |||
418 | void *ptr; | ||
419 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
420 | ASSERT_TRUE(ptr != NULL); | ||
421 | |||
422 | for (int i = 0; i < 4096; i++) | ||
423 | ((char *)ptr)[i] = i; | ||
424 | |||
425 | ((char*)buf)[4096] = 0x12; | ||
426 | readKernel(map_fd, buf, 4096); | ||
427 | ASSERT_EQ(((char*)buf)[4096], 0x12); | ||
428 | |||
429 | for (int i = 0; i < 4096; i++) | ||
430 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
431 | |||
432 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
433 | ASSERT_EQ(0, close(map_fd)); | ||
434 | } | ||
435 | |||
436 | free(alloc); | ||
437 | } | ||
438 | |||
439 | TEST_F(Device, KernelWrite) | ||
440 | { | ||
441 | void *alloc = malloc(8192 + 1024); | ||
442 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
443 | |||
444 | for (int i = 0; i < 4096; i++) | ||
445 | ((char *)buf)[i] = i; | ||
446 | |||
447 | for (unsigned int heapMask : m_allHeaps) { | ||
448 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
449 | int map_fd = -1; | ||
450 | unsigned int flags = 0; | ||
451 | |||
452 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
453 | ASSERT_GE(map_fd, 0); | ||
454 | |||
455 | void *ptr; | ||
456 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
457 | ASSERT_TRUE(ptr != NULL); | ||
458 | |||
459 | dirtyCache(ptr, 4096); | ||
460 | |||
461 | writeKernel(map_fd, buf, 4096); | ||
462 | |||
463 | for (int i = 0; i < 4096; i++) | ||
464 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
465 | |||
466 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
467 | ASSERT_EQ(0, close(map_fd)); | ||
468 | } | ||
469 | |||
470 | free(alloc); | ||
471 | } | ||
472 | |||
473 | TEST_F(Device, DMARead) | ||
474 | { | ||
475 | void *alloc = malloc(8192 + 1024); | ||
476 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
477 | |||
478 | for (unsigned int heapMask : m_allHeaps) { | ||
479 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
480 | int map_fd = -1; | ||
481 | unsigned int flags = 0; | ||
482 | |||
483 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
484 | ASSERT_GE(map_fd, 0); | ||
485 | |||
486 | void *ptr; | ||
487 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
488 | ASSERT_TRUE(ptr != NULL); | ||
489 | |||
490 | for (int i = 0; i < 4096; i++) | ||
491 | ((char *)ptr)[i] = i; | ||
492 | |||
493 | readDMA(map_fd, buf, 4096); | ||
494 | |||
495 | for (int i = 0; i < 4096; i++) | ||
496 | ASSERT_EQ((char)i, ((char *)buf)[i]); | ||
497 | |||
498 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
499 | ASSERT_EQ(0, close(map_fd)); | ||
500 | } | ||
501 | |||
502 | free(alloc); | ||
503 | } | ||
504 | |||
505 | TEST_F(Device, DMAWrite) | ||
506 | { | ||
507 | void *alloc = malloc(8192 + 1024); | ||
508 | void *buf = (void *)(ALIGN((unsigned long)alloc, 4096) + 1024); | ||
509 | |||
510 | for (int i = 0; i < 4096; i++) | ||
511 | ((char *)buf)[i] = i; | ||
512 | |||
513 | for (unsigned int heapMask : m_allHeaps) { | ||
514 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
515 | int map_fd = -1; | ||
516 | unsigned int flags = 0; | ||
517 | |||
518 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
519 | ASSERT_GE(map_fd, 0); | ||
520 | |||
521 | void *ptr; | ||
522 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
523 | ASSERT_TRUE(ptr != NULL); | ||
524 | |||
525 | dirtyCache(ptr, 4096); | ||
526 | |||
527 | writeDMA(map_fd, buf, 4096); | ||
528 | |||
529 | for (int i = 0; i < 4096; i++) | ||
530 | ASSERT_EQ((char)i, ((char *)ptr)[i]) << i; | ||
531 | |||
532 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
533 | ASSERT_EQ(0, close(map_fd)); | ||
534 | } | ||
535 | |||
536 | free(alloc); | ||
537 | } | ||
538 | |||
539 | TEST_F(Device, IsCached) | ||
540 | { | ||
541 | void *buf = malloc(4096); | ||
542 | |||
543 | for (unsigned int heapMask : m_allHeaps) { | ||
544 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
545 | int map_fd = -1; | ||
546 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
547 | |||
548 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, flags, &map_fd)); | ||
549 | ASSERT_GE(map_fd, 0); | ||
550 | |||
551 | void *ptr; | ||
552 | ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
553 | ASSERT_TRUE(ptr != NULL); | ||
554 | |||
555 | dirtyCache(ptr, 4096); | ||
556 | |||
557 | readDMA(map_fd, buf, 4096); | ||
558 | |||
559 | bool same = true; | ||
560 | for (int i = 4096-16; i >= 0; i -= 16) | ||
561 | if (((char *)buf)[i] != i) | ||
562 | same = false; | ||
563 | ASSERT_FALSE(same); | ||
564 | |||
565 | ASSERT_EQ(0, munmap(ptr, 4096)); | ||
566 | ASSERT_EQ(0, close(map_fd)); | ||
567 | } | ||
568 | } | ||
diff --git a/libion/tests/exit_test.cpp b/libion/tests/exit_test.cpp new file mode 100644 index 000000000..cdd3e27e7 --- /dev/null +++ b/libion/tests/exit_test.cpp | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <sys/mman.h> | ||
18 | |||
19 | #include <gtest/gtest.h> | ||
20 | |||
21 | #include <ion/ion.h> | ||
22 | |||
23 | #include "ion_test_fixture.h" | ||
24 | |||
25 | class Exit : public IonAllHeapsTest { | ||
26 | }; | ||
27 | |||
28 | TEST_F(Exit, WithAlloc) | ||
29 | { | ||
30 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
31 | for (unsigned int heapMask : m_allHeaps) { | ||
32 | for (size_t size : allocationSizes) { | ||
33 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
34 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
35 | EXPECT_EXIT({ | ||
36 | ion_user_handle_t handle = 0; | ||
37 | |||
38 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle)); | ||
39 | ASSERT_TRUE(handle != 0); | ||
40 | exit(0); | ||
41 | }, ::testing::ExitedWithCode(0), ""); | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | TEST_F(Exit, WithAllocFd) | ||
47 | { | ||
48 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
49 | for (unsigned int heapMask : m_allHeaps) { | ||
50 | for (size_t size : allocationSizes) { | ||
51 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
52 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
53 | EXPECT_EXIT({ | ||
54 | int handle_fd = -1; | ||
55 | |||
56 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &handle_fd)); | ||
57 | ASSERT_NE(-1, handle_fd); | ||
58 | exit(0); | ||
59 | }, ::testing::ExitedWithCode(0), ""); | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | TEST_F(Exit, WithRepeatedAllocFd) | ||
65 | { | ||
66 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
67 | for (unsigned int heapMask : m_allHeaps) { | ||
68 | for (size_t size : allocationSizes) { | ||
69 | for (unsigned int i = 0; i < 1024; i++) { | ||
70 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
71 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
72 | ASSERT_EXIT({ | ||
73 | int handle_fd = -1; | ||
74 | |||
75 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &handle_fd)); | ||
76 | ASSERT_NE(-1, handle_fd); | ||
77 | exit(0); | ||
78 | }, ::testing::ExitedWithCode(0), "") | ||
79 | << "failed on heap " << heapMask | ||
80 | << " and size " << size | ||
81 | << " on iteration " << i; | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | |||
88 | TEST_F(Exit, WithMapping) | ||
89 | { | ||
90 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
91 | for (unsigned int heapMask : m_allHeaps) { | ||
92 | for (size_t size : allocationSizes) { | ||
93 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
94 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
95 | EXPECT_EXIT({ | ||
96 | int map_fd = -1; | ||
97 | |||
98 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd)); | ||
99 | ASSERT_GE(map_fd, 0); | ||
100 | |||
101 | void *ptr; | ||
102 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
103 | ASSERT_TRUE(ptr != NULL); | ||
104 | exit(0); | ||
105 | }, ::testing::ExitedWithCode(0), ""); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | } | ||
110 | |||
111 | TEST_F(Exit, WithPartialMapping) | ||
112 | { | ||
113 | static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024}; | ||
114 | for (unsigned int heapMask : m_allHeaps) { | ||
115 | for (size_t size : allocationSizes) { | ||
116 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
117 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
118 | EXPECT_EXIT({ | ||
119 | int map_fd = -1; | ||
120 | |||
121 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd)); | ||
122 | ASSERT_GE(map_fd, 0); | ||
123 | |||
124 | void *ptr; | ||
125 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
126 | ASSERT_TRUE(ptr != NULL); | ||
127 | |||
128 | ASSERT_EQ(0, munmap(ptr, size / 2)); | ||
129 | exit(0); | ||
130 | }, ::testing::ExitedWithCode(0), ""); | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | TEST_F(Exit, WithMappingCached) | ||
136 | { | ||
137 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
138 | for (unsigned int heapMask : m_allHeaps) { | ||
139 | for (size_t size : allocationSizes) { | ||
140 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
141 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
142 | EXPECT_EXIT({ | ||
143 | int map_fd = -1; | ||
144 | |||
145 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &map_fd)); | ||
146 | ASSERT_GE(map_fd, 0); | ||
147 | |||
148 | void *ptr; | ||
149 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
150 | ASSERT_TRUE(ptr != NULL); | ||
151 | exit(0); | ||
152 | }, ::testing::ExitedWithCode(0), ""); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | } | ||
157 | |||
158 | TEST_F(Exit, WithPartialMappingCached) | ||
159 | { | ||
160 | static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024}; | ||
161 | for (unsigned int heapMask : m_allHeaps) { | ||
162 | for (size_t size : allocationSizes) { | ||
163 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
164 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
165 | EXPECT_EXIT({ | ||
166 | int map_fd = -1; | ||
167 | |||
168 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED, &map_fd)); | ||
169 | ASSERT_GE(map_fd, 0); | ||
170 | |||
171 | void *ptr; | ||
172 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
173 | ASSERT_TRUE(ptr != NULL); | ||
174 | |||
175 | ASSERT_EQ(0, munmap(ptr, size / 2)); | ||
176 | exit(0); | ||
177 | }, ::testing::ExitedWithCode(0), ""); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | TEST_F(Exit, WithMappingNeedsSync) | ||
183 | { | ||
184 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
185 | for (unsigned int heapMask : m_allHeaps) { | ||
186 | for (size_t size : allocationSizes) { | ||
187 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
188 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
189 | EXPECT_EXIT({ | ||
190 | int map_fd = -1; | ||
191 | |||
192 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC, &map_fd)); | ||
193 | ASSERT_GE(map_fd, 0); | ||
194 | |||
195 | void *ptr; | ||
196 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
197 | ASSERT_TRUE(ptr != NULL); | ||
198 | exit(0); | ||
199 | }, ::testing::ExitedWithCode(0), ""); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | } | ||
204 | |||
205 | TEST_F(Exit, WithPartialMappingNeedsSync) | ||
206 | { | ||
207 | static const size_t allocationSizes[] = {64*1024, 1024*1024, 2*1024*1024}; | ||
208 | for (unsigned int heapMask : m_allHeaps) { | ||
209 | for (size_t size : allocationSizes) { | ||
210 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
211 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
212 | EXPECT_EXIT({ | ||
213 | int map_fd = -1; | ||
214 | |||
215 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC, &map_fd)); | ||
216 | ASSERT_GE(map_fd, 0); | ||
217 | |||
218 | void *ptr; | ||
219 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
220 | ASSERT_TRUE(ptr != NULL); | ||
221 | |||
222 | ASSERT_EQ(0, munmap(ptr, size / 2)); | ||
223 | exit(0); | ||
224 | }, ::testing::ExitedWithCode(0), ""); | ||
225 | } | ||
226 | } | ||
227 | } | ||
diff --git a/libion/tests/formerly_valid_handle_test.cpp b/libion/tests/formerly_valid_handle_test.cpp new file mode 100644 index 000000000..01ab8f373 --- /dev/null +++ b/libion/tests/formerly_valid_handle_test.cpp | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <sys/mman.h> | ||
18 | |||
19 | #include <gtest/gtest.h> | ||
20 | |||
21 | #include <ion/ion.h> | ||
22 | |||
23 | #include "ion_test_fixture.h" | ||
24 | |||
25 | class FormerlyValidHandle : public IonTest { | ||
26 | public: | ||
27 | virtual void SetUp(); | ||
28 | virtual void TearDown(); | ||
29 | ion_user_handle_t m_handle; | ||
30 | }; | ||
31 | |||
32 | void FormerlyValidHandle::SetUp() | ||
33 | { | ||
34 | IonTest::SetUp(); | ||
35 | ASSERT_EQ(0, ion_alloc(m_ionFd, 4096, 0, 1/* ion_env->m_firstHeap */, 0, &m_handle)); | ||
36 | ASSERT_TRUE(m_handle != 0); | ||
37 | ASSERT_EQ(0, ion_free(m_ionFd, m_handle)); | ||
38 | } | ||
39 | |||
40 | void FormerlyValidHandle::TearDown() | ||
41 | { | ||
42 | m_handle = 0; | ||
43 | } | ||
44 | |||
45 | TEST_F(FormerlyValidHandle, free) | ||
46 | { | ||
47 | ASSERT_EQ(-EINVAL, ion_free(m_ionFd, m_handle)); | ||
48 | } | ||
49 | |||
50 | TEST_F(FormerlyValidHandle, map) | ||
51 | { | ||
52 | int map_fd; | ||
53 | unsigned char *ptr; | ||
54 | |||
55 | ASSERT_EQ(-EINVAL, ion_map(m_ionFd, m_handle, 4096, PROT_READ, 0, 0, &ptr, &map_fd)); | ||
56 | } | ||
57 | |||
58 | TEST_F(FormerlyValidHandle, share) | ||
59 | { | ||
60 | int share_fd; | ||
61 | |||
62 | ASSERT_EQ(-EINVAL, ion_share(m_ionFd, m_handle, &share_fd)); | ||
63 | } | ||
diff --git a/libion/tests/invalid_values_test.cpp b/libion/tests/invalid_values_test.cpp new file mode 100644 index 000000000..77fea177d --- /dev/null +++ b/libion/tests/invalid_values_test.cpp | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <sys/mman.h> | ||
18 | |||
19 | #include <gtest/gtest.h> | ||
20 | |||
21 | #include <ion/ion.h> | ||
22 | |||
23 | #include "ion_test_fixture.h" | ||
24 | |||
25 | class InvalidValues : public IonAllHeapsTest { | ||
26 | public: | ||
27 | virtual void SetUp(); | ||
28 | virtual void TearDown(); | ||
29 | ion_user_handle_t m_validHandle; | ||
30 | int m_validShareFd; | ||
31 | ion_user_handle_t const m_badHandle = -1; | ||
32 | }; | ||
33 | |||
34 | void InvalidValues::SetUp() | ||
35 | { | ||
36 | IonAllHeapsTest::SetUp(); | ||
37 | ASSERT_EQ(0, ion_alloc(m_ionFd, 4096, 0, m_firstHeap, 0, &m_validHandle)) | ||
38 | << m_ionFd << " " << m_firstHeap; | ||
39 | ASSERT_TRUE(m_validHandle != 0); | ||
40 | ASSERT_EQ(0, ion_share(m_ionFd, m_validHandle, &m_validShareFd)); | ||
41 | } | ||
42 | |||
43 | void InvalidValues::TearDown() | ||
44 | { | ||
45 | ASSERT_EQ(0, ion_free(m_ionFd, m_validHandle)); | ||
46 | ASSERT_EQ(0, close(m_validShareFd)); | ||
47 | m_validHandle = 0; | ||
48 | IonAllHeapsTest::TearDown(); | ||
49 | } | ||
50 | |||
51 | TEST_F(InvalidValues, ion_close) | ||
52 | { | ||
53 | EXPECT_EQ(-EBADF, ion_close(-1)); | ||
54 | } | ||
55 | |||
56 | TEST_F(InvalidValues, ion_alloc) | ||
57 | { | ||
58 | ion_user_handle_t handle; | ||
59 | /* invalid ion_fd */ | ||
60 | int ret = ion_alloc(0, 4096, 0, m_firstHeap, 0, &handle); | ||
61 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
62 | /* invalid ion_fd */ | ||
63 | EXPECT_EQ(-EBADF, ion_alloc(-1, 4096, 0, m_firstHeap, 0, &handle)); | ||
64 | /* no heaps */ | ||
65 | EXPECT_EQ(-ENODEV, ion_alloc(m_ionFd, 4096, 0, 0, 0, &handle)); | ||
66 | for (unsigned int heapMask : m_allHeaps) { | ||
67 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
68 | /* zero size */ | ||
69 | EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 0, 0, heapMask, 0, &handle)); | ||
70 | /* too large size */ | ||
71 | EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, -1, 0, heapMask, 0, &handle)); | ||
72 | /* bad alignment */ | ||
73 | EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 4096, -1, heapMask, 0, &handle)); | ||
74 | /* NULL handle */ | ||
75 | EXPECT_EQ(-EINVAL, ion_alloc(m_ionFd, 4096, 0, heapMask, 0, NULL)); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | TEST_F(InvalidValues, ion_alloc_fd) | ||
80 | { | ||
81 | int fd; | ||
82 | /* invalid ion_fd */ | ||
83 | int ret = ion_alloc_fd(0, 4096, 0, m_firstHeap, 0, &fd); | ||
84 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
85 | /* invalid ion_fd */ | ||
86 | EXPECT_EQ(-EBADF, ion_alloc_fd(-1, 4096, 0, m_firstHeap, 0, &fd)); | ||
87 | /* no heaps */ | ||
88 | EXPECT_EQ(-ENODEV, ion_alloc_fd(m_ionFd, 4096, 0, 0, 0, &fd)); | ||
89 | for (unsigned int heapMask : m_allHeaps) { | ||
90 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
91 | /* zero size */ | ||
92 | EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 0, 0, heapMask, 0, &fd)); | ||
93 | /* too large size */ | ||
94 | EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, -1, 0, heapMask, 0, &fd)); | ||
95 | /* bad alignment */ | ||
96 | EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 4096, -1, heapMask, 0, &fd)); | ||
97 | /* NULL handle */ | ||
98 | EXPECT_EQ(-EINVAL, ion_alloc_fd(m_ionFd, 4096, 0, heapMask, 0, NULL)); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | TEST_F(InvalidValues, ion_free) | ||
103 | { | ||
104 | /* invalid ion fd */ | ||
105 | int ret = ion_free(0, m_validHandle); | ||
106 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
107 | /* invalid ion fd */ | ||
108 | EXPECT_EQ(-EBADF, ion_free(-1, m_validHandle)); | ||
109 | /* zero handle */ | ||
110 | EXPECT_EQ(-EINVAL, ion_free(m_ionFd, 0)); | ||
111 | /* bad handle */ | ||
112 | EXPECT_EQ(-EINVAL, ion_free(m_ionFd, m_badHandle)); | ||
113 | } | ||
114 | |||
115 | TEST_F(InvalidValues, ion_map) | ||
116 | { | ||
117 | int map_fd; | ||
118 | unsigned char *ptr; | ||
119 | |||
120 | /* invalid ion fd */ | ||
121 | int ret = ion_map(0, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd); | ||
122 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
123 | /* invalid ion fd */ | ||
124 | EXPECT_EQ(-EBADF, ion_map(-1, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd)); | ||
125 | /* zero handle */ | ||
126 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, 0, 4096, PROT_READ, 0, 0, &ptr, &map_fd)); | ||
127 | /* bad handle */ | ||
128 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_badHandle, 4096, PROT_READ, 0, 0, &ptr, &map_fd)); | ||
129 | /* zero length */ | ||
130 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 0, PROT_READ, 0, 0, &ptr, &map_fd)); | ||
131 | /* bad prot */ | ||
132 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, -1, 0, 0, &ptr, &map_fd)); | ||
133 | /* bad offset */ | ||
134 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, -1, &ptr, &map_fd)); | ||
135 | /* NULL ptr */ | ||
136 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, 0, NULL, &map_fd)); | ||
137 | /* NULL map_fd */ | ||
138 | EXPECT_EQ(-EINVAL, ion_map(m_ionFd, m_validHandle, 4096, PROT_READ, 0, 0, &ptr, NULL)); | ||
139 | } | ||
140 | |||
141 | TEST_F(InvalidValues, ion_share) | ||
142 | { | ||
143 | int share_fd; | ||
144 | |||
145 | /* invalid ion fd */ | ||
146 | int ret = ion_share(0, m_validHandle, &share_fd); | ||
147 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
148 | /* invalid ion fd */ | ||
149 | EXPECT_EQ(-EBADF, ion_share(-1, m_validHandle, &share_fd)); | ||
150 | /* zero handle */ | ||
151 | EXPECT_EQ(-EINVAL, ion_share(m_ionFd, 0, &share_fd)); | ||
152 | /* bad handle */ | ||
153 | EXPECT_EQ(-EINVAL, ion_share(m_ionFd, m_badHandle, &share_fd)); | ||
154 | /* NULL share_fd */ | ||
155 | EXPECT_EQ(-EINVAL, ion_share(m_ionFd, m_validHandle, NULL)); | ||
156 | } | ||
157 | |||
158 | TEST_F(InvalidValues, ion_import) | ||
159 | { | ||
160 | ion_user_handle_t handle; | ||
161 | |||
162 | /* invalid ion fd */ | ||
163 | int ret = ion_import(0, m_validShareFd, &handle); | ||
164 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
165 | /* invalid ion fd */ | ||
166 | EXPECT_EQ(-EBADF, ion_import(-1, m_validShareFd, &handle)); | ||
167 | /* bad share_fd */ | ||
168 | EXPECT_EQ(-EINVAL, ion_import(m_ionFd, 0, &handle)); | ||
169 | /* invalid share_fd */ | ||
170 | EXPECT_EQ(-EBADF, ion_import(m_ionFd, -1, &handle)); | ||
171 | /* NULL handle */ | ||
172 | EXPECT_EQ(-EINVAL, ion_import(m_ionFd, m_validShareFd, NULL)); | ||
173 | } | ||
174 | |||
175 | TEST_F(InvalidValues, ion_sync_fd) | ||
176 | { | ||
177 | /* invalid ion fd */ | ||
178 | int ret = ion_sync_fd(0, m_validShareFd); | ||
179 | EXPECT_TRUE(ret == -EINVAL || ret == -ENOTTY); | ||
180 | /* invalid ion fd */ | ||
181 | EXPECT_EQ(-EBADF, ion_sync_fd(-1, m_validShareFd)); | ||
182 | /* bad share_fd */ | ||
183 | EXPECT_EQ(-EINVAL, ion_sync_fd(m_ionFd, 0)); | ||
184 | /* invalid share_fd */ | ||
185 | EXPECT_EQ(-EBADF, ion_sync_fd(m_ionFd, -1)); | ||
186 | } | ||
diff --git a/libion/tests/ion_test_fixture.cpp b/libion/tests/ion_test_fixture.cpp new file mode 100644 index 000000000..e20c73005 --- /dev/null +++ b/libion/tests/ion_test_fixture.cpp | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <gtest/gtest.h> | ||
18 | |||
19 | #include <ion/ion.h> | ||
20 | |||
21 | #include "ion_test_fixture.h" | ||
22 | |||
23 | IonTest::IonTest() : m_ionFd(-1) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | void IonTest::SetUp() { | ||
28 | m_ionFd = ion_open(); | ||
29 | ASSERT_GE(m_ionFd, 0); | ||
30 | } | ||
31 | |||
32 | void IonTest::TearDown() { | ||
33 | ion_close(m_ionFd); | ||
34 | } | ||
35 | |||
36 | IonAllHeapsTest::IonAllHeapsTest() : | ||
37 | m_firstHeap(0), | ||
38 | m_lastHeap(0), | ||
39 | m_allHeaps() | ||
40 | { | ||
41 | } | ||
42 | |||
43 | void IonAllHeapsTest::SetUp() { | ||
44 | int fd = ion_open(); | ||
45 | ASSERT_GE(fd, 0); | ||
46 | |||
47 | for (int i = 1; i != 0; i <<= 1) { | ||
48 | ion_user_handle_t handle = 0; | ||
49 | int ret; | ||
50 | ret = ion_alloc(fd, 4096, 0, i, 0, &handle); | ||
51 | if (ret == 0 && handle != 0) { | ||
52 | ion_free(fd, handle); | ||
53 | if (!m_firstHeap) { | ||
54 | m_firstHeap = i; | ||
55 | } | ||
56 | m_lastHeap = i; | ||
57 | m_allHeaps.push_back(i); | ||
58 | } else { | ||
59 | ASSERT_EQ(-ENODEV, ret); | ||
60 | } | ||
61 | } | ||
62 | ion_close(fd); | ||
63 | |||
64 | EXPECT_NE(0U, m_firstHeap); | ||
65 | EXPECT_NE(0U, m_lastHeap); | ||
66 | |||
67 | RecordProperty("Heaps", m_allHeaps.size()); | ||
68 | IonTest::SetUp(); | ||
69 | } | ||
70 | |||
71 | void IonAllHeapsTest::TearDown() { | ||
72 | IonTest::TearDown(); | ||
73 | } | ||
diff --git a/libion/tests/ion_test_fixture.h b/libion/tests/ion_test_fixture.h new file mode 100644 index 000000000..4098214c0 --- /dev/null +++ b/libion/tests/ion_test_fixture.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #ifndef ION_TEST_FIXTURE_H_ | ||
18 | #define ION_TEST_FIXTURE_H_ | ||
19 | |||
20 | #include <gtest/gtest.h> | ||
21 | |||
22 | using ::testing::Test; | ||
23 | |||
24 | class IonTest : public virtual Test { | ||
25 | public: | ||
26 | IonTest(); | ||
27 | virtual ~IonTest() {}; | ||
28 | virtual void SetUp(); | ||
29 | virtual void TearDown(); | ||
30 | int m_ionFd; | ||
31 | }; | ||
32 | |||
33 | class IonAllHeapsTest : public IonTest { | ||
34 | public: | ||
35 | IonAllHeapsTest(); | ||
36 | virtual ~IonAllHeapsTest() {}; | ||
37 | virtual void SetUp(); | ||
38 | virtual void TearDown(); | ||
39 | |||
40 | unsigned int m_firstHeap; | ||
41 | unsigned int m_lastHeap; | ||
42 | |||
43 | std::vector<unsigned int> m_allHeaps; | ||
44 | }; | ||
45 | |||
46 | #endif /* ION_TEST_FIXTURE_H_ */ | ||
diff --git a/libion/tests/map_test.cpp b/libion/tests/map_test.cpp new file mode 100644 index 000000000..c006dc81a --- /dev/null +++ b/libion/tests/map_test.cpp | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #include <sys/mman.h> | ||
18 | |||
19 | #include <gtest/gtest.h> | ||
20 | |||
21 | #include <ion/ion.h> | ||
22 | |||
23 | #include "ion_test_fixture.h" | ||
24 | |||
25 | class Map : public IonAllHeapsTest { | ||
26 | }; | ||
27 | |||
28 | TEST_F(Map, MapHandle) | ||
29 | { | ||
30 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
31 | for (unsigned int heapMask : m_allHeaps) { | ||
32 | for (size_t size : allocationSizes) { | ||
33 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
34 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
35 | ion_user_handle_t handle = 0; | ||
36 | |||
37 | ASSERT_EQ(0, ion_alloc(m_ionFd, size, 0, heapMask, 0, &handle)); | ||
38 | ASSERT_TRUE(handle != 0); | ||
39 | |||
40 | int map_fd = -1; | ||
41 | unsigned char *ptr = NULL; | ||
42 | ASSERT_EQ(0, ion_map(m_ionFd, handle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0, &ptr, &map_fd)); | ||
43 | ASSERT_TRUE(ptr != NULL); | ||
44 | ASSERT_GE(map_fd, 0); | ||
45 | |||
46 | ASSERT_EQ(0, close(map_fd)); | ||
47 | |||
48 | ASSERT_EQ(0, ion_free(m_ionFd, handle)); | ||
49 | |||
50 | memset(ptr, 0xaa, size); | ||
51 | |||
52 | ASSERT_EQ(0, munmap(ptr, size)); | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | |||
57 | TEST_F(Map, MapFd) | ||
58 | { | ||
59 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
60 | for (unsigned int heapMask : m_allHeaps) { | ||
61 | for (size_t size : allocationSizes) { | ||
62 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
63 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
64 | int map_fd = -1; | ||
65 | |||
66 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, 0, &map_fd)); | ||
67 | ASSERT_GE(map_fd, 0); | ||
68 | |||
69 | void *ptr; | ||
70 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
71 | ASSERT_TRUE(ptr != NULL); | ||
72 | |||
73 | ASSERT_EQ(0, close(map_fd)); | ||
74 | |||
75 | memset(ptr, 0xaa, size); | ||
76 | |||
77 | ASSERT_EQ(0, munmap(ptr, size)); | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | |||
82 | TEST_F(Map, MapOffset) | ||
83 | { | ||
84 | for (unsigned int heapMask : m_allHeaps) { | ||
85 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
86 | int map_fd = -1; | ||
87 | |||
88 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, PAGE_SIZE * 2, 0, heapMask, 0, &map_fd)); | ||
89 | ASSERT_GE(map_fd, 0); | ||
90 | |||
91 | unsigned char *ptr; | ||
92 | ptr = (unsigned char *)mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
93 | ASSERT_TRUE(ptr != NULL); | ||
94 | |||
95 | memset(ptr, 0, PAGE_SIZE); | ||
96 | memset(ptr + PAGE_SIZE, 0xaa, PAGE_SIZE); | ||
97 | |||
98 | ASSERT_EQ(0, munmap(ptr, PAGE_SIZE * 2)); | ||
99 | |||
100 | ptr = (unsigned char *)mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, PAGE_SIZE); | ||
101 | ASSERT_TRUE(ptr != NULL); | ||
102 | |||
103 | ASSERT_EQ(ptr[0], 0xaa); | ||
104 | ASSERT_EQ(ptr[PAGE_SIZE - 1], 0xaa); | ||
105 | |||
106 | ASSERT_EQ(0, munmap(ptr, PAGE_SIZE)); | ||
107 | |||
108 | ASSERT_EQ(0, close(map_fd)); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | TEST_F(Map, MapCached) | ||
113 | { | ||
114 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
115 | for (unsigned int heapMask : m_allHeaps) { | ||
116 | for (size_t size : allocationSizes) { | ||
117 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
118 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
119 | int map_fd = -1; | ||
120 | unsigned int flags = ION_FLAG_CACHED; | ||
121 | |||
122 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, flags, &map_fd)); | ||
123 | ASSERT_GE(map_fd, 0); | ||
124 | |||
125 | void *ptr; | ||
126 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
127 | ASSERT_TRUE(ptr != NULL); | ||
128 | |||
129 | ASSERT_EQ(0, close(map_fd)); | ||
130 | |||
131 | memset(ptr, 0xaa, size); | ||
132 | |||
133 | ASSERT_EQ(0, munmap(ptr, size)); | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | TEST_F(Map, MapCachedNeedsSync) | ||
139 | { | ||
140 | static const size_t allocationSizes[] = {4*1024, 64*1024, 1024*1024, 2*1024*1024}; | ||
141 | for (unsigned int heapMask : m_allHeaps) { | ||
142 | for (size_t size : allocationSizes) { | ||
143 | SCOPED_TRACE(::testing::Message() << "heap " << heapMask); | ||
144 | SCOPED_TRACE(::testing::Message() << "size " << size); | ||
145 | int map_fd = -1; | ||
146 | unsigned int flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; | ||
147 | |||
148 | ASSERT_EQ(0, ion_alloc_fd(m_ionFd, size, 0, heapMask, flags, &map_fd)); | ||
149 | ASSERT_GE(map_fd, 0); | ||
150 | |||
151 | void *ptr; | ||
152 | ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, map_fd, 0); | ||
153 | ASSERT_TRUE(ptr != NULL); | ||
154 | |||
155 | ASSERT_EQ(0, close(map_fd)); | ||
156 | |||
157 | memset(ptr, 0xaa, size); | ||
158 | |||
159 | ASSERT_EQ(0, munmap(ptr, size)); | ||
160 | } | ||
161 | } | ||
162 | } | ||