1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18ab762bb740405d0fefcccf4a0899a234f995be13Narayan Kamathpackage org.apache.harmony.tests.java.lang; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughesimport java.io.File; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 24fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughesimport java.util.ArrayList; 2514f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughesimport libcore.io.Libcore; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ProcessTest extends junit.framework.TestCase { 2814f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughes // Test that failures to exec don't leave zombies lying around. 29fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes public void test_55017() throws Exception { 30fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes ArrayList<Process> children = new ArrayList<Process>(); 31fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes for (int i = 0; i < 256; ++i) { 32fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes try { 33fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes children.add(Runtime.getRuntime().exec(new String[] { "/system/bin/does-not-exist" }, null, null)); 34fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes System.gc(); 35fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } catch (IOException expected) { 36fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 38fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals(0, children.size()); 39fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 4014f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughes String pid = Integer.toString(Libcore.os.getpid()); 41fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes boolean onDevice = new File("/system/bin").exists(); 4214f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughes String[] psCommand = onDevice ? new String[] { "ps", "--ppid", pid } 4314f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughes : new String[] { "ps", "S", "--ppid", pid }; 44fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Process ps = Runtime.getRuntime().exec(psCommand, null, null); 45fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes int zombieCount = 0; 46fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes for (String line : readAndCloseStream(ps.getInputStream()).split("\n")) { 47fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes if (line.contains(" Z ") || line.contains(" Z+ ")) { 4814f694589bb5944e7f3e6862600ba25b15a37d18Elliott Hughes ++zombieCount; 49fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 51fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals(0, zombieCount); 52fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 53fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 54fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes public void test_getOutputStream() throws Exception { 55fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String[] commands = { "cat", "-"}; 56fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Process p = Runtime.getRuntime().exec(commands, null, null); 57fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes OutputStream os = p.getOutputStream(); 58fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes // send data, and check if it is echoed back correctly 59fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String str1 = "Some data for testing communication between processes\n"; 60fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String str2 = "More data that serves the same purpose.\n"; 61fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String str3 = "Here is some more data.\n"; 62fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes os.write(str1.getBytes()); 63fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes try { 64fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Thread.sleep(1000); 65fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } catch (InterruptedException e) { 66fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes e.printStackTrace(); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 68fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes os.write(str2.getBytes()); 69fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes os.write(str3.getBytes()); 70fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes os.close(); 71f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 72fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String received = readAndCloseStream(p.getInputStream()); 73fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals(str1 + str2 + str3, received); 74f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 75fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String stderr = readAndCloseStream(p.getErrorStream()); 76fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals("", stderr); 77f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 78fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes p.waitFor(); 79fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes p.destroy(); 80fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes public void test_getErrorStream() throws Exception { 83fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String[] commands = { "cat", "--no-such-option"}; 84fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Process p = Runtime.getRuntime().exec(commands, null, null); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 86fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes p.getOutputStream().close(); 87f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 88fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String received = readAndCloseStream(p.getInputStream()); 89fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals("", received); 90f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 91fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String stderr = readAndCloseStream(p.getErrorStream()); 92432abb6e8635e3dcac46648e158b5dc2c71b84fcNarayan Kamath assertTrue(stderr, stderr.contains("no-such-option")); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes p.waitFor(); 95fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes p.destroy(); 96fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 97f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 98fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes private String readAndCloseStream(InputStream is) throws IOException { 99fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes StringBuffer result = new StringBuffer(); 100fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes while (true) { 101fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes int c = is.read(); 102fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes if (c == -1) { 103fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes break; 104fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 105fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes result.append((char) c); 106fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 107fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes is.close(); 108fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes return result.toString(); 109fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 110fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 111fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes public void test_exitValue() throws Exception { 112da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin String[] commands = { "sh", "-c", "exit 0" }; 113fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Process process = Runtime.getRuntime().exec(commands, null, null); 114fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.waitFor(); 115fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertEquals(0, process.exitValue()); 116fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 117da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin String[] commandsNonZeroExit = { "sh", "-c", "exit 34" }; 118da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin process = Runtime.getRuntime().exec(commandsNonZeroExit, null, null); 119da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin process.waitFor(); 120da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin assertEquals(34, process.exitValue()); 121da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin 122fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes String[] commandsSleep = { "sleep", "3000" }; 123fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process = Runtime.getRuntime().exec(commandsSleep, null, null); 124fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.destroy(); 125fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.waitFor(); // destroy is asynchronous. 126fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes assertTrue(process.exitValue() != 0); 127fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 128fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process = Runtime.getRuntime().exec(new String[] { "sleep", "3000" }, null, null); 129fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes try { 130fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.exitValue(); 131fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes fail(); 132fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } catch(IllegalThreadStateException expected) { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 134fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 135fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes 136fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes public void test_destroy() throws Exception { 137da57c8f771867837ebdbc6047180595dfdd013d7Paul Duffin String[] commands = { "sh", "-c", "exit 0"}; 138fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes Process process = Runtime.getRuntime().exec(commands, null, null); 139fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.destroy(); 140fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.destroy(); 141fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes process.destroy(); 142fd6fca42f9be9cf158cd6dd2e4c426f20d0e426fElliott Hughes } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 144