summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorBjorn Bringert <bringert@android.com>2009-05-29 11:46:12 +0100
committerBjorn Bringert <bringert@android.com>2009-05-29 13:28:14 +0100
commit761e0918d30b6a3f292625b44b86dffd1538bc78 (patch)
tree6b2cdf84b7ad5244391b18b4dbe524f071da0f29 /tests
parent9fc2e9c965c68d56a0caf812f7f6d38d15317063 (diff)
downloadframeworks_base-761e0918d30b6a3f292625b44b86dffd1538bc78.zip
frameworks_base-761e0918d30b6a3f292625b44b86dffd1538bc78.tar.gz
frameworks_base-761e0918d30b6a3f292625b44b86dffd1538bc78.tar.bz2
Unmap memory in MemoryFile.close().
As reported in http://b/issue?id=1398215 MemoryFile did not munmap(2) the ashmem region after closing it. This causes the process to leak virtual address space. This change fixes the problem by calling munmap(2) in close(). The unmapping is done by a helper method deactivate(). The change also replaces the use of an int for the file descriptor with a FileDescriptor object to make sure that we keep track of when the file descriptor has been closed. I chose to implement it this way because I will need decativate() and a FileDescriptor object in an upcoming change that allows sending MemoryFile file descriptors between processes. The change also adds a number of tests for the behavior of close(). The testCloseRead() and testCloseWrite() fail with the old MemoryFile implementation, and testCloseLeak() causes a segfault. They all pass now.
Diffstat (limited to 'tests')
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java77
1 files changed, 73 insertions, 4 deletions
diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java
index 508afcf..5161f7b 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java
@@ -17,16 +17,17 @@
package com.android.unit_tests.os;
import android.os.MemoryFile;
+import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.IOException;
-
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
public class MemoryFileTest extends TestCase {
@@ -94,6 +95,74 @@ public class MemoryFileTest extends TestCase {
file.close();
}
+ // Tests that close() is idempotent
+ @SmallTest
+ public void testCloseClose() throws Exception {
+ MemoryFile file = new MemoryFile("MemoryFileTest", 1000000);
+ byte[] data = new byte[512];
+ file.writeBytes(data, 0, 0, 128);
+ file.close();
+ file.close();
+ }
+
+ // Tests that we can't read from a closed memory file
+ @SmallTest
+ public void testCloseRead() throws Exception {
+ MemoryFile file = new MemoryFile("MemoryFileTest", 1000000);
+ file.close();
+
+ try {
+ byte[] data = new byte[512];
+ assertEquals(128, file.readBytes(data, 0, 0, 128));
+ fail("readBytes() after close() did not throw IOException.");
+ } catch (IOException e) {
+ // this is what should happen
+ }
+ }
+
+ // Tests that we can't write to a closed memory file
+ @SmallTest
+ public void testCloseWrite() throws Exception {
+ MemoryFile file = new MemoryFile("MemoryFileTest", 1000000);
+ file.close();
+
+ try {
+ byte[] data = new byte[512];
+ file.writeBytes(data, 0, 0, 128);
+ fail("writeBytes() after close() did not throw IOException.");
+ } catch (IOException e) {
+ // this is what should happen
+ }
+ }
+
+ // Tests that we can't call allowPurging() after close()
+ @SmallTest
+ public void testCloseAllowPurging() throws Exception {
+ MemoryFile file = new MemoryFile("MemoryFileTest", 1000000);
+ byte[] data = new byte[512];
+ file.writeBytes(data, 0, 0, 128);
+ file.close();
+
+ try {
+ file.allowPurging(true);
+ fail("allowPurging() after close() did not throw IOException.");
+ } catch (IOException e) {
+ // this is what should happen
+ }
+ }
+
+ // Tests that we don't leak file descriptors or mmap areas
+ @LargeTest
+ public void testCloseLeak() throws Exception {
+ // open enough memory files that we should run out of
+ // file descriptors or address space if we leak either.
+ for (int i = 0; i < 1025; i++) {
+ MemoryFile file = new MemoryFile("MemoryFileTest", 5000000);
+ file.writeBytes(testString, 0, 0, testString.length);
+ file.close();
+ }
+ }
+
private static final byte[] testString = new byte[] {
3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9, 3, 7, 5, 1, 0, 5, 8, 2, 0, 9, 7, 4, 9, 4, 4, 5, 9, 2, 3, 0, 7, 8, 1, 6, 4,
0, 6, 2, 8, 6, 2, 0, 8, 9, 9, 8, 6, 2, 8, 0, 3, 4, 8, 2, 5, 3, 4, 2, 1, 1, 7, 0, 6, 7, 9, 8, 2, 1, 4, 8, 0, 8, 6, 5, 1, 3, 2, 8, 2, 3, 0, 6, 6, 4, 7, 0, 9, 3, 8, 4, 4, 6, 0, 9, 5, 5, 0, 5, 8, 2, 2, 3, 1, 7, 2,