1/*
2 * Copyright (C) 2016 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
17package android.util;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertNotNull;
21import static org.junit.Assert.assertSame;
22import static org.junit.Assert.assertTrue;
23import static org.junit.Assert.fail;
24
25import android.os.Parcel;
26import android.support.test.runner.AndroidJUnit4;
27import libcore.io.IoUtils;
28import org.junit.Test;
29import org.junit.runner.RunWith;
30
31@RunWith(AndroidJUnit4.class)
32public class MemoryIntArrayTest {
33
34    @Test
35    public void testSize() throws Exception {
36        MemoryIntArray array = null;
37        try {
38            array = new MemoryIntArray(3, false);
39            assertEquals("size must be three", 3, array.size());
40        } finally {
41            IoUtils.closeQuietly(array);
42        }
43    }
44
45    @Test
46    public void testGetSet() throws Exception {
47        MemoryIntArray array = null;
48        try {
49            array = new MemoryIntArray(3, false);
50
51            array.set(0, 1);
52            array.set(1, 2);
53            array.set(2, 3);
54
55            assertEquals("First element should be 1", 1, array.get(0));
56            assertEquals("First element should be 2", 2, array.get(1));
57            assertEquals("First element should be 3", 3, array.get(2));
58        } finally {
59            IoUtils.closeQuietly(array);
60        }
61    }
62
63    @Test
64    public void testWritable() throws Exception {
65        MemoryIntArray array = null;
66        try {
67            array = new MemoryIntArray(3, true);
68            assertTrue("Must be mutable", array.isWritable());
69        } finally {
70            IoUtils.closeQuietly(array);
71        }
72    }
73
74    @Test
75    public void testClose() throws Exception {
76        MemoryIntArray array = null;
77        try {
78            array = new MemoryIntArray(3, false);
79            array.close();
80            assertTrue("Must be closed", array.isClosed());
81        } finally {
82            if (array != null && !array.isClosed()) {
83                IoUtils.closeQuietly(array);
84            }
85        }
86    }
87
88    @Test
89    public void testMarshalledGetSet() throws Exception {
90        MemoryIntArray firstArray = null;
91        MemoryIntArray secondArray = null;
92        try {
93            firstArray = new MemoryIntArray(3, false);
94
95            firstArray.set(0, 1);
96            firstArray.set(1, 2);
97            firstArray.set(2, 3);
98
99            Parcel parcel = Parcel.obtain();
100            parcel.writeParcelable(firstArray, 0);
101            parcel.setDataPosition(0);
102            secondArray = parcel.readParcelable(null);
103            parcel.recycle();
104
105            assertNotNull("Should marshall file descriptor", secondArray);
106
107            assertEquals("First element should be 1", 1, secondArray.get(0));
108            assertEquals("First element should be 2", 2, secondArray.get(1));
109            assertEquals("First element should be 3", 3, secondArray.get(2));
110        } finally {
111            IoUtils.closeQuietly(firstArray);
112            IoUtils.closeQuietly(secondArray);
113        }
114    }
115
116    @Test
117    public void testInteractOnceClosed() throws Exception {
118        MemoryIntArray array = null;
119        try {
120            array = new MemoryIntArray(3, false);
121            array.close();
122
123            array.close();
124
125            try {
126                array.size();
127                fail("Cannot interact with a closed instance");
128            } catch (IllegalStateException e) {
129                /* expected */
130            }
131
132            try {
133                array.get(0);
134                fail("Cannot interact with a closed instance");
135            } catch (IllegalStateException e) {
136                /* expected */
137            }
138
139            try {
140                array.set(0, 1);
141                fail("Cannot interact with a closed instance");
142            } catch (IllegalStateException e) {
143                /* expected */
144            }
145
146            try {
147                array.isWritable();
148                fail("Cannot interact with a closed instance");
149            } catch (IllegalStateException e) {
150                /* expected */
151            }
152        } finally {
153            if (array != null && !array.isClosed()) {
154                IoUtils.closeQuietly(array);
155            }
156        }
157    }
158
159    @Test
160    public void testInteractPutOfBounds() throws Exception {
161        MemoryIntArray array = null;
162        try {
163            array = new MemoryIntArray(3, false);
164
165            try {
166                array.get(-1);
167                fail("Cannot interact out of array bounds");
168            } catch (IndexOutOfBoundsException e) {
169                /* expected */
170            }
171
172            try {
173                array.get(3);
174                fail("Cannot interact out of array bounds");
175            } catch (IndexOutOfBoundsException e) {
176                /* expected */
177            }
178
179            try {
180                array.set(-1, 0);
181                fail("Cannot interact out of array bounds");
182            } catch (IndexOutOfBoundsException e) {
183                /* expected */
184            }
185
186            try {
187                array.set(3, 0);
188                fail("Cannot interact out of array bounds");
189            } catch (IndexOutOfBoundsException e) {
190                /* expected */
191            }
192        } finally {
193            IoUtils.closeQuietly(array);
194        }
195    }
196
197    @Test
198    public void testOverMaxSize() throws Exception {
199        MemoryIntArray array = null;
200        try {
201            array = new MemoryIntArray(MemoryIntArray.getMaxSize() + 1, false);
202            fail("Cannot use over max size");
203        } catch (IllegalArgumentException e) {
204            /* expected */
205        } finally {
206            IoUtils.closeQuietly(array);
207        }
208    }
209
210    @Test
211    public void testNotMutableByUnprivilegedClients() throws Exception {
212        RemoteIntArray remoteIntArray = new RemoteIntArray(1, false);
213        try {
214            assertNotNull("Couldn't get remote instance", remoteIntArray);
215            MemoryIntArray localIntArray = remoteIntArray.peekInstance();
216            assertNotNull("Couldn't get local instance", localIntArray);
217
218            remoteIntArray.set(0, 1);
219            assertSame("Remote should be able to modify", 1, remoteIntArray.get(0));
220
221            try {
222                localIntArray.set(0, 0);
223                fail("Local shouldn't be able to modify");
224            } catch (UnsupportedOperationException e) {
225                /* expected */
226            }
227            assertSame("Local shouldn't be able to modify", 1, localIntArray.get(0));
228            assertSame("Local shouldn't be able to modify", 1, remoteIntArray.get(0));
229        } finally {
230            remoteIntArray.destroy();
231        }
232    }
233}
234