summaryrefslogtreecommitdiffstats
path: root/libion
diff options
context:
space:
mode:
authorColin Cross2013-11-08 01:06:58 -0600
committerColin Cross2013-12-19 21:31:46 -0600
commit363441b120aa7ff4ec7c639bac099e775c2ace69 (patch)
tree4aef851bb4d982f88748694f9e67baf6e480ed84 /libion
parentb04f75ab129e471eb0b45571f0c319c516de0c02 (diff)
downloadplatform-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.mk2
-rw-r--r--libion/tests/Android.mk34
-rw-r--r--libion/tests/allocate_test.cpp145
-rw-r--r--libion/tests/device_test.cpp568
-rw-r--r--libion/tests/exit_test.cpp227
-rw-r--r--libion/tests/formerly_valid_handle_test.cpp63
-rw-r--r--libion/tests/invalid_values_test.cpp186
-rw-r--r--libion/tests/ion_test_fixture.cpp73
-rw-r--r--libion/tests/ion_test_fixture.h46
-rw-r--r--libion/tests/map_test.cpp162
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
16LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers 16LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers
17LOCAL_SHARED_LIBRARIES := liblog 17LOCAL_SHARED_LIBRARIES := liblog
18include $(BUILD_EXECUTABLE) 18include $(BUILD_EXECUTABLE)
19
20include $(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
17LOCAL_PATH:= $(call my-dir)
18
19include $(CLEAR_VARS)
20LOCAL_MODULE := ion-unit-tests
21LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
22LOCAL_CFLAGS += -g -Wall -Werror -std=gnu++11 -Wno-missing-field-initializers
23LOCAL_SHARED_LIBRARIES += libion
24LOCAL_STATIC_LIBRARIES += libgtest_main
25LOCAL_C_INCLUDES := $(LOCAL_PATH)/../kernel-headers
26LOCAL_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
34include $(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
24class Allocate : public IonAllHeapsTest {
25};
26
27TEST_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
42TEST_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
57TEST_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
72TEST_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
91TEST_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
138TEST_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
32class 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
45void Device::SetUp()
46{
47 IonAllHeapsTest::SetUp();
48 m_deviceFd = open("/dev/ion-test", O_RDWR);
49 ASSERT_GE(m_deviceFd, 0);
50}
51
52void Device::TearDown()
53{
54 ASSERT_EQ(0, close(m_deviceFd));
55 IonAllHeapsTest::TearDown();
56}
57
58void 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
72void 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
86void 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
100void 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
114void 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
125void 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
134TEST_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
168TEST_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
202TEST_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
234TEST_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
268TEST_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
302TEST_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
336TEST_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
370TEST_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}
405TEST_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
439TEST_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
473TEST_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
505TEST_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
539TEST_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
25class Exit : public IonAllHeapsTest {
26};
27
28TEST_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
46TEST_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
64TEST_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
88TEST_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
111TEST_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
135TEST_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
158TEST_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
182TEST_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
205TEST_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
25class FormerlyValidHandle : public IonTest {
26 public:
27 virtual void SetUp();
28 virtual void TearDown();
29 ion_user_handle_t m_handle;
30};
31
32void 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
40void FormerlyValidHandle::TearDown()
41{
42 m_handle = 0;
43}
44
45TEST_F(FormerlyValidHandle, free)
46{
47 ASSERT_EQ(-EINVAL, ion_free(m_ionFd, m_handle));
48}
49
50TEST_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
58TEST_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
25class 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
34void 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
43void 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
51TEST_F(InvalidValues, ion_close)
52{
53 EXPECT_EQ(-EBADF, ion_close(-1));
54}
55
56TEST_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
79TEST_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
102TEST_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
115TEST_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
141TEST_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
158TEST_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
175TEST_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
23IonTest::IonTest() : m_ionFd(-1)
24{
25}
26
27void IonTest::SetUp() {
28 m_ionFd = ion_open();
29 ASSERT_GE(m_ionFd, 0);
30}
31
32void IonTest::TearDown() {
33 ion_close(m_ionFd);
34}
35
36IonAllHeapsTest::IonAllHeapsTest() :
37 m_firstHeap(0),
38 m_lastHeap(0),
39 m_allHeaps()
40{
41}
42
43void 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
71void 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
22using ::testing::Test;
23
24class 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
33class 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
25class Map : public IonAllHeapsTest {
26};
27
28TEST_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
57TEST_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
82TEST_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
112TEST_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
138TEST_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}