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 
TEST_F(Exit,WithAlloc)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 
TEST_F(Exit,WithAllocFd)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 
TEST_F(Exit,WithRepeatedAllocFd)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 
TEST_F(Exit,WithMapping)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 
TEST_F(Exit,WithPartialMapping)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 
TEST_F(Exit,WithMappingCached)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 
TEST_F(Exit,WithPartialMappingCached)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 
TEST_F(Exit,WithMappingNeedsSync)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 
TEST_F(Exit,WithPartialMappingNeedsSync)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 }
228